diff --git a/SQL/database_changelog.md b/SQL/database_changelog.md index ae588adf65de5b..b0f6ad08b25559 100644 --- a/SQL/database_changelog.md +++ b/SQL/database_changelog.md @@ -2,7 +2,7 @@ Any time you make a change to the schema files, remember to increment the databa Make sure to also update `DB_MAJOR_VERSION` and `DB_MINOR_VERSION`, which can be found in `code/__DEFINES/subsystem.dm`. -The latest database version is 5.25 (5.24 for /tg/); The query to update the schema revision table is: +The latest database version is 5.27 (5.25 for /tg/); The query to update the schema revision table is: ```sql INSERT INTO `schema_revision` (`major`, `minor`) VALUES (5, 25); @@ -15,6 +15,13 @@ INSERT INTO `SS13_schema_revision` (`major`, `minor`) VALUES (5, 25); In any query remember to add a prefix to the table names if you use one. +----------------------------------------------------- +Version 5.27, 27 September 2023, by Jimmyl +Removes the text_adventures table because it is no longer used +```sql + DROP TABLE IF EXISTS `text_adventures`; +``` + ----------------------------------------------------- Version 5.26, 17 May 2023, by LemonInTheDark Modified the library action table to fit ckeys properly, and to properly store ips. diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index ecc615880e86f3..0637e0da6f60c0 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -660,19 +660,6 @@ CREATE TABLE `game_log` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; --- --- Table structure for table `text_adventures` --- -DROP TABLE IF EXISTS `text_adventures`; -CREATE TABLE `text_adventures` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `adventure_data` LONGTEXT NOT NULL, - `uploader` VARCHAR(32) NOT NULL, - `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `approved` TINYINT(1) NOT NULL DEFAULT FALSE, - PRIMARY KEY (`id`) -) ENGINE=InnoDB; - -- -- Table structure for table `admin_connections` -- diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index 659162158ec985..37c370f875ad18 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -644,19 +644,6 @@ CREATE TABLE `SS13_discord_links` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB; --- --- Table structure for table `text_adventures` --- -DROP TABLE IF EXISTS `SS13_text_adventures`; -CREATE TABLE `SS13_text_adventures` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `adventure_data` LONGTEXT NOT NULL, - `uploader` VARCHAR(32) NOT NULL, - `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `approved` TINYINT(1) NOT NULL DEFAULT FALSE, - PRIMARY KEY (`id`) -) ENGINE=InnoDB; - -- -- Table structure for table `admin_connections` -- diff --git a/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm b/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm index 0330ddf80317b0..e89864fdc7ce1f 100644 --- a/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm +++ b/_maps/RandomRuins/IceRuins/skyrat/icemoon_underground_syndicate_base1_skyrat.dmm @@ -123,6 +123,14 @@ }, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) +"aP" = ( +/obj/structure/frame/machine{ + anchored = 1; + state = 2; + icon_state = "box_1" + }, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/testlab) "aT" = ( /obj/structure/table/glass, /obj/machinery/reagentgrinder{ @@ -152,17 +160,13 @@ /turf/open/floor/catwalk_floor/iron, /area/ruin/syndicate_lava_base/dormitories) "bd" = ( -/obj/structure/table/reinforced, /obj/machinery/light/directional/south, -/obj/effect/spawner/random/food_or_drink/donkpockets{ - pixel_y = 7; - pixel_x = 10 - }, -/obj/item/storage/box/donkpockets{ - pixel_y = 5; - pixel_x = -7 +/obj/structure/closet/secure_closet/freezer/kitchen{ + req_access = list("syndicate") }, -/turf/open/floor/iron/kitchen, +/obj/item/reagent_containers/condiment/milk, +/obj/item/reagent_containers/condiment/soymilk, +/turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/bar) "bf" = ( /obj/structure/rack, @@ -200,8 +204,10 @@ }, /area/ruin/syndicate_lava_base/cargo) "bu" = ( -/obj/machinery/processor, -/turf/open/floor/iron/dark/smooth_large, +/obj/machinery/button/door/directional/west{ + id = "interdynekitchen" + }, +/turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "bv" = ( /obj/machinery/door/airlock/command{ @@ -241,10 +247,6 @@ /obj/effect/turf_decal/box/white, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) -"bL" = ( -/obj/machinery/autolathe/hacked, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/testlab) "bM" = ( /obj/effect/turf_decal/siding/thinplating/corner{ dir = 1 @@ -359,6 +361,14 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) +"cl" = ( +/obj/machinery/airalarm/directional/south, +/obj/machinery/hydroponics/constructable, +/obj/machinery/door/window/survival_pod{ + dir = 1 + }, +/turf/open/floor/grass, +/area/ruin/syndicate_lava_base/bar) "cm" = ( /obj/structure/filingcabinet, /obj/item/folder/syndicate/mining, @@ -366,11 +376,22 @@ dir = 8 }, /area/ruin/syndicate_lava_base/main) +"cn" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "cu" = ( /turf/open/floor/iron/dark/textured_corner{ dir = 4 }, /area/ruin/syndicate_lava_base/bar) +"cw" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/wood/tile, +/area/ruin/syndicate_lava_base/dormitories) "cx" = ( /obj/effect/turf_decal/tile/dark_blue, /obj/structure/disposalpipe/segment{ @@ -384,14 +405,6 @@ }, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) -"cK" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "cN" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /obj/effect/turf_decal/stripes/blue{ @@ -512,12 +525,6 @@ }, /turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) -"dp" = ( -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 8 - }, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) "ds" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -575,6 +582,14 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) +"dN" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 5 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/kitchen, +/area/ruin/syndicate_lava_base/bar) "dO" = ( /obj/machinery/light/directional/north, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -600,12 +615,16 @@ /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) "dS" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/siding/thinplating/dark{ +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 1 + }, +/obj/effect/turf_decal/siding/thinplating/dark/corner{ dir = 8 }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/siding/thinplating/dark/corner, /turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) "dT" = ( @@ -745,6 +764,7 @@ /obj/structure/disposalpipe/trunk{ dir = 1 }, +/obj/effect/turf_decal/siding/thinplating/dark/corner, /turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "eZ" = ( @@ -760,6 +780,11 @@ }, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/medbay) +"fg" = ( +/obj/structure/table/glass, +/obj/item/stack/cable_coil, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) "fq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -824,16 +849,8 @@ dir = 4 }, /area/ruin/syndicate_lava_base/main) -"fU" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "ge" = ( /obj/machinery/griddle, -/obj/machinery/firealarm/directional/north, /turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/bar) "gh" = ( @@ -851,12 +868,6 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) -"gk" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/light_switch/directional/north, -/turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/testlab) "gm" = ( /obj/structure/bookcase/random/reference, /turf/open/floor/wood/tile, @@ -951,14 +962,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/dormitories) -"gW" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/stone, -/area/ruin/syndicate_lava_base/bar) "gY" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -970,10 +973,13 @@ /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) "gZ" = ( -/obj/machinery/griddle, /obj/machinery/airalarm/directional/north{ req_access = list("syndicate") }, +/obj/machinery/microwave{ + pixel_y = 9 + }, +/obj/structure/table/reinforced, /turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/bar) "ha" = ( @@ -988,18 +994,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) -"hf" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/obj/machinery/light_switch/directional/north, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) -"hp" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 +"hr" = ( +/obj/machinery/hydroponics/constructable, +/obj/machinery/door/window/survival_pod{ + dir = 1 }, -/obj/item/storage/toolbox/mechanical, -/turf/open/floor/plating/icemoon, -/area/ruin/syndicate_lava_base/cargo) +/turf/open/floor/grass, +/area/ruin/syndicate_lava_base/bar) "ht" = ( /obj/structure/railing, /obj/structure/rack/shelf, @@ -1013,9 +1014,6 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, -/obj/machinery/airalarm/directional/north{ - req_access = list("syndicate") - }, /obj/machinery/vending/autodrobe{ onstation = 0 }, @@ -1040,19 +1038,14 @@ dir = 4 }, /obj/structure/window/reinforced/survival_pod/spawner/directional/east, +/obj/structure/closet/crate/freezer/blood, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/medbay) -"hJ" = ( -/obj/effect/turf_decal/siding/thinplating/dark/corner, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) "hL" = ( /obj/effect/turf_decal/siding/thinplating/dark{ dir = 1 }, -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 8 - }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "hT" = ( @@ -1067,6 +1060,10 @@ dir = 1 }, /area/ruin/syndicate_lava_base/cargo) +"ie" = ( +/obj/machinery/light/small/directional/east, +/turf/open/floor/iron/checker, +/area/ruin/syndicate_lava_base/bar) "ih" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, @@ -1243,8 +1240,9 @@ /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) "jy" = ( -/obj/structure/table/reinforced, -/obj/item/storage/bag/tray, +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 6 + }, /turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "jA" = ( @@ -1319,6 +1317,13 @@ }, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) +"kb" = ( +/obj/structure/lattice/catwalk, +/obj/structure/railing{ + dir = 9 + }, +/turf/open/lava/plasma/ice_moon, +/area/ruin/syndicate_lava_base/testlab) "kc" = ( /obj/structure/toilet{ dir = 4 @@ -1344,10 +1349,10 @@ /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) "kl" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/siding/thinplating/dark{ +/obj/effect/turf_decal/siding/thinplating/dark/corner{ dir = 4 }, +/obj/effect/turf_decal/siding/thinplating/dark/corner, /turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) "km" = ( @@ -1409,9 +1414,6 @@ /turf/closed/wall/r_wall/syndicate/nodiagonal, /area/ruin/syndicate_lava_base/main) "kU" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, @@ -1424,8 +1426,11 @@ /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/medbay) "kZ" = ( -/obj/machinery/vending/dinnerware, -/turf/open/floor/iron/dark/smooth_large, +/obj/machinery/firealarm/directional/west{ + dir = 4; + pixel_x = -28 + }, +/turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "lb" = ( /obj/effect/turf_decal/stripes/line{ @@ -1438,6 +1443,12 @@ }, /turf/open/floor/plating/icemoon, /area/ruin/syndicate_lava_base/medbay) +"lc" = ( +/obj/structure/chair/sofa/left/maroon{ + dir = 8 + }, +/turf/open/floor/wood/tile, +/area/ruin/syndicate_lava_base/dormitories) "lj" = ( /obj/structure/cable, /turf/open/floor/catwalk_floor/iron_dark, @@ -1471,9 +1482,7 @@ /area/ruin/syndicate_lava_base/cargo) "lP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/chair/sofa/left/brown{ - dir = 1 - }, +/obj/structure/bookcase/random/nonfiction, /turf/open/floor/wood/tile, /area/ruin/syndicate_lava_base/dormitories) "lT" = ( @@ -1503,8 +1512,7 @@ /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) "mg" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/siding/thinplating/dark, /turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) "mp" = ( @@ -1513,6 +1521,13 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) +"mr" = ( +/obj/structure/reagent_dispensers/watertank/high, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "my" = ( /obj/machinery/door/airlock/research{ name = "Xenobiology Lab" @@ -1553,10 +1568,11 @@ /area/ruin/syndicate_lava_base/testlab) "nb" = ( /obj/machinery/light/directional/west, +/obj/structure/closet/crate/bin, /turf/open/floor/iron/checker, /area/ruin/syndicate_lava_base/bar) "nc" = ( -/obj/structure/bookcase/random/nonfiction, +/obj/structure/chair/sofa/right/maroon, /turf/open/floor/wood/tile, /area/ruin/syndicate_lava_base/dormitories) "nd" = ( @@ -1651,21 +1667,16 @@ /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) "nP" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/obj/machinery/vending/hydronutrients{ - onstation = 0 +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 1 }, -/turf/open/floor/iron/dark/smooth_large, +/obj/effect/turf_decal/siding/thinplating/dark, +/turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) "nS" = ( /turf/open/floor/iron/checker, /area/ruin/syndicate_lava_base/bar) "nT" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, /obj/structure/disposalpipe/segment{ dir = 10 }, @@ -1703,6 +1714,14 @@ /obj/structure/chair/sofa/bench/right, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) +"oj" = ( +/obj/structure/table/reinforced, +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 4 + }, +/obj/item/storage/bag/tray, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/bar) "ol" = ( /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) @@ -1715,7 +1734,7 @@ /turf/open/floor/wood, /area/ruin/syndicate_lava_base/dormitories) "ov" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/testlab) "ox" = ( @@ -1808,6 +1827,12 @@ /obj/structure/window/reinforced/survival_pod/spawner/directional/east, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/medbay) +"oZ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/light/directional/south, +/turf/open/floor/wood/tile, +/area/ruin/syndicate_lava_base/dormitories) "pc" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -1818,16 +1843,11 @@ /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/virology) "pe" = ( -/obj/machinery/door/airlock/grunge{ - name = "Bar" - }, -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 1 +/obj/machinery/chem_master/condimaster{ + name = "BrewMaster 3000" }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, -/turf/open/floor/stone, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/dark/small, /area/ruin/syndicate_lava_base/bar) "pg" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -1903,20 +1923,13 @@ /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) "pK" = ( -/obj/effect/turf_decal/siding/thinplating/dark/end{ - dir = 4 - }, -/obj/structure/table/reinforced, -/obj/machinery/door/firedoor, -/obj/machinery/door/window/survival_pod{ - dir = 4; - req_access = list("syndicate") - }, -/obj/machinery/door/window/survival_pod{ - dir = 8; - req_access = list("syndicate") +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/door/airlock/public/glass{ + name = "Kitchen-Botany" }, -/turf/open/floor/iron/kitchen, +/turf/open/floor/iron/dark/small, /area/ruin/syndicate_lava_base/bar) "pN" = ( /obj/effect/turf_decal/stripes/line{ @@ -1925,11 +1938,6 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) -"pP" = ( -/obj/machinery/hydroponics/constructable, -/obj/machinery/airalarm/directional/south, -/turf/open/misc/grass, -/area/ruin/syndicate_lava_base/bar) "pU" = ( /obj/machinery/camera/autoname/directional/west{ network = list("intd13") @@ -1974,10 +1982,13 @@ /turf/open/floor/iron/showroomfloor, /area/ruin/syndicate_lava_base/cargo) "qC" = ( -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 1 - }, /obj/machinery/light/directional/south, +/obj/structure/table, +/obj/machinery/fax{ + fax_name = "Interdyne Pharmaceuticals"; + pixel_y = 7; + name = "Interdyne Fax Machine" + }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/testlab) "qH" = ( @@ -1989,7 +2000,8 @@ dir = 1 }, /obj/machinery/door/airlock{ - name = "Cabin 2" + name = "Cabin 2"; + id_tag = "IDynbin2" }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -2000,11 +2012,6 @@ /obj/machinery/computer/libraryconsole/bookmanagement, /turf/open/floor/wood/large, /area/ruin/syndicate_lava_base/dormitories) -"qT" = ( -/obj/structure/sink/directional/west, -/obj/structure/mirror/directional/east, -/turf/open/floor/iron/checker, -/area/ruin/syndicate_lava_base/bar) "qU" = ( /obj/machinery/light/directional/north, /turf/open/floor/iron/dark, @@ -2040,6 +2047,12 @@ }, /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) +"ry" = ( +/obj/machinery/vending/hydroseeds{ + onstation = 0 + }, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "rD" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -2118,12 +2131,7 @@ /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) "sm" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/siding/thinplating/dark/end, /turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) "so" = ( @@ -2145,14 +2153,13 @@ "ss" = ( /obj/structure/table/wood, /obj/machinery/light/directional/west, -/obj/item/key/atv, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) "st" = ( -/obj/structure/table/reinforced, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 }, +/obj/machinery/anesthetic_machine, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/medbay) "sv" = ( @@ -2160,6 +2167,14 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/smooth_large, /area/ruin/syndicate_lava_base/cargo) +"sA" = ( +/obj/machinery/door/airlock{ + name = "Unisex Restroom"; + id_tag = "IDyneWC" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/bar) "sB" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -2297,18 +2312,22 @@ /turf/open/floor/plating, /area/ruin/syndicate_lava_base/bar) "tS" = ( -/obj/structure/closet/secure_closet/freezer/kitchen{ - req_access = list("syndicate") +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 4 }, -/obj/item/reagent_containers/condiment/milk, -/obj/item/reagent_containers/condiment/soymilk, -/obj/structure/window/reinforced/survival_pod/spawner/directional/south, -/turf/open/floor/iron/dark/smooth_large, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "tT" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/button/door/directional/east{ + specialfunctions = 4; + normaldoorcontrol = 1; + name = "Dorm Bolt Control"; + id = "IDyneDO" + }, /turf/open/floor/carpet/orange, /area/ruin/syndicate_lava_base/cargo) "ub" = ( @@ -2377,6 +2396,14 @@ /obj/structure/table/reinforced, /obj/item/storage/backpack/duffelbag/syndie/surgery, /obj/machinery/airalarm/directional/north, +/obj/item/healthanalyzer{ + pixel_x = -5; + pixel_y = 5 + }, +/obj/item/clothing/mask/breath/anesthetic{ + pixel_x = 8; + pixel_y = 5 + }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/medbay) "uB" = ( @@ -2410,12 +2437,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) -"vi" = ( -/obj/structure/chair/sofa/right/brown{ - dir = 8 - }, -/turf/open/floor/wood/tile, -/area/ruin/syndicate_lava_base/dormitories) "vl" = ( /obj/structure/sign/departments/chemistry/directional/east, /obj/structure/table/glass, @@ -2425,10 +2446,8 @@ /obj/item/storage/box/beakers/bluespace, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) -"vo" = ( -/obj/structure/chair/sofa/corp/left{ - dir = 1 - }, +"vo" = ( +/obj/effect/spawner/random/vending/snackvend, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) "vq" = ( @@ -2446,13 +2465,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) -"vw" = ( -/obj/structure/frame/computer{ - dir = 4; - anchored = 1 - }, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/testlab) "vy" = ( /obj/machinery/button/door/directional/north{ pixel_y = 34; @@ -2462,8 +2474,8 @@ /turf/open/floor/carpet/royalblack, /area/ruin/syndicate_lava_base/telecomms) "vz" = ( -/obj/structure/closet/crate/bin, -/obj/item/soap/syndie, +/obj/machinery/shower/directional/north, +/obj/structure/curtain, /turf/open/floor/iron/checker, /area/ruin/syndicate_lava_base/bar) "vB" = ( @@ -2542,6 +2554,13 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) +"wm" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/window/reinforced/plasma/spawner/directional/east, +/turf/open/floor/plating, +/area/ruin/syndicate_lava_base/cargo) "wn" = ( /obj/machinery/porta_turret/syndicate{ dir = 10; @@ -2626,6 +2645,14 @@ dir = 8 }, /obj/effect/turf_decal/tile/dark_blue, +/obj/item/storage/box/medipens{ + pixel_x = 4; + pixel_y = 13 + }, +/obj/item/reagent_containers/cup/beaker/cryoxadone{ + pixel_x = -6; + pixel_y = 10 + }, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) "wX" = ( @@ -2672,8 +2699,22 @@ "xo" = ( /obj/item/bedsheet/dorms_double, /obj/structure/bed/double, +/obj/machinery/button/door/directional/east{ + specialfunctions = 4; + normaldoorcontrol = 1; + name = "Dorm Bolt Control"; + id = "IDyneBeta" + }, /turf/open/floor/iron/smooth_large, /area/ruin/syndicate_lava_base/cargo) +"xq" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "xs" = ( /obj/machinery/door/airlock/medical/glass{ name = "Pharmacy"; @@ -2742,10 +2783,8 @@ /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) "yi" = ( -/obj/machinery/door/airlock{ - name = "Unisex Toilet"; - id_tag = "interdynerec1" - }, +/obj/structure/sink/directional/south, +/obj/structure/mirror/directional/north, /turf/open/floor/iron/checker, /area/ruin/syndicate_lava_base/bar) "yn" = ( @@ -2768,7 +2807,8 @@ /area/ruin/syndicate_lava_base/cargo) "yu" = ( /obj/machinery/door/airlock/mining{ - name = "Shaft Miner Dormitory Beta" + name = "Shaft Miner Dormitory Beta"; + id_tag = "IDyneBeta" }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -2797,12 +2837,10 @@ /turf/closed/wall/r_wall/syndicate, /area/ruin/syndicate_lava_base/testlab) "yF" = ( -/obj/structure/frame/machine{ - anchored = 1; - state = 2; - icon_state = "box_1" +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 1 }, -/turf/open/floor/iron/dark/smooth_large, +/turf/open/floor/iron, /area/ruin/syndicate_lava_base/testlab) "yG" = ( /obj/machinery/camera/autoname/directional/east{ @@ -2810,24 +2848,16 @@ }, /turf/open/lava/plasma/ice_moon, /area/ruin/syndicate_lava_base/dormitories) -"yH" = ( -/obj/effect/turf_decal/stripes/corner, -/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, -/obj/machinery/door/airlock{ - name = "Unisex Restrooms" - }, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/bar) "yJ" = ( -/obj/structure/sink/directional/west, -/turf/open/misc/grass, +/obj/machinery/smartfridge/food, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/dark/small, /area/ruin/syndicate_lava_base/bar) "yM" = ( -/obj/effect/turf_decal/siding/thinplating/dark, /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/north, /obj/effect/mapping_helpers/apc/syndicate_access, -/turf/open/floor/iron, +/turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/testlab) "yP" = ( /obj/structure/chair{ @@ -2884,8 +2914,13 @@ /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) "zq" = ( -/obj/machinery/hydroponics/constructable, -/turf/open/misc/grass, +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/machinery/light/directional/east, +/obj/effect/turf_decal/siding/thinplating/dark, +/turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) "zu" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/west, @@ -2954,13 +2989,6 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) -"Au" = ( -/obj/structure/table/reinforced, -/obj/item/book/manual/wiki/cooking_to_serve_man{ - pixel_y = 2 - }, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "AC" = ( /obj/effect/mob_spawn/ghost_role/human/lavaland_syndicate/shaftminer/ice, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -3021,7 +3049,7 @@ /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) "BB" = ( -/obj/machinery/biogenerator, +/obj/structure/table, /turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/bar) "BC" = ( @@ -3087,7 +3115,9 @@ /turf/open/floor/plating, /area/ruin/syndicate_lava_base/engineering) "Ca" = ( -/obj/structure/filingcabinet, +/obj/machinery/vending/syndichem{ + onstation = 0 + }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/medbay) "Cc" = ( @@ -3125,6 +3155,9 @@ /obj/machinery/light/directional/west, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) +"CA" = ( +/turf/open/floor/grass, +/area/ruin/syndicate_lava_base/bar) "CC" = ( /obj/structure/table, /turf/open/floor/iron/dark, @@ -3240,10 +3273,20 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) +"DC" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 4 + }, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) "DE" = ( /obj/structure/table, /turf/open/floor/iron/smooth_large, /area/ruin/syndicate_lava_base/cargo) +"DG" = ( +/obj/item/clothing/mask/gas/syndicate, +/turf/closed/wall/r_wall/syndicate/nodiagonal, +/area/ruin/syndicate_lava_base/main) "DH" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -3278,9 +3321,6 @@ /area/ruin/syndicate_lava_base/main) "DY" = ( /obj/item/storage/toolbox/syndicate, -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/testlab) @@ -3336,6 +3376,11 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) +"EJ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "EK" = ( /obj/machinery/camera/autoname/directional/north{ network = list("intd13") @@ -3354,11 +3399,8 @@ /turf/open/floor/plating, /area/ruin/syndicate_lava_base/bar) "EO" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, /obj/effect/decal/cleanable/oil/streak, -/turf/open/floor/plating/icemoon, +/turf/open/floor/plating, /area/ruin/syndicate_lava_base/cargo) "EP" = ( /obj/machinery/door/firedoor, @@ -3401,13 +3443,6 @@ dir = 8 }, /area/ruin/syndicate_lava_base/medbay) -"Fa" = ( -/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, -/obj/machinery/door/airlock{ - name = "Unisex Restrooms" - }, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/bar) "Fi" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/disposalpipe/segment{ @@ -3473,6 +3508,12 @@ }, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/dormitories) +"Fq" = ( +/obj/structure/table/glass, +/obj/structure/towel_bin, +/obj/item/soap/syndie, +/turf/open/floor/iron/checker, +/area/ruin/syndicate_lava_base/bar) "Fu" = ( /obj/machinery/light/directional/west, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -3488,7 +3529,8 @@ dir = 4 }, /obj/machinery/door/airlock{ - name = "Cabin 4" + name = "Cabin 4"; + id_tag = "IDynbin4" }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -3502,7 +3544,8 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/door/airlock/mining{ - name = "Shaft Miner Dormitory Beta" + name = "Shaft Miner Dormitory Charlie"; + id_tag = "IDyneCharlie" }, /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/iron/dark, @@ -3577,11 +3620,15 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) +"FV" = ( +/obj/structure/table/reinforced, +/obj/machinery/processor, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/bar) "FW" = ( -/obj/structure/chair/office/light{ - dir = 1 - }, /obj/effect/turf_decal/siding/thinplating/dark/corner, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) "Gb" = ( @@ -3611,6 +3658,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/smooth_large, /area/ruin/syndicate_lava_base/cargo) +"Gp" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) "Gr" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -3679,6 +3732,13 @@ /area/ruin/syndicate_lava_base/engineering) "He" = ( /obj/structure/table/reinforced, +/obj/item/reagent_containers/condiment/enzyme{ + pixel_y = 8 + }, +/obj/item/reagent_containers/condiment/peppermill{ + pixel_x = 6 + }, +/obj/item/reagent_containers/condiment/saltshaker, /turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "Hn" = ( @@ -3700,6 +3760,8 @@ /area/ruin/syndicate_lava_base/testlab) "Hx" = ( /obj/effect/turf_decal/siding/thinplating/dark, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) "Hy" = ( @@ -3805,6 +3867,19 @@ dir = 8 }, /area/ruin/syndicate_lava_base/cargo) +"Ip" = ( +/obj/machinery/button/door/directional/west{ + id = "IDyneWC"; + normaldoorcontrol = 1; + specialfunctions = 4; + name = "Door Lock" + }, +/obj/machinery/dryer{ + pixel_x = 8; + pixel_y = 20 + }, +/turf/open/floor/iron/checker, +/area/ruin/syndicate_lava_base/bar) "Is" = ( /obj/machinery/camera/autoname/directional/east{ network = list("intd13") @@ -3850,15 +3925,7 @@ /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/medbay) "IP" = ( -/obj/structure/table/reinforced, -/obj/item/kitchen/rollingpin, -/obj/item/reagent_containers/condiment/saltshaker, -/obj/item/reagent_containers/condiment/peppermill{ - pixel_x = 6 - }, -/obj/item/reagent_containers/condiment/enzyme{ - pixel_y = 8 - }, +/obj/effect/turf_decal/siding/thinplating/dark, /turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "IS" = ( @@ -3882,15 +3949,13 @@ /turf/open/floor/plating, /area/ruin/syndicate_lava_base/cargo) "Jq" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, /obj/machinery/chem_dispenser/mutagensaltpeter, /turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/bar) "Jx" = ( /obj/machinery/door/airlock{ - name = "Bedroom" + name = "Bedroom"; + id_tag = "IDyneDO" }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -3997,13 +4062,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) -"Kv" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, -/obj/effect/turf_decal/siding/thinplating/dark/corner, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "Kz" = ( /obj/structure/sign/departments/science/directional/west, /turf/open/floor/iron, @@ -4018,9 +4076,7 @@ /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/north, /obj/effect/mapping_helpers/apc/syndicate_access, -/obj/machinery/vending/syndichem{ - onstation = 0 - }, +/obj/structure/filingcabinet, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) "KD" = ( @@ -4038,7 +4094,7 @@ dir = 1 }, /turf/open/floor/iron/large, -/area/ruin/syndicate_lava_base/main) +/area/ruin/syndicate_lava_base/telecomms) "KP" = ( /turf/open/floor/iron/smooth_edge{ dir = 8 @@ -4059,6 +4115,21 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) +"KY" = ( +/obj/machinery/button/flasher{ + id = "IDyneBrigFlash"; + pixel_x = 6; + pixel_y = 34 + }, +/obj/machinery/button/door/directional/north{ + id = "IDyneBrig"; + normaldoorcontrol = 1; + name = "Brig Bolt Control"; + specialfunctions = 4; + req_access = list("syndicate") + }, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/main) "Lc" = ( /obj/structure/frame/machine{ anchored = 1; @@ -4073,10 +4144,8 @@ /turf/open/floor/plating, /area/ruin/syndicate_lava_base/bar) "Ld" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 4 +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 6 }, /turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) @@ -4094,9 +4163,9 @@ /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/testlab) "Lg" = ( -/obj/structure/reagent_dispensers/watertank/high, /obj/machinery/light/directional/east, -/turf/open/misc/grass, +/obj/machinery/hydroponics/constructable, +/turf/open/floor/grass, /area/ruin/syndicate_lava_base/bar) "Lh" = ( /obj/structure/fans/tiny, @@ -4114,7 +4183,9 @@ /obj/effect/turf_decal/siding/thinplating/dark{ dir = 1 }, -/obj/effect/turf_decal/siding/thinplating/dark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, /turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "Lm" = ( @@ -4140,6 +4211,10 @@ }, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/bar) +"LB" = ( +/obj/machinery/autolathe/hacked, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/testlab) "LC" = ( /obj/machinery/conveyor{ id = "interdynedisp" @@ -4147,11 +4222,13 @@ /turf/open/floor/plating, /area/ruin/syndicate_lava_base/bar) "LD" = ( -/obj/machinery/hydroponics/constructable, /obj/machinery/firealarm/directional/east{ dir = 8 }, -/turf/open/misc/grass, +/obj/machinery/vending/hydronutrients{ + onstation = 0 + }, +/turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) "LK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -4218,8 +4295,13 @@ }, /area/ruin/syndicate_lava_base/medbay) "Mp" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 +/obj/machinery/light_switch/directional/south, +/obj/structure/table, +/obj/item/paper_bin{ + pixel_y = 4 + }, +/obj/item/pen{ + pixel_y = 4 }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/testlab) @@ -4246,7 +4328,8 @@ "MC" = ( /obj/effect/turf_decal/siding/wood, /obj/machinery/door/airlock{ - name = "Cabin 1" + name = "Cabin 1"; + id_tag = "IDynbin1" }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -4276,8 +4359,11 @@ /turf/open/floor/catwalk_floor/iron, /area/ruin/syndicate_lava_base/main) "MP" = ( -/obj/effect/turf_decal/siding/thinplating/dark, -/turf/open/floor/iron, +/obj/structure/frame/computer{ + anchored = 1; + dir = 4 + }, +/turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/testlab) "MR" = ( /obj/structure/window/reinforced/tinted/spawner/directional/south, @@ -4309,6 +4395,12 @@ /area/ruin/syndicate_lava_base/medbay) "Nv" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/button/door/directional/west{ + specialfunctions = 4; + id = "IDyneDelta"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1 + }, /turf/open/floor/iron/smooth_edge{ dir = 4 }, @@ -4338,18 +4430,11 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndicate_lava_base/cargo) -"NN" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 4 - }, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "NS" = ( -/obj/structure/table/reinforced, -/obj/machinery/microwave{ - pixel_y = 9 +/obj/structure/closet/secure_closet/freezer/meat{ + req_access = list("syndicate") }, -/turf/open/floor/iron/kitchen, +/turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/bar) "NV" = ( /obj/effect/turf_decal/siding/thinplating{ @@ -4371,6 +4456,9 @@ /obj/machinery/light/directional/north, /obj/structure/table/glass, /obj/structure/bedsheetbin, +/obj/machinery/airalarm/directional/north{ + req_access = list("syndicate") + }, /turf/open/floor/iron/cafeteria, /area/ruin/syndicate_lava_base/dormitories) "Oe" = ( @@ -4399,6 +4487,18 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) +"Ou" = ( +/obj/structure/table/reinforced, +/obj/effect/spawner/random/food_or_drink/donkpockets{ + pixel_y = 7; + pixel_x = 10 + }, +/obj/item/storage/box/donkpockets{ + pixel_y = 5; + pixel_x = -7 + }, +/turf/open/floor/iron/kitchen, +/area/ruin/syndicate_lava_base/bar) "Ov" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/north, /obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored{ @@ -4434,11 +4534,17 @@ /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) "OH" = ( -/obj/structure/chair/sofa/corp/right{ - dir = 1 +/obj/machinery/vending/cigarette/syndicate{ + onstation = 0 }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) +"OI" = ( +/obj/machinery/vending/dinnerware{ + onstation = 0 + }, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/bar) "ON" = ( /obj/machinery/limbgrower, /obj/effect/turf_decal/tile/blue{ @@ -4606,12 +4712,6 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/medbay) -"Qe" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "Qi" = ( /obj/structure/sink/directional/west, /obj/structure/mirror/directional/east, @@ -4646,9 +4746,12 @@ /obj/effect/turf_decal/stripes/corner{ dir = 4 }, -/obj/machinery/door/airlock/maintenance/external, /obj/structure/fans/tiny, /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/security/old{ + name = "Brig Hold"; + id_tag = "IDyneBrig" + }, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/cargo) "QN" = ( @@ -4659,14 +4762,6 @@ /obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/dormitories) -"Rc" = ( -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "Rd" = ( /obj/effect/turf_decal/siding/thinplating/dark/corner{ dir = 8 @@ -4677,12 +4772,9 @@ /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) -"Re" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/decal/cleanable/oil, -/turf/open/floor/plating/icemoon, +"Re" = ( +/obj/structure/bed/maint, +/turf/open/floor/plating, /area/ruin/syndicate_lava_base/cargo) "Rl" = ( /obj/structure/railing, @@ -4767,8 +4859,15 @@ /turf/closed/wall/r_wall/syndicate/nodiagonal, /area/ruin/syndicate_lava_base/cargo) "RZ" = ( -/obj/structure/lattice/catwalk, -/turf/open/lava/plasma/ice_moon, +/obj/machinery/flasher/directional/south{ + pixel_x = -6; + id = "IDyneBrigFlash" + }, +/turf/open/floor/plating, +/area/ruin/syndicate_lava_base/cargo) +"Sb" = ( +/obj/effect/decal/cleanable/oil, +/turf/open/floor/plating, /area/ruin/syndicate_lava_base/cargo) "Sd" = ( /obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, @@ -4818,13 +4917,6 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) -"Sy" = ( -/obj/machinery/disposal/bin, -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/turf/open/misc/grass, -/area/ruin/syndicate_lava_base/bar) "SG" = ( /obj/structure/sign/departments/cargo/directional/north, /turf/open/floor/iron, @@ -4837,10 +4929,6 @@ /obj/structure/cable, /turf/open/floor/carpet/royalblack, /area/ruin/syndicate_lava_base/telecomms) -"SI" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "SJ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -4855,7 +4943,8 @@ dir = 4 }, /obj/machinery/door/airlock{ - name = "Cabin 3" + name = "Cabin 3"; + id_tag = "IDynbin3" }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -4908,9 +4997,6 @@ /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) "Tl" = ( -/obj/machinery/button/door/directional/north{ - id = "interdynekitchen" - }, /obj/machinery/oven/range, /turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/bar) @@ -4958,13 +5044,6 @@ }, /turf/closed/wall/r_wall/syndicate/nodiagonal, /area/ruin/syndicate_lava_base/main) -"Tx" = ( -/obj/structure/window/reinforced/survival_pod/spawner/directional/north, -/obj/structure/closet/secure_closet/freezer/meat{ - req_access = list("syndicate") - }, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/bar) "TB" = ( /obj/machinery/light_switch/directional/west, /turf/open/floor/iron, @@ -5031,6 +5110,12 @@ "Uf" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/button/door/directional/north{ + name = "Dorm Bolt Control"; + id = "IDynbin4"; + normaldoorcontrol = 1; + specialfunctions = 4 + }, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/dormitories) "Uj" = ( @@ -5099,13 +5184,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/general/hidden, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/testlab) -"Vb" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/item/stack/rods/ten, -/turf/open/floor/plating/icemoon, -/area/ruin/syndicate_lava_base/cargo) "Ve" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/stripes/line, @@ -5152,10 +5230,29 @@ /obj/item/bedsheet/dorms_double, /turf/open/floor/iron/smooth_large, /area/ruin/syndicate_lava_base/cargo) +"Vu" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/button/door/directional/west{ + specialfunctions = 4; + id = "IDynbin1"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1 + }, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "Vy" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) +"Vz" = ( +/obj/machinery/hydroponics/constructable, +/turf/open/floor/grass, +/area/ruin/syndicate_lava_base/bar) +"VC" = ( +/obj/machinery/light/directional/south, +/turf/open/floor/grass, +/area/ruin/syndicate_lava_base/bar) "VE" = ( /obj/machinery/door/airlock/public/glass{ name = "Bar" @@ -5202,6 +5299,10 @@ }, /turf/closed/wall/r_wall/syndicate/nodiagonal, /area/ruin/syndicate_lava_base/medbay) +"VP" = ( +/obj/structure/chair/sofa/corner/maroon, +/turf/open/floor/wood/tile, +/area/ruin/syndicate_lava_base/dormitories) "VQ" = ( /obj/structure/fans/tiny, /obj/machinery/atmospherics/pipe/smart/manifold4w/general/hidden, @@ -5226,22 +5327,6 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) -"Wg" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/structure/chair/sofa/corner/brown{ - dir = 8 - }, -/obj/machinery/light/directional/south, -/turf/open/floor/wood/tile, -/area/ruin/syndicate_lava_base/dormitories) -"Wj" = ( -/obj/machinery/vending/hydroseeds{ - onstation = 0 - }, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/bar) "Wp" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -5249,11 +5334,19 @@ /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) "Wt" = ( -/obj/item/stack/cable_coil, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/catwalk_floor/iron_dark, +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 1 + }, +/turf/open/floor/iron, /area/ruin/syndicate_lava_base/testlab) +"Wu" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "Wx" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -5265,25 +5358,25 @@ /turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) "Wz" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/table/reinforced, +/obj/item/kitchen/rollingpin, /turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "WC" = ( -/obj/structure/lattice/catwalk, -/obj/structure/railing{ +/obj/effect/turf_decal/stripes/line{ dir = 4 }, -/turf/open/lava/plasma/ice_moon, +/obj/structure/window/reinforced/plasma/spawner/directional/east, +/obj/item/kirbyplants/random, +/turf/open/floor/plating, /area/ruin/syndicate_lava_base/cargo) "WD" = ( /turf/open/floor/plating, /area/ruin/syndicate_lava_base/engineering) "WE" = ( /obj/machinery/door/airlock/mining{ - name = "Shaft Miner Dormitory Alpha" + name = "Shaft Miner Dormitory Alpha"; + id_tag = "IDyneAlpha" }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -5318,15 +5411,21 @@ /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) +"WX" = ( +/obj/machinery/flasher/directional/north{ + id = "IDyneBrigFlash" + }, +/turf/open/floor/plating, +/area/ruin/syndicate_lava_base/cargo) "Xa" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, /obj/structure/frame/machine{ anchored = 1; state = 2; icon_state = "box_1" }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, /turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/testlab) "Xc" = ( @@ -5334,6 +5433,11 @@ /obj/structure/window/reinforced/survival_pod/spawner/directional/west, /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) +"Xh" = ( +/obj/machinery/biogenerator, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/dark/small, +/area/ruin/syndicate_lava_base/bar) "Xo" = ( /obj/machinery/smartfridge/organ, /obj/structure/railing, @@ -5346,9 +5450,15 @@ /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) "Xw" = ( -/obj/machinery/hydroponics/constructable, /obj/machinery/light/directional/west, -/turf/open/misc/grass, +/obj/machinery/firealarm/directional/west{ + dir = 4; + pixel_x = -28 + }, +/obj/structure/chair/office/light{ + dir = 1 + }, +/turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) "Xz" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/east, @@ -5395,13 +5505,11 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) -"XR" = ( -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) +"XP" = ( +/obj/structure/lattice/catwalk, +/obj/item/storage/toolbox/mechanical, +/turf/open/lava/plasma/ice_moon, +/area/ruin/syndicate_lava_base/testlab) "XS" = ( /obj/machinery/door/airlock/research{ name = "Science Division" @@ -5430,6 +5538,12 @@ /obj/structure/bed/double, /obj/item/bedsheet/dorms_double, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/machinery/button/door/directional/east{ + specialfunctions = 4; + normaldoorcontrol = 1; + name = "Dorm Bolt Control"; + id = "IDyneCharlie" + }, /turf/open/floor/iron/smooth_large, /area/ruin/syndicate_lava_base/cargo) "Ya" = ( @@ -5438,6 +5552,17 @@ /obj/effect/spawner/random/trash/grime, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/bar) +"Yb" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/button/door/directional/west{ + specialfunctions = 4; + id = "IDynbin2"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1 + }, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "Yc" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -5453,6 +5578,17 @@ }, /turf/open/floor/catwalk_floor/iron, /area/ruin/syndicate_lava_base/medbay) +"Yk" = ( +/obj/item/bedsheet/dorms_double, +/obj/structure/bed/double, +/obj/machinery/button/door/directional/east{ + specialfunctions = 4; + normaldoorcontrol = 1; + name = "Dorm Bolt Control"; + id = "IDyneAlpha" + }, +/turf/open/floor/iron/smooth_large, +/area/ruin/syndicate_lava_base/cargo) "Yl" = ( /obj/effect/mob_spawn/ghost_role/human/lavaland_syndicate, /obj/machinery/light/directional/north, @@ -5499,10 +5635,9 @@ /turf/open/floor/wood/large, /area/ruin/syndicate_lava_base/dormitories) "YI" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "YM" = ( @@ -5541,24 +5676,14 @@ /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) "Zh" = ( -/obj/structure/toilet{ - dir = 8 - }, -/obj/machinery/light/small/directional/north, -/obj/machinery/button/door/directional/east{ - id = "interdynerec1"; - normaldoorcontrol = 1; - specialfunctions = 4 - }, +/obj/structure/toilet, +/obj/structure/window/reinforced/tinted/spawner/directional/west, /turf/open/floor/iron/checker, /area/ruin/syndicate_lava_base/bar) "Zi" = ( /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) "Zj" = ( -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 4 - }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/light/directional/south, /turf/open/floor/iron, @@ -5574,11 +5699,32 @@ "Zo" = ( /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) +"Zp" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/button/door/directional/south{ + name = "Dorm Bolt Control"; + id = "IDynbin3"; + normaldoorcontrol = 1; + specialfunctions = 4 + }, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "Zr" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/east, /obj/structure/window/reinforced/survival_pod/spawner/directional/north, /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) +"Zw" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/door/airlock/mining{ + name = "Shaft Miner Dormitory Delta"; + id_tag = "IDyneDelta" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/cargo) "Zx" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, @@ -6038,7 +6184,7 @@ kf Mc LR dT -jo +fg Tn kf km @@ -6094,10 +6240,10 @@ ab ab ab VL -hJ GD GD GD +DC Zj kf YS @@ -6154,12 +6300,12 @@ ab ab VL MP -vw -yF +aP +LB yF DY kf -gk +kr kw Lf wa @@ -6271,10 +6417,10 @@ ab ab ab VL -MP -yF +aP +aP Xa -bL +yF Mp kf gA @@ -6330,10 +6476,10 @@ ab ab ab VL -dp LP -Eh LP +Eh +Gp qC kf sr @@ -6346,12 +6492,12 @@ PK zF YM xY -gT +Vu MC UO HU qK -gT +Yb xY Fo zF @@ -6389,7 +6535,7 @@ ab ab ab kf -hf +jo ov mG bk @@ -6432,7 +6578,7 @@ uQ tT UI RV -xo +Yk Io DE Bt @@ -6445,7 +6591,7 @@ sv RV ab ab -de +kb de kf kf @@ -6640,7 +6786,7 @@ nz gT zF eu -Uf +Zp zF hu xm @@ -6681,7 +6827,7 @@ Ym uw gj RV -eC +XP eC Pw VL @@ -6736,7 +6882,7 @@ Ci Am DZ RV -Fz +Zw RV RV RV @@ -6814,7 +6960,7 @@ ZU Uo up up -Ad +oZ zF dO iG @@ -6871,8 +7017,8 @@ DH WK ZU nc -eZ au +cw lP zF Jd @@ -6898,7 +7044,7 @@ aa ac ac ab -ab +AR RV RV RV @@ -6929,10 +7075,10 @@ Zo DH Zo ZU -tJ +VP +lc eZ -vi -Wg +tJ zF WS ZQ @@ -7097,7 +7243,7 @@ HL ci Fl WK -ZU +DG oc cP cY @@ -7225,7 +7371,7 @@ jA GA td td -td +sA td td td @@ -7267,8 +7413,8 @@ Wa Fk RV Re -Vb -hp +ag +ag EO QK Zo @@ -7282,8 +7428,8 @@ FU Zo jA Zo -yH -nS +td +Ip nS nb vt @@ -7325,12 +7471,12 @@ mp Hy cf RV -RZ -RZ -RZ +WX +ag +Sb RZ RV -Zo +KY gF ED ED @@ -7343,10 +7489,10 @@ XH nn td yi -td nS nS -Fa +Fq +td sF dR sc @@ -7384,9 +7530,9 @@ Vy bN RV RV -WC -WC -WC +wm +wm +wm WC RV Zl @@ -7402,8 +7548,8 @@ Zo Zl td Zh -td -qT +ie +nS vz td sF @@ -7412,9 +7558,9 @@ sF td Tl hL -fU +EA Wz -XR +NJ IP NS td @@ -7470,11 +7616,11 @@ oG sF td ge -Qe +hL He +Ou NJ -SI -NJ +IP bd sZ WM @@ -7529,12 +7675,12 @@ oG sF td gZ -Kv -NN +hL +NJ YI -Rc +NJ jy -Au +OI td ab ab @@ -7588,12 +7734,12 @@ dR If td PI -Li -Tx +dN tS -cK -EA -td +tS +jy +oj +FV td ab ab @@ -7648,12 +7794,12 @@ sc td td pK -td -td +yJ +Xh pe td td -ab +ap ab ab ab @@ -7704,15 +7850,15 @@ td Ol dR sF -Pm +Ro Xw +EJ +Wu zT -zq -zq mg -zq -td -ab +Vz +Vz +ap ab ab ab @@ -7763,15 +7909,15 @@ td rP dR sF -Ro +Pm FW -RE +xq RE kl Ld -zq -td -ab +CA +VC +ap ab ab ac @@ -7827,10 +7973,10 @@ Hx ta BB nP -gW -pP -td -ab +Vz +hr +cl +ap ab ab ab @@ -7885,11 +8031,11 @@ Pm Hx Jq bf -Wj -gW -zq -td -ab +nP +Vz +hr +hr +ap ab ab ac @@ -7942,13 +8088,13 @@ SJ zI Wx gz -dS -dS +cn +cn dS sm -Sy -td -ab +CA +CA +ap ab ab ab @@ -8000,14 +8146,14 @@ tv ph Lw Pm -zq +mr LD +ry zq -zq -yJ +Vz Lg -td -ab +Vz +ap ab ab ab @@ -8066,7 +8212,7 @@ ap ap ap ap -ab +ap ab ab ab diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_mookvillage.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_mookvillage.dmm new file mode 100644 index 00000000000000..5db8dd37a24f27 --- /dev/null +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_mookvillage.dmm @@ -0,0 +1,643 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"b" = ( +/obj/structure/bonfire/prelit, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"c" = ( +/turf/open/floor/holofloor/wood, +/area/lavaland/surface/outdoors) +"d" = ( +/obj/structure/railing{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"e" = ( +/obj/structure/flora/ash/fireblossom, +/mob/living/basic/mining/mook/worker/tribal_chief, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"f" = ( +/obj/structure/chair/wood{ + dir = 1 + }, +/turf/open/floor/holofloor/wood, +/area/lavaland/surface/outdoors) +"g" = ( +/obj/structure/bed/maint, +/turf/open/floor/holofloor/wood, +/area/lavaland/surface/outdoors) +"h" = ( +/turf/closed/wall/mineral/wood, +/area/lavaland/surface/outdoors) +"i" = ( +/obj/structure/chair/wood, +/turf/open/floor/holofloor/wood, +/area/lavaland/surface/outdoors) +"j" = ( +/obj/structure/closet/cabinet, +/obj/item/food/grown/banana, +/obj/item/food/meat/slab/goliath, +/turf/open/floor/holofloor/wood, +/area/lavaland/surface/outdoors) +"k" = ( +/obj/structure/table/wood/shuttle_bar, +/obj/item/flashlight/flare/candle/infinite, +/turf/open/floor/holofloor/wood, +/area/lavaland/surface/outdoors) +"l" = ( +/obj/structure/flora/ash/fireblossom, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"m" = ( +/obj/item/flashlight/lantern{ + on = 1 + }, +/turf/open/floor/holofloor/wood, +/area/lavaland/surface/outdoors) +"n" = ( +/obj/structure/flora/ash/fireblossom, +/mob/living/basic/mining/mook/worker, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"o" = ( +/obj/structure/railing/corner, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"p" = ( +/obj/structure/material_stand, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"q" = ( +/obj/item/fishing_rod, +/obj/structure/bed/maint, +/turf/open/floor/holofloor/wood, +/area/lavaland/surface/outdoors) +"r" = ( +/turf/open/floor/carpet/lone, +/area/lavaland/surface/outdoors) +"s" = ( +/obj/effect/landmark/mook_village, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"t" = ( +/obj/structure/chair/pew/left, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"u" = ( +/obj/structure/railing, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"v" = ( +/obj/structure/railing/corner{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"w" = ( +/obj/structure/railing{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"x" = ( +/obj/structure/table/wood/shuttle_bar, +/obj/item/clothing/head/costume/garland/poppy, +/turf/open/floor/holofloor/wood, +/area/lavaland/surface/outdoors) +"y" = ( +/turf/open/misc/grass/jungle, +/area/lavaland/surface/outdoors) +"z" = ( +/mob/living/basic/mining/mook/worker/bard, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"A" = ( +/obj/structure/chair/pew/right, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"C" = ( +/obj/structure/sign/nanotrasen, +/turf/closed/wall/mineral/wood, +/area/lavaland/surface/outdoors) +"E" = ( +/obj/structure/flora/grass/jungle/b, +/turf/open/misc/grass/jungle, +/area/lavaland/surface/outdoors) +"F" = ( +/obj/structure/chair/pew, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"G" = ( +/obj/structure/bed/pod, +/obj/item/bedsheet/nanotrasen, +/turf/open/floor/holofloor/wood, +/area/lavaland/surface/outdoors) +"H" = ( +/obj/structure/railing/corner{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"I" = ( +/mob/living/basic/mining/mook, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"J" = ( +/obj/structure/railing{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"M" = ( +/obj/structure/chair/pew/right{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"O" = ( +/obj/structure/table/wood/shuttle_bar, +/obj/item/hatchet/wooden, +/obj/item/storage/belt/champion/wrestling, +/turf/open/floor/holofloor/wood, +/area/lavaland/surface/outdoors) +"P" = ( +/mob/living/basic/mining/mook/worker, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"Q" = ( +/obj/structure/flora/tree/jungle/style_5, +/turf/open/misc/grass/jungle, +/area/lavaland/surface/outdoors) +"S" = ( +/obj/item/flashlight/lantern{ + on = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"V" = ( +/obj/structure/chair/pew{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"W" = ( +/obj/structure/flora/tree/jungle/style_3, +/turf/open/misc/grass/jungle, +/area/lavaland/surface/outdoors) +"Y" = ( +/obj/structure/chair/pew/left{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"Z" = ( +/obj/structure/railing/corner{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) + +(1,1,1) = {" +a +a +a +a +a +a +a +l +a +a +a +a +a +a +a +a +a +a +a +a +"} +(2,1,1) = {" +a +a +a +a +a +a +l +S +a +a +a +a +a +a +a +t +a +a +a +a +"} +(3,1,1) = {" +a +a +a +a +a +a +a +a +a +a +p +a +a +a +a +F +a +a +a +a +"} +(4,1,1) = {" +h +h +h +h +h +h +a +s +a +a +a +a +a +a +a +F +a +b +a +a +"} +(5,1,1) = {" +c +c +j +g +c +c +a +S +a +a +a +a +P +a +S +F +a +a +a +a +"} +(6,1,1) = {" +c +m +c +c +c +c +r +n +a +P +a +a +a +a +a +A +a +a +a +a +"} +(7,1,1) = {" +c +c +c +c +c +c +r +a +I +a +a +a +a +a +l +e +Y +V +V +M +"} +(8,1,1) = {" +c +i +k +f +c +c +a +a +a +o +w +w +w +Z +I +a +a +a +a +a +"} +(9,1,1) = {" +h +h +h +h +h +h +a +a +a +u +y +y +Q +d +a +a +a +P +a +a +"} +(10,1,1) = {" +a +a +a +a +a +a +a +I +a +u +y +y +E +d +a +a +l +a +a +a +"} +(11,1,1) = {" +a +a +l +l +a +a +a +a +a +u +y +W +E +d +a +a +a +a +a +a +"} +(12,1,1) = {" +a +a +a +a +a +P +a +a +a +u +y +y +Q +d +a +a +a +a +a +a +"} +(13,1,1) = {" +a +a +a +a +a +a +a +a +a +v +J +J +J +H +a +a +P +a +a +a +"} +(14,1,1) = {" +h +h +h +h +h +h +h +z +S +l +a +a +I +l +l +a +I +a +a +l +"} +(15,1,1) = {" +g +g +g +g +q +g +g +l +a +a +a +a +a +a +a +a +a +a +a +a +"} +(16,1,1) = {" +c +c +c +c +c +c +c +r +a +a +a +a +h +c +c +c +h +a +a +a +"} +(17,1,1) = {" +c +c +c +m +c +c +c +r +a +P +a +a +h +O +c +c +h +a +a +a +"} +(18,1,1) = {" +g +g +g +g +g +g +g +a +a +a +a +a +C +x +c +c +h +a +a +a +"} +(19,1,1) = {" +h +h +h +h +h +h +h +a +a +l +a +S +h +m +c +G +h +a +a +a +"} +(20,1,1) = {" +a +a +a +a +a +a +a +a +a +a +a +a +h +c +c +c +h +a +a +a +"} diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm index 4cc31bca411739..7497b5bb9079db 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1.dmm @@ -3716,7 +3716,7 @@ "OZ" = ( /obj/effect/turf_decal/bot, /obj/effect/decal/cleanable/dirt, -/obj/machinery/suit_storage_unit/syndicate, +/obj/machinery/suit_storage_unit/syndicate/lavaland, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/engineering) diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_watcher_grave.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_watcher_grave.dmm new file mode 100644 index 00000000000000..99af5bdced481f --- /dev/null +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_watcher_grave.dmm @@ -0,0 +1,345 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/closed/mineral/volcanic/lava_land_surface, +/area/lavaland/surface/outdoors) +"b" = ( +/obj/structure/stone_tile/surrounding_tile, +/obj/item/food/egg/watcher, +/turf/open/misc/asteroid/basalt/wasteland/basin, +/area/lavaland/surface/outdoors) +"c" = ( +/obj/structure/flora/ash/tall_shroom, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"f" = ( +/obj/structure/stone_tile/cracked{ + pixel_x = 16 + }, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"g" = ( +/obj/structure/stone_tile/block/cracked, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"h" = ( +/obj/structure/stone_tile/cracked, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"i" = ( +/obj/structure/stone_tile/cracked{ + pixel_y = -16 + }, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"j" = ( +/obj/effect/mapping_helpers/bombable_wall, +/turf/closed/indestructible/riveted/boss/wasteland, +/area/lavaland/surface/outdoors) +"l" = ( +/turf/closed/mineral/gibtonite/volcanic, +/area/lavaland/surface/outdoors) +"m" = ( +/turf/open/chasm/lavaland, +/area/lavaland/surface/outdoors) +"o" = ( +/obj/effect/mob_spawn/corpse/goliath/pierced, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"q" = ( +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"r" = ( +/obj/structure/stone_tile/slab/cracked, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"t" = ( +/obj/structure/stone_tile/cracked{ + pixel_x = 16 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"u" = ( +/obj/structure/flora/ash/stem_shroom, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"v" = ( +/obj/effect/mob_spawn/corpse/watcher/crushed, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"y" = ( +/obj/structure/stone_tile/block/cracked{ + pixel_y = -16 + }, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"A" = ( +/obj/structure/flora/rock/style_random, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"B" = ( +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"C" = ( +/obj/structure/flora/ash/cacti, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"D" = ( +/obj/structure/stone_tile/surrounding/cracked, +/obj/structure/stone_tile/center/cracked, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"E" = ( +/obj/structure/stone_tile/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"I" = ( +/turf/template_noop, +/area/template_noop) +"J" = ( +/obj/structure/stone_tile/slab/cracked{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"M" = ( +/obj/structure/flora/ash/fireblossom, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"R" = ( +/turf/closed/indestructible/riveted/boss/wasteland, +/area/lavaland/surface/outdoors) +"U" = ( +/obj/structure/stone_tile/slab/cracked, +/obj/effect/mob_spawn/corpse/watcher/goliath_chewed, +/turf/open/misc/asteroid/basalt/wasteland, +/area/lavaland/surface/outdoors) +"W" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) + +(1,1,1) = {" +I +I +I +I +I +I +I +I +I +I +I +I +I +"} +(2,1,1) = {" +I +I +I +I +a +I +W +W +M +I +I +I +I +"} +(3,1,1) = {" +I +I +I +l +a +a +a +t +a +a +I +I +I +"} +(4,1,1) = {" +I +I +a +a +R +R +R +j +R +a +a +I +I +"} +(5,1,1) = {" +I +a +a +R +R +u +R +q +R +m +a +I +I +"} +(6,1,1) = {" +I +a +a +R +A +f +q +f +m +m +m +I +I +"} +(7,1,1) = {" +I +I +a +R +D +U +h +q +C +m +m +m +I +"} +(8,1,1) = {" +I +l +a +R +y +b +g +B +q +q +m +m +I +"} +(9,1,1) = {" +I +a +a +R +c +i +o +r +q +R +a +a +I +"} +(10,1,1) = {" +I +I +a +R +R +A +u +h +c +R +a +l +I +"} +(11,1,1) = {" +I +I +a +a +R +R +R +q +R +R +a +I +I +"} +(12,1,1) = {" +I +I +I +a +a +a +R +j +R +a +a +I +I +"} +(13,1,1) = {" +I +I +I +I +I +W +M +J +E +W +I +I +I +"} +(14,1,1) = {" +I +I +I +I +I +I +t +v +W +I +I +I +I +"} +(15,1,1) = {" +I +I +I +I +I +I +I +W +W +I +I +I +I +"} diff --git a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_arena.dmm b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_arena.dmm index 47fd82ad04301a..a062f3cc436ff3 100644 --- a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_arena.dmm +++ b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_arena.dmm @@ -115,7 +115,7 @@ }, /mob/living/basic/mining/hivelord/no_wander{ color = "red"; - name = "gate guardian"; + name = "gate guardian" }, /turf/open/lava/smooth/lava_land_surface{ slowdown = 0 @@ -309,7 +309,7 @@ }, /mob/living/basic/mining/hivelord/no_wander{ color = "red"; - name = "gate guardian"; + name = "gate guardian" }, /turf/open/lava/smooth/lava_land_surface{ slowdown = 0 @@ -627,7 +627,7 @@ }, /mob/living/basic/mining/hivelord/no_wander{ color = "red"; - name = "gate guardian"; + name = "gate guardian" }, /turf/open/indestructible/boss, /area/lavaland/surface/outdoors) @@ -777,7 +777,7 @@ }, /mob/living/basic/mining/hivelord/no_wander{ color = "red"; - name = "gate guardian"; + name = "gate guardian" }, /turf/open/indestructible/boss, /area/lavaland/surface/outdoors) diff --git a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm index 957a669e53c3f0..7ceaba23094313 100644 --- a/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm +++ b/_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_syndicate_base1_skyrat.dmm @@ -26,6 +26,11 @@ /obj/effect/decal/cleanable/blood/old, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/medbay) +"an" = ( +/obj/structure/chair/sofa/right/maroon, +/obj/machinery/light/directional/north, +/turf/open/floor/wood/tile, +/area/ruin/syndicate_lava_base/dormitories) "as" = ( /obj/effect/mob_spawn/ghost_role/human/lavaland_syndicate/deckofficer{ dir = 4 @@ -39,14 +44,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) -"aF" = ( -/obj/machinery/door/airlock{ - name = "Bedroom" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/cargo) "aG" = ( /obj/structure/chair/office/light, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -77,6 +74,9 @@ }, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) +"aS" = ( +/turf/open/floor/grass, +/area/ruin/syndicate_lava_base/bar) "aT" = ( /obj/structure/table/optable, /turf/open/floor/plating, @@ -89,14 +89,6 @@ /obj/structure/fans/tiny, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/medbay) -"bb" = ( -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/light/directional/south, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) "bc" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/east, /obj/structure/window/reinforced/survival_pod/spawner/directional/south, @@ -132,14 +124,6 @@ "br" = ( /turf/open/floor/carpet/orange, /area/ruin/syndicate_lava_base/cargo) -"bt" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "bu" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -169,12 +153,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) -"bC" = ( -/obj/structure/table/wood, -/obj/item/flashlight/lamp, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/carpet/orange, -/area/ruin/syndicate_lava_base/cargo) "bF" = ( /obj/structure/table/wood, /obj/machinery/light/directional/west, @@ -200,18 +178,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/showroomfloor, /area/ruin/syndicate_lava_base/cargo) -"bR" = ( -/obj/machinery/door/airlock/grunge{ - name = "Bar" - }, -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, -/turf/open/floor/stone, -/area/ruin/syndicate_lava_base/bar) "bS" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, @@ -227,6 +193,18 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/showroomfloor, /area/ruin/syndicate_lava_base/cargo) +"bW" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/vending/autodrobe{ + onstation = 0 + }, +/turf/open/floor/iron/cafeteria, +/area/ruin/syndicate_lava_base/dormitories) "bY" = ( /obj/effect/turf_decal/siding/thinplating{ dir = 1 @@ -303,12 +281,19 @@ /obj/structure/cable, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) -"cy" = ( -/obj/structure/table/reinforced, -/obj/item/storage/backpack/duffelbag/syndie/surgery, -/obj/structure/window/reinforced/survival_pod/spawner/directional/west, -/turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/medbay) +"ct" = ( +/obj/machinery/light/small/directional/east, +/obj/machinery/ammo_workbench, +/turf/open/floor/iron/edge{ + dir = 8 + }, +/area/ruin/syndicate_lava_base/main) +"cv" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) "cB" = ( /obj/structure/flora/bush/flowers_br, /obj/structure/window/reinforced/plasma/plastitanium, @@ -341,6 +326,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) +"cX" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/machinery/light/directional/east, +/obj/effect/turf_decal/siding/thinplating/dark, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "da" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -357,6 +351,12 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) +"de" = ( +/obj/machinery/vending/cigarette/syndicate{ + onstation = 0 + }, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/dormitories) "df" = ( /obj/structure/table/wood, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -380,10 +380,6 @@ "dn" = ( /turf/open/floor/plating, /area/ruin/syndicate_lava_base/cargo) -"do" = ( -/obj/machinery/vending/dinnerware, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/bar) "dy" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -403,15 +399,21 @@ /obj/effect/mapping_helpers/airlock/access/all/syndicate/leader, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) -"dJ" = ( -/obj/structure/closet/secure_closet/freezer/kitchen{ - req_access = list("syndicate") +"dF" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/wood/tile, +/area/ruin/syndicate_lava_base/dormitories) +"dG" = ( +/obj/structure/table/glass, +/obj/item/storage/box/rndboards{ + pixel_y = 15; + pixel_x = 2 }, -/obj/item/reagent_containers/condiment/milk, -/obj/item/reagent_containers/condiment/soymilk, -/obj/structure/window/reinforced/survival_pod/spawner/directional/south, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/bar) +/obj/item/storage/part_replacer{ + pixel_y = 6 + }, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) "dN" = ( /obj/machinery/door/airlock/external, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -421,13 +423,18 @@ /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/cargo) -"dP" = ( +"dZ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/light/directional/south, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) +"eb" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 + dir = 5 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/stone, +/turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "eg" = ( /obj/machinery/light/directional/south, @@ -454,14 +461,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/closed/wall/r_wall/syndicate/nodiagonal, /area/ruin/syndicate_lava_base/engineering) -"es" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/obj/item/bedsheet/dorms, -/obj/structure/bed, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/dormitories) "et" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/west, /obj/machinery/light/directional/south, @@ -487,6 +486,16 @@ "eA" = ( /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) +"eI" = ( +/obj/machinery/airalarm/directional/north{ + req_access = list("syndicate") + }, +/obj/machinery/microwave{ + pixel_y = 9 + }, +/obj/structure/table/reinforced, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/bar) "eK" = ( /obj/machinery/vending/games{ onstation = 0 @@ -498,13 +507,6 @@ /obj/machinery/light/directional/north, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) -"eM" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, -/obj/effect/turf_decal/siding/thinplating/dark, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "eT" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /obj/structure/rack, @@ -516,24 +518,6 @@ /obj/machinery/light/directional/north, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/engineering) -"fe" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 4 - }, -/obj/machinery/door/airlock{ - name = "Cabin 4" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/dormitories) -"fg" = ( -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "fj" = ( /obj/structure/tank_dispenser, /turf/open/floor/iron/dark, @@ -573,6 +557,16 @@ }, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/testlab) +"fx" = ( +/obj/structure/sink/directional/south, +/obj/structure/mirror/directional/north, +/turf/open/floor/iron/checker, +/area/ruin/syndicate_lava_base/bar) +"fC" = ( +/obj/machinery/light/directional/west, +/obj/item/kirbyplants/random, +/turf/open/floor/iron/checker, +/area/ruin/syndicate_lava_base/bar) "fF" = ( /obj/structure/table/wood, /obj/item/storage/dice, @@ -597,19 +591,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood/tile, /area/ruin/syndicate_lava_base/dormitories) -"fW" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/item/kirbyplants/random, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/obj/machinery/airalarm/directional/south{ - req_access = list("syndicate") - }, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/medbay) "fX" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -619,21 +600,6 @@ }, /turf/open/floor/catwalk_floor/iron, /area/ruin/syndicate_lava_base/main) -"fY" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/machinery/airalarm/directional/north{ - req_access = list("syndicate") - }, -/obj/machinery/vending/autodrobe{ - onstation = 0 - }, -/turf/open/floor/iron/cafeteria, -/area/ruin/syndicate_lava_base/dormitories) "gb" = ( /obj/machinery/light/directional/north, /turf/open/floor/iron/dark, @@ -653,6 +619,20 @@ }, /turf/open/floor/catwalk_floor/iron, /area/ruin/syndicate_lava_base/bar) +"gg" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/item/kirbyplants/random, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/machinery/airalarm/directional/south{ + req_access = list("syndicate") + }, +/obj/machinery/light_switch/directional/west, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/medbay) "gj" = ( /obj/machinery/door/airlock/external, /obj/effect/mapping_helpers/airlock/cyclelink_helper{ @@ -719,15 +699,12 @@ }, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/cargo) -"gJ" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, -/obj/structure/disposalpipe/segment{ - dir = 10 +"gO" = ( +/obj/machinery/door/window/survival_pod{ + req_access = list("syndicate") }, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/medbay) "gQ" = ( /obj/machinery/conveyor{ dir = 4; @@ -772,11 +749,6 @@ /obj/machinery/atmospherics/components/binary/valve/digital/layer2, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/engineering) -"ho" = ( -/obj/structure/table/reinforced, -/obj/item/storage/bag/tray, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "hq" = ( /obj/structure/window/reinforced/tinted/spawner/directional/south, /obj/structure/window/reinforced/tinted/spawner/directional/north, @@ -820,11 +792,6 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) -"hV" = ( -/obj/machinery/griddle, -/obj/machinery/firealarm/directional/north, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/bar) "hY" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/north, /obj/machinery/atmospherics/components/unary/vent_pump/siphon/monitored{ @@ -843,10 +810,15 @@ /obj/structure/table, /turf/open/floor/plating/lavaland_atmos, /area/ruin/syndicate_lava_base/cargo) -"ie" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 4 +"id" = ( +/obj/structure/table/reinforced, +/obj/item/reagent_containers/condiment/enzyme{ + pixel_y = 8 + }, +/obj/item/reagent_containers/condiment/peppermill{ + pixel_x = 6 }, +/obj/item/reagent_containers/condiment/saltshaker, /turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "if" = ( @@ -862,15 +834,15 @@ }, /turf/open/floor/iron/edge, /area/ruin/syndicate_lava_base/main) +"ij" = ( +/obj/structure/table/reinforced, +/obj/machinery/processor, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/bar) "ik" = ( /obj/structure/bookcase/random/fiction, /turf/open/floor/wood/tile, /area/ruin/syndicate_lava_base/dormitories) -"im" = ( -/obj/machinery/hydroponics/constructable, -/obj/machinery/light/directional/west, -/turf/open/misc/grass, -/area/ruin/syndicate_lava_base/bar) "is" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -880,6 +852,11 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/virology) +"it" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) "iw" = ( /obj/structure/table, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -892,22 +869,23 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) +"iC" = ( +/obj/machinery/light/directional/east, +/obj/machinery/hydroponics/constructable, +/turf/open/floor/grass, +/area/ruin/syndicate_lava_base/bar) +"iG" = ( +/obj/machinery/porta_turret/syndicate{ + dir = 5; + faction = list("Syndicate","neutral") + }, +/turf/closed/wall/r_wall/syndicate/nodiagonal, +/area/ruin/syndicate_lava_base/engineering) "iH" = ( /obj/structure/railing, /obj/effect/turf_decal/loading_area, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) -"iL" = ( -/obj/machinery/door/airlock/mining{ - name = "Shaft Miner Dormitory Beta" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, -/turf/open/floor/iron/smooth_half{ - dir = 1 - }, -/area/ruin/syndicate_lava_base/cargo) "iO" = ( /obj/effect/turf_decal/tile/brown, /obj/effect/turf_decal/tile/yellow{ @@ -917,13 +895,6 @@ /obj/effect/turf_decal/box/white, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) -"iU" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "je" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/plating, @@ -955,12 +926,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) -"jk" = ( -/obj/machinery/porta_turret/syndicate{ - faction = list("Syndicate","neutral") - }, -/turf/closed/wall/r_wall/syndicate/nodiagonal, -/area/ruin/syndicate_lava_base/main) "jn" = ( /obj/effect/turf_decal/tile/dark_blue{ dir = 1 @@ -981,22 +946,19 @@ }, /turf/open/floor/wood/large, /area/ruin/syndicate_lava_base/dormitories) -"jA" = ( -/obj/structure/bed, -/obj/item/bedsheet/qm{ - name = "deck officer's bedsheet" +"jB" = ( +/obj/effect/turf_decal/siding/thinplating/corner{ + dir = 1 }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/carpet/orange, +/turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) -"jB" = ( -/obj/effect/turf_decal/siding/thinplating/corner{ - dir = 1 +"jF" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 }, +/obj/machinery/anesthetic_machine, /turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/cargo) +/area/ruin/syndicate_lava_base/medbay) "jK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -1019,6 +981,10 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) +"jR" = ( +/obj/effect/decal/cleanable/oil/streak, +/turf/open/floor/plating, +/area/ruin/syndicate_lava_base/cargo) "jS" = ( /obj/structure/closet/crate, /obj/item/storage/box/stockparts/deluxe, @@ -1037,6 +1003,17 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) +"kg" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/button/door/directional/west{ + specialfunctions = 4; + id = "Dynbin2"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1 + }, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "kq" = ( /obj/structure/sign/departments/chemistry/directional/east, /obj/structure/table/glass, @@ -1046,17 +1023,10 @@ /obj/item/storage/box/beakers/bluespace, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) -"ku" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 4 - }, -/obj/machinery/door/airlock{ - name = "Cabin 3" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/dormitories) +"ks" = ( +/obj/machinery/oven/range, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/bar) "kw" = ( /obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden, /obj/effect/turf_decal/stripes/line, @@ -1108,13 +1078,6 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) -"kY" = ( -/obj/machinery/button/door/directional/north{ - id = "interdynekitchen" - }, -/obj/machinery/oven/range, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/bar) "lf" = ( /obj/machinery/door/window/survival_pod{ dir = 8; @@ -1122,6 +1085,17 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) +"lo" = ( +/obj/machinery/firealarm/directional/west{ + dir = 4; + pixel_x = -28 + }, +/turf/open/floor/iron/kitchen, +/area/ruin/syndicate_lava_base/bar) +"lq" = ( +/obj/machinery/light_switch/directional/north, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/dormitories) "ls" = ( /obj/machinery/door/firedoor, /obj/structure/table/reinforced, @@ -1131,12 +1105,6 @@ /obj/item/folder/white, /turf/open/floor/iron/white/side, /area/ruin/syndicate_lava_base/medbay) -"lu" = ( -/obj/structure/chair/sofa/right/brown{ - dir = 8 - }, -/turf/open/floor/wood/tile, -/area/ruin/syndicate_lava_base/dormitories) "lv" = ( /obj/machinery/vending/barbervend{ onstation = 0 @@ -1155,15 +1123,9 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) -"lE" = ( -/obj/structure/table/reinforced, -/obj/item/kitchen/rollingpin, -/obj/item/reagent_containers/condiment/saltshaker, -/obj/item/reagent_containers/condiment/peppermill{ - pixel_x = 6 - }, -/obj/item/reagent_containers/condiment/enzyme{ - pixel_y = 8 +"lC" = ( +/obj/machinery/button/door/directional/west{ + id = "interdynekitchen" }, /turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) @@ -1182,6 +1144,11 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) +"lR" = ( +/obj/machinery/smartfridge/food, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/dark/small, +/area/ruin/syndicate_lava_base/bar) "lS" = ( /obj/structure/displaycase{ alert = 0; @@ -1205,6 +1172,13 @@ /obj/structure/dresser, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) +"md" = ( +/obj/effect/turf_decal/siding/thinplating/light{ + dir = 4 + }, +/obj/structure/window/reinforced/survival_pod/spawner/directional/east, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/medbay) "mk" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -1263,13 +1237,6 @@ /obj/structure/disposalpipe/junction/flip, /turf/open/floor/catwalk_floor/iron, /area/ruin/syndicate_lava_base/main) -"mB" = ( -/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, -/obj/machinery/door/airlock{ - name = "Unisex Restrooms" - }, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/bar) "mD" = ( /obj/effect/turf_decal/siding/brown{ dir = 9 @@ -1295,6 +1262,34 @@ "mN" = ( /turf/open/floor/engine/o2, /area/ruin/syndicate_lava_base/engineering) +"mV" = ( +/obj/effect/turf_decal/siding/thinplating/light{ + dir = 4 + }, +/obj/structure/window/reinforced/survival_pod/spawner/directional/east, +/obj/structure/table/reinforced, +/obj/item/reagent_containers/cup/beaker/cryoxadone{ + pixel_x = -6; + pixel_y = 6 + }, +/obj/item/reagent_containers/cup/beaker/cryoxadone{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/item/storage/pill_bottle/mannitol, +/obj/item/reagent_containers/dropper, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/medbay) +"na" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/obj/structure/bed/double{ + dir = 1 + }, +/obj/item/bedsheet/dorms_double{ + dir = 1 + }, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "nd" = ( /obj/structure/sign/directions/science{ dir = 8; @@ -1331,13 +1326,6 @@ "no" = ( /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) -"np" = ( -/obj/structure/lattice/catwalk, -/obj/structure/railing{ - dir = 4 - }, -/turf/open/lava/smooth/lava_land_surface, -/area/ruin/syndicate_lava_base/cargo) "nq" = ( /obj/structure/dresser, /turf/open/floor/wood, @@ -1354,13 +1342,13 @@ }, /turf/open/floor/plating/lavaland_atmos, /area/ruin/syndicate_lava_base/cargo) -"nH" = ( -/obj/effect/turf_decal/stripes/line{ +"nD" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ dir = 4 }, -/obj/item/stack/rods/ten, -/turf/open/floor/plating/lavaland_atmos, -/area/ruin/syndicate_lava_base/cargo) +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/kitchen, +/area/ruin/syndicate_lava_base/bar) "nT" = ( /turf/open/floor/iron/dark/textured_large, /area/ruin/syndicate_lava_base/bar) @@ -1392,10 +1380,6 @@ /obj/structure/disposalpipe/trunk, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/medbay) -"oe" = ( -/obj/machinery/cryo_cell, -/turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/medbay) "oi" = ( /obj/effect/turf_decal/siding/thinplating/dark/corner, /obj/machinery/door/airlock/public/glass{ @@ -1404,17 +1388,28 @@ /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) -"oq" = ( -/obj/machinery/door/airlock/mining{ - name = "Shaft Miner Dormitory Alpha" +"ok" = ( +/obj/structure/table/reinforced, +/obj/item/storage/backpack/duffelbag/syndie/surgery, +/obj/machinery/airalarm/directional/north, +/obj/item/healthanalyzer{ + pixel_x = -5; + pixel_y = 5 + }, +/obj/item/clothing/mask/breath/anesthetic{ + pixel_x = 8; + pixel_y = 5 + }, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/medbay) +"ow" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 4 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, -/turf/open/floor/iron/smooth_half{ - dir = 1 - }, -/area/ruin/syndicate_lava_base/cargo) +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "oA" = ( /obj/machinery/door/window/survival_pod{ req_access = list("syndicate"); @@ -1461,6 +1456,10 @@ /obj/structure/cable, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/engineering) +"oT" = ( +/obj/machinery/hydroponics/constructable, +/turf/open/floor/grass, +/area/ruin/syndicate_lava_base/bar) "oW" = ( /obj/machinery/light/directional/south, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -1487,13 +1486,14 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) -"pe" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 +"pk" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 1 }, -/obj/effect/decal/cleanable/oil/streak, -/turf/open/floor/plating/lavaland_atmos, -/area/ruin/syndicate_lava_base/cargo) +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) "pq" = ( /obj/machinery/door/airlock/mining/glass{ name = "Cargo Bay" @@ -1508,6 +1508,13 @@ dir = 8 }, /area/ruin/syndicate_lava_base/cargo) +"pt" = ( +/obj/structure/reagent_dispensers/watertank/high, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "py" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 @@ -1528,6 +1535,12 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/virology) +"pz" = ( +/obj/effect/turf_decal/siding/thinplating/dark, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "pD" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -1549,15 +1562,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/engineering) -"pM" = ( -/obj/structure/table/reinforced, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/obj/item/healthanalyzer, -/obj/structure/window/reinforced/survival_pod/spawner/directional/west, -/turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/medbay) "pR" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, @@ -1606,14 +1610,6 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) -"qr" = ( -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "qs" = ( /obj/machinery/door/airlock/public/glass{ name = "Bar" @@ -1636,14 +1632,17 @@ /obj/structure/window/reinforced/survival_pod/spawner/directional/south, /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) -"qK" = ( +"qE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 4 +/obj/machinery/button/door/directional/south{ + name = "Dorm Bolt Control"; + id = "Dynbin3"; + normaldoorcontrol = 1; + specialfunctions = 4 }, -/turf/open/floor/stone, -/area/ruin/syndicate_lava_base/bar) +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "qL" = ( /obj/effect/turf_decal/tile/dark_blue, /obj/effect/turf_decal/tile/blue{ @@ -1655,11 +1654,6 @@ }, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) -"qN" = ( -/obj/structure/reagent_dispensers/watertank/high, -/obj/machinery/light/directional/east, -/turf/open/misc/grass, -/area/ruin/syndicate_lava_base/bar) "qT" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/south, /obj/structure/window/reinforced/survival_pod/spawner/directional/east, @@ -1678,15 +1672,17 @@ /obj/structure/window/reinforced/survival_pod/spawner/directional/south, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/testlab) -"qV" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/obj/machinery/light/directional/north, -/turf/open/floor/wood/tile, -/area/ruin/syndicate_lava_base/dormitories) "qX" = ( /obj/structure/cable, /turf/open/floor/catwalk_floor/iron_dark, /area/ruin/syndicate_lava_base/testlab) +"rb" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 1 + }, +/obj/effect/turf_decal/siding/thinplating/dark, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "rf" = ( /obj/structure/railing{ dir = 4 @@ -1705,12 +1701,17 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) -"rl" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 +"rj" = ( +/obj/machinery/light/small/directional/east, +/turf/open/floor/iron/checker, +/area/ruin/syndicate_lava_base/bar) +"rm" = ( +/obj/structure/table/reinforced, +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 4 }, -/obj/effect/turf_decal/siding/thinplating/dark/corner, -/turf/open/floor/iron/kitchen, +/obj/item/storage/bag/tray, +/turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/bar) "rq" = ( /turf/closed/wall/r_wall/syndicate/nodiagonal, @@ -1741,6 +1742,8 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/structure/table/reinforced, +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma/advanced/unzipped, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) "rQ" = ( @@ -1749,6 +1752,22 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/bar) +"rV" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, +/obj/effect/turf_decal/stripes/blue{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/medbay) +"rW" = ( +/obj/structure/bed/maint, +/turf/open/floor/plating, +/area/ruin/syndicate_lava_base/cargo) +"sb" = ( +/obj/structure/table/glass, +/obj/item/stack/cable_coil, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) "sd" = ( /obj/structure/sign/directions/vault{ dir = 8; @@ -1756,11 +1775,47 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) +"sf" = ( +/obj/machinery/light/directional/south, +/obj/structure/closet/secure_closet/freezer/kitchen{ + req_access = list("syndicate") + }, +/obj/item/reagent_containers/condiment/milk, +/obj/item/reagent_containers/condiment/soymilk, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/bar) +"sj" = ( +/obj/effect/turf_decal/tile/blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/obj/machinery/light/directional/north, +/obj/structure/table/glass, +/obj/structure/bedsheetbin, +/obj/machinery/airalarm/directional/north{ + req_access = list("syndicate") + }, +/turf/open/floor/iron/cafeteria, +/area/ruin/syndicate_lava_base/dormitories) "sl" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/west, /obj/structure/window/reinforced/survival_pod/spawner/directional/north, /turf/open/floor/engine/n2, /area/ruin/syndicate_lava_base/engineering) +"sn" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/structure/fans/tiny, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/airlock/security/old{ + name = "Brig Hold"; + id_tag = "DyneBrig" + }, +/turf/open/floor/plating, +/area/ruin/syndicate_lava_base/cargo) "so" = ( /obj/machinery/light/directional/north, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -1770,20 +1825,31 @@ /obj/structure/bookcase/random/reference, /turf/open/floor/wood/tile, /area/ruin/syndicate_lava_base/dormitories) +"sD" = ( +/obj/structure/tank_holder/anesthetic, +/obj/structure/railing, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/medbay) +"sI" = ( +/obj/effect/turf_decal/siding/thinplating/dark/end, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) +"sK" = ( +/obj/effect/turf_decal/siding/thinplating{ + dir = 8 + }, +/obj/machinery/light_switch/directional/north, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/cargo) "sL" = ( /obj/effect/turf_decal/siding/thinplating/dark{ dir = 4 }, /turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) -"sQ" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 8 - }, -/turf/open/floor/iron/kitchen, +"sP" = ( +/obj/machinery/chem_dispenser/mutagensaltpeter, +/turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/bar) "sY" = ( /obj/machinery/atmospherics/miner/oxygen, @@ -1797,6 +1863,11 @@ dir = 1 }, /area/ruin/syndicate_lava_base/medbay) +"tt" = ( +/obj/machinery/shower/directional/north, +/obj/structure/curtain, +/turf/open/floor/iron/checker, +/area/ruin/syndicate_lava_base/bar) "tv" = ( /obj/structure/railing{ dir = 8 @@ -1806,10 +1877,12 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) -"tA" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) +"tx" = ( +/obj/structure/table/glass, +/obj/structure/towel_bin, +/obj/item/soap/syndie, +/turf/open/floor/iron/checker, +/area/ruin/syndicate_lava_base/bar) "tD" = ( /turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) @@ -1864,36 +1937,38 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) +"tT" = ( +/obj/machinery/vending/hydroseeds{ + onstation = 0 + }, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "tW" = ( /obj/structure/chair/office/light{ dir = 1 }, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) +"ub" = ( +/obj/machinery/flasher/directional/north{ + id = "DyneBrigFlash" + }, +/turf/open/floor/plating, +/area/ruin/syndicate_lava_base/cargo) "un" = ( /turf/open/floor/iron/dark/textured_corner{ dir = 4 }, /area/ruin/syndicate_lava_base/bar) -"ur" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 4 +"uy" = ( +/obj/machinery/door/airlock{ + name = "Bedroom"; + id_tag = "DyneDO" }, -/obj/machinery/door/airlock/maintenance/external, -/obj/structure/fans/tiny, -/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, -/turf/open/floor/plating, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/wood, /area/ruin/syndicate_lava_base/cargo) -"us" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/structure/chair/sofa/corner/brown{ - dir = 8 - }, -/obj/machinery/light/directional/south, -/turf/open/floor/wood/tile, -/area/ruin/syndicate_lava_base/dormitories) "uD" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -1913,17 +1988,23 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/testlab) -"uK" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 1 +"uJ" = ( +/obj/structure/table/reinforced, +/obj/effect/spawner/random/food_or_drink/donkpockets{ + pixel_y = 7; + pixel_x = 10 }, -/obj/machinery/door/airlock{ - name = "Cabin 2" +/obj/item/storage/box/donkpockets{ + pixel_y = 5; + pixel_x = -7 }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/dormitories) +/turf/open/floor/iron/kitchen, +/area/ruin/syndicate_lava_base/bar) +"uP" = ( +/obj/machinery/light/floor, +/obj/machinery/cryo_cell, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/medbay) "uX" = ( /obj/effect/turf_decal/tile/dark_blue{ dir = 1 @@ -1942,20 +2023,6 @@ }, /turf/open/floor/engine/n2, /area/ruin/syndicate_lava_base/engineering) -"vg" = ( -/obj/structure/chair/office/light{ - dir = 1 - }, -/obj/effect/turf_decal/siding/thinplating/dark/corner, -/turf/open/floor/stone, -/area/ruin/syndicate_lava_base/bar) -"vh" = ( -/obj/structure/table/reinforced, -/obj/item/book/manual/wiki/cooking_to_serve_man{ - pixel_y = 2 - }, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "vi" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -1971,18 +2038,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) -"vm" = ( -/obj/structure/toilet{ - dir = 8 - }, -/obj/machinery/light/small/directional/north, -/obj/machinery/button/door/directional/east{ - id = "interdynerec1"; - normaldoorcontrol = 1; - specialfunctions = 4 - }, -/turf/open/floor/iron/checker, -/area/ruin/syndicate_lava_base/bar) "vt" = ( /obj/effect/turf_decal/tile/bar{ dir = 4 @@ -1998,6 +2053,16 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) +"vH" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/structure/bed/double, +/obj/item/bedsheet/dorms_double, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) +"vJ" = ( +/obj/machinery/light_switch/directional/north, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/bar) "vK" = ( /obj/structure/table, /obj/item/storage/box/drinkingglasses{ @@ -2012,6 +2077,13 @@ /obj/structure/flora/rock/pile, /turf/open/misc/asteroid/basalt, /area/ruin/syndicate_lava_base/cargo) +"vQ" = ( +/obj/machinery/hydroponics/constructable, +/obj/machinery/door/window/survival_pod{ + dir = 1 + }, +/turf/open/floor/grass, +/area/ruin/syndicate_lava_base/bar) "vR" = ( /obj/structure/frame/machine{ anchored = 1; @@ -2034,6 +2106,16 @@ "vZ" = ( /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) +"wb" = ( +/obj/effect/turf_decal/siding/wood, +/obj/machinery/door/airlock{ + name = "Cabin 1"; + id_tag = "Dynbin1" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "wc" = ( /obj/machinery/door/airlock/public/glass{ name = "Dormitories" @@ -2071,17 +2153,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) -"ws" = ( -/obj/structure/window/reinforced/survival_pod/spawner/directional/north, -/obj/structure/closet/secure_closet/freezer/meat{ - req_access = list("syndicate") +"wt" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 }, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/bar) -"wu" = ( -/obj/machinery/hydroponics/constructable, -/obj/machinery/airalarm/directional/south, -/turf/open/misc/grass, +/turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "wx" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/east, @@ -2107,19 +2183,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) -"wA" = ( -/obj/structure/table/reinforced, -/obj/machinery/light/directional/south, -/obj/effect/spawner/random/food_or_drink/donkpockets{ - pixel_y = 7; - pixel_x = 10 - }, -/obj/item/storage/box/donkpockets{ - pixel_y = 5; - pixel_x = -7 - }, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "wB" = ( /obj/structure/lattice/catwalk, /obj/structure/railing{ @@ -2134,6 +2197,23 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) +"wD" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) +"wJ" = ( +/obj/structure/table, +/obj/machinery/button/door/directional/east{ + specialfunctions = 4; + normaldoorcontrol = 1; + name = "Dorm Bolt Control"; + id = "DyneAlpha" + }, +/turf/open/floor/iron/smooth_large, +/area/ruin/syndicate_lava_base/cargo) "wL" = ( /obj/machinery/door/airlock{ name = "Library Backroom" @@ -2164,10 +2244,30 @@ /obj/effect/mapping_helpers/apc/syndicate_access, /turf/open/floor/iron/cafeteria, /area/ruin/syndicate_lava_base/dormitories) +"wU" = ( +/obj/structure/window/reinforced/survival_pod/spawner/directional/south, +/obj/effect/turf_decal/siding/thinplating/light{ + dir = 4 + }, +/obj/structure/window/reinforced/survival_pod/spawner/directional/east, +/obj/structure/closet/crate/freezer/blood, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/medbay) "wW" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) +"wY" = ( +/obj/machinery/light_switch/directional/south, +/obj/structure/table, +/obj/item/paper_bin{ + pixel_y = 4 + }, +/obj/item/pen{ + pixel_y = 4 + }, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) "xk" = ( /obj/machinery/conveyor_switch/oneway{ id = "interdynecargoin" @@ -2192,12 +2292,36 @@ }, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/dormitories) +"xo" = ( +/obj/machinery/airalarm/directional/north, +/obj/machinery/atmospherics/components/unary/portables_connector/visible, +/obj/machinery/portable_atmospherics/canister/anesthetic_mix, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/medbay) +"xp" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 6 + }, +/turf/open/floor/iron/kitchen, +/area/ruin/syndicate_lava_base/bar) "xr" = ( /obj/structure/chair{ dir = 4 }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/bar) +"xs" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/machinery/door/airlock{ + name = "Cabin 2"; + id_tag = "Dynbin2" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "xw" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -2207,12 +2331,13 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) -"xx" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 +"xJ" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk{ + dir = 1 }, -/obj/machinery/chem_dispenser/mutagensaltpeter, -/turf/open/floor/iron/dark/smooth_large, +/obj/effect/turf_decal/siding/thinplating/dark/corner, +/turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "xL" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, @@ -2281,17 +2406,6 @@ }, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/engineering) -"yf" = ( -/obj/structure/frame/machine{ - anchored = 1; - state = 2; - icon_state = "box_1" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/testlab) "yh" = ( /obj/machinery/conveyor{ dir = 8; @@ -2309,6 +2423,18 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) +"yk" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 4 + }, +/obj/effect/turf_decal/siding/thinplating/dark/corner, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) +"yp" = ( +/obj/structure/table/reinforced, +/obj/item/kitchen/rollingpin, +/turf/open/floor/iron/kitchen, +/area/ruin/syndicate_lava_base/bar) "yr" = ( /obj/machinery/conveyor{ dir = 8; @@ -2317,6 +2443,10 @@ /obj/structure/plasticflaps, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/cargo) +"yw" = ( +/obj/effect/decal/cleanable/oil, +/turf/open/floor/plating, +/area/ruin/syndicate_lava_base/cargo) "yy" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -2330,13 +2460,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/catwalk_floor/iron, /area/ruin/syndicate_lava_base/bar) -"yB" = ( -/obj/structure/table/reinforced, -/obj/machinery/microwave{ - pixel_y = 9 - }, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "yE" = ( /obj/effect/turf_decal/siding/thinplating/dark{ dir = 8 @@ -2366,11 +2489,32 @@ }, /turf/open/floor/plating/lavaland_atmos, /area/ruin/syndicate_lava_base/engineering) +"yV" = ( +/obj/structure/toilet, +/obj/structure/window/reinforced/tinted/spawner/directional/west, +/turf/open/floor/iron/checker, +/area/ruin/syndicate_lava_base/bar) "zc" = ( /obj/effect/turf_decal/siding/thinplating/dark, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) +"zd" = ( +/obj/structure/closet/secure_closet/freezer/meat{ + req_access = list("syndicate") + }, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/bar) +"zj" = ( +/obj/machinery/light/directional/south, +/obj/structure/table, +/obj/machinery/fax{ + fax_name = "Interdyne Pharmaceuticals"; + pixel_y = 7; + name = "Interdyne Fax Machine" + }, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) "zl" = ( /obj/structure/chair/stool/bar{ dir = 4 @@ -2391,6 +2535,12 @@ /obj/structure/chair/office/light, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) +"zr" = ( +/obj/machinery/vending/dinnerware{ + onstation = 0 + }, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/bar) "zt" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -2464,10 +2614,6 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) -"zI" = ( -/obj/structure/table/reinforced, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "zJ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, @@ -2479,15 +2625,45 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) -"Aa" = ( -/obj/machinery/hydroponics/constructable, -/turf/open/misc/grass, +"zO" = ( +/obj/structure/closet/crate/bin, +/turf/open/floor/iron/checker, /area/ruin/syndicate_lava_base/bar) +"zP" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/light/directional/south, +/turf/open/floor/wood/tile, +/area/ruin/syndicate_lava_base/dormitories) +"zS" = ( +/obj/structure/table/wood, +/obj/item/flashlight/lamp, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/button/door/directional/east{ + specialfunctions = 4; + normaldoorcontrol = 1; + name = "Dorm Bolt Control"; + id = "DyneDO" + }, +/turf/open/floor/carpet/orange, +/area/ruin/syndicate_lava_base/cargo) "Ac" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) +"Ae" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/machinery/door/airlock{ + name = "Cabin 4"; + id_tag = "Dynbin4" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "Ai" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, @@ -2508,12 +2684,6 @@ /obj/structure/cable, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/engineering) -"Al" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "An" = ( /obj/machinery/light/directional/south, /turf/open/floor/iron, @@ -2531,13 +2701,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) -"Au" = ( -/obj/machinery/hydroponics/constructable, -/obj/machinery/firealarm/directional/east{ - dir = 8 - }, -/turf/open/misc/grass, -/area/ruin/syndicate_lava_base/bar) "Aw" = ( /obj/structure/ore_box, /obj/structure/railing{ @@ -2593,13 +2756,6 @@ /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/medbay) -"AU" = ( -/obj/machinery/griddle, -/obj/machinery/airalarm/directional/north{ - req_access = list("syndicate") - }, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/bar) "AV" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -2638,6 +2794,10 @@ }, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/bar) +"Bq" = ( +/obj/structure/table, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/bar) "Bw" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -2669,10 +2829,19 @@ /obj/structure/table, /turf/open/floor/plating/lavaland_atmos, /area/ruin/syndicate_lava_base/testlab) -"BK" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) +"BN" = ( +/obj/item/disk/surgery/forgottenship, +/obj/structure/table/reinforced, +/obj/item/storage/box/medipens{ + pixel_x = 4; + pixel_y = 13 + }, +/obj/item/reagent_containers/cup/beaker/cryoxadone{ + pixel_x = -6; + pixel_y = 10 + }, +/turf/open/floor/iron/white, +/area/ruin/syndicate_lava_base/medbay) "BP" = ( /obj/structure/table, /obj/machinery/chem_dispenser/drinks/beer/fullupgrade{ @@ -2752,14 +2921,6 @@ /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/main) -"Cl" = ( -/obj/item/storage/toolbox/syndicate, -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) "Co" = ( /obj/effect/mob_spawn/ghost_role/human/lavaland_syndicate/shaftminer{ dir = 4 @@ -2783,6 +2944,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) +"CD" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 6 + }, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "CJ" = ( /obj/structure/chair/office{ dir = 8 @@ -2829,6 +2996,19 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) +"CT" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 1 + }, +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 8 + }, +/obj/effect/turf_decal/siding/thinplating/dark/corner, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "CU" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/iron, @@ -2859,11 +3039,28 @@ }, /turf/open/floor/iron/smooth_edge, /area/ruin/syndicate_lava_base/medbay) +"Dc" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "De" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/south, /obj/machinery/portable_atmospherics/pump, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/engineering) +"Df" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/structure/frame/machine{ + anchored = 1; + state = 2; + icon_state = "box_1" + }, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/testlab) "Dk" = ( /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/bar) @@ -2881,10 +3078,6 @@ /obj/machinery/light/directional/south, /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) -"Dy" = ( -/obj/machinery/processor, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/bar) "DJ" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, @@ -2941,6 +3134,14 @@ /obj/item/hairbrush/tactical, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) +"EP" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/window/reinforced/plasma/spawner/directional/east, +/obj/item/kirbyplants/random, +/turf/open/floor/plating, +/area/ruin/syndicate_lava_base/cargo) "EZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -3083,45 +3284,14 @@ }, /turf/open/floor/plating/lavaland_atmos, /area/ruin/syndicate_lava_base/medbay) -"FF" = ( -/obj/effect/turf_decal/siding/wood, -/obj/machinery/door/airlock{ - name = "Cabin 1" - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/dormitories) "FG" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/engineering) -"FI" = ( -/obj/machinery/light/small/directional/west, -/obj/structure/frame/machine{ - anchored = 1; - icon_state = "box_1"; - state = 2 - }, -/obj/item/circuitboard/machine/ammo_workbench, -/obj/item/disk/ammo_workbench/advanced, -/turf/open/floor/iron/edge{ - dir = 4 - }, -/area/ruin/syndicate_lava_base/main) "FJ" = ( /obj/machinery/libraryscanner, /turf/open/floor/wood/large, /area/ruin/syndicate_lava_base/dormitories) -"FK" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/obj/structure/bed, -/obj/item/bedsheet/dorms, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/dormitories) -"FO" = ( -/turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/medbay) "FT" = ( /obj/machinery/door/airlock/medical/glass{ name = "Medical Wing"; @@ -3149,49 +3319,25 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) -"Ge" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 4 +"Gc" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 }, -/turf/open/floor/stone, -/area/ruin/syndicate_lava_base/bar) -"Gl" = ( -/obj/machinery/airalarm/directional/west{ - req_access = list("syndicate") +/obj/structure/bed/double, +/obj/item/bedsheet/qm/double{ + name = "deck officer's bedsheet" }, -/turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/medbay) -"Gp" = ( -/obj/structure/bed, -/obj/item/bedsheet/brown, -/turf/open/floor/iron/smooth_large, +/turf/open/floor/carpet/orange, /area/ruin/syndicate_lava_base/cargo) -"Gr" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible, -/obj/machinery/portable_atmospherics/canister/anesthetic_mix, -/turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/medbay) "Gs" = ( /obj/effect/turf_decal/siding/thinplating/dark, /turf/open/floor/stone, /area/ruin/syndicate_lava_base/bar) -"Gu" = ( -/obj/effect/turf_decal/siding/thinplating/dark, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) "GB" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) -"GF" = ( -/obj/effect/turf_decal/siding/thinplating/dark, -/obj/structure/cable, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/effect/mapping_helpers/apc/syndicate_access, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) "GS" = ( /obj/machinery/atmospherics/components/binary/pump/on{ dir = 1 @@ -3210,6 +3356,24 @@ /obj/machinery/chem_mass_spec, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) +"Hf" = ( +/obj/machinery/button/door/directional/west{ + id = "DyneWC"; + normaldoorcontrol = 1; + name = "Door Lock" + }, +/obj/machinery/dryer{ + pixel_x = 8; + pixel_y = 20 + }, +/turf/open/floor/iron/checker, +/area/ruin/syndicate_lava_base/bar) +"Ho" = ( +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/effect/mapping_helpers/apc/syndicate_access, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/testlab) "Hs" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -3220,12 +3384,6 @@ }, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/bar) -"Ht" = ( -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 8 - }, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) "Hz" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron, @@ -3237,6 +3395,17 @@ /obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/testlab) +"HF" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/button/door/directional/north{ + name = "Dorm Bolt Control"; + id = "Dynbin4"; + normaldoorcontrol = 1; + specialfunctions = 4 + }, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "HI" = ( /obj/structure/sign/directions/medical{ dir = 4; @@ -3266,6 +3435,14 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) +"HN" = ( +/obj/effect/spawner/random/vending/snackvend, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/dormitories) +"HQ" = ( +/obj/effect/turf_decal/siding/thinplating/dark, +/turf/open/floor/iron/kitchen, +/area/ruin/syndicate_lava_base/bar) "HR" = ( /obj/structure/sink/directional/east, /turf/open/floor/iron, @@ -3314,6 +3491,21 @@ /obj/structure/sign/departments/medbay/alt/directional/east, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) +"Ir" = ( +/obj/machinery/firealarm/directional/east{ + dir = 8 + }, +/obj/machinery/vending/hydronutrients{ + onstation = 0 + }, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) +"It" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner{ + dir = 4 + }, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) "Iv" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -3354,6 +3546,14 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/testlab) +"IL" = ( +/obj/machinery/airalarm/directional/south, +/obj/machinery/hydroponics/constructable, +/obj/machinery/door/window/survival_pod{ + dir = 1 + }, +/turf/open/floor/grass, +/area/ruin/syndicate_lava_base/bar) "IO" = ( /obj/machinery/door/airlock{ name = "Library" @@ -3363,10 +3563,6 @@ /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/dormitories) -"IR" = ( -/obj/structure/bookcase/random/nonfiction, -/turf/open/floor/wood/tile, -/area/ruin/syndicate_lava_base/dormitories) "IT" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, @@ -3375,19 +3571,6 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) -"IY" = ( -/obj/structure/chair/sofa/corp/left{ - dir = 1 - }, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/dormitories) -"IZ" = ( -/obj/structure/frame/computer{ - dir = 4; - anchored = 1 - }, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/testlab) "Jb" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -3448,6 +3631,11 @@ /obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) +"JN" = ( +/obj/structure/bed/double, +/obj/item/bedsheet/dorms_double, +/turf/open/floor/iron/smooth_large, +/area/ruin/syndicate_lava_base/cargo) "JR" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -3492,10 +3680,11 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) -"Ka" = ( -/obj/structure/sink/directional/west, -/turf/open/misc/grass, -/area/ruin/syndicate_lava_base/bar) +"Kd" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/bookcase/random/nonfiction, +/turf/open/floor/wood/tile, +/area/ruin/syndicate_lava_base/dormitories) "Kh" = ( /obj/structure/table/glass, /obj/machinery/reagentgrinder{ @@ -3609,13 +3798,6 @@ dir = 8 }, /area/ruin/syndicate_lava_base/main) -"KT" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/decal/cleanable/oil, -/turf/open/floor/plating/lavaland_atmos, -/area/ruin/syndicate_lava_base/cargo) "KX" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, @@ -3677,6 +3859,12 @@ "Lq" = ( /turf/closed/wall/r_wall/syndicate/nodiagonal, /area/ruin/syndicate_lava_base/engineering) +"Ls" = ( +/obj/effect/turf_decal/siding/thinplating/dark/corner, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "Lw" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -3696,13 +3884,16 @@ dir = 4 }, /area/ruin/syndicate_lava_base/medbay) -"LK" = ( -/obj/structure/table/glass, -/obj/item/storage/box/rndboards{ - pixel_y = 4 +"LH" = ( +/obj/structure/table, +/obj/machinery/button/door/directional/east{ + specialfunctions = 4; + normaldoorcontrol = 1; + name = "Dorm Bolt Control"; + id = "DyneBeta" }, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) +/turf/open/floor/iron/smooth_large, +/area/ruin/syndicate_lava_base/cargo) "LL" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -3718,11 +3909,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) -"LP" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/dormitories) "LS" = ( /obj/structure/table/glass, /obj/item/book/random{ @@ -3809,13 +3995,6 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) -"MP" = ( -/obj/machinery/door/airlock{ - name = "Unisex Toilet"; - id_tag = "interdynerec1" - }, -/turf/open/floor/iron/checker, -/area/ruin/syndicate_lava_base/bar) "MR" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/stripes/line, @@ -3824,12 +4003,22 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/engineering) -"MW" = ( -/obj/machinery/disposal/bin, -/obj/structure/disposalpipe/trunk{ - dir = 1 +"MU" = ( +/obj/structure/chair/sofa/left/maroon{ + dir = 8 }, -/turf/open/floor/iron/kitchen, +/turf/open/floor/wood/tile, +/area/ruin/syndicate_lava_base/dormitories) +"MX" = ( +/obj/machinery/chem_master/condimaster{ + name = "BrewMaster 3000" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/dark/small, +/area/ruin/syndicate_lava_base/bar) +"MY" = ( +/obj/machinery/light/directional/south, +/turf/open/floor/grass, /area/ruin/syndicate_lava_base/bar) "Nc" = ( /obj/machinery/light/directional/east, @@ -3853,13 +4042,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) -"Ng" = ( -/obj/machinery/disposal/bin, -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/turf/open/misc/grass, -/area/ruin/syndicate_lava_base/bar) "Nh" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, @@ -3870,11 +4052,6 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) -"Nj" = ( -/obj/structure/sink/directional/west, -/obj/structure/mirror/directional/east, -/turf/open/floor/iron/checker, -/area/ruin/syndicate_lava_base/bar) "Nl" = ( /obj/machinery/seed_extractor, /turf/open/floor/iron/dark/smooth_large, @@ -3898,15 +4075,6 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) -"NK" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/turf/open/floor/stone, -/area/ruin/syndicate_lava_base/bar) "NO" = ( /obj/structure/chair/comfy/barber_chair{ dir = 8 @@ -3914,6 +4082,13 @@ /obj/structure/mirror/directional/west, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) +"NS" = ( +/obj/machinery/flasher/directional/south{ + pixel_x = -6; + id = "DyneBrigFlash" + }, +/turf/open/floor/plating, +/area/ruin/syndicate_lava_base/cargo) "NT" = ( /obj/machinery/porta_turret/syndicate{ dir = 1 @@ -3933,32 +4108,21 @@ /obj/effect/turf_decal/stripes/red/box, /turf/open/floor/iron/textured_large, /area/ruin/syndicate_lava_base/main) +"Oi" = ( +/obj/machinery/light/directional/west, +/obj/machinery/firealarm/directional/west{ + dir = 4; + pixel_x = -28 + }, +/obj/structure/chair/office/light{ + dir = 1 + }, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "Oo" = ( /obj/structure/lattice/catwalk, /turf/open/lava/smooth/lava_land_surface, /area/ruin/syndicate_lava_base/engineering) -"Or" = ( -/obj/machinery/light/small/directional/east, -/turf/open/floor/iron/edge{ - dir = 8 - }, -/area/ruin/syndicate_lava_base/main) -"Ot" = ( -/obj/effect/turf_decal/stripes/corner, -/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, -/obj/machinery/door/airlock{ - name = "Unisex Restrooms" - }, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/bar) -"Ou" = ( -/obj/structure/bed, -/obj/item/bedsheet/dorms, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/dormitories) "Ow" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/west, /turf/open/floor/engine, @@ -4004,6 +4168,29 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) +"ON" = ( +/obj/machinery/door/airlock/mining{ + name = "Shaft Miner Dormitory Alpha"; + id_tag = "DyneAlpha" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/iron/smooth_half{ + dir = 1 + }, +/area/ruin/syndicate_lava_base/cargo) +"OR" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/button/door/directional/west{ + specialfunctions = 4; + id = "Dynbin1"; + name = "Dorm Bolt Control"; + normaldoorcontrol = 1 + }, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "OS" = ( /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -4022,6 +4209,11 @@ /obj/structure/window/reinforced/plasma/plastitanium, /turf/open/floor/grass, /area/ruin/syndicate_lava_base/medbay) +"Pb" = ( +/obj/item/storage/toolbox/syndicate, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/testlab) "Pd" = ( /obj/structure/table, /turf/open/floor/iron/dark, @@ -4036,11 +4228,15 @@ }, /turf/open/floor/catwalk_floor/iron, /area/ruin/syndicate_lava_base/medbay) -"Pk" = ( -/obj/structure/tank_holder/anesthetic, -/obj/structure/window/reinforced/survival_pod/spawner/directional/west, -/turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/medbay) +"Pj" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/iron/kitchen, +/area/ruin/syndicate_lava_base/bar) "Pr" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -4067,12 +4263,11 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/virology) -"PE" = ( -/obj/item/stack/cable_coil, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +"PG" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/catwalk_floor/iron_dark, -/area/ruin/syndicate_lava_base/testlab) +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/stone, +/area/ruin/syndicate_lava_base/bar) "PM" = ( /turf/open/floor/iron/edge{ dir = 1 @@ -4089,12 +4284,6 @@ dir = 1 }, /area/ruin/syndicate_lava_base/main) -"PV" = ( -/obj/structure/chair/sofa/corp/right{ - dir = 1 - }, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/dormitories) "PZ" = ( /turf/open/floor/wood/large, /area/ruin/syndicate_lava_base/dormitories) @@ -4105,6 +4294,22 @@ /obj/machinery/computer/cryopod/interdyne/directional/west, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/dormitories) +"Qc" = ( +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/door/airlock/public/glass{ + name = "Kitchen-Botany" + }, +/turf/open/floor/iron/dark/small, +/area/ruin/syndicate_lava_base/bar) +"Qg" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/structure/window/reinforced/plasma/spawner/directional/east, +/turf/open/floor/plating, +/area/ruin/syndicate_lava_base/cargo) "Qk" = ( /obj/structure/table/glass, /obj/item/clothing/glasses/science, @@ -4120,18 +4325,6 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) -"Qn" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/obj/machinery/light/directional/north, -/obj/structure/table/glass, -/obj/structure/bedsheetbin, -/turf/open/floor/iron/cafeteria, -/area/ruin/syndicate_lava_base/dormitories) "Qp" = ( /obj/machinery/light/directional/north, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -4209,11 +4402,17 @@ /area/ruin/syndicate_lava_base/bar) "QS" = ( /obj/machinery/porta_turret/syndicate{ - dir = 6; + dir = 6; + faction = list("Syndicate","neutral") + }, +/turf/closed/wall/r_wall/syndicate/nodiagonal, +/area/ruin/syndicate_lava_base/main) +"QV" = ( +/obj/machinery/porta_turret/syndicate{ faction = list("Syndicate","neutral") }, /turf/closed/wall/r_wall/syndicate/nodiagonal, -/area/ruin/syndicate_lava_base/main) +/area/ruin/syndicate_lava_base/bar) "QW" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/disposalpipe/segment{ @@ -4234,13 +4433,14 @@ /obj/structure/table, /turf/open/floor/iron/smooth_large, /area/ruin/syndicate_lava_base/cargo) -"Rf" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 +"Re" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 }, -/obj/item/storage/toolbox/mechanical, -/turf/open/floor/plating/lavaland_atmos, -/area/ruin/syndicate_lava_base/cargo) +/obj/structure/bed/double, +/obj/item/bedsheet/dorms_double, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "Ro" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -4272,6 +4472,14 @@ }, /turf/open/floor/catwalk_floor/iron, /area/ruin/syndicate_lava_base/medbay) +"Rt" = ( +/obj/machinery/door/airlock{ + name = "Unisex Restroom"; + id_tag = "DyneWC" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/bar) "Ru" = ( /obj/structure/frame/machine{ anchored = 1; @@ -4314,14 +4522,6 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) -"RL" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) "RN" = ( /obj/structure/closet/secure_closet/personal/cabinet, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -4334,6 +4534,11 @@ /obj/machinery/light/directional/north, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/medbay) +"RT" = ( +/obj/machinery/biogenerator, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/dark/small, +/area/ruin/syndicate_lava_base/bar) "RV" = ( /obj/structure/table/wood, /obj/machinery/computer/libraryconsole/bookmanagement, @@ -4345,11 +4550,12 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/testlab) -"Sc" = ( -/obj/machinery/vending/hydroseeds{ - onstation = 0 +"RZ" = ( +/obj/effect/turf_decal/siding/thinplating/dark{ + dir = 1 }, -/turf/open/floor/iron/dark/smooth_large, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/kitchen, /area/ruin/syndicate_lava_base/bar) "Sh" = ( /obj/machinery/airalarm/directional/south{ @@ -4380,18 +4586,9 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/dormitories) -"St" = ( -/obj/structure/closet/crate/bin, -/obj/item/soap/syndie, -/turf/open/floor/iron/checker, -/area/ruin/syndicate_lava_base/bar) "Sy" = ( /turf/open/misc/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"Sz" = ( -/obj/item/kirbyplants/random, -/turf/open/floor/iron/checker, -/area/ruin/syndicate_lava_base/bar) "SC" = ( /obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, /turf/open/floor/plating, @@ -4432,13 +4629,12 @@ }, /turf/open/floor/iron/dark, /area/ruin/syndicate_lava_base/cargo) -"Tg" = ( -/obj/effect/turf_decal/siding/thinplating/dark/corner{ - dir = 1 +"Th" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 }, -/obj/machinery/light/directional/south, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) +/turf/open/floor/iron/kitchen, +/area/ruin/syndicate_lava_base/bar) "Tl" = ( /obj/structure/sign/departments/science/directional/west, /turf/open/floor/iron, @@ -4453,15 +4649,6 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/bar) -"Tt" = ( -/obj/item/disk/surgery/forgottenship, -/obj/structure/table/reinforced, -/obj/item/reagent_containers/cup/beaker/cryoxadone{ - pixel_x = -6; - pixel_y = 10 - }, -/turf/open/floor/iron/white, -/area/ruin/syndicate_lava_base/medbay) "Tw" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -4476,10 +4663,6 @@ "Tx" = ( /turf/closed/wall/r_wall/syndicate/nodiagonal, /area/ruin/syndicate_lava_base/bar) -"Tz" = ( -/obj/machinery/light/directional/west, -/turf/open/floor/iron/checker, -/area/ruin/syndicate_lava_base/bar) "TJ" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -4515,19 +4698,27 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/catwalk_floor/iron, /area/ruin/syndicate_lava_base/dormitories) -"Ud" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 4 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) "Ug" = ( /obj/structure/railing, /obj/effect/turf_decal/box/white, /obj/structure/rack/shelf, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/cargo) +"Ui" = ( +/obj/machinery/button/door/directional/north{ + id = "DyneBrig"; + normaldoorcontrol = 1; + name = "Brig Bolt Control"; + specialfunctions = 4; + req_access = list("syndicate") + }, +/obj/machinery/button/flasher{ + id = "DyneBrigFlash"; + pixel_x = 6; + pixel_y = 34 + }, +/turf/open/floor/iron, +/area/ruin/syndicate_lava_base/main) "Up" = ( /obj/machinery/modular_computer/preset/curator{ dir = 1 @@ -4563,6 +4754,10 @@ "UO" = ( /turf/open/floor/plating, /area/ruin/syndicate_lava_base/engineering) +"UP" = ( +/obj/structure/chair/sofa/corner/maroon, +/turf/open/floor/wood/tile, +/area/ruin/syndicate_lava_base/dormitories) "UX" = ( /obj/machinery/door/airlock/research{ name = "Xenobiology Lab" @@ -4596,6 +4791,21 @@ /obj/item/choice_beacon/music, /turf/open/floor/wood/large, /area/ruin/syndicate_lava_base/dormitories) +"Vf" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/wood/tile, +/area/ruin/syndicate_lava_base/dormitories) +"Vh" = ( +/obj/machinery/light/small/directional/west, +/obj/structure/rack, +/obj/item/clothing/mask/gas/syndicate, +/obj/item/clothing/mask/gas/syndicate, +/obj/item/clothing/mask/gas/syndicate, +/obj/item/clothing/mask/gas/syndicate, +/turf/open/floor/iron/edge{ + dir = 4 + }, +/area/ruin/syndicate_lava_base/main) "Vi" = ( /obj/machinery/smartfridge/food, /turf/open/floor/iron, @@ -4674,14 +4884,22 @@ /obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/medbay) -"VU" = ( -/obj/machinery/biogenerator, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/bar) "VY" = ( /obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/medbay) +"Wa" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/structure/bed/double{ + dir = 1 + }, +/obj/item/bedsheet/dorms_double{ + dir = 1 + }, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "Wd" = ( /obj/machinery/smartfridge/organ, /obj/structure/railing, @@ -4694,12 +4912,6 @@ }, /turf/open/lava/smooth/lava_land_surface, /area/ruin/syndicate_lava_base/engineering) -"Wl" = ( -/obj/structure/bed, -/obj/item/bedsheet/dorms, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/wood, -/area/ruin/syndicate_lava_base/dormitories) "Wm" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron, @@ -4707,25 +4919,18 @@ "Wq" = ( /turf/open/floor/iron, /area/ruin/syndicate_lava_base/medbay) -"Wr" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer, -/turf/open/floor/iron/dark, -/area/ruin/syndicate_lava_base/medbay) "Wx" = ( /turf/closed/wall/r_wall/syndicate/nodiagonal, /area/ruin/syndicate_lava_base/main) +"WB" = ( +/obj/machinery/griddle, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/bar) "WG" = ( /obj/structure/window/reinforced/survival_pod/spawner/directional/east, /obj/structure/window/reinforced/survival_pod/spawner/directional/north, /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) -"WK" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/chair/sofa/left/brown{ - dir = 1 - }, -/turf/open/floor/wood/tile, -/area/ruin/syndicate_lava_base/dormitories) "WM" = ( /obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, /obj/machinery/door/poddoor{ @@ -4843,15 +5048,6 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) -"XA" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/obj/machinery/vending/hydronutrients{ - onstation = 0 - }, -/turf/open/floor/iron/dark/smooth_large, -/area/ruin/syndicate_lava_base/bar) "XD" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -4869,6 +5065,18 @@ }, /turf/open/floor/engine, /area/ruin/syndicate_lava_base/testlab) +"XI" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/obj/machinery/door/airlock{ + name = "Cabin 3"; + id_tag = "Dynbin3" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/wood, +/area/ruin/syndicate_lava_base/dormitories) "XJ" = ( /obj/structure/table/glass, /obj/machinery/firealarm/directional/west{ @@ -4877,15 +5085,6 @@ /obj/machinery/reagentgrinder, /turf/open/floor/iron/white, /area/ruin/syndicate_lava_base/medbay) -"XN" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/turf/open/floor/stone, -/area/ruin/syndicate_lava_base/bar) "XO" = ( /obj/machinery/door/airlock{ name = "Disposals" @@ -4894,6 +5093,13 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/ruin/syndicate_lava_base/bar) +"XQ" = ( +/obj/structure/frame/computer{ + anchored = 1; + dir = 4 + }, +/turf/open/floor/iron/dark/smooth_large, +/area/ruin/syndicate_lava_base/testlab) "XR" = ( /obj/structure/table/wood, /obj/item/modular_computer/laptop/preset/syndicate, @@ -4918,11 +5124,6 @@ /obj/machinery/light/directional/north, /turf/open/floor/iron/dark/smooth_large, /area/ruin/syndicate_lava_base/bar) -"XZ" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/stone, -/area/ruin/syndicate_lava_base/bar) "Yb" = ( /obj/effect/mob_spawn/ghost_role/human/lavaland_syndicate, /obj/machinery/light/directional/north, @@ -4973,6 +5174,13 @@ /obj/machinery/processor/slime, /turf/open/floor/wood, /area/ruin/syndicate_lava_base/testlab) +"Yv" = ( +/obj/structure/window/reinforced/survival_pod/spawner/directional/south, +/obj/machinery/atmospherics/components/unary/thermomachine/freezer/on{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/ruin/syndicate_lava_base/medbay) "Yz" = ( /obj/item/disk/design_disk/limbs/ethereal{ pixel_y = 2 @@ -5000,6 +5208,18 @@ }, /turf/open/floor/plating/lavaland_atmos, /area/ruin/syndicate_lava_base/medbay) +"YE" = ( +/obj/machinery/door/airlock/mining{ + name = "Shaft Miner Dormitory Beta"; + id_tag = "DyneBeta" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/iron/smooth_half{ + dir = 1 + }, +/area/ruin/syndicate_lava_base/cargo) "YF" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -5141,33 +5361,6 @@ }, /turf/open/floor/iron, /area/ruin/syndicate_lava_base/main) -"ZI" = ( -/obj/effect/turf_decal/siding/thinplating/dark{ - dir = 8 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) -"ZL" = ( -/obj/effect/turf_decal/siding/thinplating/dark/end{ - dir = 4 - }, -/obj/structure/table/reinforced, -/obj/machinery/door/firedoor, -/obj/machinery/door/window/survival_pod{ - dir = 4; - req_access = list("syndicate") - }, -/obj/machinery/door/window/survival_pod{ - dir = 8; - req_access = list("syndicate") - }, -/turf/open/floor/iron/kitchen, -/area/ruin/syndicate_lava_base/bar) -"ZM" = ( -/obj/effect/turf_decal/siding/thinplating/dark/corner, -/turf/open/floor/iron, -/area/ruin/syndicate_lava_base/testlab) "ZO" = ( /obj/machinery/door/airlock/vault{ id_tag = "syndie_lavaland_vault" @@ -5572,8 +5765,8 @@ ab OW FX IF -LK -Mv +dG +sb RJ OW YF @@ -5629,11 +5822,11 @@ ab ab ab HA -ZM IH IH IH -bb +It +dZ OW YW fv @@ -5688,11 +5881,11 @@ ab ab ab HA -Gu -IZ +XQ Ru -Ru -Cl +ME +RY +Pb OW Zd Ku @@ -5747,11 +5940,11 @@ ab ab ab OW -GF +Ho qX Jb -PE -RL +pk +it UX Zd Ku @@ -5806,11 +5999,11 @@ ab ab ab HA -Gu Ru -yf -ME +Ru +Df RY +wY OW Zn Do @@ -5865,11 +6058,11 @@ ab ab ab HA -Ht Kq -KL Kq -Tg +KL +cv +zj OW Ky BS @@ -5879,16 +6072,16 @@ KY KY et Vb -FK +na IT -Ss -FF +OR +wb Fz Xs -uK -Ss +xs +kg IT -es +Wa Vb ab ab @@ -5924,8 +6117,8 @@ ab ab ab OW +Mv Hz -tA LL CU uE @@ -5964,16 +6157,16 @@ ab ab Zz cP -bC -jA +zS +Gc Zz -Gp +JN gs -QZ +wJ hq -QZ +LH gs -Gp +JN Zz ab ab @@ -6022,16 +6215,16 @@ ab ab ab Zz -aF +uy Zz Zz Zz Zz -oq +ON Zz Zz Zz -iL +YE Zz Zz ab @@ -6062,7 +6255,7 @@ Vb wS CB JS -IY +HN Vb oE nq @@ -6118,10 +6311,10 @@ Vb Yb IT Vb -Qn +sj CB JS -PV +de Vb Ps Lb @@ -6174,16 +6367,16 @@ df Xv Ss Vb -Wl -LP +vH +qE Vb -fY +bW CB JS Vb Vb -LP -Ou +HF +Re Vb ab ab @@ -6234,14 +6427,14 @@ Vb IO Vb Vb -ku +XI Vb wx CB JS Qa Vb -fe +Ae Vb Vb ab @@ -6346,10 +6539,10 @@ Zq ZH JB Wx -qV +dF fO fO -yy +zP Vb so da @@ -6405,12 +6598,12 @@ ZA ZA An Wx -IR -Lg +an LS -WK +Vf +Kd Vb -JS +lq YJ JS JS @@ -6464,10 +6657,10 @@ Zq ZA Zq Wx -ik +UP +MU Lg -lu -us +ik Vb wc EZ @@ -6575,7 +6768,7 @@ fX Zq Wx HL -FI +Vh FC Wx qj @@ -6675,7 +6868,7 @@ ab NT Zz Zz -rh +sK rh rh wC @@ -6693,7 +6886,7 @@ fX gd Wx KS -Or +ct PS Wx BW @@ -6760,11 +6953,11 @@ nh jN Tx Tx +Rt Tx Tx Tx -Tx -WW +vJ QQ wo Oy @@ -6801,11 +6994,11 @@ Sr Sr Fc Zz -KT -nH -Rf -pe -ur +rW +dn +dn +jR +sn Zq nh Zq @@ -6817,11 +7010,11 @@ nd Zq nh Zq -Ot -IC +Tx +Hf IC -Tz -Sz +fC +zO Tx JC Hs @@ -6860,12 +7053,12 @@ vi vi Fk Zz -ZW -ZW -ZW -ZW +ub +dn +yw +NS Zz -Zq +Ui cD Ao Ao @@ -6877,21 +7070,21 @@ Ao AV oY Tx -MP -Tx +fx IC IC -mB +tx +Tx WW QQ ml Tx ZS -eM -Dy -do -gJ -MW +Pj +lC +lo +wt +xJ Tx Tx ab @@ -6919,10 +7112,10 @@ vZ jS Zz Zz -np -np -np -np +Qg +Qg +Qg +EP Zz JB AH @@ -6936,22 +7129,22 @@ Zq Zq JB Tx -vm -Tx -Nj -St +yV +rj +IC +tt Tx WW Cg WW Tx -kY -sQ -ZI -iU -fg -lE -yB +ks +RZ +Fm +yp +ci +HQ +zd Tx ab ab @@ -7004,14 +7197,14 @@ WW Cg WW Tx -hV -Al -zI +WB +RZ +id +uJ ci -BK -ci -wA -jk +HQ +sf +QV ab ab ab @@ -7063,13 +7256,13 @@ WW Cg WW Tx -AU -rl -ie -Ud -qr -ho -vh +eI +RZ +ci +Th +ci +xp +zr Tx ab ab @@ -7123,12 +7316,12 @@ QQ ky Tx XX -eM -ws -dJ -bt -Fm -Tx +eb +nD +nD +xp +rm +ij Tx ab ab @@ -7182,16 +7375,16 @@ JV ml Tx Tx -ZL -Tx +Qc +lR +RT +MX Tx -bR Tx Tx ab ab ab -ab ag ag "} @@ -7239,18 +7432,18 @@ Tx To QQ WW -YO -im +KA +Oi +PG +Dc tD -Aa -Aa -XZ -Aa +Gs +oT +oT Tx ab ab ab -ab ag ag "} @@ -7274,7 +7467,7 @@ ab ab ab ab -Va +rq rq rq rq @@ -7298,17 +7491,17 @@ Tx Jq QQ WW -KA -vg -sL +YO +Ls +ow sL -Ge -qK -Aa +yk +CD +aS +MY Tx ab ab -ab ag ag aa @@ -7344,7 +7537,7 @@ Zc KX Pr zy -fW +gg ZX Li zv @@ -7358,17 +7551,17 @@ WW Cg WW YO -Gs +pz Nl -VU -XA -dP -wu +Bq +rb +oT +vQ +IL Tx ab ab ab -ab ag ag "} @@ -7417,16 +7610,16 @@ WW Cg WW YO -Gs -xx +pz +sP oX -Sc -dP -Aa +rb +oT +vQ +vQ Tx ab ab -ab ag ag aa @@ -7477,16 +7670,16 @@ uD Nf cc xw -XN -XN -XN -NK -Ng +wD +wD +CT +sI +aS +aS Tx ab ab ab -ab ag ag "} @@ -7535,17 +7728,17 @@ Gb ce Tq YO -Aa -Au -Aa -Aa -Ka -qN +pt +Ir +tT +cX +oT +iC +oT Tx ab ab ab -ab ag ag "} @@ -7570,9 +7763,9 @@ ab ab ab kD -Wr +xo xL -Gl +Yv NH Yp ZX @@ -7601,7 +7794,7 @@ Lq Lq Lq Lq -ab +Lq ab ab ab @@ -7629,9 +7822,9 @@ ab ab ab kD -oe -xL -FO +uP +rV +gO NH Yp ZX @@ -7688,9 +7881,9 @@ ab ab ab kD -Gr -xL -FO +mV +md +wU WU NH FT @@ -7747,11 +7940,11 @@ ab ab ab kD -cy -pM -Pk +ok +jF +sD Xf -Tt +BN ZX IA LC @@ -7938,12 +8131,12 @@ ZX ZX ZX ZX -ZX +QS ab ab ab ab -kL +iG Lq Lq Lq diff --git a/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm b/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm index a1b7d571679565..2383c4688e3eb4 100644 --- a/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm +++ b/_maps/RandomRuins/SpaceRuins/dangerous_research.dmm @@ -1307,10 +1307,7 @@ /turf/open/floor/iron/dark, /area/ruin/space/has_grav/dangerous_research/lab) "re" = ( -/mob/living/simple_animal/hostile/heretic_summon/raw_prophet{ - AIStatus = 1; - stop_automated_movement = 0 - }, +/mob/living/basic/heretic_summon/raw_prophet/ruins, /turf/open/floor/plating/rust, /area/ruin/space/has_grav/dangerous_research/medical) "ri" = ( @@ -1987,10 +1984,7 @@ /obj/effect/decal/cleanable/glass, /obj/item/shard, /obj/item/stack/sheet/iron, -/mob/living/simple_animal/hostile/heretic_summon/rust_spirit{ - AIStatus = 1; - stop_automated_movement = 0 - }, +/mob/living/basic/heretic_summon/rust_walker, /turf/open/floor/plating/rust, /area/ruin/space/has_grav/dangerous_research/lab) "zR" = ( @@ -2020,10 +2014,7 @@ dir = 1 }, /obj/effect/decal/cleanable/blood/footprints, -/mob/living/simple_animal/hostile/heretic_summon/raw_prophet{ - AIStatus = 1; - stop_automated_movement = 0 - }, +/mob/living/basic/heretic_summon/raw_prophet/ruins, /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/iron/white, /area/ruin/space/has_grav/dangerous_research/medical) @@ -3723,10 +3714,7 @@ /turf/open/floor/engine/airless, /area/ruin/space/has_grav/dangerous_research/maint) "Xh" = ( -/mob/living/simple_animal/hostile/heretic_summon/rust_spirit{ - AIStatus = 1; - stop_automated_movement = 0 - }, +/mob/living/basic/heretic_summon/rust_walker, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, @@ -3868,10 +3856,7 @@ /turf/open/floor/iron/white, /area/ruin/space/has_grav/dangerous_research/medical) "YZ" = ( -/mob/living/simple_animal/hostile/heretic_summon/rust_spirit{ - AIStatus = 1; - stop_automated_movement = 0 - }, +/mob/living/basic/heretic_summon/rust_walker, /turf/open/floor/plating/rust, /area/ruin/space/has_grav/dangerous_research/lab) "Zc" = ( diff --git a/_maps/RandomRuins/SpaceRuins/listeningstation.dmm b/_maps/RandomRuins/SpaceRuins/listeningstation.dmm index 256555eca0ce74..366005b95a68ab 100644 --- a/_maps/RandomRuins/SpaceRuins/listeningstation.dmm +++ b/_maps/RandomRuins/SpaceRuins/listeningstation.dmm @@ -234,7 +234,6 @@ anchored = 1 }, /obj/machinery/door/window/brigdoor{ - dir = 2; req_access = list("syndicate"); name = "Self Destruct Option" }, @@ -305,9 +304,6 @@ /turf/open/floor/plating, /area/ruin/space/has_grav/listeningstation) "rr" = ( -/obj/machinery/door/airlock{ - name = "Emergency Backup" - }, /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -392,7 +388,6 @@ /area/ruin/space/has_grav/listeningstation) "xh" = ( /obj/machinery/computer/records/medical/syndie{ - dir = 2; req_access = list("syndicate") }, /obj/machinery/light/small/directional/north, @@ -813,6 +808,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/mapping_helpers/broken_floor, +/obj/machinery/door/airlock{ + name = "Emergency Backup" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, /turf/open/floor/plating, /area/ruin/space/has_grav/listeningstation) "RK" = ( diff --git a/_maps/RandomRuins/SpaceRuins/russian_derelict.dmm b/_maps/RandomRuins/SpaceRuins/russian_derelict.dmm index 5b7d0ba43da888..953bde1f094419 100644 --- a/_maps/RandomRuins/SpaceRuins/russian_derelict.dmm +++ b/_maps/RandomRuins/SpaceRuins/russian_derelict.dmm @@ -461,6 +461,10 @@ /obj/structure/cable, /turf/open/floor/plating/airless, /area/ruin/space/solars/ks13/sb_bow_solars) +"fe" = ( +/obj/item/circuitboard/computer/solar_control, +/turf/open/floor/iron, +/area/ruin/space/ks13/engineering/sb_bow_solars_control) "fg" = ( /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/iron/airless, @@ -493,7 +497,7 @@ pixel_x = -6; pixel_y = 6 }, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "fL" = ( /obj/machinery/door/window/left/directional/west{ @@ -854,6 +858,9 @@ }, /turf/open/floor/iron, /area/ruin/space/ks13/ai/corridor) +"lq" = ( +/turf/open/floor/circuit/red/off, +/area/ruin/space/ks13/ai/corridor) "lw" = ( /obj/structure/lattice, /obj/item/chair, @@ -1181,7 +1188,7 @@ /obj/item/stack/sheet/glass/fifty, /obj/item/stack/sheet/glass/fifty, /obj/item/stack/sheet/glass/fifty, -/turf/open/floor/iron/airless, +/turf/open/floor/circuit/red/airless, /area/ruin/space/ks13/ai/vault) "pc" = ( /obj/effect/decal/cleanable/blood/splatter, @@ -1391,7 +1398,7 @@ pixel_y = 6 }, /obj/item/circuitboard/machine/cryo_tube, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "qh" = ( /obj/structure/fluff/oldturret, @@ -1660,10 +1667,6 @@ /area/ruin/space/ks13/hallway/aft) "rI" = ( /obj/structure/table_frame/wood, -/obj/item/clothing/head/helmet/chaplain{ - armor = null; - desc = "The Chaplains crusader helment. It seems old and dented." - }, /turf/open/floor/wood, /area/ruin/space/ks13/service/chapel_office) "rJ" = ( @@ -2487,6 +2490,11 @@ /obj/structure/cable, /turf/open/floor/iron/airless, /area/ruin/space/ks13/hallway/aft) +"wt" = ( +/obj/effect/decal/cleanable/dirt, +/obj/item/clothing/head/chaplain/bishopmitre, +/turf/open/floor/iron/dark, +/area/ruin/space/ks13/service/chapel_office) "wu" = ( /obj/structure/rack, /obj/effect/decal/cleanable/dirt, @@ -2623,7 +2631,7 @@ /obj/item/stack/sheet/iron/fifty, /obj/item/stack/sheet/iron/fifty, /obj/item/stack/sheet/iron/fifty, -/turf/open/floor/iron/airless, +/turf/open/floor/circuit/red/airless, /area/ruin/space/ks13/ai/vault) "xb" = ( /obj/structure/frame/computer{ @@ -2769,7 +2777,7 @@ pixel_y = 6 }, /obj/item/circuitboard/machine/chem_dispenser/drinks/beer, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "xN" = ( /obj/structure/rack, @@ -3008,6 +3016,11 @@ /obj/effect/spawner/structure/window/hollow/reinforced/middle, /turf/open/floor/plating/airless, /area/ruin/space/ks13/engineering/aft_solars_control) +"yY" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/structure/closet/crate/solarpanel_small, +/turf/open/floor/iron/airless, +/area/space/nearstation) "yZ" = ( /obj/structure/grille/broken, /obj/effect/decal/cleanable/glass, @@ -3153,6 +3166,13 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating/airless, /area/ruin/space/ks13/ai/vault) +"zJ" = ( +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/crate/solarpanel_small, +/turf/open/floor/iron/airless, +/area/ruin/space/ks13/hallway/central) "zK" = ( /obj/machinery/light/small/directional/east, /obj/effect/decal/cleanable/dirt, @@ -3474,7 +3494,7 @@ pixel_y = 6 }, /obj/item/circuitboard/machine/smes, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "Bv" = ( /obj/effect/decal/cleanable/glass, @@ -3869,7 +3889,7 @@ pixel_y = 6 }, /obj/item/ai_module/core/full/drone, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "DL" = ( /obj/structure/table, @@ -4575,7 +4595,7 @@ pixel_y = 6 }, /obj/item/circuitboard/machine/space_heater, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "Hh" = ( /obj/effect/decal/cleanable/dirt, @@ -4967,7 +4987,7 @@ pixel_x = -6; pixel_y = -6 }, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "Jz" = ( /obj/effect/mapping_helpers/burnt_floor, @@ -5361,12 +5381,12 @@ pixel_y = 6 }, /obj/item/circuitboard/machine/protolathe/offstation, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "LM" = ( /obj/machinery/light/small/directional/north, /obj/structure/cable, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "LN" = ( /turf/closed/wall, @@ -6037,7 +6057,7 @@ pixel_x = -6; pixel_y = -6 }, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "Pq" = ( /obj/effect/decal/cleanable/dirt, @@ -6407,7 +6427,7 @@ "Rm" = ( /obj/structure/rack, /obj/item/circuitboard/computer/crew, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "Ro" = ( /obj/structure/grille/broken, @@ -7530,7 +7550,7 @@ /obj/item/stack/sheet/mineral/silver{ amount = 15 }, -/turf/open/floor/iron/airless, +/turf/open/floor/circuit/red/airless, /area/ruin/space/ks13/ai/vault) "WO" = ( /obj/effect/spawner/random/maintenance, @@ -7609,7 +7629,7 @@ /obj/machinery/power/apc/auto_name/directional/north, /obj/effect/mapping_helpers/apc/no_charge, /obj/structure/cable, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "Xj" = ( /obj/effect/decal/cleanable/dirt, @@ -7675,6 +7695,10 @@ /obj/structure/cable, /turf/open/floor/iron/white/airless, /area/ruin/space/ks13/medical/medbay) +"XI" = ( +/obj/machinery/light/small/directional/south, +/turf/open/floor/circuit/red/off, +/area/ruin/space/ks13/ai/corridor) "XJ" = ( /obj/machinery/power/apc/auto_name/directional/west, /obj/effect/mapping_helpers/apc/no_charge, @@ -7735,6 +7759,13 @@ }, /turf/open/floor/iron, /area/ruin/space/ks13/command/bridge) +"Yb" = ( +/obj/structure/cable, +/obj/structure/frame/computer{ + anchored = 1 + }, +/turf/open/floor/iron, +/area/ruin/space/ks13/engineering/sb_bow_solars_control) "Yc" = ( /turf/closed/wall/r_wall, /area/ruin/space/ks13/ai/corridor) @@ -7835,7 +7866,7 @@ /area/ruin/space/ks13/hallway/aft) "YC" = ( /obj/structure/fluff/oldturret, -/turf/open/floor/iron, +/turf/open/floor/circuit/red/off, /area/ruin/space/ks13/ai/corridor) "YE" = ( /obj/structure/plaque/static_plaque/golden/commission/ks13, @@ -7980,7 +8011,7 @@ /obj/item/stack/sheet/mineral/plasma{ amount = 15 }, -/turf/open/floor/iron/airless, +/turf/open/floor/circuit/red/airless, /area/ruin/space/ks13/ai/vault) "Zq" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ @@ -8045,7 +8076,7 @@ /obj/item/stack/sheet/iron/fifty, /obj/item/stack/sheet/iron/fifty, /obj/item/stack/sheet/iron/fifty, -/turf/open/floor/iron/airless, +/turf/open/floor/circuit/red/airless, /area/ruin/space/ks13/ai/vault) "ZC" = ( /obj/structure/table/glass, @@ -8559,7 +8590,7 @@ xB vl NO uf -oU +yY zN qG aa @@ -8772,7 +8803,7 @@ aa aa rk MB -sh +wt Eu sh sh @@ -10761,13 +10792,13 @@ aa aa aa aa -rk aa aa aa -rk -rk -rk +aa +aa +aa +aa aa aa aa @@ -10873,16 +10904,16 @@ aa aa aa aa -rk aa -rk -rk -rk aa aa aa -rk -rk +aa +aa +aa +aa +aa +aa aa aa aa @@ -10986,16 +11017,16 @@ aa aa aa aa -rk -Yc -Yc -Yc -Yc -Yc -Yc -Yc aa -rk +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -11100,24 +11131,24 @@ aa aa aa aa -rk -Yc -Pw -fU -zA -fU -Yc aa -rk -rk -rk -rk -rk -rk -rk -rk -rk -rk +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa aa aa aa @@ -11212,32 +11243,32 @@ aa aa aa aa +aa rk -Yc -Yc -eA -Yc -Yc -fU -Yc -Jw -Jw -Jw -Jw -Jw -Jw -Jw -Jw -Jw -Jw -rk -rk +aa +aa +aa rk rk rk aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa rk rk rk @@ -11325,31 +11356,31 @@ aa aa aa aa +rk aa rk rk rk -Yc -AW -KO -Yc -Bw -Bw -Bw -Bw -Bw -Bw -IF -IF -RL aa aa +aa +rk rk aa aa aa aa aa +aa +aa +aa +aa +aa +aa +aa +aa +aa +aa rk rk rk @@ -11438,22 +11469,15 @@ aa aa aa aa -aa -aa -aa rk Yc Yc -lk Yc -Jw -Jw -Jw -Jw -Jw -Jw -Jw -Jw +Yc +Yc +Yc +Yc +aa rk aa aa @@ -11464,6 +11488,13 @@ aa aa aa aa +aa +aa +aa +aa +aa +aa +aa rk Kb rk @@ -11552,24 +11583,24 @@ aa aa aa aa -aa -aa -aa rk Yc +Pw fU +zA fU -fU -fU -fU -fU -fU -fU -YC Yc +aa +rk +rk +rk +rk +rk +rk +rk +rk rk rk -aa aa aa aa @@ -11664,23 +11695,24 @@ aa aa aa aa -aa -aa -aa -aa -aa -Yc -Yc -Yc -Yc -Yc +rk Yc Yc +eA Yc -st Yc +fU Yc -aa +Jw +Jw +Jw +Jw +Jw +Jw +Jw +Jw +Jw +Jw rk aa aa @@ -11690,7 +11722,6 @@ aa aa aa aa -aa rk sU Wk @@ -11778,22 +11809,22 @@ aa aa aa aa -aa -aa -aa -aa -Yc -YC -fU -fU -fU -fU -fU -fU -fU +rk +rk +rk Yc +AW +KO Yc -aa +sg +Bw +Bw +Bw +Bw +Bw +IF +IF +RL aa aa aa @@ -11893,20 +11924,20 @@ aa aa aa aa -aa -aa -Yc -Yc -st -Yc -Yc -Yc -Yc -Yc +rk Yc Yc +lk Yc -aa +Jw +Jw +Jw +Jw +Jw +Jw +Jw +Jw +rk aa aa aa @@ -12007,8 +12038,7 @@ aa aa aa aa -aa -Yc +rk Yc fU fU @@ -12017,10 +12047,11 @@ fU fU fU fU +fU YC Yc -aa -aa +rk +rk aa aa uu @@ -12042,11 +12073,11 @@ bm PI zv PI +Jc xJ xJ xJ -xJ -xJ +Jc zv PI zv @@ -12133,9 +12164,9 @@ st Yc Yc aa -aa rk aa +aa uu NJ QJ @@ -12246,8 +12277,8 @@ fU Yc Yc aa -IF -rk +aa +aa aa yf bN @@ -12359,8 +12390,8 @@ Yc Yc Yc aa -Bw -Gf +aa +aa aa yf wQ @@ -12472,8 +12503,8 @@ fU YC Yc aa -Bw -Gf +aa +aa aa yf WF @@ -12494,12 +12525,12 @@ PI zv PI zv -xJ -xJ +Jc xJ xJ xJ PI +PI fg FI pi @@ -12586,7 +12617,7 @@ Yc Yc Yc Bw -Gf +Jw aa yf yf @@ -12803,15 +12834,15 @@ Yc Yc Yc Yc -fU +lq Bu Hg fJ -fU +lq YC Yc Yc -IF +Xa aa aa aa @@ -13030,11 +13061,11 @@ Yc Yc Yc Xi -fU +lq qf Rm -fU -fU +lq +lq Yc LL Yc @@ -13149,7 +13180,7 @@ fU fU fU PW -KO +XI Yc aa aa @@ -13259,7 +13290,7 @@ LM xL Po Jy -fU +lq YC Yc DK @@ -13638,7 +13669,7 @@ QR NG yl XC -Qz +zJ Mz QR yg @@ -15734,7 +15765,7 @@ aa aa xS pR -pR +fe xS VB cR @@ -15846,7 +15877,7 @@ bP aa aa xS -VB +Yb IK xS pR diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/cargodiselost.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/cargodiselost.dmm index 57d2cafa4df14f..577fcf2f3a93de 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/cargodiselost.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/cargodiselost.dmm @@ -850,7 +850,7 @@ /area/ruin/space/has_grav/cargodise_freighter/cargo) "nv" = ( /obj/structure/table/reinforced, -/obj/item/gun/ballistic/automatic/pistol/makarov, +/obj/item/gun/ballistic/automatic/pistol/sol, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/cargodise_freighter/vault) "nw" = ( diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/clothing_facility.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/clothing_facility.dmm index a1f3c7868b8a6d..b8c0a4e576cbc0 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/clothing_facility.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/clothing_facility.dmm @@ -57,14 +57,14 @@ /turf/open/floor/engine, /area/ruin/space/has_grav/powered/skyrat/clothing_facility) "n" = ( -/obj/item/card/id/advanced/colourable{ - pixel_y = 6 - }, +/obj/item/card/id/advanced/silver/generic, /obj/structure/rack, -/obj/item/card/id/advanced/colourable{ +/obj/item/card/id/advanced/silver/generic{ pixel_y = 3 }, -/obj/item/card/id/advanced/colourable, +/obj/item/card/id/advanced/silver/generic{ + pixel_y = 6 + }, /turf/open/floor/engine, /area/ruin/space/has_grav/powered/skyrat/clothing_facility) "o" = ( diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/gorilla.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/gorilla.dmm index b36c9c867e4bc7..aecf79a010ea04 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/gorilla.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/gorilla.dmm @@ -6,7 +6,7 @@ /obj/structure/chair/sofa/right/brown{ dir = 4 }, -/mob/living/simple_animal/hostile/gorilla{ +/mob/living/basic/gorilla{ anchored = 1; dir = 4; faction = list("neutral") diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm index e12bdf68d11d37..0e37692de278d2 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/interdynefob.dmm @@ -1011,9 +1011,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 }, -/obj/structure/closet/secure_closet/personal{ - icon_state = "cabinet" - }, +/obj/structure/closet/secure_closet/personal, /obj/item/clothing/under/misc/syndicate_souvenir{ has_sensor = 0; pixel_y = -4 @@ -1893,6 +1891,8 @@ /obj/effect/turf_decal/trimline/dark_blue/filled/line, /obj/effect/turf_decal/siding/dark, /obj/structure/extinguisher_cabinet/directional/west, +/obj/structure/table/glass, +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma/advanced/unzipped, /turf/open/floor/iron/white/diagonal, /area/ruin/space/has_grav/skyrat/interdynefob/medbay) "hZ" = ( @@ -3392,7 +3392,7 @@ faction = list("Syndicate","neutral") }, /turf/closed/wall/r_wall/syndicate/nodiagonal, -/area/ruin/space/has_grav/skyrat/interdynefob/bridge/vault) +/area/ruin/space/has_grav/skyrat/interdynefob/security/armory) "oK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, @@ -3776,9 +3776,7 @@ has_sensor = 0; random_sensor = 0 }, -/obj/structure/closet/secure_closet/personal{ - icon_state = "cabinet" - }, +/obj/structure/closet/secure_closet/personal, /turf/open/floor/wood/tile, /area/ruin/space/has_grav/skyrat/interdynefob/service/dorms) "qt" = ( @@ -5167,8 +5165,7 @@ /area/ruin/space/has_grav/skyrat/interdynefob/cargo/hangar) "xk" = ( /obj/machinery/chem_dispenser/drinks/fullupgrade{ - dir = 8; - pixel_y = 0 + dir = 8 }, /obj/structure/table/wood, /turf/open/floor/wood/tile, @@ -5821,9 +5818,7 @@ dir = 4 }, /obj/item/clothing/under/syndicate/skyrat/baseball, -/obj/structure/closet/secure_closet/personal{ - icon_state = "cabinet" - }, +/obj/structure/closet/secure_closet/personal, /turf/open/floor/wood/tile, /area/ruin/space/has_grav/skyrat/interdynefob/service/dorms) "AC" = ( @@ -6608,7 +6603,6 @@ /turf/open/floor/iron/dark/textured_large, /area/ruin/space/has_grav/skyrat/interdynefob/engineering) "EC" = ( -/obj/structure/reagent_dispensers/wall/peppertank/directional/west, /obj/item/grenade/barrier{ pixel_y = 10 }, @@ -7192,13 +7186,14 @@ }, /obj/machinery/light/cold/directional/west, /obj/structure/rack/gunrack, -/obj/item/gun/ballistic/shotgun/riot/syndicate, -/obj/item/gun/ballistic/shotgun/riot/syndicate{ - pixel_x = -10 +/obj/item/gun/ballistic/automatic/sol_smg/evil{ + pixel_x = -8 }, -/obj/item/gun/ballistic/shotgun/riot/syndicate{ - pixel_x = -5; - pixel_y = -3 +/obj/item/gun/ballistic/shotgun/riot/sol/evil{ + pixel_x = 0 + }, +/obj/item/gun/ballistic/automatic/sol_rifle/evil{ + pixel_x = 8 }, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/skyrat/interdynefob/security/armory) @@ -9628,14 +9623,13 @@ }, /obj/machinery/firealarm/directional/west, /obj/structure/rack/gunrack, -/obj/item/gun/ballistic/automatic/pistol{ - pixel_x = -4; - pixel_y = 4 +/obj/item/gun/ballistic/automatic/pistol/sol/evil{ + pixel_x = -5 }, -/obj/item/gun/ballistic/automatic/pistol{ - pixel_x = -8 +/obj/item/gun/ballistic/automatic/pistol/sol/evil, +/obj/item/gun/ballistic/automatic/pistol/sol/evil{ + pixel_x = 5 }, -/obj/item/gun/ballistic/automatic/pistol, /turf/open/floor/mineral/plastitanium/red, /area/ruin/space/has_grav/skyrat/interdynefob/security/armory) "Sq" = ( @@ -11181,6 +11175,14 @@ }, /turf/open/floor/iron/dark, /area/ruin/space/has_grav/skyrat/interdynefob/research) +"YU" = ( +/obj/effect/turf_decal/siding/dark{ + dir = 4 + }, +/obj/structure/closet/secure_closet/armory_kiboko_but_evil, +/obj/structure/reagent_dispensers/wall/peppertank/directional/west, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/skyrat/interdynefob/security/armory) "Zd" = ( /obj/machinery/disposal/bin, /obj/effect/turf_decal/siding/thinplating/end{ @@ -11873,6 +11875,7 @@ PX PX PX PX +PX Vk Oi VP @@ -11882,7 +11885,6 @@ wg wg wg wg -wg "} (10,1,1) = {" wg @@ -11926,6 +11928,7 @@ Lv bS Hc Sp +YU EC PX Vk @@ -11937,7 +11940,6 @@ wg wg wg wg -wg "} (11,1,1) = {" wg @@ -11981,10 +11983,10 @@ mA uo uo uo +uo LY oG PX -PX NB NB xr diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon2.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon2.dmm index 1897f962201ace..877faaad71f5fc 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon2.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon2.dmm @@ -5057,7 +5057,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/light/dim/directional/east, /obj/effect/turf_decal/tile/red/anticorner, -/obj/item/ammo_box/magazine/multi_sprite/g17, +/obj/item/ammo_box/magazine/c35sol_pistol, /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/ruin/space/has_grav/port_tarkon/secoff) @@ -5395,7 +5395,7 @@ "ED" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/item/ammo_box/magazine/multi_sprite/g17, +/obj/item/ammo_box/magazine/c35sol_pistol, /obj/effect/decal/cleanable/dirt, /turf/open/floor/cult, /area/ruin/space/has_grav/port_tarkon/secoff) @@ -5894,7 +5894,7 @@ /area/ruin/space/has_grav/port_tarkon/garden) "Hk" = ( /obj/structure/cable, -/obj/item/ammo_box/magazine/multi_sprite/g17, +/obj/item/ammo_box/magazine/c35sol_pistol, /obj/effect/decal/cleanable/dirt, /turf/open/floor/cult, /area/ruin/space/has_grav/port_tarkon/secoff) @@ -6228,7 +6228,7 @@ dir = 4 }, /obj/effect/decal/cleanable/blood, -/obj/item/ammo_box/magazine/multi_sprite/g17, +/obj/item/ammo_box/magazine/c35sol_pistol, /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/ruin/space/has_grav/port_tarkon/centerhall) @@ -8511,7 +8511,7 @@ }, /obj/effect/turf_decal/delivery/blue, /obj/effect/turf_decal/tile/neutral/half, -/obj/item/ammo_box/magazine/multi_sprite/g17, +/obj/item/ammo_box/magazine/c35sol_pistol, /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/ruin/space/has_grav/port_tarkon/centerhall) @@ -8972,7 +8972,7 @@ /obj/effect/turf_decal/tile/neutral/half{ dir = 1 }, -/obj/item/ammo_box/magazine/multi_sprite/g17, +/obj/item/ammo_box/magazine/c35sol_pistol, /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/ruin/space/has_grav/port_tarkon/centerhall) diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon3.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon3.dmm index ae5484c9891da9..0589f45fba18c9 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon3.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon3.dmm @@ -6829,12 +6829,12 @@ "NX" = ( /obj/structure/rack, /obj/effect/decal/cleanable/dirt, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /obj/item/gun/ballistic/automatic/m6pdw, /obj/item/gun/ballistic/automatic/m6pdw, /obj/effect/turf_decal/tile/red/half{ diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon4.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon4.dmm index 6e42ed738cdc29..5514e997812365 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon4.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon4.dmm @@ -5983,12 +5983,12 @@ /area/ruin/space/has_grav/port_tarkon/secoff) "NX" = ( /obj/structure/rack, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /obj/item/gun/ballistic/automatic/m6pdw, /obj/item/gun/ballistic/automatic/m6pdw, /obj/effect/turf_decal/tile/red/half{ diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon5.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon5.dmm index eef26fbf6d9b78..5ebeb6648402e0 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon5.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/port_tarkon/defcon5.dmm @@ -6559,12 +6559,12 @@ /area/ruin/space/has_grav/port_tarkon/afthall) "NX" = ( /obj/structure/rack, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, -/obj/item/ammo_box/magazine/multi_sprite/g17, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /obj/item/gun/ballistic/automatic/m6pdw, /obj/item/gun/ballistic/automatic/m6pdw, /obj/effect/turf_decal/tile/red/half{ diff --git a/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm b/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm index 764240489836e7..254fe9eecd5aa5 100644 --- a/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm +++ b/_maps/RandomRuins/SpaceRuins/skyrat/wreckedhomestead.dmm @@ -84,11 +84,6 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/iron/airless, /area/ruin/unpowered) -"oa" = ( -/obj/machinery/rnd/bepis, -/obj/effect/mapping_helpers/burnt_floor, -/turf/open/floor/iron/airless, -/area/ruin/unpowered) "on" = ( /obj/structure/closet/secure_closet/brig, /obj/structure/window/reinforced/spawner/directional/west, @@ -133,6 +128,11 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron/dark/airless, /area/ruin/unpowered) +"tP" = ( +/obj/machinery/cryo_cell, +/obj/effect/mapping_helpers/burnt_floor, +/turf/open/floor/plating/airless, +/area/ruin/unpowered) "ve" = ( /obj/machinery/atmospherics/components/unary/thermomachine/freezer{ dir = 1 @@ -160,11 +160,6 @@ }, /turf/open/floor/plating/airless, /area/ruin/unpowered) -"Az" = ( -/obj/machinery/cryo_cell, -/obj/effect/mapping_helpers/burnt_floor, -/turf/open/floor/plating/airless, -/area/ruin/unpowered) "Bf" = ( /turf/closed/wall/mineral/titanium, /area/ruin/unpowered) @@ -1208,7 +1203,7 @@ wY Bf Wp Bf -Az +tP Dh ve mP @@ -1275,7 +1270,7 @@ Wv kN dL Bf -oa +kN Bf Bf Bf diff --git a/_maps/RandomZLevels/TheBeach.dmm b/_maps/RandomZLevels/TheBeach.dmm index 18d0a7fdc8628c..7b36dfb1471e06 100644 --- a/_maps/RandomZLevels/TheBeach.dmm +++ b/_maps/RandomZLevels/TheBeach.dmm @@ -1,401 +1,411 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE -"aa" = ( -/turf/closed/indestructible/sandstone, +"ae" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/vending/clothing, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"ab" = ( -/turf/open/indestructible/binary{ - density = 1; - desc = "I can't move through this."; - icon = 'icons/turf/beach.dmi'; - icon_state = "water"; - name = "deep ocean water" +"ah" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 8 }, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"af" = ( -/turf/open/misc/beach/coast{ - dir = 9 +"ai" = ( +/obj/structure/table/wood, +/obj/item/knife/kitchen{ + pixel_y = 12; + pixel_x = -13 }, +/obj/item/clothing/head/utility/chefhat, +/turf/open/floor/wood/large, /area/awaymission/beach) -"ag" = ( -/turf/open/misc/beach/coast{ - dir = 1 - }, +"an" = ( +/obj/structure/rack, +/obj/item/mop, +/obj/item/extinguisher, +/turf/open/floor/wood/large, /area/awaymission/beach) -"ah" = ( -/turf/open/misc/beach/coast{ - dir = 5 +"at" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 }, +/obj/machinery/door/airlock/wood{ + name = "Room 7"; + id_tag = "beach_room_7" + }, +/turf/open/floor/wood, /area/awaymission/beach) -"aj" = ( -/turf/open/misc/beach/coast{ - dir = 8 +"aw" = ( +/obj/structure/table/glass, +/obj/machinery/coffeemaker/impressa{ + pixel_y = 13; + pixel_x = -1 + }, +/obj/item/reagent_containers/cup/glass/mug{ + pixel_x = -6; + pixel_y = 2 }, +/obj/item/reagent_containers/cup/glass/mug{ + pixel_x = 11; + pixel_y = -1 + }, +/turf/open/floor/iron/dark/diagonal, /area/awaymission/beach) -"ak" = ( -/turf/open/misc/beach/sand, +"aB" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, /area/awaymission/beach) -"al" = ( -/obj/structure/flora/tree/palm{ - desc = "How did you get here?"; - icon_state = "palm2"; - name = "\proper island palm tree" +"aC" = ( +/obj/structure/table/bronze, +/obj/item/reagent_containers/condiment/bbqsauce{ + pixel_y = 13; + pixel_x = 3 }, -/turf/open/misc/beach/sand, +/obj/item/reagent_containers/condiment/hotsauce{ + pixel_y = 9; + pixel_x = -3 + }, +/turf/open/floor/wood/large, /area/awaymission/beach) -"am" = ( -/turf/open/misc/beach/coast{ - dir = 4 +"aE" = ( +/obj/item/cigbutt{ + pixel_y = 21; + pixel_x = -13 }, +/turf/open/floor/wood/large, /area/awaymission/beach) -"an" = ( -/obj/structure/flora/coconuts{ - pixel_x = 17; - pixel_y = 7 +"aT" = ( +/obj/machinery/shower/directional/west, +/obj/effect/turf_decal/siding/wood{ + dir = 9 }, -/turf/open/misc/beach/sand, +/turf/open/floor/wood, /area/awaymission/beach) -"ao" = ( -/turf/open/misc/beach/coast{ - dir = 10 +"aU" = ( +/obj/machinery/door/airlock/wood{ + name = "Garage" }, +/turf/open/floor/iron/dark/herringbone, /area/awaymission/beach) -"ap" = ( -/turf/open/misc/beach/coast, +"aX" = ( +/obj/machinery/space_heater, +/obj/structure/sign/clock/directional/north, +/turf/open/floor/wood, /area/awaymission/beach) -"aq" = ( -/turf/open/misc/beach/coast{ - dir = 6 +"bg" = ( +/obj/structure/no_effect_signpost{ + pixel_y = 6; + desc = "Northwest: Hotel. South: Seaside Bar. East: Dressing Rooms." }, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"as" = ( -/obj/structure/flora/rock/style_random{ - desc = "A volcanic rock."; - name = "coastal rock" - }, -/obj/structure/flora/bush/stalky/style_random{ - desc = "It can't be smoked."; - name = "sea weed" - }, -/turf/open/indestructible/binary{ - density = 1; - desc = "I can't move through this."; - icon = 'icons/turf/beach.dmi'; - icon_state = "water"; - name = "deep ocean water" +"bi" = ( +/turf/open/floor/iron/white/textured_large, +/area/awaymission/beach) +"bx" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/door/airlock/wood{ + name = "Bathroom"; + id_tag = "toiletfarbeach" }, +/turf/open/floor/iron/white, /area/awaymission/beach) -"at" = ( -/obj/structure/flora/rock/style_random{ - desc = "A volcanic rock."; - name = "coastal rock" - }, -/turf/open/indestructible/binary{ - density = 1; - desc = "I can't move through this."; - icon = 'icons/turf/beach.dmi'; - icon_state = "water"; - name = "deep ocean water" - }, -/area/awaymission/beach) -"au" = ( -/obj/structure/closet/crate/wooden{ - desc = "Now this is what island exploration is all about."; - name = "Treasure Chest" - }, -/obj/item/clothing/head/costume/pirate, -/obj/item/clothing/glasses/eyepatch, -/obj/item/clothing/suit/costume/pirate, -/obj/item/claymore/cutlass{ - desc = "A piratey, foam sword used by kids to train themselves in the business of \"negotiating\" the transfer of treasure."; - force = 0; - name = "foam cutlass"; - throwforce = 0 +"by" = ( +/obj/structure/table/bronze, +/obj/item/clothing/suit/costume/hawaiian{ + pixel_y = 2; + pixel_x = 5 }, -/obj/item/claymore/cutlass{ - desc = "A piratey, foam sword used by kids to train themselves in the business of \"negotiating\" the transfer of treasure."; - force = 0; - name = "foam cutlass"; - throwforce = 0 +/obj/item/clothing/suit/costume/hawaiian{ + pixel_y = 6; + pixel_x = -4 }, -/turf/open/misc/beach/sand, +/turf/open/floor/wood/parquet, /area/awaymission/beach) -"av" = ( -/turf/open/water/beach, +"bz" = ( +/obj/structure/table/bronze, +/obj/item/clothing/suit/costume/hawaiian{ + pixel_y = 7; + pixel_x = -3 + }, +/obj/machinery/light/directional/west, +/turf/open/floor/wood/parquet, /area/awaymission/beach) -"ay" = ( -/turf/open/misc/beach/coast/corner{ +"bC" = ( +/obj/vehicle/ridden/atv{ dir = 4 }, +/turf/open/floor/iron/dark/herringbone, /area/awaymission/beach) -"az" = ( -/turf/open/misc/beach/coast/corner{ - dir = 8 +"bH" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/railing{ + dir = 1 }, +/turf/open/floor/wood/parquet, /area/awaymission/beach) -"aA" = ( -/obj/structure/flora/tree/palm, +"bY" = ( +/obj/structure/fluff/beach_umbrella/cap, /turf/open/misc/beach/sand, /area/awaymission/beach) -"aB" = ( -/mob/living/basic/crab/kreb, +"cj" = ( +/obj/effect/turf_decal/siding/dark_red{ + dir = 4 + }, +/obj/item/trash/can{ + pixel_y = -9; + pixel_x = 10 + }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"aC" = ( -/obj/item/flashlight/flare/torch, -/turf/open/misc/beach/sand, +"cn" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/clothing/under/costume/lobster, +/obj/item/clothing/head/costume/lobsterhat, +/turf/open/floor/wood, /area/awaymission/beach) -"aD" = ( -/obj/structure/flora/coconuts, -/turf/open/misc/beach/sand, +"cp" = ( +/obj/structure/closet/crate/bin, +/turf/open/floor/wood, /area/awaymission/beach) -"aE" = ( -/obj/structure/chair{ - dir = 4 +"cq" = ( +/obj/machinery/light/directional/west, +/turf/open/floor/carpet/cyan, +/area/awaymission/beach) +"cv" = ( +/obj/structure/table/wood, +/obj/item/food/grown/watermelon{ + pixel_y = 8; + pixel_x = 6 }, +/obj/item/food/watermelonslice, /turf/open/misc/beach/sand, /area/awaymission/beach) -"aF" = ( -/obj/structure/bonfire/prelit, +"cw" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 24 + }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"aG" = ( -/obj/item/clothing/mask/gas/tiki_mask, +"cD" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 10 + }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"aH" = ( -/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind{ - pixel_x = -17; - pixel_y = 17 +"cE" = ( +/obj/structure/chair{ + dir = 8 }, -/turf/open/misc/beach/sand, +/turf/open/floor/iron/dark/textured_large, /area/awaymission/beach) -"aI" = ( -/obj/item/melee/skateboard/hoverboard{ - pixel_x = -16; - pixel_y = 1 +"cG" = ( +/obj/item/toy/beach_ball, +/turf/open/misc/beach/coast/corner{ + dir = 4 }, -/turf/open/water/beach, /area/awaymission/beach) -"aK" = ( -/mob/living/basic/crab, -/turf/open/misc/beach/sand, +"cR" = ( +/turf/open/floor/iron/freezer, /area/awaymission/beach) -"aO" = ( -/obj/effect/baseturf_helper/beach/sand, +"cX" = ( +/obj/structure/closet/crate/hydroponics, +/obj/item/popsicle_stick, +/obj/item/popsicle_stick, +/obj/item/popsicle_stick, +/obj/item/reagent_containers/condiment/flour, +/obj/item/reagent_containers/condiment/flour, +/obj/item/reagent_containers/condiment/rice, +/obj/item/reagent_containers/condiment/rice, +/obj/item/food/grown/banana/bunch, /turf/open/misc/beach/sand, /area/awaymission/beach) -"aQ" = ( -/obj/machinery/gateway/away, -/obj/effect/turf_decal/sand, -/turf/open/misc/beach/sand, +"cZ" = ( +/obj/machinery/door/airlock/wood{ + name = "Room 1"; + id_tag = "beach_room_1" + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood, /area/awaymission/beach) -"aS" = ( +"db" = ( /obj/item/reagent_containers/cup/soda_cans/lemon_lime{ pixel_x = -12; pixel_y = 14 }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"aT" = ( -/turf/open/misc/beach/coast/corner{ +"dc" = ( +/obj/effect/turf_decal/siding/wood/corner{ dir = 1 }, +/turf/open/floor/wood/large, /area/awaymission/beach) -"aX" = ( -/turf/closed/wall/mineral/sandstone, -/area/awaymission/beach) -"ba" = ( -/obj/effect/turf_decal/sand, -/turf/open/misc/beach/sand, -/area/awaymission/beach) -"bb" = ( -/obj/structure/dresser{ - density = 0; - pixel_y = 18 +"dg" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 }, -/turf/open/floor/wood, +/obj/machinery/vending/cigarette/beach, +/turf/open/floor/wood/large, /area/awaymission/beach) -"bc" = ( -/obj/structure/mirror/directional/north, -/turf/open/floor/wood, +"dh" = ( +/obj/machinery/vending/cola/pwr_game, +/turf/open/floor/eighties, /area/awaymission/beach) -"bd" = ( -/turf/open/floor/wood, +"di" = ( +/obj/effect/turf_decal/siding/wood, +/turf/open/water/beach, /area/awaymission/beach) -"be" = ( -/obj/machinery/computer/security/telescreen/entertainment/directional/north, -/turf/open/floor/wood, +"dk" = ( +/obj/item/cigbutt{ + pixel_y = -11; + pixel_x = -15 + }, +/turf/open/floor/iron/dark/diagonal, /area/awaymission/beach) -"bf" = ( +"dq" = ( /obj/effect/turf_decal/sand, -/obj/effect/turf_decal/stripes/asteroid/line{ +/obj/effect/turf_decal/siding/wood{ dir = 9 }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"bg" = ( -/obj/effect/turf_decal/sand, -/obj/effect/turf_decal/stripes/asteroid/line{ - dir = 1 - }, -/turf/open/misc/beach/sand, +"dr" = ( +/obj/structure/musician/piano, +/turf/open/floor/wood, /area/awaymission/beach) -"bh" = ( -/obj/effect/turf_decal/sand, -/obj/effect/turf_decal/stripes/asteroid/line{ - dir = 5 +"dx" = ( +/obj/structure/sign/directions/dorms/directional/north{ + pixel_y = 35 }, -/turf/open/misc/beach/sand, -/area/awaymission/beach) -"bi" = ( -/obj/machinery/button/door/directional/east{ - id = "changlinhut2"; - name = "changing room lock"; - normaldoorcontrol = 1; - specialfunctions = 4 +/obj/structure/sign/directions/medical/directional/north{ + pixel_y = 29 }, -/turf/open/floor/wood, +/obj/machinery/computer/slot_machine, +/turf/open/floor/wood/large, /area/awaymission/beach) -"bj" = ( -/obj/machinery/button/door/directional/west{ - id = "changlinhut1"; - name = "changing room lock"; - normaldoorcontrol = 1; - specialfunctions = 4 +"dL" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Locker Room" }, -/turf/open/floor/wood, +/turf/open/floor/wood/parquet, /area/awaymission/beach) -"bk" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/obj/item/clothing/glasses/heat, -/turf/open/floor/wood, +"dO" = ( +/obj/effect/baseturf_helper/beach/water, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"bl" = ( -/obj/structure/bed, -/obj/item/bedsheet/dorms, -/obj/machinery/button/door/directional/east{ - id = "theloveshack1"; - name = "door lock"; - normaldoorcontrol = 1; - specialfunctions = 4 +"dR" = ( +/obj/machinery/door/airlock/wood{ + name = "Balcony"; + id_tag = "beach_room_x" }, -/turf/open/floor/wood, -/area/awaymission/beach) -"bm" = ( -/obj/structure/bed, -/obj/item/bedsheet/dorms, -/obj/machinery/button/door/directional/east{ - id = "theloveshack2"; - name = "door lock"; - normaldoorcontrol = 1; - specialfunctions = 4 +/obj/structure/railing/corner/end{ + dir = 8 }, /turf/open/floor/wood, /area/awaymission/beach) -"bn" = ( -/obj/structure/bed, -/obj/item/bedsheet/dorms, -/obj/machinery/button/door/directional/east{ - id = "theloveshack3"; - name = "door lock"; - normaldoorcontrol = 1; - specialfunctions = 4 +"dS" = ( +/obj/item/kirbyplants/organic/applebush{ + pixel_x = 7 }, -/turf/open/floor/wood, -/area/awaymission/beach) -"bo" = ( -/turf/open/misc/beach/coast/corner, -/area/awaymission/beach) -"bp" = ( -/obj/effect/turf_decal/sand, -/obj/effect/turf_decal/stripes/asteroid/line{ - dir = 8 +/obj/item/kirbyplants/organic/plant17{ + pixel_y = 2; + pixel_x = -8 }, -/turf/open/misc/beach/sand, +/turf/open/floor/wood/large, /area/awaymission/beach) -"bq" = ( -/obj/effect/turf_decal/sand, -/obj/machinery/telecomms/allinone, +"dV" = ( +/obj/effect/turf_decal/siding/blue, /turf/open/misc/beach/sand, /area/awaymission/beach) -"br" = ( -/obj/effect/turf_decal/sand, -/obj/effect/turf_decal/stripes/asteroid/line{ - dir = 4 +"ea" = ( +/obj/structure/table/bronze, +/obj/structure/desk_bell{ + pixel_x = 7; + pixel_y = 8 }, -/turf/open/misc/beach/sand, +/turf/open/floor/wood/large, /area/awaymission/beach) -"bs" = ( -/obj/machinery/door/airlock/sandstone{ - id_tag = "changlinhut2"; - name = "Changing Room" +"eE" = ( +/obj/structure/table/glass, +/obj/machinery/microwave{ + pixel_y = 15 }, -/turf/open/floor/wood, +/obj/item/cigbutt{ + pixel_y = 2; + pixel_x = -12 + }, +/turf/open/floor/iron/dark/diagonal, /area/awaymission/beach) -"bt" = ( -/obj/machinery/door/airlock/sandstone{ - id_tag = "changlinhut1"; - name = "Changing Room" +"eH" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 5 }, -/turf/open/floor/wood, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"bu" = ( +"eT" = ( /obj/structure/table/wood, -/obj/item/reagent_containers/cup/glass/bottle/whiskey{ - pixel_y = 3 +/obj/item/clothing/mask/cigarette/cigar{ + pixel_y = 16; + pixel_x = -2 }, -/turf/open/floor/wood, -/area/awaymission/beach) -"bx" = ( -/obj/effect/turf_decal/sand, -/obj/effect/turf_decal/stripes/asteroid/line{ - dir = 10 +/obj/item/reagent_containers/cup/glass/coffee{ + pixel_x = 8; + pixel_y = 9 }, -/turf/open/misc/beach/sand, -/area/awaymission/beach) -"by" = ( -/obj/effect/turf_decal/sand, -/obj/effect/turf_decal/stripes/asteroid/line, -/turf/open/misc/beach/sand, +/obj/machinery/cell_charger, +/turf/open/floor/iron/dark/diagonal, /area/awaymission/beach) -"bz" = ( -/obj/effect/turf_decal/sand, -/obj/effect/turf_decal/stripes/asteroid/line{ - dir = 6 +"fa" = ( +/obj/structure/table/reinforced, +/obj/item/toy/plush/slimeplushie{ + pixel_y = 8; + pixel_x = 4 }, -/turf/open/misc/beach/sand, +/turf/open/floor/iron/white/textured_large, /area/awaymission/beach) -"bA" = ( -/obj/structure{ - desc = "Bar and beach south, dorms east."; - icon = 'icons/obj/fluff/general.dmi'; - icon_state = "signpost"; - name = "directions signpost" +"fd" = ( +/obj/structure/table/bronze, +/obj/structure/desk_bell{ + pixel_x = -11; + pixel_y = 9 }, -/turf/open/misc/beach/sand, -/area/awaymission/beach) -"bB" = ( -/obj/machinery/door/airlock/sandstone{ - id_tag = "theloveshack1"; - name = "Beach Hut" +/obj/item/phone{ + pixel_y = 9; + pixel_x = 8 }, -/turf/open/floor/wood, +/turf/open/floor/carpet, /area/awaymission/beach) -"bC" = ( -/obj/machinery/door/airlock/sandstone{ - id_tag = "theloveshack2"; - name = "Beach Hut" +"fe" = ( +/obj/effect/turf_decal/siding/wood, +/obj/item/cigbutt{ + pixel_y = -9; + pixel_x = 13 }, -/turf/open/floor/wood, +/turf/open/water/beach, /area/awaymission/beach) -"bD" = ( -/obj/machinery/door/airlock/sandstone{ - id_tag = "theloveshack3"; - name = "Beach Hut" +"fi" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/plating, +/area/awaymission/beach) +"fj" = ( +/obj/machinery/door/airlock/wood{ + name = "Room 3"; + id_tag = "beach_room_3" + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 }, /turf/open/floor/wood, /area/awaymission/beach) -"bE" = ( +"fm" = ( /obj/structure/flora/tree/palm{ pixel_y = 25 }, @@ -405,401 +415,392 @@ }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"bF" = ( -/obj/structure/bedsheetbin, -/obj/effect/turf_decal/sand, +"fu" = ( +/obj/structure/window/reinforced/spawner/directional/west, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/item/binoculars{ + pixel_y = 20 + }, +/obj/item/megaphone{ + pixel_y = 2; + pixel_x = 1 + }, /obj/structure/table/wood, -/turf/open/misc/beach/sand, -/area/awaymission/beach) -"bG" = ( -/obj/item/clothing/shoes/sandal, -/obj/item/clothing/shoes/sandal, -/obj/item/clothing/shoes/sandal, -/obj/structure/closet/crate, -/obj/effect/turf_decal/sand, -/turf/open/misc/beach/sand, -/area/awaymission/beach) -"bH" = ( -/obj/structure/closet/athletic_mixed, -/obj/effect/turf_decal/sand, -/turf/open/misc/beach/sand, -/area/awaymission/beach) -"bI" = ( -/obj/machinery/door/airlock/sandstone{ - id_tag = "loveshack"; - name = "Beach Hut" +/obj/effect/turf_decal/siding/wood{ + dir = 10 }, /turf/open/floor/wood, /area/awaymission/beach) -"bJ" = ( -/obj/machinery/door/airlock/sandstone{ - id_tag = "theloveshack4"; - name = "Beach Hut" +"fv" = ( +/obj/machinery/chem_master/condimaster{ + name = "CondiMaster Neo" }, -/turf/open/floor/wood, +/turf/open/floor/wood/large, /area/awaymission/beach) -"bK" = ( -/obj/machinery/door/airlock/sandstone{ - id_tag = "theloveshack5"; - name = "Beach Hut" +"fz" = ( +/obj/structure/window/reinforced/spawner/directional/north, +/obj/structure/window/reinforced/spawner/directional/west, +/obj/structure/table/wood, +/obj/item/storage/medkit/o2{ + pixel_y = 4; + pixel_x = 1 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 9 }, /turf/open/floor/wood, /area/awaymission/beach) -"bL" = ( -/obj/structure/toilet{ - pixel_y = 8 +"fI" = ( +/obj/structure/table/bronze, +/obj/item/clothing/suit/costume/hawaiian{ + pixel_y = 6; + pixel_x = 4 }, -/obj/effect/turf_decal/sand, -/turf/open/floor/iron/white, -/area/awaymission/beach) -"bM" = ( -/obj/structure/mirror/directional/east, -/obj/effect/turf_decal/sand, -/obj/structure/sink/directional/south, -/turf/open/floor/iron/white, -/area/awaymission/beach) -"bN" = ( -/obj/structure/mirror/directional/west, -/obj/effect/turf_decal/sand, -/obj/structure/sink/directional/south, -/turf/open/floor/iron/white, +/turf/open/floor/wood/parquet, /area/awaymission/beach) -"bO" = ( -/obj/structure/table/wood, -/obj/item/reagent_containers/cup/glass/bottle/tequila{ - pixel_y = 2 +"fM" = ( +/obj/effect/turf_decal/siding/blue{ + dir = 4 }, -/turf/open/floor/wood, -/area/awaymission/beach) -"bP" = ( -/obj/item/trash/chips{ - pixel_x = -18; - pixel_y = 7 +/obj/structure/chair/plastic{ + dir = 4 }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"bQ" = ( -/obj/effect/turf_decal/sand, -/turf/open/floor/iron/white, -/area/awaymission/beach) -"bR" = ( -/obj/effect/turf_decal/sand, -/obj/machinery/button/door/directional/east{ - id = "toilet1"; - name = "restroom lock"; - normaldoorcontrol = 1; - specialfunctions = 4 +"fU" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 14 }, -/turf/open/floor/iron/white, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"bS" = ( -/obj/effect/turf_decal/sand, -/obj/machinery/button/door/directional/west{ - id = "toilet2"; - name = "restroom lock"; - normaldoorcontrol = 1; - specialfunctions = 4 +"fV" = ( +/obj/machinery/light/directional/east, +/obj/effect/turf_decal/siding/wood{ + dir = 8 }, -/turf/open/floor/iron/white, +/turf/open/floor/wood/large, /area/awaymission/beach) -"bT" = ( -/obj/structure/bed, -/obj/item/bedsheet/red, -/obj/machinery/button/door/directional/east{ - id = "loveshack"; - name = "love shack lock"; - normaldoorcontrol = 1; - specialfunctions = 4 - }, -/turf/open/floor/wood, +"fX" = ( +/obj/structure/chair, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"bU" = ( -/obj/structure/bed, -/obj/item/bedsheet/dorms, -/obj/machinery/button/door/directional/east{ - id = "theloveshack4"; - name = "door lock"; - normaldoorcontrol = 1; - specialfunctions = 4 +"gd" = ( +/obj/effect/spawner/random/entertainment/arcade{ + dir = 8 }, -/turf/open/floor/wood, +/turf/open/floor/eighties, /area/awaymission/beach) -"bV" = ( -/obj/structure/sign/poster/ripped/directional/east, +"gi" = ( +/obj/effect/turf_decal/siding/dark_red{ + dir = 4 + }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"bW" = ( -/obj/structure/bed, -/obj/item/bedsheet/dorms, -/obj/machinery/button/door/directional/east{ - id = "theloveshack5"; - name = "door lock"; - normaldoorcontrol = 1; - specialfunctions = 4 +"gj" = ( +/obj/effect/turf_decal/siding/blue{ + dir = 8 }, -/turf/open/floor/wood, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"bX" = ( -/obj/machinery/door/airlock/sandstone{ - id_tag = "toilet1"; - name = "Restroom Stall" +"gk" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 }, -/obj/effect/turf_decal/sand, -/turf/open/floor/iron/white, +/turf/closed/wall/mineral/wood, /area/awaymission/beach) -"bY" = ( -/obj/machinery/door/airlock/sandstone{ - id_tag = "toilet2"; - name = "Restroom Stall" +"gw" = ( +/obj/item/stack/sheet/mineral/sandstone{ + pixel_x = -8 }, -/obj/effect/turf_decal/sand, -/turf/open/floor/iron/white, -/area/awaymission/beach) -"bZ" = ( -/obj/structure/dresser{ - density = 0 +/obj/item/stack/sheet/mineral/sandstone{ + pixel_x = 5 }, -/turf/open/floor/wood, -/area/awaymission/beach) -"ca" = ( -/obj/machinery/computer/security/telescreen/entertainment/directional/south, -/turf/open/floor/wood, -/area/awaymission/beach) -"cb" = ( -/obj/structure/sign/poster/contraband/syndicate_recruitment/directional/west, -/turf/open/misc/beach/sand, -/area/awaymission/beach) -"cc" = ( -/obj/item/trash/can{ - pixel_x = 14; +/obj/item/stack/sheet/mineral/sandstone{ + pixel_x = 1; pixel_y = 7 }, +/obj/item/stack/sheet/mineral/sandstone{ + pixel_x = -12; + pixel_y = 6 + }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"cd" = ( -/obj/machinery/vending/cola/starkist, -/obj/effect/turf_decal/sand, -/turf/open/misc/beach/sand, +"gG" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/water/beach, /area/awaymission/beach) -"cf" = ( -/obj/structure/table/wood, -/turf/open/floor/wood, +"gI" = ( +/obj/structure/flora/tree/palm/style_2{ + pixel_y = 4 + }, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"cg" = ( -/obj/effect/turf_decal/sand, -/obj/machinery/vending/cola/space_up, +"gP" = ( +/obj/structure/chair/plastic, /turf/open/misc/beach/sand, /area/awaymission/beach) -"ch" = ( -/obj/structure/flora/tree/palm, -/obj/structure/flora/coconuts, +"gR" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"ci" = ( -/obj/structure/closet/gmcloset, -/turf/open/floor/wood, +"hf" = ( +/obj/effect/turf_decal/siding/wood/corner, +/turf/open/water/beach, /area/awaymission/beach) -"cj" = ( -/obj/structure/closet/secure_closet/bar/all_access, -/obj/item/storage/box/drinkingglasses, -/obj/item/storage/box/drinkingglasses, -/obj/item/storage/box/drinkingglasses, -/obj/item/storage/box/drinkingglasses, -/obj/item/storage/box/drinkingglasses, -/obj/item/storage/box/drinkingglasses, -/turf/open/floor/wood, +"ho" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/machinery/door/poddoor/shutters{ + id = "BeachBoats" + }, +/turf/open/water/beach, /area/awaymission/beach) -"ck" = ( -/obj/effect/mob_spawn/corpse/human/bartender, +"hp" = ( +/obj/structure/table/bronze, +/obj/structure/sign/poster/random/directional/east, +/obj/machinery/button/door/directional/south{ + id = "beach_room_10" + }, +/obj/item/table_clock{ + pixel_y = 4 + }, /turf/open/floor/wood, /area/awaymission/beach) -"cl" = ( -/obj/machinery/processor, -/obj/structure/table/wood, +"hC" = ( +/obj/structure/railing{ + dir = 8 + }, /turf/open/floor/wood, /area/awaymission/beach) -"cn" = ( -/obj/machinery/vending/boozeomat/all_access{ - desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one. May not work for bartenders that don't have Nanotrasen bank accounts." +"hD" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 }, -/turf/open/floor/wood, +/obj/item/clothing/mask/breath/medical{ + pixel_y = 7; + pixel_x = -9 + }, +/obj/item/clothing/mask/breath/medical{ + pixel_y = 4; + pixel_x = 3 + }, +/obj/item/clothing/gloves/latex, +/obj/structure/table/glass, +/turf/open/floor/wood/large, /area/awaymission/beach) -"co" = ( -/obj/structure/table/wood, -/obj/machinery/chem_dispenser/drinks/fullupgrade, -/obj/structure/sign/picture_frame{ - pixel_y = 32 +"hL" = ( +/turf/open/misc/beach/coast/corner{ + dir = 1 }, -/turf/open/floor/wood, /area/awaymission/beach) -"cp" = ( -/obj/structure/table/wood, -/obj/machinery/chem_dispenser/drinks/beer/fullupgrade, -/turf/open/floor/wood, +"hQ" = ( +/obj/effect/turf_decal/siding/wood/corner, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/turf/open/water/beach, /area/awaymission/beach) -"cq" = ( -/obj/structure/table/wood, -/obj/machinery/microwave, +"im" = ( +/obj/structure/table/bronze, +/obj/structure/sign/poster/random/directional/east, +/obj/item/table_clock{ + pixel_y = 4 + }, /turf/open/floor/wood, /area/awaymission/beach) -"cr" = ( -/obj/structure/closet/secure_closet/freezer/kitchen/all_access, -/obj/item/storage/fancy/egg_box, -/obj/item/reagent_containers/condiment/milk, -/obj/item/reagent_containers/condiment/milk, -/obj/item/reagent_containers/condiment/flour, -/obj/item/reagent_containers/condiment/flour, -/obj/item/reagent_containers/condiment/mayonnaise, -/obj/item/reagent_containers/condiment/sugar, -/obj/item/reagent_containers/condiment/sugar, -/obj/item/reagent_containers/condiment/enzyme, -/turf/open/floor/wood, +"io" = ( +/obj/effect/spawner/random/entertainment/arcade{ + dir = 4 + }, +/turf/open/floor/wood/large, /area/awaymission/beach) -"cs" = ( -/obj/effect/spawner/random/vending/snackvend, -/obj/effect/turf_decal/sand, -/turf/open/misc/beach/sand, +"iq" = ( +/obj/machinery/washing_machine, +/obj/machinery/light/directional/north, +/turf/open/floor/plastic, /area/awaymission/beach) -"ct" = ( -/obj/effect/turf_decal/stripes/white/corner, -/turf/open/misc/beach/sand, +"iw" = ( +/obj/structure/sign/poster/official/fruit_bowl/directional/north, +/turf/open/floor/carpet, /area/awaymission/beach) -"cu" = ( -/obj/effect/turf_decal/stripes/white/line, -/turf/open/misc/beach/sand, +"iy" = ( +/obj/structure/sign/poster/contraband/pwr_game/directional/west, +/turf/open/floor/eighties, /area/awaymission/beach) -"cv" = ( -/obj/effect/turf_decal/stripes/white/corner{ +"iA" = ( +/obj/effect/turf_decal/siding/wood{ dir = 8 }, -/turf/open/misc/beach/sand, -/area/awaymission/beach) -"cw" = ( -/obj/structure/closet/secure_closet/freezer/meat/open, -/obj/item/food/meat/slab/goliath, -/obj/item/food/meat/slab/xeno, -/obj/item/food/meat/slab/spider, -/obj/item/food/meat/slab/killertomato, -/obj/item/food/meat/slab/bear, -/obj/item/food/meat/slab/rawcrab, -/obj/item/food/meat/slab/rawcrab, -/obj/item/food/meat/slab/rawcrab, -/obj/item/food/meat/slab/rawcrab, -/obj/item/food/meat/slab/rawcrab, -/turf/open/floor/wood, +/turf/open/water/beach, /area/awaymission/beach) -"cx" = ( -/obj/effect/turf_decal/stripes/white/line{ - dir = 4 +"iF" = ( +/obj/item/trash/candy{ + pixel_y = 9; + pixel_x = -9 }, -/turf/open/misc/beach/sand, -/area/awaymission/beach) -"cy" = ( -/obj/effect/turf_decal/stripes/white/full, -/turf/open/misc/beach/sand, +/turf/open/floor/wood/large, /area/awaymission/beach) -"cz" = ( -/obj/effect/turf_decal/stripes/white/line{ +"iI" = ( +/mob/living/basic/crab, +/obj/effect/turf_decal/stripes/red/line{ dir = 8 }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"cA" = ( -/obj/structure/mineral_door/wood{ - name = "bar" - }, -/turf/open/floor/wood, +"iJ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/rack, +/obj/effect/spawner/random/maintenance/three, +/obj/effect/decal/cleanable/cobweb, +/obj/item/wheelchair, +/turf/open/floor/plating, /area/awaymission/beach) -"cC" = ( -/obj/structure/table/wood, -/obj/item/food/burger/crab{ +"iM" = ( +/obj/structure/table/glass, +/obj/item/storage/box/coffeepack{ + pixel_x = 2; + pixel_y = 4 + }, +/obj/item/storage/box/donkpockets{ + pixel_y = 10; + pixel_x = 11 + }, +/obj/item/storage/fancy/donut_box{ + pixel_y = 18; pixel_x = -11 }, -/turf/open/floor/wood, +/obj/item/food/donut/berry{ + pixel_y = 5; + pixel_x = -6 + }, +/turf/open/floor/iron/dark/diagonal, /area/awaymission/beach) -"cD" = ( -/obj/structure/table/wood, -/obj/item/reagent_containers/cup/rag{ - pixel_y = 7 +"iN" = ( +/obj/structure/table/wood/poker, +/obj/item/stack/spacecash/c100{ + pixel_y = 5 }, -/obj/item/food/burger/crab{ - pixel_x = -14; - pixel_y = 9 +/obj/item/toy/cards/deck{ + pixel_y = 13; + pixel_x = -5 }, -/turf/open/floor/wood, -/area/awaymission/beach) -"cE" = ( -/obj/structure/table/wood, -/obj/item/reagent_containers/cup/soda_cans/dr_gibb, -/turf/open/floor/wood, +/turf/open/floor/wood/large, /area/awaymission/beach) -"cF" = ( +"iU" = ( /obj/structure/table/wood, -/obj/item/reagent_containers/cup/soda_cans/lemon_lime, -/turf/open/floor/wood, +/obj/machinery/chem_dispenser/drinks/fullupgrade{ + dir = 4 + }, +/turf/open/floor/wood/large, /area/awaymission/beach) -"cG" = ( -/obj/item/toy/beach_ball, +"iW" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"cH" = ( -/obj/effect/turf_decal/sand, -/obj/structure/chair/stool/directional/north, -/turf/open/misc/beach/sand, +"iY" = ( +/obj/structure/sign/departments/custodian/directional/north{ + pixel_x = -32 + }, +/turf/open/floor/wood/large, /area/awaymission/beach) -"cI" = ( -/obj/effect/turf_decal/sand, -/obj/machinery/barsign/all_access/directional/north, -/turf/open/misc/beach/sand, +"jm" = ( +/obj/structure/table/reinforced, +/obj/machinery/cell_charger{ + pixel_y = 13; + pixel_x = 21 + }, +/obj/item/clothing/glasses/hud/health{ + pixel_y = 1; + pixel_x = 18 + }, +/obj/item/stack/medical/gauze{ + pixel_x = -15; + pixel_y = 10 + }, +/obj/item/storage/belt/medical{ + pixel_y = 3; + pixel_x = -3 + }, +/obj/machinery/light/directional/north, +/turf/open/floor/iron/white/textured_large, /area/awaymission/beach) -"cJ" = ( -/obj/effect/turf_decal/stripes/white/corner, -/obj/effect/turf_decal/stripes/white/line{ - dir = 4 +"jF" = ( +/obj/machinery/vending/boozeomat/all_access{ + desc = "A technological marvel, supposedly able to mix just the mixture you'd like to drink the moment you ask for one. May not work for bartenders that don't have Nanotrasen bank accounts." }, -/turf/open/misc/beach/sand, +/turf/open/floor/wood/large, /area/awaymission/beach) -"cL" = ( -/obj/structure/table, -/obj/item/clothing/under/color/rainbow, -/obj/item/clothing/glasses/sunglasses, -/obj/item/clothing/head/collectable/petehat{ - pixel_y = 5 +"jH" = ( +/obj/item/storage/box/fishing_hooks{ + pixel_y = 14 + }, +/obj/item/storage/box/fishing_lines{ + pixel_y = 12; + pixel_x = 18 }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"cM" = ( -/obj/structure/table, -/obj/item/food/chips, -/turf/open/misc/beach/sand, +"jI" = ( +/obj/structure/railing{ + dir = 10 + }, +/obj/item/kirbyplants/organic/plant8{ + pixel_y = 9; + pixel_x = 6 + }, +/turf/open/floor/wood, /area/awaymission/beach) -"cN" = ( -/obj/structure/table, -/obj/item/reagent_containers/cup/soda_cans/sodawater, -/obj/item/reagent_containers/cup/soda_cans/shamblers, -/obj/item/reagent_containers/cup/soda_cans/pwr_game, -/obj/item/reagent_containers/cup/soda_cans/air, -/obj/item/reagent_containers/cup/soda_cans/canned_laughter, -/obj/item/reagent_containers/cup/soda_cans/tonic, +"jM" = ( +/obj/item/clothing/head/soft/black{ + pixel_x = -1; + pixel_y = -3 + }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"cO" = ( -/obj/structure/chair, -/turf/open/misc/beach/sand, +"jU" = ( +/obj/machinery/door/airlock/maintenance, +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/floor/plating, /area/awaymission/beach) -"cP" = ( -/obj/item/reagent_containers/cup/soda_cans/lemon_lime{ - pixel_x = -12; - pixel_y = -7 +"jW" = ( +/turf/closed/wall/mineral/sandstone, +/area/awaymission/beach) +"jZ" = ( +/obj/structure/bed/double, +/obj/item/bedsheet/hop/double{ + desc = "A blue bedsheet. Likely from the beach hotel."; + name = "blue bedsheet" }, -/obj/item/reagent_containers/cup/soda_cans/dr_gibb{ - pixel_x = 13; - pixel_y = -7 +/turf/open/floor/carpet/cyan, +/area/awaymission/beach) +"ke" = ( +/obj/effect/turf_decal/sand/plating, +/obj/item/reagent_containers/cup/bucket/wooden{ + pixel_y = 17; + pixel_x = -6 }, -/obj/structure/fluff/beach_umbrella, /turf/open/misc/beach/sand, /area/awaymission/beach) -"cQ" = ( +"kh" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"kl" = ( /obj/item/reagent_containers/cup/soda_cans/starkist{ pixel_x = -12; pixel_y = -6 @@ -807,14786 +808,68764 @@ /obj/structure/fluff/beach_umbrella/cap, /turf/open/misc/beach/sand, /area/awaymission/beach) -"cR" = ( -/obj/item/reagent_containers/cup/soda_cans/cola{ - pixel_x = -8; - pixel_y = -4 +"ko" = ( +/obj/structure/closet/secure_closet/freezer/empty, +/obj/item/food/popsicle/creamsicle_berry, +/obj/item/food/popsicle/creamsicle_berry, +/obj/item/food/popsicle/creamsicle_orange, +/obj/item/food/popsicle/creamsicle_orange, +/obj/item/food/popsicle/jumbo, +/obj/item/food/popsicle/pineapple_pop, +/obj/item/food/popsicle/pineapple_pop, +/obj/item/food/fishmeat, +/obj/item/food/fishmeat, +/obj/item/food/fishmeat, +/obj/item/food/fishmeat, +/obj/item/food/fishmeat, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"kp" = ( +/obj/effect/decal/cleanable/oil, +/obj/machinery/button/door/directional/south{ + id = "BeachGarage" }, -/turf/open/misc/beach/sand, +/turf/open/floor/iron/dark/herringbone, /area/awaymission/beach) -"cS" = ( -/obj/item/reagent_containers/cup/soda_cans/dr_gibb{ - pixel_x = -9; - pixel_y = -9 +"kz" = ( +/obj/item/storage/medkit/regular{ + pixel_y = 15; + pixel_x = -2 }, -/obj/structure/fluff/beach_umbrella/engine, -/turf/open/misc/beach/sand, +/obj/structure/table/glass, +/obj/item/emergency_bed{ + pixel_y = 6 + }, +/turf/open/floor/iron/white/textured_large, /area/awaymission/beach) -"cT" = ( -/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind, -/turf/open/misc/beach/sand, +"kB" = ( +/obj/structure/closet/crate/bin, +/turf/open/floor/wood/large, /area/awaymission/beach) -"cU" = ( -/obj/item/reagent_containers/cup/soda_cans/cola{ +"kC" = ( +/obj/structure/sign/chalkboard_menu{ + pixel_y = 32 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"kD" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/clothing/glasses/heat, +/obj/item/clothing/head/cowboy/brown, +/turf/open/floor/wood, +/area/awaymission/beach) +"kG" = ( +/obj/effect/baseturf_helper/beach/sand, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"kI" = ( +/obj/machinery/light/directional/west, +/turf/open/floor/carpet, +/area/awaymission/beach) +"kR" = ( +/obj/machinery/button/door/directional/north{ + id = "beach_room_12" + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"kZ" = ( +/turf/open/floor/eighties, +/area/awaymission/beach) +"lb" = ( +/obj/structure/railing/corner/end/flip{ + dir = 4 + }, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"lf" = ( +/obj/structure/chair/stool/directional/south, +/obj/machinery/light/directional/north, +/turf/open/floor/iron/freezer, +/area/awaymission/beach) +"li" = ( +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade{ + dir = 4 + }, +/obj/structure/table/wood, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"lk" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 9 + }, +/obj/effect/turf_decal/tile/dark/half{ + pixel_y = -1; + pixel_x = 5; + dir = 8 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"ll" = ( +/obj/machinery/door/airlock/wood{ + name = "Room 11"; + id_tag = "beach_room_11" + }, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood, +/area/awaymission/beach) +"ls" = ( +/obj/structure/flora/coconuts, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"lz" = ( +/obj/machinery/door/airlock/wood{ + name = "Room 10"; + id_tag = "beach_room_10" + }, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood, +/area/awaymission/beach) +"lB" = ( +/obj/machinery/door/poddoor/shutters{ + id = "BeachBoats" + }, +/turf/open/water/beach, +/area/awaymission/beach) +"lP" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 16 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"lS" = ( +/obj/machinery/medical_kiosk, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"lY" = ( +/obj/structure/reagent_dispensers/fueltank, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/plating, +/area/awaymission/beach) +"mb" = ( +/obj/structure/chair/stool/bar/directional/west, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"mf" = ( +/obj/item/toy/seashell, +/turf/open/misc/beach/coast/corner{ + dir = 8 + }, +/area/awaymission/beach) +"mg" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/clothing/under/costume/pirate, +/turf/open/floor/wood, +/area/awaymission/beach) +"mi" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"mk" = ( +/obj/machinery/door/airlock/wood{ + name = "Trash Disposal" + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"mp" = ( +/obj/item/radio/off{ + pixel_y = 16; + pixel_x = -5 + }, +/obj/item/storage/box/monkeycubes{ + pixel_y = 10; + pixel_x = 4 + }, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 2 + }, +/obj/structure/table/glass, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"mG" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/turf_decal/tile/dark/half{ + pixel_y = -1; + pixel_x = 5; + dir = 8 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"mJ" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"mN" = ( +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"mO" = ( +/obj/item/reagent_containers/cup/soda_cans/sol_dry{ + pixel_y = 18; + pixel_x = 9 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"mP" = ( +/obj/structure/table/wood, +/obj/item/tape{ + pixel_y = 7; + pixel_x = 11 + }, +/obj/item/reagent_containers/cup/glass/coffee{ + pixel_x = -7; + pixel_y = 12 + }, +/obj/effect/spawner/random/bureaucracy/pen{ + pixel_x = -3; + pixel_y = -2 + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"mT" = ( +/obj/machinery/vending/games, +/turf/open/floor/eighties, +/area/awaymission/beach) +"mU" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/clothing/under/costume/sailor, +/turf/open/floor/wood, +/area/awaymission/beach) +"ni" = ( +/turf/open/misc/beach/coast{ + dir = 10 + }, +/area/awaymission/beach) +"nq" = ( +/obj/effect/turf_decal/sand, +/mob/living/basic/crab, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"nr" = ( +/obj/structure/mineral_door/sandstone{ + name = "Sandcastle" + }, +/obj/effect/turf_decal/sand/plating, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"ns" = ( +/obj/item/retractor{ + pixel_y = 8; + pixel_x = -2 + }, +/obj/item/cautery{ + pixel_y = 10 + }, +/obj/item/hemostat{ + pixel_y = -11 + }, +/obj/item/bonesetter{ + pixel_y = -12 + }, +/obj/structure/table/glass, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"nC" = ( +/obj/effect/turf_decal/tile/dark_red/full, +/turf/open/floor/iron/smooth_large, +/area/awaymission/beach) +"nD" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/machinery/door/airlock/wood{ + name = "Room 1" + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"nK" = ( +/obj/machinery/medical_kiosk, +/turf/open/floor/iron/white/textured_large, +/area/awaymission/beach) +"nO" = ( +/obj/item/kirbyplants/organic/plant8{ + pixel_y = 5 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"nV" = ( +/obj/structure/flora/tree/palm/style_2{ + pixel_y = 25 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"nW" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Beach Access" + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"oa" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Rooms" + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"ob" = ( +/obj/machinery/door/airlock/wood{ + name = "Employees' Only" + }, +/turf/open/floor/plastic, +/area/awaymission/beach) +"oi" = ( +/obj/effect/turf_decal/siding/wood, +/obj/machinery/shower/directional/south, +/obj/structure/sink/directional/east, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"om" = ( +/obj/item/trash/can{ + pixel_y = -5; + pixel_x = 4 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"oq" = ( +/obj/structure/rack, +/obj/item/melee/skateboard/hoverboard{ + pixel_x = -7 + }, +/obj/item/melee/skateboard/hoverboard, +/obj/item/melee/skateboard/hoverboard{ + pixel_x = 7 + }, +/turf/open/misc/beach/coast/corner{ + dir = 4 + }, +/area/awaymission/beach) +"ot" = ( +/obj/structure/chair/plastic{ + dir = 4 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"ow" = ( +/obj/machinery/reagentgrinder{ + pixel_y = 15; + pixel_x = -1 + }, +/obj/structure/table/bronze, +/obj/structure/desk_bell{ + pixel_x = 12; + pixel_y = 3 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"oC" = ( +/obj/structure/closet/crate/bin, +/obj/item/flashlight/glowstick/yellow, +/obj/item/trash/candy, +/turf/open/floor/eighties, +/area/awaymission/beach) +"oX" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/machinery/button/door/directional/west{ + id = "beach_room_7" + }, +/obj/item/clothing/suit/apron/overalls, +/turf/open/floor/wood, +/area/awaymission/beach) +"pd" = ( +/obj/effect/turf_decal/siding/dark_red{ + dir = 8 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"pr" = ( +/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind{ + pixel_x = -17; + pixel_y = 17 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"pt" = ( +/obj/structure/table/bronze, +/obj/item/book/manual/wiki/barman_recipes{ + pixel_x = 9; + pixel_y = 7; + name = "Tropical Mixing for Tropical Bartenders" + }, +/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass{ + pixel_y = 10; + pixel_x = -12 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"pw" = ( +/obj/structure/railing{ + dir = 1 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"pC" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/machinery/button/door/directional/south{ + id = "BeachBoats" + }, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"pD" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 19; + pixel_x = 10 + }, +/obj/machinery/hydroponics/constructable, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"pE" = ( +/obj/machinery/door/airlock/security/glass{ + name = "Temporary Holding Cell" + }, +/obj/effect/mapping_helpers/airlock/unres{ + dir = 8 + }, +/obj/effect/mapping_helpers/airlock/access/all/security/entrance, +/turf/open/floor/iron/dark/textured_large, +/area/awaymission/beach) +"pF" = ( +/obj/structure/flora/tree/palm/style_2{ + pixel_y = 3; + pixel_x = -4 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"pM" = ( +/obj/structure/marker_beacon/teal, +/turf/open/water/beach, +/area/awaymission/beach) +"pN" = ( +/obj/machinery/processor, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"pO" = ( +/obj/machinery/door/airlock/wood{ + name = "Docks" + }, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"pT" = ( +/obj/item/flashlight/flare/torch{ + pixel_x = -11; + pixel_y = -6 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"pX" = ( +/obj/structure/sink/kitchen/directional/south, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"qf" = ( +/obj/structure/table/bronze, +/obj/item/pai_card{ + desc = "A real Nanotrasen success, these personal AIs provide all of the companionship of an AI without any law related red-tape."; + name = "\improper Nanotrasen-brand personal AI device exhibit"; + pixel_y = 2 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"qk" = ( +/obj/machinery/telecomms/allinone, +/obj/item/wirecutters{ + pixel_y = 9 + }, +/obj/machinery/light/directional/south, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"ql" = ( +/obj/effect/turf_decal/siding/blue/corner{ + dir = 1 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"qt" = ( +/obj/structure/table/wood, +/obj/item/melee/baseball_bat{ + pixel_y = 3; + pixel_x = 6 + }, +/obj/item/clothing/glasses/blindfold/white{ + pixel_y = 7; + pixel_x = -5 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"qy" = ( +/obj/machinery/door/airlock/wood{ + name = "Arcade" + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"qC" = ( +/obj/machinery/button/door/directional/west{ + id = "beach_room_1" + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"qX" = ( +/obj/structure/chair/stool/bar/directional/east, +/obj/machinery/light/directional/west, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"rd" = ( +/obj/structure/closet/crate/trashcart/laundry, +/turf/open/floor/plastic, +/area/awaymission/beach) +"re" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/clothing/suit/jacket/letterman_red, +/turf/open/floor/wood, +/area/awaymission/beach) +"rq" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 19; + pixel_x = 8 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"ru" = ( +/obj/machinery/light/directional/south, +/turf/open/floor/wood, +/area/awaymission/beach) +"rA" = ( +/obj/item/reagent_containers/cup/soda_cans/cola{ + pixel_x = -8; + pixel_y = -6 + }, +/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind{ + pixel_x = 15 + }, +/obj/structure/fluff/beach_umbrella/science, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"rE" = ( +/obj/effect/turf_decal/siding/wood, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"rF" = ( +/obj/machinery/grill, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"rQ" = ( +/obj/structure/table/bronze, +/obj/item/paper_bin/carbon{ + pixel_y = 8 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"rR" = ( +/obj/effect/turf_decal/siding/dark_red/corner{ + dir = 1 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"sc" = ( +/obj/structure/fluff/beach_umbrella/syndi, +/obj/item/reagent_containers/cup/soda_cans/wellcheers{ + pixel_y = -10; + pixel_x = -6 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"sd" = ( +/obj/item/cigbutt{ + pixel_y = -4; + pixel_x = 2 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"sj" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"sp" = ( +/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"sL" = ( +/obj/effect/turf_decal/sand, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"sM" = ( +/obj/machinery/shower/directional/west, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"sP" = ( +/obj/structure/table/wood, +/obj/item/stack/arcadeticket{ + pixel_y = 3; + pixel_x = -5 + }, +/obj/item/reagent_containers/cup/soda_cans/pwr_game{ + pixel_y = 12; + pixel_x = -8 + }, +/obj/item/paper_bin/carbon{ + pixel_y = 6; + pixel_x = 4 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"sS" = ( +/turf/open/floor/plastic, +/area/awaymission/beach) +"sU" = ( +/obj/item/toy/plush/moth{ + pixel_y = 5 + }, +/turf/open/floor/carpet/red, +/area/awaymission/beach) +"to" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/obj/machinery/shower/directional/south, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"tr" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 6 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"tx" = ( +/obj/machinery/button/door/directional/north{ + id = "beach_room_3" + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"tz" = ( +/obj/structure/tank_holder/extinguisher{ + pixel_y = 11 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"tD" = ( +/obj/structure/table/glass, +/obj/item/paper{ + pixel_y = 7; + pixel_x = 2 + }, +/obj/item/screwdriver{ + pixel_y = 13; + pixel_x = 3 + }, +/obj/item/paper_bin/carbon{ + pixel_y = 4; + pixel_x = -6 + }, +/obj/effect/spawner/random/bureaucracy/pen{ + pixel_x = 7 + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"tE" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 19; + pixel_x = 7 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"tJ" = ( +/turf/open/misc/beach/coast/corner{ + dir = 8 + }, +/area/awaymission/beach) +"tK" = ( +/obj/structure/table, +/obj/item/book/manual/wiki/engineering_guide{ + pixel_y = 7; + pixel_x = -6 + }, +/obj/item/pen{ + pixel_x = 7; + pixel_y = 6 + }, +/obj/item/clothing/head/utility/welding{ + pixel_x = -10; + pixel_y = -8 + }, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"tP" = ( +/obj/structure/chair/plastic{ + dir = 8 + }, +/obj/item/reagent_containers/cup/soda_cans/starkist{ + pixel_y = 10; + pixel_x = -17 + }, +/obj/item/fishing_rod{ + pixel_x = -13; + pixel_y = 2 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"tU" = ( +/obj/structure/table/bronze, +/turf/open/floor/carpet, +/area/awaymission/beach) +"uc" = ( +/obj/item/stack/arcadeticket{ + pixel_y = 5; + pixel_x = 13 + }, +/turf/open/floor/eighties, +/area/awaymission/beach) +"ug" = ( +/obj/structure/chair/stool/directional/south, +/turf/open/floor/iron/freezer, +/area/awaymission/beach) +"um" = ( +/obj/structure/table/bronze, +/obj/machinery/button/door/directional/south{ + id = "beach_room_11" + }, +/obj/item/storage/toolbox/fishing{ + pixel_y = 2 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"un" = ( +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"uo" = ( +/obj/effect/turf_decal/stripes/red/line{ + dir = 8 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"uq" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Hotel's Facilities" + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"us" = ( +/obj/structure/closet/crate/bin, +/obj/structure/sign/clock/directional/north, +/turf/open/floor/wood, +/area/awaymission/beach) +"uu" = ( +/obj/structure/table/bronze, +/obj/item/reagent_containers/condiment/ketchup{ + pixel_y = 14; + pixel_x = 1 + }, +/obj/item/reagent_containers/condiment/mayonnaise{ + pixel_y = 8; + pixel_x = 8 + }, +/obj/machinery/light/directional/east, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"uv" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/turf_decal/tile/dark/half{ + pixel_x = 5; + dir = 8 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"uz" = ( +/turf/open/floor/carpet/red, +/area/awaymission/beach) +"uG" = ( +/turf/open/floor/carpet/green, +/area/awaymission/beach) +"uJ" = ( +/obj/structure/table/wood, +/obj/item/food/donut/plain{ + pixel_y = -2; + pixel_x = 14 + }, +/obj/item/assembly/signaler{ + pixel_x = -6; + pixel_y = -5 + }, +/obj/effect/spawner/random/bureaucracy/folder{ + pixel_y = 11; + pixel_x = 4 + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"uL" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"uN" = ( +/obj/structure/table, +/obj/item/storage/belt/utility, +/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass{ + pixel_y = 14; + pixel_x = -8 + }, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"uP" = ( +/obj/structure/chair/plastic{ + dir = 1 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"uT" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/awaymission/beach) +"uV" = ( +/obj/structure/closet/crate/trashcart/filled, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"uY" = ( +/obj/item/toy/seashell{ + pixel_x = 12; + pixel_y = 5 + }, +/turf/open/misc/beach/coast{ + dir = 4 + }, +/area/awaymission/beach) +"uZ" = ( +/obj/item/circular_saw{ + pixel_y = 4 + }, +/obj/item/scalpel{ + pixel_y = 15 + }, +/obj/structure/table/glass, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"vc" = ( +/obj/structure/dresser, +/turf/open/floor/wood, +/area/awaymission/beach) +"vf" = ( +/obj/vehicle/ridden/atv{ + dir = 4 + }, +/obj/effect/decal/cleanable/oil, +/turf/open/floor/iron/dark/herringbone, +/area/awaymission/beach) +"vq" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/landmark/awaystart, +/turf/open/floor/plating, +/area/awaymission/beach) +"vx" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/effect/turf_decal/tile/dark/half{ + pixel_y = -1; + pixel_x = 5; + dir = 8 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"vF" = ( +/obj/structure/table/bronze, +/obj/structure/sign/poster/random/directional/east, +/obj/machinery/button/door/directional/south{ + id = "beach_room_8" + }, +/obj/item/camera{ + pixel_y = 5 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"vM" = ( +/obj/structure/bed/double, +/obj/item/bedsheet/hos/double{ + name = "bedsheet"; + desc = "A bedsheet from the beach hotel." + }, +/turf/open/floor/carpet, +/area/awaymission/beach) +"vR" = ( +/obj/machinery/light/directional/north, +/turf/open/floor/wood, +/area/awaymission/beach) +"vX" = ( +/obj/structure/chair/stool/bamboo{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"wd" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"wt" = ( +/obj/machinery/vending/cigarette/beach, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"wv" = ( +/obj/structure/railing/corner/end/flip{ + dir = 4 + }, +/obj/item/wrench{ + pixel_y = -1; + pixel_x = 6 + }, +/obj/item/storage/toolbox/fishing{ + pixel_y = -8; + pixel_x = -3 + }, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"wA" = ( +/obj/structure/flora/tree/palm, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"wC" = ( +/obj/structure/window/reinforced/spawner/directional/east, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"wL" = ( +/obj/structure/table/bronze, +/obj/item/food/grown/banana/bunch{ + pixel_y = 10; + offset_at_init = 0 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"wX" = ( +/obj/machinery/door/airlock/wood{ + name = "Room 9"; + id_tag = "beach_room_9" + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"wY" = ( +/obj/effect/turf_decal/sand/plating, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"xi" = ( +/obj/effect/turf_decal/sand, +/turf/closed/wall/mineral/wood, +/area/awaymission/beach) +"xo" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/button/door/directional/east{ + id = "toilet3beach"; + name = "restroom lock"; + normaldoorcontrol = 1; + specialfunctions = 4 + }, +/obj/structure/toilet{ + pixel_y = 8 + }, +/obj/structure/sink/directional/west, +/obj/item/cigbutt{ + pixel_y = -7; + pixel_x = -13 + }, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/white, +/area/awaymission/beach) +"xp" = ( +/obj/structure/sign/poster/official/tactical_game_cards/directional/west, +/turf/open/floor/eighties, +/area/awaymission/beach) +"xr" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/machinery/door/airlock/wood{ + name = "Tropical Kitchen" + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"xv" = ( +/turf/closed/wall/mineral/wood, +/area/awaymission/beach) +"xE" = ( +/obj/structure/table/wood, +/obj/item/storage/box/drinkingglasses{ + pixel_y = 18; + pixel_x = -5 + }, +/obj/item/reagent_containers/cup/glass/shaker{ + pixel_y = 12; + pixel_x = -7 + }, +/obj/item/clothing/head/hats/tophat{ + pixel_y = 2; + pixel_x = 3 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"xI" = ( +/obj/effect/turf_decal/sand, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"yc" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/eighties, +/area/awaymission/beach) +"yn" = ( +/obj/effect/turf_decal/siding/wood, +/obj/item/kirbyplants/organic/plant8{ + pixel_y = 6 + }, +/obj/machinery/light/directional/east, +/turf/open/floor/eighties, +/area/awaymission/beach) +"yq" = ( +/obj/item/storage/toolbox/fishing{ + pixel_x = 2; + pixel_y = -13 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"yt" = ( +/obj/structure/table/bronze, +/obj/item/camera{ + pixel_y = 12; + pixel_x = 6 + }, +/obj/item/camera_film{ + pixel_y = 4; + pixel_x = -2 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"yE" = ( +/obj/machinery/door/airlock/wood{ + name = "Room 8"; + id_tag = "beach_room_8" + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"yF" = ( +/obj/structure/chair/plastic, +/obj/item/fishing_rod{ + pixel_x = 11; + pixel_y = -8 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"yL" = ( +/obj/item/cigbutt{ + pixel_y = -7; + pixel_x = 14 + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"yO" = ( +/obj/effect/turf_decal/siding/wood, +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 12; + pixel_x = 3 + }, +/obj/item/stock_parts/cell/emproof{ + pixel_x = -4; + pixel_y = 6 + }, +/obj/item/clothing/head/soft/mime{ + pixel_y = 3; + pixel_x = 5 + }, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"yT" = ( +/obj/item/toy/seashell{ + pixel_y = -5 + }, +/turf/open/misc/beach/coast, +/area/awaymission/beach) +"yX" = ( +/obj/structure/table/wood/poker, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"yZ" = ( +/obj/machinery/space_heater, +/obj/machinery/button/door/directional/north{ + id = "beach_room_2" + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"zp" = ( +/obj/structure/table/wood, +/obj/item/clothing/suit/apron/chef{ + pixel_y = 5; + pixel_x = 2 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"zr" = ( +/obj/item/toy/dodgeball{ + name = "William"; + desc = "It's just not the same thing."; + pixel_y = -4; + pixel_x = 7 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"zs" = ( +/obj/effect/spawner/random/entertainment/arcade{ + dir = 4 + }, +/turf/open/floor/eighties, +/area/awaymission/beach) +"zA" = ( +/obj/structure/chair/office{ + dir = 8 + }, +/obj/item/cigbutt{ + pixel_y = -6; + pixel_x = -12 + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"zH" = ( +/obj/structure/table/wood/poker, +/obj/item/storage/dice{ + pixel_y = 3; + pixel_x = 5 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"zI" = ( +/obj/machinery/defibrillator_mount/directional/west, +/obj/structure/bed/pod{ + desc = "An old medical bed, just waiting for replacement with something up to date."; + dir = 4; + name = "medical bed" + }, +/obj/machinery/iv_drip{ + pixel_y = 21; + pixel_x = -4 + }, +/turf/open/floor/iron/white/textured_large, +/area/awaymission/beach) +"zK" = ( +/obj/structure/table, +/obj/item/weldingtool{ + pixel_y = -7; + pixel_x = 4 + }, +/obj/item/trash/can{ + pixel_y = 10; + pixel_x = -5 + }, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"zX" = ( +/obj/item/storage/toolbox/fishing{ + pixel_x = 10 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Aa" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/condiment/enzyme{ + layer = 5; + pixel_x = 9; + pixel_y = 5 + }, +/obj/item/food/seaweedsheet{ + pixel_y = 6; + pixel_x = -4 + }, +/obj/item/food/seaweedsheet{ + pixel_x = -15; + pixel_y = 2 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Ar" = ( +/turf/open/floor/carpet/blue, +/area/awaymission/beach) +"Av" = ( +/obj/item/reagent_containers/cup/soda_cans/cola{ + pixel_x = -8; + pixel_y = -4 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"AB" = ( +/obj/structure/table/bronze, +/obj/item/pai_card{ + desc = "A real Nanotrasen success, these personal AIs provide all of the companionship of an AI without any law related red-tape."; + name = "\improper Nanotrasen-brand personal AI device exhibit"; + pixel_y = 4 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"AG" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/clothing/suit/jacket/letterman_nanotrasen, +/obj/item/clothing/glasses/salesman, +/turf/open/floor/wood, +/area/awaymission/beach) +"AH" = ( +/obj/item/reagent_containers/cup/bucket/wooden{ + pixel_y = -5; + pixel_x = -11 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"AP" = ( +/obj/machinery/door/airlock/wood{ + name = "Changing Room" + }, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/floor/iron/freezer, +/area/awaymission/beach) +"AU" = ( +/obj/structure/fluff/beach_umbrella/syndi, +/obj/item/reagent_containers/cup/soda_cans/cola{ + pixel_x = -8; + pixel_y = -6 + }, +/obj/item/reagent_containers/cup/soda_cans/thirteenloko{ + pixel_x = 15; + pixel_y = -11 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"AW" = ( +/obj/machinery/door/airlock/wood{ + name = "Room 2"; + id_tag = "beach_room_2" + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/sign/poster/random/directional/east, +/turf/open/floor/wood, +/area/awaymission/beach) +"Bl" = ( +/obj/structure/statue/sandstone/venus{ + dir = 4; + pixel_y = 9; + anchored = 1 + }, +/obj/structure/flora/bush/flowers_br/style_random, +/turf/open/floor/grass, +/area/awaymission/beach) +"Bm" = ( +/obj/machinery/washing_machine, +/turf/open/floor/plastic, +/area/awaymission/beach) +"Bq" = ( +/obj/machinery/computer/operating{ + dir = 8 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Bv" = ( +/obj/machinery/door/poddoor/shutters{ + dir = 4; + id = "BeachGarage" + }, +/turf/open/floor/plating, +/area/awaymission/beach) +"BD" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/structure/railing/corner/end{ + dir = 8 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"BK" = ( +/turf/open/misc/beach/coast, +/area/awaymission/beach) +"BL" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"BN" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/obj/machinery/vending/cola/red, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"BQ" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Cb" = ( +/obj/structure/table/wood, +/obj/item/modular_computer/laptop{ + pixel_y = 5 + }, +/obj/item/multitool{ + pixel_x = -8; + pixel_y = -8 + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"Ce" = ( +/obj/structure/table, +/obj/item/wrench{ + pixel_y = 4 + }, +/obj/item/storage/toolbox/emergency, +/obj/effect/decal/cleanable/oil, +/turf/open/floor/iron/dark/herringbone, +/area/awaymission/beach) +"Cf" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"Cg" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/button/door/directional/east{ + id = "toiletfarbeach"; + name = "restroom lock"; + normaldoorcontrol = 1; + specialfunctions = 4 + }, +/obj/structure/toilet{ + pixel_y = 8 + }, +/obj/structure/sink/directional/west, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/white, +/area/awaymission/beach) +"Cl" = ( +/obj/machinery/vending/dinnerware, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Cp" = ( +/obj/structure/fluff/beach_umbrella/syndi, +/turf/open/misc/beach/coast/corner{ + dir = 8 + }, +/area/awaymission/beach) +"Cv" = ( +/obj/effect/turf_decal/siding/blue{ + dir = 8 + }, +/obj/structure/chair/plastic{ + dir = 8 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Cy" = ( +/obj/structure/closet/crate/bin, +/obj/item/trash/candy, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"CF" = ( +/obj/structure/flora/tree/palm/style_2{ + pixel_y = 25 + }, +/obj/item/stack/sheet/mineral/sandstone/thirty{ + pixel_y = -10; + pixel_x = -5 + }, +/obj/item/stack/sheet/mineral/sandstone/thirty{ + pixel_y = -2; + pixel_x = 9 + }, +/obj/item/stack/sheet/mineral/sandstone/thirty{ + pixel_y = -4; + pixel_x = 1 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"CG" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"CH" = ( +/obj/structure/railing{ + dir = 5 + }, +/obj/item/kirbyplants/organic/plant8{ + pixel_y = 3; + pixel_x = -2 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"CJ" = ( +/obj/effect/turf_decal/siding/wood/corner, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"CQ" = ( +/obj/machinery/space_heater, +/turf/open/floor/wood, +/area/awaymission/beach) +"CR" = ( +/obj/structure/table/bronze, +/obj/item/camera{ + pixel_y = 5 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"CY" = ( +/obj/machinery/shower/directional/south, +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"Da" = ( +/obj/effect/turf_decal/sand, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Dj" = ( +/obj/item/kirbyplants/organic/plant8{ + pixel_y = 4; + pixel_x = 8 + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"Dv" = ( +/obj/item/storage/bag/tray, +/obj/item/food/grown/watermelon{ + pixel_y = 4; + pixel_x = -1 + }, +/obj/effect/turf_decal/stripes/red/box, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Dy" = ( +/obj/effect/turf_decal/siding/wood/corner, +/obj/item/stack/arcadeticket{ + pixel_y = 12; + pixel_x = -16 + }, +/turf/open/floor/eighties, +/area/awaymission/beach) +"DD" = ( +/obj/structure/closet{ + name = "Holding Cell Storage" + }, +/obj/item/taperecorder, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"DF" = ( +/obj/item/toy/seashell{ + pixel_y = 3; + pixel_x = -6 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"DH" = ( +/obj/effect/turf_decal/siding/dark_red{ + dir = 1 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"DR" = ( +/obj/structure/table/bronze, +/obj/item/camera{ + pixel_y = 8; + pixel_x = -3 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"DU" = ( +/obj/structure/table/bronze, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"DV" = ( +/obj/structure/table/bronze, +/obj/machinery/button/door/directional/south{ + id = "beach_room_4" + }, +/obj/item/storage/toolbox/fishing{ + pixel_y = 2 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"DY" = ( +/obj/machinery/oven/range, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Ea" = ( +/obj/machinery/griddle, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Eb" = ( +/obj/structure/closet/crate/freezer, +/obj/item/food/meat/slab/rawcrab, +/obj/item/food/meat/slab/rawcrab, +/obj/item/food/meat/slab/rawcrab, +/obj/item/food/meat/slab/chicken, +/obj/item/food/meat/slab/chicken, +/obj/item/food/meat/slab/chicken, +/obj/item/food/meat/slab, +/obj/item/food/meat/slab, +/obj/item/food/meat/slab, +/obj/item/stack/sheet/mineral/coal/ten, +/obj/item/stack/sheet/mineral/coal/ten, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Ej" = ( +/obj/item/tank/internals/anesthetic{ + pixel_y = 4 + }, +/obj/item/stack/medical/bone_gel{ + pixel_y = 16; + pixel_x = -7 + }, +/obj/item/clothing/mask/breath/medical{ + pixel_y = 3; + pixel_x = 3 + }, +/obj/structure/table/bronze, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Em" = ( +/turf/open/floor/carpet/cyan, +/area/awaymission/beach) +"Er" = ( +/obj/item/toy/seashell{ + pixel_y = -15 + }, +/obj/item/toy/seashell{ + pixel_y = -3; + pixel_x = -18 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Es" = ( +/obj/structure/table/bronze, +/obj/item/table_clock{ + pixel_y = 13 + }, +/obj/structure/sign/poster/random/directional/east, +/turf/open/floor/wood, +/area/awaymission/beach) +"EB" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 16; + pixel_x = 12 + }, +/obj/structure/flora/coconuts, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"EC" = ( +/obj/effect/turf_decal/siding/blue{ + dir = 1 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"EF" = ( +/obj/structure/railing/corner/end{ + dir = 8 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"EG" = ( +/obj/machinery/recharge_station, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"EH" = ( +/obj/structure/mop_bucket/janitorialcart{ + dir = 8 + }, +/obj/machinery/light/directional/south, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"EO" = ( +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/box/lights/mixed{ + pixel_x = -4; + pixel_y = 18 + }, +/obj/item/storage/box/lights/mixed{ + pixel_x = 6; + pixel_y = 12 + }, +/obj/item/grenade/chem_grenade/cleaner{ + pixel_x = -7; + pixel_y = 12 + }, +/obj/structure/table, +/obj/item/reagent_containers/cup/bucket{ + pixel_x = 10; + pixel_y = 4 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"EP" = ( +/obj/machinery/door/airlock/wood{ + name = "Janitorial" + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"EU" = ( +/obj/item/reagent_containers/cup/soda_cans/cola{ + pixel_x = -8; + pixel_y = 13 + }, +/turf/open/floor/carpet/blue, +/area/awaymission/beach) +"Fb" = ( +/turf/open/misc/beach/coast{ + dir = 4 + }, +/area/awaymission/beach) +"Fe" = ( +/obj/item/storage/box/gloves{ + pixel_y = 14; + pixel_x = 7 + }, +/turf/open/floor/iron/white/textured_large, +/area/awaymission/beach) +"Ff" = ( +/obj/item/reagent_containers/cup/soda_cans/lemon_lime{ + pixel_x = -12 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Fg" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/clothing/suit/jacket/letterman_syndie, +/turf/open/floor/wood, +/area/awaymission/beach) +"Fk" = ( +/obj/item/toy/seashell, +/turf/open/misc/beach/coast, +/area/awaymission/beach) +"Ft" = ( +/obj/structure/window/reinforced/spawner/directional/east, +/obj/structure/window/reinforced/spawner/directional/north{ + layer = 2.9 + }, +/obj/structure/chair/stool/directional/south, +/obj/item/clothing/glasses/sunglasses{ + pixel_y = -2; + pixel_x = 2 + }, +/obj/item/bikehorn/airhorn{ + pixel_y = -15; + pixel_x = -13 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"Fu" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 31 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"FB" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/button/door/directional/east{ + id = "toilet2beach"; + name = "restroom lock"; + normaldoorcontrol = 1; + specialfunctions = 4 + }, +/obj/structure/toilet{ + pixel_y = 8 + }, +/obj/structure/sink/directional/west, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/white, +/area/awaymission/beach) +"FD" = ( +/obj/item/toy/seashell{ + pixel_x = -7; + pixel_y = 5 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"FE" = ( +/obj/effect/turf_decal/siding/wood/corner, +/turf/open/floor/eighties, +/area/awaymission/beach) +"FF" = ( +/obj/machinery/gateway/away, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/awaymission/beach) +"FH" = ( +/obj/structure/table/wood, +/obj/item/food/grown/watermelon{ + pixel_y = 13; + pixel_x = 6 + }, +/obj/item/food/grown/watermelon{ + pixel_y = 8; + pixel_x = -4 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"FJ" = ( +/obj/item/instrument/guitar{ + pixel_y = 4; + pixel_x = -1 + }, +/turf/open/misc/beach/coast, +/area/awaymission/beach) +"FK" = ( +/obj/item/toy/seashell{ + pixel_x = 12; + pixel_y = -9 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"FL" = ( +/obj/effect/turf_decal/siding/blue/corner{ + dir = 8 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"FM" = ( +/obj/structure/railing{ + dir = 9 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"FP" = ( +/obj/item/kirbyplants/organic/plant24{ + pixel_x = 7; + pixel_y = 10 + }, +/obj/item/reagent_containers/cup/watering_can{ + pixel_x = -3; + pixel_y = 15 + }, +/obj/structure/table, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"FU" = ( +/obj/structure/railing/corner/end/flip{ + dir = 4 + }, +/obj/item/cigbutt{ + pixel_y = -6; + pixel_x = -12 + }, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"FY" = ( +/obj/effect/turf_decal/sand, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 1 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Ge" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/awaymission/beach) +"Gf" = ( +/obj/machinery/light/directional/south, +/turf/open/floor/carpet, +/area/awaymission/beach) +"Gh" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"Gi" = ( +/obj/structure/closet/crate/bin, +/obj/item/reagent_containers/syringe{ + pixel_y = -4; + pixel_x = 3 + }, +/obj/effect/spawner/random/trash/food_packaging, +/turf/open/floor/iron/white/textured_large, +/area/awaymission/beach) +"Gm" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/door/airlock/wood{ + name = "Bathroom"; + id_tag = "toilet1beach" + }, +/turf/open/floor/iron/white, +/area/awaymission/beach) +"Gn" = ( +/turf/open/floor/wood, +/area/awaymission/beach) +"Gq" = ( +/obj/structure/tank_holder/extinguisher{ + pixel_y = 11 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Gu" = ( +/obj/machinery/light/directional/north, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"GC" = ( +/turf/open/floor/carpet, +/area/awaymission/beach) +"GG" = ( +/obj/item/toy/seashell, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"GI" = ( +/obj/structure/bonfire, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"GN" = ( +/obj/machinery/icecream_vat, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Ha" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/reagent_dispensers/fueltank/large, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"Hg" = ( +/obj/item/stack/sheet/mineral/sandstone{ + pixel_x = -11; + pixel_y = -2 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Hn" = ( +/obj/structure/flora/tree/palm/style_2{ + pixel_y = 6 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Hq" = ( +/obj/structure/closet/secure_closet/personal, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"Hv" = ( +/obj/structure/dresser, +/obj/machinery/light/directional/north, +/turf/open/floor/wood, +/area/awaymission/beach) +"HF" = ( +/obj/machinery/light/small/directional/north, +/turf/open/floor/iron/dark/herringbone, +/area/awaymission/beach) +"HU" = ( +/obj/structure/table/bronze, +/obj/item/camera{ + pixel_y = 12; + pixel_x = -10 + }, +/obj/item/camera{ + pixel_y = 4; + pixel_x = 1 + }, +/obj/item/camera_film{ + pixel_y = -11; + pixel_x = -10 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"HV" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"Ia" = ( +/obj/effect/turf_decal/siding/wood, +/turf/closed/wall/mineral/wood, +/area/awaymission/beach) +"Ic" = ( +/obj/structure/table/reinforced, +/obj/item/defibrillator/loaded{ + pixel_y = 7 + }, +/turf/open/floor/iron/white/textured_large, +/area/awaymission/beach) +"Ih" = ( +/obj/structure/table/reinforced, +/obj/item/storage/medkit/brute{ + pixel_y = 9; + pixel_x = 2 + }, +/obj/item/storage/medkit/o2{ + pixel_y = 15; + pixel_x = 2 + }, +/obj/item/reagent_containers/cup/bottle/multiver{ + pixel_x = -9; + pixel_y = 3 + }, +/obj/item/reagent_containers/syringe{ + pixel_y = -4; + pixel_x = 3 + }, +/turf/open/floor/iron/white/textured_large, +/area/awaymission/beach) +"Il" = ( +/obj/machinery/vending/autodrobe/all_access, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"It" = ( +/obj/item/clothing/head/soft/green, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Iw" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plating, +/area/awaymission/beach) +"IA" = ( +/obj/structure/fluff/beach_umbrella/science, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"IE" = ( +/obj/structure/table/bronze, +/obj/item/clothing/suit/costume/hawaiian{ + pixel_y = 1; + pixel_x = 7 + }, +/obj/item/clothing/suit/costume/hawaiian{ + pixel_x = -14 + }, +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"II" = ( +/obj/machinery/shower/directional/west, +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"IP" = ( +/obj/machinery/computer/order_console/cook, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"IW" = ( +/obj/structure/closet/athletic_mixed, +/turf/open/floor/iron/freezer, +/area/awaymission/beach) +"IZ" = ( +/mob/living/basic/crab, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Ja" = ( +/obj/structure/table/bronze, +/obj/item/reagent_containers/condiment/peppermill{ + pixel_y = 12 + }, +/obj/item/reagent_containers/condiment/saltshaker{ + pixel_x = -5; + pixel_y = 9 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Ji" = ( +/obj/effect/turf_decal/stripes/white/full, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Jj" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/machinery/door/airlock/wood{ + name = "Room 6"; + id_tag = "beach_room_6" + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"Jo" = ( +/obj/item/reagent_containers/cup/glass/bottle/beer/light{ + pixel_x = -14; + pixel_y = 15 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Jr" = ( +/obj/machinery/light/directional/west, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"JF" = ( +/obj/structure/marker_beacon/burgundy, +/turf/open/water/beach, +/area/awaymission/beach) +"JG" = ( +/obj/machinery/door/airlock/wood{ + name = "Room 4"; + id_tag = "beach_room_4" + }, +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood, +/area/awaymission/beach) +"JO" = ( +/obj/machinery/vending/cigarette/beach, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"JQ" = ( +/turf/open/floor/iron/stairs, +/area/awaymission/beach) +"JR" = ( +/obj/structure/chair/stool/bamboo{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood/corner, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Ka" = ( +/obj/structure/bed/pod{ + desc = "An old medical bed, just waiting for replacement with something up to date."; + dir = 4; + name = "medical bed" + }, +/obj/machinery/defibrillator_mount/directional/east, +/obj/machinery/iv_drip{ + pixel_y = 21; + pixel_x = -4 + }, +/turf/open/floor/iron/white/textured_large, +/area/awaymission/beach) +"Kh" = ( +/turf/open/misc/beach/coast/corner, +/area/awaymission/beach) +"Km" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 7; + pixel_x = 9 + }, +/obj/effect/turf_decal/siding/wood, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Kn" = ( +/obj/structure/statue/sandstone/venus{ + dir = 4; + pixel_y = 9 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Kw" = ( +/obj/item/reagent_containers/cup/soda_cans/dr_gibb{ + pixel_x = -9; + pixel_y = -9 + }, +/obj/structure/fluff/beach_umbrella/engine, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Ky" = ( +/obj/structure/table/reinforced, +/obj/item/storage/medkit/o2{ + pixel_y = 17; + pixel_x = -1 + }, +/obj/item/storage/medkit/brute{ + pixel_y = 23; + pixel_x = -1 + }, +/obj/item/food/lollipop{ + pixel_y = 8; + pixel_x = 12 + }, +/obj/item/food/lollipop{ + pixel_y = 5; + pixel_x = 12 + }, +/obj/item/reagent_containers/cup/bottle/multiver{ + pixel_x = -9; + pixel_y = 9 + }, +/turf/open/floor/iron/white/textured_large, +/area/awaymission/beach) +"KB" = ( +/obj/structure/dresser, +/obj/structure/sign/clock/directional/east, +/turf/open/floor/wood, +/area/awaymission/beach) +"KK" = ( +/obj/effect/turf_decal/siding/dark_red, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"KL" = ( +/obj/item/stack/sheet/mineral/sandstone{ + pixel_x = 11 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"KV" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/spawner/random/structure/crate, +/turf/open/floor/plating, +/area/awaymission/beach) +"KW" = ( +/obj/structure/fluff/beach_umbrella/syndi, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"La" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/spawner/random/structure/crate_empty, +/obj/effect/spawner/random/maintenance/two, +/obj/item/storage/toolbox/fishing{ + pixel_y = 2 + }, +/turf/open/floor/plating, +/area/awaymission/beach) +"Ld" = ( +/obj/item/toy/seashell{ pixel_x = -8; + pixel_y = 9 + }, +/turf/open/misc/beach/coast/corner{ + dir = 1 + }, +/area/awaymission/beach) +"Le" = ( +/turf/open/misc/beach/coast{ + dir = 8 + }, +/area/awaymission/beach) +"Lg" = ( +/obj/structure/chair/office{ + dir = 4 + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"Ll" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 1 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Lt" = ( +/obj/structure/rack, +/obj/effect/turf_decal/sand, +/obj/item/clothing/shoes/sandal{ + pixel_y = 4; + pixel_x = 8 + }, +/obj/item/clothing/shoes/sandal{ + pixel_x = 4 + }, +/obj/item/clothing/shoes/sandal{ + pixel_y = -4 + }, +/obj/item/clothing/shoes/sandal{ + pixel_y = -7; + pixel_x = -3 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"LC" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 1 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"LJ" = ( +/obj/structure/railing/corner/end/flip{ + dir = 1 + }, +/obj/machinery/door/airlock/wood{ + name = "Balcony"; + id_tag = "beach_room_x" + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"LQ" = ( +/obj/effect/turf_decal/tile/dark_red/full, +/obj/machinery/vending/cola/red, +/turf/open/floor/iron/smooth_large, +/area/awaymission/beach) +"LS" = ( +/obj/machinery/space_heater, +/obj/machinery/light/directional/north, +/turf/open/floor/wood, +/area/awaymission/beach) +"Mm" = ( +/obj/structure/table/bronze, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Mn" = ( +/obj/structure/table/wood, +/obj/item/book/manual/chef_recipes{ + pixel_x = 2; + pixel_y = 6 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Mo" = ( +/obj/structure/statue/sandstone/venus{ + pixel_y = 9; + dir = 1; + anchored = 1 + }, +/obj/structure/flora/bush/flowers_br/style_random, +/turf/open/floor/grass, +/area/awaymission/beach) +"Mr" = ( +/obj/effect/turf_decal/siding/blue/corner{ + dir = 4 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"MD" = ( +/obj/structure/table/wood, +/obj/effect/spawner/random/entertainment/lighter, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"MF" = ( +/turf/open/misc/beach/coast/corner{ + dir = 4 + }, +/area/awaymission/beach) +"MG" = ( +/obj/structure/chair/stool/bamboo{ + dir = 4 + }, +/obj/effect/turf_decal/siding/wood/corner, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"MH" = ( +/obj/structure/closet, +/obj/item/key/atv{ + pixel_x = -4 + }, +/obj/item/key/atv{ + pixel_x = 5; + pixel_y = 3 + }, +/obj/item/key/atv{ + pixel_x = 1; + pixel_y = 1 + }, +/obj/item/clothing/head/soft/black, +/obj/item/clothing/head/soft/black, +/obj/item/clothing/head/soft/black, +/obj/effect/decal/cleanable/oil, +/obj/item/clothing/glasses/sunglasses, +/obj/item/clothing/glasses/heat, +/turf/open/floor/iron/dark/herringbone, +/area/awaymission/beach) +"MK" = ( +/turf/open/floor/iron/dark/herringbone, +/area/awaymission/beach) +"MN" = ( +/obj/item/stack/arcadeticket{ + pixel_y = -1; + pixel_x = -6 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"MO" = ( +/obj/item/trash/boritos/purple{ + pixel_y = -16; + pixel_x = -5 + }, +/turf/open/floor/eighties, +/area/awaymission/beach) +"MP" = ( +/obj/structure/table/bronze, +/obj/structure/sign/poster/random/directional/east, +/obj/item/camera{ + pixel_y = 5 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"MT" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 5 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"MV" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay Clinic" + }, +/obj/effect/turf_decal/siding/blue{ + dir = 4 + }, +/turf/open/floor/iron/white/textured_large, +/area/awaymission/beach) +"MX" = ( +/obj/structure/chair/plastic{ + dir = 8 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"MZ" = ( +/turf/open/misc/beach/coast{ + dir = 9 + }, +/area/awaymission/beach) +"Nb" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/random/maintenance, +/obj/machinery/light/small/directional/west, +/turf/open/floor/plating, +/area/awaymission/beach) +"Nd" = ( +/obj/machinery/button/door/directional/south{ + id = "beach_room_5" + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"Ne" = ( +/obj/structure/closet/crate/bin, +/obj/effect/spawner/random/trash/cigbutt, +/obj/effect/spawner/random/trash/food_packaging, +/obj/machinery/light/directional/north, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"Nf" = ( +/obj/structure/table/wood, +/obj/item/food/seaweedsheet, +/obj/item/kitchen/rollingpin{ + pixel_x = -12; + pixel_y = 3 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Nh" = ( +/obj/effect/turf_decal/sand, +/obj/structure/bedsheetbin{ + pixel_y = 3; + pixel_x = -1 + }, +/obj/structure/table, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Nk" = ( +/obj/machinery/door/airlock/wood{ + name = "Balcony"; + id_tag = "beach_room_x" + }, +/obj/structure/railing/corner/end/flip{ + dir = 1 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"Nl" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Nm" = ( +/obj/structure/flora/coconuts{ + pixel_x = -5; + pixel_y = 4 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"NF" = ( +/obj/item/toy/seashell{ + pixel_x = -10; + pixel_y = -4 + }, +/obj/structure/fluff/beach_umbrella, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"NH" = ( +/obj/machinery/door/airlock/wood/glass{ + name = "Cabin" + }, +/turf/open/floor/carpet, +/area/awaymission/beach) +"NS" = ( +/obj/structure/table/bronze, +/obj/item/storage/bag/tray, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"NU" = ( +/obj/machinery/vending/medical{ + req_access = "201" + }, +/turf/open/floor/iron/white/textured_large, +/area/awaymission/beach) +"Og" = ( +/obj/effect/turf_decal/siding/wood/corner, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"On" = ( +/obj/structure/chair{ + dir = 1 + }, +/turf/open/floor/iron/dark/textured_large, +/area/awaymission/beach) +"Ow" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/structure/railing{ + dir = 1 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"OD" = ( +/obj/structure/reagent_dispensers/watertank, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"OE" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/machinery/button/door/directional/west{ + id = "beach_room_6" + }, +/obj/item/clothing/suit/jacket/leather/biker, +/turf/open/floor/wood, +/area/awaymission/beach) +"OG" = ( +/obj/effect/turf_decal/siding/dark_red/corner, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"OK" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/turf_decal/tile/dark/half{ + pixel_y = -2; + pixel_x = 5; + dir = 8 + }, +/turf/open/water/beach, +/area/awaymission/beach) +"OT" = ( +/obj/item/reagent_containers/cup/soda_cans/lemon_lime{ + pixel_x = -12; + pixel_y = -7 + }, +/obj/item/reagent_containers/cup/soda_cans/dr_gibb{ + pixel_x = 13; + pixel_y = -7 + }, +/obj/structure/fluff/beach_umbrella, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"OU" = ( +/obj/structure/chair/plastic, +/obj/item/pai_card{ + desc = "A real Nanotrasen success, these personal AIs provide all of the companionship of an AI without any law related red-tape."; + name = "\improper Nanotrasen-brand personal AI device exhibit"; + pixel_y = 3; + pixel_x = -1 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Pe" = ( +/turf/open/misc/beach/coast{ + dir = 5 + }, +/area/awaymission/beach) +"Pk" = ( +/obj/structure/table/glass, +/obj/machinery/fax{ + fax_name = "Beach Hotel Fax"; + name = "Beach Hotel's Fax Machine"; + pixel_y = 8; + visible_to_network = 0 + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"Pn" = ( +/obj/structure/chair/office{ + dir = 8 + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"Pt" = ( +/obj/machinery/door/airlock/command/glass{ + name = "Admin" + }, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/mapping_helpers/airlock_note_placer{ + note_info = "Dear IT: Please fix the fax machine" + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"Py" = ( +/obj/structure/tank_holder/extinguisher, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"PH" = ( +/obj/effect/turf_decal/siding/blue/corner, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"PN" = ( +/obj/effect/turf_decal/sand, +/obj/effect/turf_decal/siding/wood{ + dir = 5 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Qe" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/door/airlock/wood{ + name = "Bathroom"; + id_tag = "toilet3beach" + }, +/turf/open/floor/iron/white, +/area/awaymission/beach) +"Qf" = ( +/obj/structure/dresser, +/obj/structure/sign/calendar/directional/north, +/turf/open/floor/wood, +/area/awaymission/beach) +"Qg" = ( +/turf/open/floor/wood/parquet, +/area/awaymission/beach) +"Qk" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/clothing/suit/jacket/miljacket, +/turf/open/floor/wood, +/area/awaymission/beach) +"Qr" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/food_cart, +/turf/open/floor/plating, +/area/awaymission/beach) +"Qt" = ( +/obj/item/kirbyplants/organic/plant8{ + pixel_y = 18; + pixel_x = -8 + }, +/obj/item/cigbutt{ + pixel_y = -4; + pixel_x = 2 + }, +/turf/open/floor/iron/dark/diagonal, +/area/awaymission/beach) +"QF" = ( +/obj/structure/sink/kitchen/directional/east, +/turf/open/floor/plastic, +/area/awaymission/beach) +"QG" = ( +/obj/structure/chair/plastic{ + dir = 8 + }, +/obj/item/reagent_containers/cup/soda_cans/melon_soda{ + pixel_y = 13; + pixel_x = -9 + }, +/obj/item/fishing_rod{ + pixel_x = 8; pixel_y = -6 }, -/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind{ - pixel_x = 15 +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"QI" = ( +/obj/machinery/door/airlock/wood{ + name = "Room 12"; + id_tag = "beach_room_12" + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood, +/area/awaymission/beach) +"QM" = ( +/obj/structure/table/wood, +/obj/item/stack/arcadeticket{ + pixel_y = 6; + pixel_x = -7 + }, +/obj/item/pen{ + pixel_y = 5; + pixel_x = 8 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"QN" = ( +/obj/effect/turf_decal/sand, +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"QO" = ( +/obj/item/trash/can{ + pixel_y = -9; + pixel_x = 10 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"QR" = ( +/obj/item/kirbyplants/organic/plant21{ + pixel_y = 3; + pixel_x = -6 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Rj" = ( +/turf/open/misc/beach/coast{ + dir = 6 + }, +/area/awaymission/beach) +"Rn" = ( +/obj/effect/turf_decal/stripes/red/box, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Rr" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 10; + pixel_x = 7 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Rs" = ( +/obj/structure/flora/tree/palm/style_2{ + pixel_y = 25 + }, +/obj/structure/chair/plastic{ + dir = 4 }, -/obj/structure/fluff/beach_umbrella/science, /turf/open/misc/beach/sand, /area/awaymission/beach) -"cV" = ( -/obj/structure/flora/coconuts{ - pixel_x = -5; - pixel_y = 4 +"RA" = ( +/obj/item/kirbyplants/organic/plant8{ + pixel_y = 18; + pixel_x = -8 }, -/turf/open/misc/beach/coast, +/turf/open/floor/wood/large, /area/awaymission/beach) -"cW" = ( -/obj/item/reagent_containers/cup/soda_cans/lemon_lime{ - pixel_x = -12 +"RE" = ( +/obj/structure/chair/stool/bamboo{ + dir = 1 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"RI" = ( +/obj/machinery/door/airlock/medical/glass{ + name = "Medbay Clinic" + }, +/obj/effect/turf_decal/siding/blue{ + dir = 8 + }, +/turf/open/floor/iron/white/textured_large, +/area/awaymission/beach) +"RQ" = ( +/obj/structure/closet/crate, +/obj/item/clothing/suit/hooded/carp_costume, +/obj/item/clothing/head/hooded/carp_hood, +/obj/item/toy/plush/carpplushie, +/obj/item/toy/plush/shark, +/turf/open/floor/eighties, +/area/awaymission/beach) +"Sg" = ( +/obj/structure/table/bronze, +/obj/item/reagent_containers/cup/rag{ + pixel_y = 5 + }, +/obj/item/reagent_containers/condiment/coconut_milk{ + pixel_y = 14; + pixel_x = 5 + }, +/obj/machinery/light/directional/east, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Sj" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"cX" = ( +"Sr" = ( +/obj/structure/table/wood/fancy, +/obj/effect/turf_decal/tile/dark_red/full, /obj/item/reagent_containers/cup/soda_cans/cola{ pixel_x = -5; - pixel_y = -5 + pixel_y = 14 }, -/obj/structure/fluff/beach_umbrella/security, -/turf/open/misc/beach/sand, -/area/awaymission/beach) -"cY" = ( -/obj/item/reagent_containers/cup/soda_cans/starkist{ - pixel_x = -6 +/obj/item/reagent_containers/cup/soda_cans/cola{ + pixel_y = 13; + pixel_x = 6 }, -/turf/open/misc/beach/sand, +/obj/item/reagent_containers/cup/soda_cans/cola{ + pixel_y = 10 + }, +/obj/item/reagent_containers/cup/soda_cans/cola{ + pixel_y = 6; + pixel_x = 11 + }, +/turf/open/floor/iron/smooth_large, /area/awaymission/beach) -"cZ" = ( -/obj/item/clothing/head/collectable/paper{ - desc = "What looks like an ordinary paper hat is actually a rare and valuable collector's edition paper hat. Keep away from fire, Curators, and ocean waves." +"St" = ( +/turf/open/floor/iron/stairs/old, +/area/awaymission/beach) +"Sw" = ( +/obj/structure/chair/stool/directional/south{ + dir = 8 }, -/turf/open/water/beach, +/turf/open/floor/wood, +/area/awaymission/beach) +"SB" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/awaystart, +/turf/open/floor/plating, /area/awaymission/beach) -"da" = ( -/mob/living/simple_animal/parrot, +"SI" = ( +/mob/living/basic/crab/kreb, /turf/open/misc/beach/sand, /area/awaymission/beach) -"db" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/obj/item/clothing/suit/jacket/letterman_nanotrasen, -/turf/open/floor/wood, +"Th" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/cup/beaker/large{ + pixel_y = 7 + }, +/turf/open/floor/wood/large, /area/awaymission/beach) -"dc" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/obj/item/clothing/suit/jacket/letterman_syndie, -/turf/open/floor/wood, +"Tn" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 6 + }, +/turf/open/floor/eighties, /area/awaymission/beach) -"dd" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/obj/item/clothing/suit/jacket/letterman_red, -/turf/open/floor/wood, +"Tr" = ( +/turf/open/floor/iron/dark/textured_large, /area/awaymission/beach) -"de" = ( +"Ts" = ( /obj/structure/closet/secure_closet/personal/cabinet, +/obj/item/clothing/neck/necklace/dope, /obj/item/clothing/suit/jacket/letterman, /turf/open/floor/wood, /area/awaymission/beach) -"df" = ( -/obj/structure/closet/secure_closet/personal/cabinet, -/obj/item/clothing/neck/necklace/dope, -/turf/open/floor/wood, +"TC" = ( +/obj/effect/turf_decal/siding/blue{ + dir = 4 + }, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"dg" = ( -/obj/item/clothing/glasses/heat, +"TG" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 4 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"TJ" = ( +/obj/effect/turf_decal/siding/wood/corner{ + dir = 8 + }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"hw" = ( -/obj/structure/table/wood, -/obj/item/reagent_containers/cup/glass/bottle/ale, -/turf/open/floor/wood, +"TK" = ( +/obj/item/storage/box/syringes{ + pixel_y = 14; + pixel_x = -5 + }, +/obj/item/clothing/neck/stethoscope{ + pixel_y = 3; + pixel_x = 4 + }, +/obj/structure/table/glass, +/turf/open/floor/iron/white/textured_large, /area/awaymission/beach) -"iy" = ( -/obj/item/toy/seashell, -/turf/open/misc/beach/coast, +"TO" = ( +/obj/machinery/light/directional/west, +/turf/open/floor/wood/parquet, /area/awaymission/beach) -"kK" = ( -/obj/item/toy/seashell{ - pixel_x = 5; - pixel_y = 4 +"TX" = ( +/obj/structure/table/reinforced, +/obj/item/stack/medical/mesh{ + pixel_y = 1; + pixel_x = 1 }, -/turf/open/misc/beach/sand, +/obj/item/clothing/suit/toggle/labcoat{ + pixel_y = 9; + pixel_x = -8 + }, +/obj/item/storage/box/bodybags{ + pixel_y = 17; + pixel_x = 8 + }, +/turf/open/floor/iron/white/textured_large, /area/awaymission/beach) -"kS" = ( -/obj/item/toy/seashell{ +"Ug" = ( +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/box/mousetraps{ + pixel_x = -5; + pixel_y = 14 + }, +/obj/structure/table, +/obj/item/storage/box/mousetraps{ + pixel_x = 12; + pixel_y = 15 + }, +/obj/item/grenade/chem_grenade/cleaner{ pixel_x = -7; - pixel_y = 5 + pixel_y = 6 }, -/turf/open/misc/beach/sand, +/obj/item/grenade/chem_grenade/cleaner{ + pixel_x = -1; + pixel_y = 3 + }, +/turf/open/floor/wood/large, /area/awaymission/beach) -"lx" = ( -/obj/structure/table/wood, -/obj/item/clothing/glasses/sunglasses, -/obj/item/reagent_containers/cup/glass/shaker, +"Uq" = ( +/obj/item/kirbyplants/organic/plant8{ + pixel_y = 9; + pixel_x = 6 + }, +/obj/structure/railing{ + dir = 10 + }, /turf/open/floor/wood, /area/awaymission/beach) -"lA" = ( +"Ut" = ( /obj/structure/table/wood, -/obj/item/reagent_containers/cup/glass/bottle/maltliquor{ - pixel_y = 3 +/obj/item/pai_card{ + desc = "A real Nanotrasen success, these personal AIs provide all of the companionship of an AI without any law related red-tape."; + name = "\improper Nanotrasen-brand personal AI device exhibit"; + pixel_y = 3; + pixel_x = 10 }, -/turf/open/floor/wood, +/turf/open/floor/wood/large, /area/awaymission/beach) -"mF" = ( -/obj/structure/table/wood, -/obj/item/food/burger/crab{ - pixel_x = 9; - pixel_y = 8 +"UB" = ( +/obj/structure/bed, +/turf/open/floor/iron/dark/textured_large, +/area/awaymission/beach) +"UI" = ( +/obj/effect/turf_decal/siding/dark_red/corner{ + dir = 8 }, -/turf/open/floor/wood, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"mV" = ( -/obj/item/reagent_containers/cup/glass/bottle/beer/light{ - pixel_x = -14; - pixel_y = 15 +"UK" = ( +/obj/machinery/light/directional/east, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"UX" = ( +/obj/structure/flora/tree/palm/style_2{ + pixel_y = 12; + pixel_x = -7 }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"oE" = ( -/obj/structure/table/wood, -/obj/item/food/burger/crab, -/turf/open/floor/wood, +"Vc" = ( +/obj/structure/closet/gmcloset, +/turf/open/floor/plastic, +/area/awaymission/beach) +"Vd" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Vf" = ( +/turf/open/misc/beach/coast{ + dir = 1 + }, /area/awaymission/beach) -"sG" = ( +"Vo" = ( /obj/effect/turf_decal/sand, -/obj/structure/sign/poster/contraband/smoke/directional/south, -/obj/machinery/vending/cigarette/beach, -/turf/open/misc/beach/sand, +/obj/machinery/door/airlock/wood{ + name = "Bathroom"; + id_tag = "toilet2beach" + }, +/turf/open/floor/iron/white, /area/awaymission/beach) -"wr" = ( +"Vy" = ( /obj/item/toy/seashell{ - pixel_y = -5 + pixel_x = 5; + pixel_y = 4 }, -/turf/open/misc/beach/coast, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"VG" = ( +/obj/structure/tank_holder/extinguisher, +/turf/open/floor/wood/large, /area/awaymission/beach) -"wz" = ( +"VI" = ( /obj/item/toy/seashell{ - pixel_x = -8; - pixel_y = 9 + pixel_x = 12; + pixel_y = -5 }, -/turf/open/misc/beach/coast/corner{ +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"VP" = ( +/obj/structure/dresser, +/obj/machinery/digital_clock/directional/north, +/turf/open/floor/wood, +/area/awaymission/beach) +"VQ" = ( +/obj/effect/turf_decal/siding/wood{ dir = 1 }, +/obj/item/blood_filter{ + pixel_y = 8; + pixel_x = -6 + }, +/obj/item/surgical_drapes{ + pixel_x = -1; + pixel_y = 2 + }, +/obj/item/surgical_drapes{ + pixel_x = 13; + pixel_y = 2 + }, +/obj/structure/table/glass, +/turf/open/floor/wood/large, /area/awaymission/beach) -"xA" = ( -/obj/structure/table/wood, -/obj/item/camera, -/turf/open/floor/wood, +"VY" = ( +/turf/open/misc/beach/sand, /area/awaymission/beach) -"yp" = ( -/obj/item/flashlight/flare/torch{ - pixel_x = 15; - pixel_y = -7 +"Wa" = ( +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"Wb" = ( +/obj/item/toy/seashell{ + pixel_x = 8; + pixel_y = 14 }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"zc" = ( -/obj/structure/table/wood, -/obj/item/reagent_containers/cup/glass/bottle/sake{ - pixel_y = 4 +"Wd" = ( +/obj/machinery/door/airlock/wood{ + name = "Room 5"; + id_tag = "beach_room_5" }, +/obj/effect/turf_decal/siding/wood, /turf/open/floor/wood, /area/awaymission/beach) -"ze" = ( -/obj/item/toy/seashell{ - pixel_x = 12; - pixel_y = -5 +"Wi" = ( +/obj/effect/turf_decal/sand{ + density = 1 + }, +/obj/effect/decal/fakelattice, +/turf/open/floor/pod/light{ + density = 1 }, +/area/awaymission/beach) +"Wk" = ( +/obj/structure/billboard/space_cola, +/obj/effect/turf_decal/siding/dark_red, /turf/open/misc/beach/sand, /area/awaymission/beach) -"zZ" = ( +"Wl" = ( /obj/effect/turf_decal/sand, -/obj/effect/baseturf_helper/beach/water, /turf/open/misc/beach/sand, /area/awaymission/beach) -"AR" = ( -/obj/item/toy/seashell{ - pixel_x = 8; - pixel_y = 14 +"Wv" = ( +/obj/item/reagent_containers/cup/soda_cans/starkist{ + pixel_y = 16; + pixel_x = 10 }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"Bd" = ( -/obj/item/toy/seashell{ - pixel_x = 12; - pixel_y = 5 +"Wx" = ( +/obj/item/reagent_containers/cup/glass/bottle/wine{ + pixel_y = 16; + pixel_x = -5 }, -/turf/open/misc/beach/coast{ - dir = 4 +/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass{ + pixel_y = 3; + pixel_x = -8 }, +/obj/structure/table/bronze, +/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass{ + pixel_y = 10; + pixel_x = 6 + }, +/turf/open/floor/wood/large, /area/awaymission/beach) -"EG" = ( -/obj/item/flashlight/flare/torch{ - pixel_x = -2; - pixel_y = 8 +"WC" = ( +/obj/structure/table/bronze, +/obj/item/camera{ + pixel_y = 8; + pixel_x = 6 + }, +/obj/item/pen/blue{ + pixel_x = -11; + pixel_y = 2 }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"FG" = ( -/obj/structure/table/wood, -/obj/machinery/reagentgrinder, -/turf/open/floor/wood, +"WM" = ( +/obj/item/reagent_containers/cup/soda_cans/starkist{ + pixel_x = -6 + }, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"He" = ( -/obj/structure/fluff/beach_umbrella/syndi, -/turf/open/misc/beach/coast/corner{ - dir = 8 +"WO" = ( +/obj/item/cigbutt{ + pixel_y = -6; + pixel_x = -12 }, +/obj/item/clothing/head/soft/black, +/turf/open/floor/wood/parquet, /area/awaymission/beach) -"HN" = ( -/obj/machinery/griddle, -/turf/open/floor/wood, +"Xd" = ( +/obj/structure/table/optable, +/turf/open/floor/wood/large, /area/awaymission/beach) -"Jr" = ( -/obj/machinery/oven/range, +"Xh" = ( +/obj/vehicle/ridden/atv{ + dir = 4 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"Xt" = ( +/obj/structure/table/wood/fancy, +/obj/effect/turf_decal/tile/dark_red/full, +/obj/item/reagent_containers/cup/soda_cans/cola{ + pixel_x = -13; + pixel_y = 14 + }, +/obj/item/reagent_containers/cup/soda_cans/cola{ + pixel_x = 7; + pixel_y = 8 + }, +/turf/open/floor/iron/smooth_large, +/area/awaymission/beach) +"XB" = ( +/turf/open/water/beach, +/area/awaymission/beach) +"XT" = ( +/obj/effect/turf_decal/siding/dark_red/corner{ + dir = 4 + }, +/turf/open/misc/beach/sand, +/area/awaymission/beach) +"XV" = ( +/obj/structure/closet/secure_closet/personal/cabinet, +/obj/machinery/button/door/directional/north{ + id = "beach_room_9" + }, +/obj/item/claymore/cutlass{ + desc = "A piratey, foam sword used by kids to train themselves in the business of \"negotiating\" the transfer of treasure."; + force = 0; + name = "foam cutlass"; + throwforce = 0 + }, /turf/open/floor/wood, /area/awaymission/beach) -"Kg" = ( -/obj/item/flashlight/flare/torch{ - pixel_x = 12; +"XX" = ( +/obj/structure/table/wood, +/obj/machinery/recharger, +/obj/item/reagent_containers/cup/glass/mug{ + pixel_x = -12; pixel_y = 9 }, -/turf/open/misc/beach/sand, +/obj/effect/spawner/random/bureaucracy/stamp{ + pixel_y = 14; + pixel_x = 8 + }, +/turf/open/floor/iron/dark/diagonal, /area/awaymission/beach) -"MD" = ( -/obj/item/toy/seashell, +"Yl" = ( +/obj/effect/turf_decal/sand/plating, +/obj/item/shovel{ + pixel_y = 15; + pixel_x = -8 + }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"MP" = ( -/obj/item/flashlight/flare/torch{ - pixel_x = 7; - pixel_y = -5 +"Yq" = ( +/obj/item/reagent_containers/cup/watering_can{ + pixel_y = 19; + pixel_x = -6 + }, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"YB" = ( +/obj/machinery/vending/coffee, +/turf/open/floor/wood/large, +/area/awaymission/beach) +"YL" = ( +/obj/structure/reagent_dispensers/watertank, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/awaymission/beach) +"YM" = ( +/obj/item/toy/seashell{ + pixel_x = 12; + pixel_y = 5 }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"Nr" = ( -/obj/structure/table, -/obj/item/reagent_containers/cup/glass/bottle/beer, -/obj/item/reagent_containers/cup/glass/bottle/beer, -/obj/item/reagent_containers/cup/glass/bottle/beer, -/obj/item/reagent_containers/cup/glass/bottle/beer, -/obj/item/reagent_containers/cup/glass/bottle/beer, -/obj/item/reagent_containers/cup/glass/bottle/beer, +"YV" = ( +/obj/structure/flora/tree/palm{ + pixel_y = 24; + pixel_x = -7 + }, +/obj/structure/flora/coconuts, /turf/open/misc/beach/sand, /area/awaymission/beach) -"QQ" = ( -/obj/item/reagent_containers/cup/glass/bottle/rum{ - pixel_y = 2 - }, -/obj/structure/table/wood, -/turf/open/floor/wood, +"Zj" = ( +/obj/machinery/recharge_station, +/obj/machinery/light/directional/east, +/turf/open/floor/carpet/cyan, /area/awaymission/beach) -"QU" = ( -/obj/structure/closet/crate/freezer, -/obj/item/food/meat/slab/rawcrab, -/obj/item/food/meat/slab/rawcrab, -/obj/item/food/meat/slab/rawcrab, -/obj/item/food/meat/slab/monkey, -/obj/item/food/meat/slab/monkey, -/obj/item/food/meat/slab/monkey, -/obj/item/food/meat/slab/gorilla, -/obj/item/food/meat/slab/gorilla, -/obj/item/food/meat/slab/gorilla, +"Zm" = ( +/obj/item/toy/beach_ball, /turf/open/misc/beach/sand, /area/awaymission/beach) -"Sg" = ( -/obj/structure/sink/kitchen/directional/south, -/turf/open/floor/wood, +"Zn" = ( +/obj/structure/bed/medical/emergency, +/turf/open/floor/iron/white/textured_large, /area/awaymission/beach) -"SR" = ( -/obj/machinery/food_cart, -/turf/open/misc/beach/sand, +"Zp" = ( +/turf/open/floor/wood/large, /area/awaymission/beach) -"Tr" = ( -/obj/structure/table/wood, -/obj/item/storage/photo_album, +"Zt" = ( +/obj/structure/table/bronze, +/obj/item/storage/toolbox/fishing{ + pixel_y = 2 + }, /turf/open/floor/wood, /area/awaymission/beach) -"Vn" = ( +"Zw" = ( +/obj/machinery/vending/snack, /obj/effect/turf_decal/sand, -/obj/structure/table/wood, /turf/open/misc/beach/sand, /area/awaymission/beach) -"Vx" = ( -/obj/item/reagent_containers/cup/glass/bottle/wine{ - pixel_y = 4 +"ZA" = ( +/obj/item/reagent_containers/cup/soda_cans/cola{ + pixel_x = -5; + pixel_y = -5 }, -/obj/structure/table/wood, -/turf/open/floor/wood, +/obj/structure/fluff/beach_umbrella/syndi, +/turf/open/misc/beach/sand, /area/awaymission/beach) -"Ws" = ( -/obj/item/toy/seashell{ - pixel_x = -10; - pixel_y = -4 +"ZH" = ( +/obj/structure/table/bronze, +/obj/item/paper/paperslip{ + pixel_y = 6; + pixel_x = 10 }, -/turf/open/misc/beach/sand, +/obj/item/pen/fourcolor{ + pixel_y = 7; + pixel_x = 1 + }, +/turf/open/floor/carpet, /area/awaymission/beach) -"Za" = ( -/obj/item/flashlight/flare/torch{ - pixel_x = 10; +"ZR" = ( +/obj/structure/chair/plastic, +/obj/item/clothing/head/collectable/paper{ + desc = "What looks like an ordinary paper hat is actually a rare and valuable collector's edition paper hat. Keep away from fire, Curators, and ocean waves."; pixel_y = -4 }, /turf/open/misc/beach/sand, /area/awaymission/beach) -"ZL" = ( -/obj/machinery/grill, -/turf/open/misc/beach/sand, +"ZU" = ( +/obj/item/toy/seashell{ + pixel_y = 11; + pixel_x = -7 + }, +/turf/open/misc/beach/coast, +/area/awaymission/beach) +"ZX" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/button/door/directional/east{ + id = "toilet1beach"; + name = "restroom lock"; + normaldoorcontrol = 1; + specialfunctions = 4 + }, +/obj/structure/toilet{ + pixel_y = 8 + }, +/obj/structure/sink/directional/west, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/white, +/area/awaymission/beach) +"ZZ" = ( +/obj/item/stack/arcadeticket{ + pixel_y = 6; + pixel_x = -7 + }, +/turf/open/floor/eighties, /area/awaymission/beach) (1,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (2,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (3,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (4,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (5,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (6,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (7,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (8,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (9,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (10,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (11,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (12,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (13,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +MZ +Le +Le +Le +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (14,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +Vf +YV +VY +VY +hL +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (15,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -at -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -at -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -at -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -at -ab -ab -ab -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -ab -at -ab -ab -ab -ab -ab -ab -at -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +Vf +VY +VY +VY +Er +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (16,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +Vf +VY +VY +VY +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (17,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +Vf +IZ +VY +VY +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (18,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +Pe +Fb +tJ +zr +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +hf +CG +CG +CG +Gh +XB +hf +CG +CG +CG +hQ +CG +CG +CG +Gh +XB +hf +CG +CG +CG +Gh +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (19,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +Pe +Fb +Fb +Rj +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +di +FM +hC +jI +Cf +XB +di +FM +hC +jI +gG +FM +hC +jI +Cf +XB +di +FM +hC +Uq +Cf +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (20,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +dR +Iw +Iw +xv +XB +xv +dR +Iw +Iw +xv +dR +Iw +Iw +xv +XB +xv +dR +Iw +Iw +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (21,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +vR +GC +CQ +xv +xv +xv +kR +Em +CQ +xv +Gn +GC +kD +xv +xv +xv +tx +Em +Ts +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (22,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +mg +GC +Gn +ll +Zp +QI +Gn +Em +mU +xv +aX +GC +Gn +JG +Zp +fj +Gn +Em +ru +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (23,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +Qf +vM +um +xv +Zp +xv +Qf +Zj +MP +xv +Hv +vM +DV +xv +Zp +xv +Es +jZ +vc +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (24,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -as -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +xv +xv +xv +xv +Gu +xv +xv +xv +xv +xv +xv +xv +xv +xv +Zp +xv +xv +xv +xv +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (25,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -as -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +FM +Nk +Gn +cq +CQ +xv +Zp +Zp +UK +Zp +Zp +Zp +Zp +UK +Zp +Zp +Zp +Zp +UK +VG +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (26,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +pw +Iw +AG +Em +Gn +lz +Zp +xv +xv +xv +xv +xv +xv +xv +xv +xv +Zp +xv +xv +xv +xv +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (27,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +CH +Iw +vc +jZ +hp +xv +Zp +xv +XV +GC +cp +xv +Qk +Em +Nd +xv +Gu +xv +yZ +GC +Fg +xv +XB +MZ +Le +Le +Le +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (28,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +xv +gk +xv +xv +Zp +wX +Gn +GC +ru +xv +LS +Em +Gn +Wd +Zp +AW +Gn +GC +ru +xv +MZ +MF +Vy +VY +FD +hL +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (29,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -at -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +FM +LJ +Gn +kI +cp +xv +Zp +xv +VP +vM +Zt +xv +Qf +jZ +im +xv +Zp +xv +VP +vM +Zt +xv +MF +Wb +It +VY +yq +VY +hL +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (30,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +pw +Iw +cn +GC +Gn +yE +Zp +xv +xv +xv +xv +xv +xv +xv +xv +xv +Zp +xv +xv +xv +xv +xv +MT +VY +tP +NF +QG +VY +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (31,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +CH +Iw +KB +vM +vF +xv +Zp +Zp +UK +Zp +xv +VY +xv +Zp +Zp +Zp +Zp +UK +Zp +Zp +nW +Da +Wl +VY +VY +VY +VY +VY +ls +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (32,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +xv +xv +xv +xv +Zp +xv +xv +at +xv +xv +xv +Jj +xv +xv +Zp +xv +xv +xv +xv +xv +jH +ls +VY +VY +VY +MT +VY +hL +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (33,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -af -aj -aj -aj -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +xv +xv +Ug +Yq +an +xv +Zp +xv +oX +Em +CQ +xv +OE +GC +Gn +xv +Zp +cZ +qC +Em +re +xv +VY +VY +xv +nD +xv +xv +xv +tE +hL +Le +Le +Le +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (34,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -af -ay -kK -ak -kS -aT -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +EO +Zp +EH +xv +Gu +xv +Gn +Em +ru +xv +CQ +GC +ru +xv +Zp +xv +us +Em +ru +xv +ah +xv +xv +Zp +qX +Zp +xv +xv +tE +VY +VY +VY +hL +Le +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (35,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -af -ay -AR -ak -ak -ak -ak -aT -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +RA +Zp +Zp +xv +oa +xv +VP +jZ +AB +xv +Qf +vM +Zt +xv +oa +xv +vc +jZ +CR +xv +xv +xv +Gq +iN +yX +zH +io +xv +xv +wA +VY +VY +VY +VY +hL +Le +Le +Le +Le +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (36,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -af -ay -ak -ak -ak -Ws -ak -ak -ak -aT -aj -aj -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +OD +xv +EP +xv +Zp +xv +xv +xv +xv +xv +xv +xv +xv +xv +Zp +xv +xv +xv +xv +xv +dx +Zp +Zp +mb +mb +mb +Zp +QR +Iw +VY +GG +VY +VY +uz +VY +VY +VY +VY +VY +hL +Le +ni +XB +XB +XB +XB +MZ +Le +Le +Le +Le +Le +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (37,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -af -ay -ak -ak -ak -aA -ak -ak -ak -ak -ak -ak -ak -aT -aj -aj -aj -aj -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +hf +CG +xv +xv +xv +iY +Zp +Zp +Zp +Zp +Zp +Zp +Jr +Zp +Zp +Zp +Zp +Zp +Zp +Jr +Zp +uq +Zp +Zp +Og +uL +TG +Zp +Zp +Zp +dS +Iw +VY +VY +VY +sc +sU +VY +VY +VY +ls +VY +VY +VY +hL +ni +XB +XB +XB +Vf +GG +wA +VY +VY +VY +hL +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (38,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -af -ay -ak -ak -ak -ak -ak -ak -aA -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -aT -aj -ao -av -av -av -av -af -aj -aj -aj -aj -aj -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +hf +sj +aE +Zp +mk +Zp +Zp +Zp +Zp +Zp +Zp +Zp +Zp +Zp +Zp +Zp +Zp +Zp +Zp +Zp +Zp +Zp +uq +Zp +Zp +Wa +Bl +BQ +Zp +Zp +FP +Iw +Iw +Wl +VY +VY +VY +VY +VY +VY +Ar +VY +VY +rq +VY +GG +hL +Le +Le +Le +MF +VY +VY +VY +VY +VY +GG +hL +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (39,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -aA -ak -aD -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -aT -ao -av -av -av -ag -MD -aA -ak -ak -ak -aT -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +di +iF +Zp +xv +xv +xv +aB +aB +xv +Pt +xv +xv +xv +xv +xv +Iw +RI +Iw +xv +xv +xv +xv +xv +xv +Gu +BL +Vd +dc +Zp +Zp +Iw +Iw +Wl +Wl +VY +VY +VY +VY +VY +IA +EU +VY +VY +VY +VY +VY +VY +VY +VY +VY +VY +VY +VY +VY +VY +IZ +VY +Zm +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (40,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -aA -ak -ak -ak -ak -ak -aD -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -MD -aT -aj -aj -aj -ay -ak -ak -ak -ak -ak -MD -aT -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +di +Zp +Zp +xv +aw +Qt +un +un +dk +un +Py +xv +Ky +zI +Zn +Zn +bi +nK +NU +xv +rd +rd +xv +Wx +Zp +rQ +Zp +Zp +Zp +Zp +xv +gI +Wl +nq +Wl +VY +VY +VY +ls +VY +VY +VY +VY +xv +Iw +Iw +xv +VY +xv +Iw +Iw +xv +fU +VY +VY +bY +VY +VY +hL +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (41,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -Kg -ak -ak -ak -aA -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -aK -ak -cG -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +fe +sd +uV +xv +iM +un +Lg +mP +Lg +un +tD +xv +TX +bi +bi +bi +bi +bi +bi +ob +sS +sS +xv +iw +GC +ZH +GC +GC +GC +GC +NH +GC +Wl +Wl +Wl +VY +VY +wA +VY +VY +VY +VY +xv +xv +zs +zs +xv +Iw +xv +oC +RQ +xv +xv +ls +VY +Ar +Ar +VY +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (42,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -Za -aF -EG -ak -ak -ak -ak -ak -ak -ak -aD -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -aT -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -at -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +HV +mi +uV +xv +eE +un +Cb +uJ +eT +un +Pk +xv +jm +bi +bi +TK +bi +bi +Gi +xv +Bm +sS +xv +GC +GC +tU +GC +GC +GC +Gf +xv +GC +GC +Wl +Wl +VY +VY +VY +VY +VY +VY +VY +xv +dh +kZ +MO +iy +kZ +xp +Dy +yc +MN +xv +VY +VY +VY +tr +VY +Kh +Rj +JF +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (43,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -aA -ak -ak -aG -ak -aD -ak -ak -ak -ak -ak -aA -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +HV +iA +xv +Ne +un +zA +XX +Pn +dk +qk +xv +fa +Ka +bi +kz +Fe +bi +Ih +xv +Bm +sS +xv +iw +GC +fd +GC +GC +GC +GC +NH +GC +GC +GC +Wl +VY +VY +VY +VY +VY +VY +VY +xv +xv +mT +ZZ +kZ +uc +FE +Tn +QM +Zp +Iw +VY +VY +VY +ls +VY +BK +XB +XB +XB +XB +pM +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (44,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -yp -aF -aC -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -aA -ak -bo -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +xv +un +un +un +yL +Dj +xv +xv +Iw +xv +bi +bi +bi +xv +xv +xv +iq +sS +xv +wL +Zp +qf +Zp +Zp +Zp +xv +xv +cD +GC +GC +GC +VY +VY +VY +ls +VY +VY +GG +VY +xv +Iw +xv +gd +gd +yn +Zp +Ut +Zp +xv +VY +VY +VY +VY +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (45,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -MP -ak -ak -aA -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -aD -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +un +mN +DD +mp +xv +xv +ns +uZ +xv +MV +xv +Ic +xv +Bm +QF +sS +sS +xv +xv +Zp +Og +uL +TG +Zp +Iw +cD +Lt +Wl +GC +GC +GC +VY +VY +VY +VY +VY +VY +wA +VY +Wl +xv +Iw +Iw +xv +Zp +sP +xv +xv +Hn +VY +VY +VY +VY +hL +ni +XB +XB +XB +XB +XB +XB +XB +JF +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (46,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -aD -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ch -ak -ak -ak -ak -ak -ak -ak -ak -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +pE +aB +aB +xv +xv +VQ +Zp +Zp +Zp +Zp +xv +Iw +xv +Bm +sS +sS +sS +sS +ob +Zp +Wa +Mo +BQ +Zp +Iw +Iw +Lt +Wl +Wl +GC +GC +GC +VY +VY +VY +VY +VY +VY +VY +VY +VY +VY +Wl +xv +qy +Iw +xv +tz +Wl +VY +VY +VY +IZ +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (47,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -aA -ak -ak -ak -ak -ak -aA -ak -ak -ak -ak -ak -ak -ak -ak -aA -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -aT -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +Tr +Tr +On +xv +XB +hD +Zp +Zp +Zp +Zp +Cf +XB +xv +xv +Vc +Vc +Vc +xv +xv +xv +BL +fV +dc +Zp +nO +Iw +Lt +Wl +Wl +VY +GC +GC +GC +VY +VY +VY +VY +VY +VY +VY +Wl +VY +VY +TJ +sL +Sj +Ll +VY +VY +VY +Wl +VY +VY +VY +Fk +XB +XB +XB +XB +XB +XB +XB +XB +XB +pM +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (48,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -aA -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -aK -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +aB +UB +Tr +On +aB +XB +vx +Bq +Xd +Ej +lk +LC +XB +XB +xv +xv +xv +xv +xv +iJ +xv +jU +xv +Zp +Zp +EG +Iw +Nh +Wl +ls +VY +VY +GC +GC +GC +VY +VY +VY +ls +VY +Wl +Wl +Wl +VY +Wl +VY +Wl +VY +Wl +VY +VY +VY +VY +VY +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (49,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ba -ba -ba -ba -ba -ba -ba -ba -ba -ba -ak -ak -ak -ak -iy -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +xv +cE +xv +xv +XB +HV +OK +mG +uv +LC +XB +XB +XB +xv +fi +uT +uT +Nb +SB +SB +uT +xv +wt +YB +xv +xv +Wl +VY +VY +VY +VY +VY +GC +GC +GC +VY +VY +VY +Wl +Wl +Wl +VY +Wl +VY +Wl +Wl +VY +VY +VY +Wl +VY +VY +gP +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +JF +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (50,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ba -ba -aX -aX -aX -aX -cA -aX -ba -ba -ak -ak -ak -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +xv +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +uT +FF +Ge +SB +SB +Qr +KV +xv +xv +xv +xv +VY +VY +nV +VY +GG +VY +VY +bg +GC +GC +Wl +Wl +Wl +Wl +Wl +VY +VY +Wl +Wl +VY +VY +Wl +VY +VY +VY +VY +VY +OT +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (51,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -MD -ak -ak -ak -ak -ak -ak -ak -ak -aA -bf -bp -bx -ak -ak -aX -aX -aX -aX -ak -ba -ba -cd -aX -co -bd -bd -hw -cH -ba -ak -ak -cO -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +Ge +uT +uT +vq +La +xv +xv +xv +ls +VY +VY +VY +VY +VY +VY +VY +VY +wA +VY +Wl +Wl +Wl +Wl +Wl +Wl +VY +Cy +xv +xv +Iw +Iw +xv +xv +Zw +VY +Wl +VY +VY +gP +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (52,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -at -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -az -ak -ak -ak -ak -ak -ak -ak -ak -ak -bg -bq -by -ak -ak -aX -bL -bQ -aX -ak -ba -ba -cs -aX -cn -ck -bd -hw -cH -ba -ak -ak -cP -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +xv +xv +lY +YL +xv +xv +CF +VY +VY +VY +jW +jW +jW +VY +VY +VY +VY +VY +ls +Wl +Wl +Wl +VY +VY +Wl +Wl +cX +xv +jF +iU +li +xE +xv +BN +VY +VY +VY +VY +VY +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +pM +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (53,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ak -ak -ak -ak -bh -br -bz -ak -aA -aX -bM -bR -bX -ba -ba -ba -cg -aX -cp -bd -bd -cC -cH -ba -ak -ak -cO -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +xv +xv +xv +xv +Fb +mf +VY +KL +jW +jW +wY +jW +jW +GG +VY +VY +VY +VY +Wl +Wl +Rr +VY +VY +VY +Wl +xv +xv +pX +Zp +Zp +Zp +ow +vX +wd +VY +VY +gP +VY +Kh +Rj +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (54,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -az -ak -ak -ak -ak -ak -ak -ak -ak -ak -ba -ak -ak -aD -aX -aX -aX -aX -ak -ba -ba -Vn -aX -cj -bd -bd -cD -cH -ba -ak -ak -ak -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +tJ +gw +jW +wY +Yl +wY +jW +GG +VY +aT +sM +II +Wl +Wl +VY +VY +VY +VY +Wl +xr +Zp +Zp +MD +fv +Zp +Mm +RE +Wa +VY +VY +kl +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (55,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -bf -bp -bx -ak -ak -ba -ak -ak -ak -ak -ak -ak -ak -ak -ba -ba -Vn -aX -ci -bd -bd -mF -cH -ba -ak -ak -cO -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +Hg +jW +wY +wY +wY +nr +VY +VY +xi +xi +xv +Wl +Wl +VY +VY +VY +VY +pD +xv +kC +Th +Mn +zp +Zp +Mm +RE +Wa +VY +VY +gP +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +JF +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (56,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -bg -aQ -by -zZ -ba -ba -ba -ba -ba -ba -ba -ba -ba -ba -ba -ba -sG -aX -lx -bd -bd -cE -cH -ba -ak -ak -cQ -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +AH +jW +ke +wY +wY +jW +GG +VY +xi +ZX +Gm +Wl +Wl +ls +VY +VY +VY +xv +xv +Gu +Nf +ai +Zp +Zp +pt +RE +Wa +VY +VY +Av +VY +hL +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (57,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -bh -br -bz -ak -ak -ak -bA -ba -ba -ak -ak -ak -ak -ak -ba -ba -aX -aX -aX -bd -bd -cF -cH -ba -ak -ak -cO -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +jW +jW +wY +jW +jW +GG +VY +xi +xi +xv +Wl +Wl +VY +VY +VY +DF +xv +Cl +Zp +Aa +pN +Zp +kB +Sg +JR +kh +VY +VY +VY +gP +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (58,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ba -ba -aX -aX -aX -aX -ak -ba -ba -aX -cq -bd -bd -bd -oE -cH -ba -ak -ak -cR -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -at -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +VY +jW +jW +jW +VY +VY +VY +xi +FB +Vo +Wl +Wl +VY +VY +VY +VY +Iw +Ea +Zp +Zp +Zp +Zp +aC +xv +kh +VY +VY +VY +wA +Kw +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (59,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ba -ba -aX -bN -bS -bY -ba -ba -ba -aX -Jr -bd -FG -bd -Tr -cH -ba -ak -ak -cO -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +GG +VY +VY +VY +wA +VY +xv +xi +xi +xv +Wl +Wl +VY +VY +VY +VY +Iw +IP +Zp +Zp +Zp +NS +Mm +Wa +VY +VY +VY +VY +VY +gP +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (60,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ba -ba -aX -bL -bQ -aX -ak -ba -ba -aX -HN -bd -cf -bd -xA -cH -ba -ak -aA -cS -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +VY +ls +VY +VY +VY +VY +VY +xi +xo +Qe +Wl +Wl +VY +wA +VY +VY +Iw +DY +Zp +Zp +Ja +ea +MG +kh +VY +Hn +VY +VY +VY +sp +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +pM +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (61,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ak -aX -aX -aX -aX -ak -ba -ba -aX -aX -aX -aX -ak -ba -ba -aX -Sg -bd -bd -bd -cf -cH -ba -ak -ak -cO -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +tJ +wA +VY +VY +VY +VY +VY +VY +xv +xv +xv +Wl +Wl +VY +VY +ls +VY +xv +DY +Zp +ko +uu +MG +kh +VY +VY +VY +VY +VY +VY +VY +Kh +Rj +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (62,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ak -aX -bb -bd -aX -ak -ba -ba -ak -ak -ak -ak -ak -ba -ba -aX -cf -cr -cl -cw -aX -cI -ba -ak -ak -cT -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +VY +VY +dO +VY +VY +VY +xv +JO +Wl +Wl +Wl +VY +VY +VY +VY +xv +xv +Iw +Iw +xv +dg +VY +VY +VY +VY +VY +VY +VY +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (63,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -az -ak -ak -ak -ak -ak -aX -bc -bi -bs -ba -ba -ba -bF -ak -ak -ak -ak -ba -ba -aX -aX -aX -aX -aX -aX -ba -ba -ak -ak -ak -bo -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +VY +VY +kG +VY +VY +Hn +VY +lS +Wl +Wl +VY +VY +VY +VY +VY +VY +UX +VY +om +VY +ls +VY +VY +VY +VY +VY +rF +VY +Kh +Rj +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (64,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -aX -aX -aX -aX -ak -ba -ba -bG -ak -ak -ak -ak -ba -ba -ba -ba -ba -ba -ba -ba -ba -ba -ak -ak -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +ot +VY +VY +wA +VY +VY +VY +VY +VY +Wl +Wl +VY +VY +VY +VY +wA +VY +MT +VY +VY +Hn +VY +VY +VY +VY +VY +VY +Eb +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +JF +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (65,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ba -ba -bH -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -bo -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -as -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +Fu +pr +VY +VY +ls +VY +VY +VY +VY +Wl +Wl +VY +VY +VY +VY +VY +VY +GG +VY +VY +VY +VY +VY +fz +fu +Wi +VY +VY +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (66,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -aE -ak -ak -aA -ak -ak -ak -ak -ak -ak -ba -ba -bG -ak -ak -aA -ak -ak -ak -ak -ak -ak -SR -ak -ak -ak -ak -Nr -cM -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +tJ +VY +VY +VY +VY +VY +VY +VY +VY +Wl +Wl +Wl +OG +gi +cj +XT +VY +VY +VY +ls +VY +VY +VY +Ft +wC +St +VY +VY +VY +hL +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (67,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -aH -dg -ak -aD -ak -ak -ak -ak -ak -ba -ba -bH -ak -ak -ak -ak -ak -ak -ak -ak -ak -ZL -ak -ak -ak -ak -cL -cN -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -at -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +Rs +VY +VY +VY +VY +VY +VY +VY +Hn +Wl +Wl +Wk +LQ +nC +DH +VY +VY +VY +VY +VY +VY +VY +VY +VY +VY +VY +wA +VY +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (68,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -az -ak -ak -ak -ak -ak -ak -ak -ak -ak -ba -ba -bG -ak -ak -ak -ak -ak -ak -aD -ak -ak -QU -ak -cG -ak -ak -ak -ak -aT -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +Jo +ot +VY +KW +mO +VY +VY +VY +Wl +Wl +KK +Sr +nC +DH +VY +VY +VY +VY +VY +VY +VY +VY +VY +VY +VY +VY +ls +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +pM +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (69,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -aE -ak -ak -ak -aX -aX -aX -aX -ak -ba -ba -bH -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -aA -ak -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +Fb +Cp +VY +db +Ar +Ar +VY +VY +VY +Wl +Wl +KK +Xt +nC +DH +VY +ls +VY +VY +wA +VY +VY +wA +VY +VY +IZ +VY +VY +zX +hL +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (70,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -mV -aE -ak -aX -bb -bj -bt -ba -ba -ba -bG -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -aD -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +JF +XB +XB +XB +Pe +Fb +tJ +VY +VY +VY +VY +VY +Wl +Wl +UI +pd +pd +rR +VY +VY +VY +VY +VY +VY +ot +ot +ot +ot +VY +VY +VY +yF +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (71,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -am -He -ak -aS -aX -bc -bd -aX -ak -ba -ba -bH -ak -ak -ak -aA -ak -ak -ak -aA -ak -ak -aA -ak -ak -aK -ak -ak -ak -aT -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +IA +Wv +VY +Wl +Wl +Wl +pF +VY +VY +VY +VY +QO +VY +VY +VY +PH +fM +fM +fM +fM +TC +Mr +VY +rA +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +JF +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (72,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -am -az -aX -aX -aX -aX -ak -ba -ba -bG -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -cO -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +pM +XB +XB +XB +XB +XB +XB +Vf +VY +uG +uG +VY +Wl +Wl +VY +VY +VY +VY +VY +VY +VY +GG +OU +gP +dV +VY +VY +VY +VY +VY +EC +VY +gP +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (73,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ba -ba -bH -ak -ak -ak -ak -ak -ak -ak -ak -ct -cx -cx -cx -cx -cJ -ak -ak -cU -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +tJ +VY +VY +VY +Wl +Wl +VY +VY +VY +VY +VY +VY +EB +VY +gP +gP +dV +VY +VY +VY +VY +VY +EC +VY +VY +Kh +Rj +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (74,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -aA -ak -ak -ak -ak -ba -ba -bG -ak -ak -ak -ak -ak -MD -ak -ak -cu -ak -ak -ak -ak -cu -ak -ak -cO -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +VY +VY +Wl +Wl +VY +cw +VY +VY +VY +VY +VY +VY +gP +gP +dV +VY +VY +VY +VY +VY +EC +wA +Kh +Rj +XB +XB +XB +XB +XB +XB +XB +XB +XB +pM +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (75,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ba -ba -bH -ak -ak -ak -ak -ak -ch -ak -ak -cu -ak -ak -ak -ak -cu -ak -ak -ak -bo -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +JF +XB +XB +XB +XB +XB +XB +XB +Vf +ls +VY +VY +Wl +Wl +VY +VY +VY +VY +ls +VY +Wl +VY +VY +VY +dV +VY +Zm +VY +VY +VY +EC +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (76,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ba -ba -ak -ak -ak -ak -ak -ak -ak -ak -ak -cu -ak -ak -ak -ak -cu -ak -aA -bo -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +VY +VY +Wl +Wl +Wl +Wl +Wl +VY +VY +VY +VY +VY +VY +fX +dV +VY +VY +VY +VY +VY +EC +IZ +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (77,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -aI -av -av -ag -ak -ak -ak -ak -ak -ba -ba -ak -ak -ak -ak -ak -ak -ak -ak -ak -cu -ak -ak -ak -ak -cu -ak -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +wA +VY +VY +Wl +Wl +Wl +VY +Wl +Wl +VY +Wl +VY +VY +VY +AU +dV +Ji +Ji +Ji +Ji +Ji +EC +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +JF +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (78,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -at -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -aX -aX -aX -aX -aX -ba -ba -aX -aX -aX -aX -aX -ak -ak -ak -ak -cu -ak -ak -ak -ak -cu -ak -aK -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +pM +XB +XB +XB +XB +XB +XB +MZ +cG +VY +VY +ls +Wl +Wl +VY +DU +VY +VY +VY +VY +VY +VY +VY +fX +dV +VY +VY +VY +VY +VY +EC +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (79,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -aX -bb -de -lA -aX -ba -ba -aX -bO -db -bZ -aX -ak -ak -ak -ak -cu -cy -cy -cy -cy -cy -ak -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -as -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +MZ +MF +VY +VY +GN +VY +Wl +Wl +VY +VY +VY +VY +Wl +VY +VY +wA +VY +VY +dV +VY +VY +VY +VY +VY +EC +VY +BK +XB +XB +XB +XB +XB +XB +pM +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (80,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -aX -bd -bd -bd -bB -ba -ba -bI -bd -bd -bd -aX -ak -ak -ak -ak -cu -ak -ak -ak -ak -cu -ak -ak -cV -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +JF +XB +XB +MZ +Le +oq +VY +VY +VY +VY +VY +Wl +Wl +Wl +VY +VY +VY +VY +VY +VY +ls +gP +gP +dV +VY +VY +VY +VY +VY +EC +Nm +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (81,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -af -ay -aX -be -bl -bd -aX -ba -ba -aX -bd -bT -ca -aX -ak -aA -ak -ak -cu -ak -ak -ak -ak -cu -ak -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +MZ +MF +wA +VY +VY +xv +xv +xv +xv +ae +Wl +Wl +VY +VY +VY +VY +VY +Wl +VY +gP +gP +dV +VY +VY +VY +VY +VY +EC +VY +Ld +ni +XB +XB +JF +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (82,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -af -aj -ay -ak -aX -aX -aX -aX -aX -ba -ba -aX -aX -aX -aX -aX -ak -ak -aD -ak -cu -ak -ak -ak -ak -cu -ak -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +IZ +xv +xv +xv +Hq +Hq +xv +xv +xI +QN +VY +VY +DR +yt +VY +VY +VY +gP +gP +dV +VY +VY +VY +VY +VY +EC +VY +VY +hL +ni +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (83,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -af -ay -aA -ak -ak -ak -ak -ak -ak -ak -ba -ba -ak -ak -ak -ak -ak -ak -ak -ak -ak -cu -ak -ak -ak -ak -cu -ak -ak -wz -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +MZ +MF +VY +xv +xv +Hq +TO +Qg +Qg +Qg +dL +Qg +PN +QN +VY +HU +WC +VY +VY +VY +VY +VY +FL +Cv +Cv +Cv +Cv +gj +ql +VY +ZR +VY +ZU +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (84,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -aK -ak -ak -ak -ak -ak -ak -ak -ba -ba -ak -ak -ak -ak -ak -ak -ak -ak -ak -cu -ak -ak -ak -ak -cu -ak -ak -ak -aT -ao -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +MZ +MF +VY +VY +xv +Hq +Qg +Qg +Qg +Qg +Qg +dL +Qg +Qg +Da +VY +VY +VY +ls +VY +VY +VY +VY +wA +MX +MX +MX +MX +VY +VY +VY +Ff +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (85,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -af -ay -ak -ak -ak -ak -aX -aX -aX -aX -aX -ba -ba -aX -aX -aX -aX -aX -ak -ak -ak -ak -cv -cz -cz -cz -cz -cz -ak -ak -cO -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +GG +VY +VY +xv +xv +AP +xv +xv +Hq +Qg +xv +Qg +Qg +Da +VY +VY +VY +VY +VY +VY +VY +VY +ls +VY +VY +VY +VY +VY +ls +VY +gP +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (86,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -af -ay -ak -ak -ak -ak -ak -aX -bb -df -QQ -aX -ba -ba -aX -bu -dc -bZ -aX -ak -ak -ak -ak -aA -ak -ak -ak -ak -ak -ak -ak -cW -ak -ap -av -av -av -av -cZ -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +MZ +MF +VY +GG +Wl +xv +IW +cR +IW +xv +Hq +Qg +bz +Qg +Qg +Da +VY +VY +wA +VY +VY +VY +VY +VY +VY +VY +VY +VY +wA +VY +VY +VY +ZA +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (87,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -MD -ak -ak -ak -ak -ak -aX -bd -bd -bd -bC -ba -ba -bJ -bd -bd -bd -aX -ak -ak -ak -ak -aD -ak -ak -ak -ak -ak -ak -ak -cO -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +VY +xv +aU +xv +xv +cR +cR +xv +xv +Qg +IE +Qg +Qg +Da +VY +VY +VY +ot +ot +ot +VY +ot +ot +VY +VY +VY +VY +VY +VY +VY +gP +VY +yT +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (88,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -af -ay -ak -MD -ak -ak -ak -ak -aX -be -bm -bd -aX -ba -ba -aX -bd -bU -ca -aX -ak -ak -ak -ak -ak -ak -ak -ak -aA -ak -ak -ak -cX -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +VY +xv +MK +Ce +xv +IW +cR +cR +xv +Qg +by +Qg +Qg +Da +VY +VY +VY +ot +ot +ot +VY +ot +ot +VY +VY +VY +VY +VY +gI +VY +WM +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (89,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ak -ak -aX -aX -aX -aX -aX -ba -ba -aX -aX -aX -aX -aX -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -cO -ak -wr -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +wA +VY +xv +HF +kp +xv +xv +lf +cR +xv +xv +fI +Qg +dq +FY +VY +VY +ls +VY +VY +VY +VY +VY +VY +VY +VY +VY +ot +VY +VY +VY +IZ +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (90,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -aA -aB -ak -ak -ak -ak -ak -aA -ak -ak -ak -ak -ba -ba -ak -ak -ak -cb -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -cY -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +VY +xv +MH +MK +vf +xv +ug +cR +IW +xv +Ia +sL +FY +VY +VY +VY +VY +VY +CJ +iW +iW +iW +mJ +VY +VY +gP +GI +uP +VY +VY +VY +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (91,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ch -ak -ba -ba -ak -bP -bV -cc -ak -ak -ak -ak -ak -aA -ak -ak -ak -ak -ak -ak -ak -aK -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +tJ +VY +xv +xv +MK +bC +xv +ug +cR +IW +xv +oi +VY +VY +VY +VY +wA +VY +CJ +gR +Gn +Gn +Gn +eH +mJ +IZ +pT +MX +VY +VY +VY +VI +Kh +Rj +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (92,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -az -ak -ak -ak -ak -aO -ak -aX -aX -aX -aX -aX -ba -ba -aX -aX -aX -aX -aX -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +GG +Xh +xv +Bv +Bv +xv +xv +IW +xv +xv +to +VY +VY +VY +VY +VY +VY +rE +dr +Gn +Gn +Gn +Gn +Nl +VY +VY +VY +VY +lP +ls +Kh +Rj +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (93,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -MD -ak -ak -ak -ak -ak -aX -bb -dd -Vx -aX -ba -ba -aX -zc -bk -bZ -aX -ak -ak -ak -ak -ak -ak -aK -ak -ak -ak -ak -ak -ze -bo -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +tJ +VY +VY +VY +VY +VY +xv +xv +xv +CY +VY +SI +VY +VY +VY +VY +VY +Km +Sw +Gn +Gn +Gn +Gn +JQ +VY +Zm +VY +VY +VY +VY +BK +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (94,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -az -ak -ak -ak -ak -ak -aX -bd -bd -bd -bD -ba -ba -bK -bd -bd -bd -aX -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -aA -aD -bo -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +tJ +VY +VY +VY +VY +VY +VY +gI +VY +VY +VY +VY +VY +VY +VY +jM +xv +xv +xv +xv +xv +xv +xv +Il +VY +VY +VY +VY +Kh +Rj +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (95,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -az -ak -ak -ak -ak -aX -be -bn -bd -aX -ba -ba -aX -bd -bW -ca -aX -ak -ak -aA -ak -ak -ak -ak -cG -ak -ak -ak -bo -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +tJ +IZ +VY +VY +VY +VY +VY +VY +ot +ot +VY +ot +ot +CJ +xv +xv +tK +Qg +TO +zK +uN +xv +xv +VY +VY +Kh +Fb +Rj +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (96,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -az -aK -ak -ak -aX -aX -aX -aX -aX -ba -ba -aX -aX -aX -aX -aX -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -bo -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +wA +VY +xi +xi +xv +VY +VY +VY +VY +VY +VY +VY +rE +pO +Qg +FU +lb +lb +FU +lb +wv +xv +xv +Fb +Rj +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (97,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -aA -ak -ak -ak -ak -ak -ak -ak -ak -bE -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -bo -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +tJ +VY +xi +Cg +bx +VY +VY +uo +uo +uo +uo +iI +TJ +xv +yO +Ow +Ow +Ow +Ow +Ow +bH +WO +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (98,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -az -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -bo -am -am -am -am -am -am -am -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +tJ +xv +xv +xv +VY +FH +VY +VY +VY +VY +VY +VY +xv +xv +EF +EF +EF +EF +EF +BD +pC +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (99,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -az -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -bo -am -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +tJ +YM +VY +VY +cv +Dv +VY +VY +VY +Rn +VY +FJ +xv +CG +Gh +XB +XB +XB +XB +Ha +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (100,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -az -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -bo -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Vf +VY +VY +IZ +VY +VY +VY +VY +qt +Kh +uY +Rj +xv +Kn +Cf +XB +XB +XB +XB +xv +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (101,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ag -ak -ak -ak -ak -ak -ak -ak -ak -ak -ak -ap -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +tJ +fm +VY +VY +FK +Kh +Fb +Fb +Rj +XB +XB +xv +xv +lB +ho +ho +ho +xv +xv +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (102,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -az -ak -ak -ak -ak -bo -am -am -am -Bd -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +Pe +Fb +Fb +Fb +Fb +Rj +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (103,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ah -am -am -am -am -aq -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (104,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (105,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -as -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (106,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -at -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (107,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (108,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -at -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (109,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (110,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (111,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (112,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (113,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (114,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (115,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (116,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (117,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -as -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (118,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (119,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (120,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (121,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -at -ab -ab -as -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -at -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -at -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -as -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (122,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (123,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (124,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (125,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (126,1,1) = {" -aa -aa -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (127,1,1) = {" -aa -aa -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (128,1,1) = {" -aa -aa -av -af -aj -aj -aj -ao -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (129,1,1) = {" -aa -aa -av -ag -ak -ak -da -ap -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (130,1,1) = {" -aa -aa -av -ag -au -an -ak -ap -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (131,1,1) = {" -aa -aa -av -ag -al -ak -MD -ap -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (132,1,1) = {" -aa -aa -av -ah -am -am -am -aq -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (133,1,1) = {" -aa -aa -av -av -av -av -av -av -av -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -ab -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (134,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} (135,1,1) = {" -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa -aa +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(136,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(137,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(138,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(139,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(140,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(141,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(142,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(143,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(144,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(145,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(146,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(147,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(148,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(149,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(150,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(151,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(152,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(153,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(154,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(155,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(156,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(157,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(158,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(159,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(160,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(161,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(162,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(163,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(164,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(165,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(166,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(167,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(168,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(169,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(170,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(171,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(172,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(173,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(174,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(175,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(176,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(177,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(178,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(179,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(180,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(181,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(182,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(183,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(184,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(185,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(186,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(187,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(188,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(189,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(190,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(191,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(192,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(193,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(194,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(195,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(196,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(197,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(198,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(199,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(200,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(201,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(202,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(203,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(204,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(205,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(206,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(207,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(208,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(209,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(210,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(211,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(212,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(213,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(214,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(215,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(216,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(217,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(218,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(219,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(220,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(221,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(222,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(223,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(224,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(225,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(226,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(227,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(228,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(229,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(230,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(231,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(232,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(233,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(234,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(235,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(236,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(237,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(238,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(239,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(240,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(241,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(242,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(243,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(244,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(245,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(246,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(247,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(248,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(249,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(250,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(251,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(252,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(253,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(254,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +"} +(255,1,1) = {" +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB +XB "} diff --git a/_maps/RandomZLevels/blackmesa.dmm b/_maps/RandomZLevels/blackmesa.dmm index a4aafb74536853..a4484e7711d3f4 100644 --- a/_maps/RandomZLevels/blackmesa.dmm +++ b/_maps/RandomZLevels/blackmesa.dmm @@ -270,7 +270,7 @@ /obj/structure/table, /obj/item/pen, /obj/structure/alien/weeds/xen, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/dark, /area/awaymission/black_mesa/entrance_lobby) "adq" = ( @@ -523,7 +523,7 @@ }, /obj/structure/closet/crate/bin, /obj/structure/alien/weeds/xen, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/textured_large, /area/awaymission/black_mesa/entrance_hall) "agb" = ( @@ -663,7 +663,7 @@ /obj/item/stack/sheet/plasteel, /obj/machinery/light/broken/directional/west, /obj/structure/alien/weeds/xen, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/textured, /area/awaymission/black_mesa/to_cryo_room) "ahW" = ( @@ -1175,7 +1175,7 @@ "apk" = ( /obj/structure/table, /obj/machinery/recharger, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/textured, /area/awaymission/black_mesa/gas_emitter_chamber) "apm" = ( @@ -1436,8 +1436,8 @@ /area/awaymission/black_mesa/security_outpost) "asd" = ( /obj/structure/rack/gunrack, -/obj/item/gun/ballistic/automatic/pistol/g17/mesa, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/gun/ballistic/automatic/pistol/sol, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron, /area/awaymission/black_mesa/security_outpost) "asl" = ( @@ -1623,7 +1623,7 @@ /area/awaymission/black_mesa/security_outpost) "avj" = ( /obj/structure/closet/crate/bin, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/smooth, /area/awaymission/black_mesa/gas_emitter_chamber) "avl" = ( @@ -1725,7 +1725,7 @@ /area/awaymission/black_mesa/hecu_zone_infirmary) "awC" = ( /obj/structure/closet/crate/bin, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/textured_large, /area/awaymission/black_mesa/cryo_hallway) "awH" = ( @@ -1872,7 +1872,7 @@ /turf/closed/indestructible/rock/xen, /area/awaymission/black_mesa/xen/freeman_hallway) "ayQ" = ( -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron, /area/awaymission/black_mesa/security_outpost) "ayU" = ( @@ -2031,7 +2031,7 @@ /obj/structure/chair/sofa/bench/right{ dir = 8 }, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/mineral/titanium/white, /area/awaymission/black_mesa/tram_room) "aAx" = ( @@ -2286,7 +2286,7 @@ /area/awaymission/black_mesa/xen/vortigaunt_village_nihilanth) "aDf" = ( /obj/structure/table, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron, /area/awaymission/black_mesa/security_outpost) "aDk" = ( @@ -2672,8 +2672,8 @@ /area/awaymission/black_mesa/entrance_lobby) "aHU" = ( /obj/structure/closet/secure_closet/security/black_mesa, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/gun/ballistic/automatic/pistol/g17/mesa, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/gun/ballistic/automatic/pistol/sol, /turf/open/floor/iron, /area/awaymission/black_mesa/entrance_lobby) "aHX" = ( @@ -2803,7 +2803,7 @@ /area/awaymission/black_mesa/entrance_hall) "aKd" = ( /obj/effect/decal/cleanable/blood/footprints, -/obj/item/gun/ballistic/shotgun/m23, +/obj/item/gun/ballistic/shotgun/riot/sol, /turf/open/floor/iron/dark, /area/awaymission/black_mesa/security_outpost) "aKg" = ( @@ -2896,7 +2896,7 @@ /turf/open/floor/iron/dark, /area/awaymission/black_mesa/hecu_zone_camp) "aKR" = ( -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/smooth_large, /area/awaymission/black_mesa/gas_emitter_chamber) "aKS" = ( @@ -2948,7 +2948,7 @@ /area/awaymission/black_mesa/security_outpost) "aLJ" = ( /obj/structure/closet/crate/bin, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/textured, /area/awaymission/black_mesa/to_cryo_room) "aLO" = ( @@ -3375,7 +3375,7 @@ /area/awaymission/black_mesa/entrance) "aRc" = ( /obj/structure/closet/crate/large, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/smooth, /area/awaymission/black_mesa/cryo_storage) "aRd" = ( @@ -3921,7 +3921,7 @@ "aYk" = ( /obj/structure/closet/crate/bin, /obj/machinery/light/cold, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/smooth_large, /area/awaymission/black_mesa/cryo_hallway) "aYr" = ( @@ -4020,7 +4020,7 @@ /area/awaymission/black_mesa/xen/freeman_hallway) "aYY" = ( /obj/effect/mob_spawn/corpse/human/scientist_zombie, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating/elevatorshaft, /area/awaymission/black_mesa/cryo_room) @@ -4371,8 +4371,8 @@ /area/awaymission/black_mesa/hecu_zone_infirmary) "bFy" = ( /obj/structure/closet/crate/bin, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/smooth_large, /area/awaymission/black_mesa/high_security_hallway) "bGe" = ( @@ -4915,9 +4915,9 @@ /area/awaymission/black_mesa/black_ops_downstairs_atrium) "cEy" = ( /obj/structure/rack/shelf, -/obj/item/ammo_box/magazine/cm68, -/obj/item/ammo_box/magazine/cm68, -/obj/item/ammo_box/magazine/cm68, +/obj/item/ammo_box/magazine/c40sol_rifle, +/obj/item/ammo_box/magazine/c40sol_rifle, +/obj/item/ammo_box/magazine/c40sol_rifle, /turf/open/floor/wood/parquet, /area/awaymission/black_mesa/employee_dorm_room) "cFH" = ( @@ -5008,7 +5008,7 @@ /turf/open/floor/iron/smooth_large, /area/awaymission/black_mesa/entrance_internal_hall) "cPC" = ( -/mob/living/simple_animal/hostile/blob/blobspore/independent, +/mob/living/basic/blob_minion/spore, /obj/structure/blob/normal, /turf/open/floor/engine, /area/awaymission/black_mesa/hecu_zone_test_chambers) @@ -5530,8 +5530,8 @@ /area/awaymission/black_mesa/xen/acid_lake_building) "dJX" = ( /obj/structure/table, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/wood/parquet, /area/awaymission/black_mesa/employee_dorm_room) "dLt" = ( @@ -5803,9 +5803,9 @@ /area/awaymission/black_mesa/lambda_hallway) "eif" = ( /obj/structure/rack/gunrack, -/obj/item/ammo_box/advanced/smartgun, -/obj/item/ammo_box/advanced/smartgun, -/obj/item/ammo_box/advanced/smartgun, +/obj/item/ammo_box/magazine/c980_grenade, +/obj/item/ammo_box/c980grenade/shrapnel, +/obj/item/ammo_casing/c980grenade/shrapnel/phosphor, /turf/open/floor/iron/dark, /area/awaymission/black_mesa/xen/acid_lake_building) "eij" = ( @@ -5839,8 +5839,8 @@ /obj/item/grenade/frag, /obj/item/grenade/frag, /obj/item/gun_maintenance_supplies, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/smooth_large, /area/awaymission/black_mesa/high_security_armory) "ems" = ( @@ -6201,7 +6201,7 @@ /area/awaymission/black_mesa/black_ops_armory) "fah" = ( /obj/structure/closet/crate/large, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/plating, /area/awaymission/black_mesa/entrance_tunnel) "fao" = ( @@ -6414,10 +6414,10 @@ /area/awaymission/black_mesa/hecu_zone_camp) "fpy" = ( /obj/structure/rack/shelf, -/obj/item/gun/ballistic/automatic/pistol/g17/mesa, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/gun/ballistic/automatic/pistol/sol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/wood/parquet, /area/awaymission/black_mesa/employee_dorm_room) "fpS" = ( @@ -6826,9 +6826,9 @@ /obj/item/stock_parts/cell/high, /obj/structure/alien/weeds/xen, /obj/structure/closet/wardrobe, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/dark, /area/awaymission/black_mesa/equipment_room) "gov" = ( @@ -6968,7 +6968,7 @@ /area/awaymission/black_mesa/high_security_hallway) "gCt" = ( /obj/structure/rack/gunrack, -/obj/item/gun/ballistic/automatic/smartgun/scoped, +/obj/item/gun/ballistic/automatic/sol_grenade_launcher, /turf/open/floor/iron/dark, /area/awaymission/black_mesa/xen/acid_lake_building) "gCB" = ( @@ -7017,7 +7017,7 @@ /area/awaymission/black_mesa/xen/lost_camp) "gIf" = ( /obj/structure/table, -/obj/item/gun/ballistic/automatic/pistol/g17/mesa, +/obj/item/gun/ballistic/automatic/pistol/sol, /turf/open/floor/plating, /area/awaymission/black_mesa/equipment_room) "gIr" = ( @@ -7106,7 +7106,7 @@ /turf/open/floor/engine, /area/awaymission/black_mesa/xen/entering_zone) "gTe" = ( -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/misc/xen, /area/awaymission/black_mesa/xen/freeman_puzzle) "gTh" = ( @@ -7298,7 +7298,7 @@ /turf/open/floor/iron/dark, /area/awaymission/black_mesa/science_decon_room) "hiT" = ( -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/iron/textured_large, /area/awaymission/black_mesa/employee_dorm_room) @@ -7371,7 +7371,7 @@ /area/awaymission/black_mesa/science_decon_room) "hok" = ( /obj/structure/closet/crate/bin, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/smooth_large, /area/awaymission/black_mesa/deep_sci_hall) "how" = ( @@ -7552,7 +7552,7 @@ /area/awaymission/black_mesa/resonant_chamber) "hGV" = ( /obj/structure/rack/shelf, -/obj/item/gun/ballistic/automatic/cfa_rifle, +/obj/item/gun/ballistic/automatic/sol_rifle, /turf/open/floor/wood/parquet, /area/awaymission/black_mesa/employee_dorm_room) "hHb" = ( @@ -8452,7 +8452,7 @@ "jts" = ( /obj/structure/table, /obj/item/extinguisher, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/textured_large, /area/awaymission/black_mesa/genetics) "jtA" = ( @@ -8693,7 +8693,7 @@ /area/awaymission/black_mesa/science_internal) "jOY" = ( /obj/structure/closet/crate/bin, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/carpet/blue, /area/awaymission/black_mesa/high_security_hallway) "jPD" = ( @@ -9388,7 +9388,7 @@ /turf/open/floor/iron/white, /area/awaymission/black_mesa/hecu_zone_camp) "ldC" = ( -/mob/living/simple_animal/hostile/blob/blobbernaut/independent, +/mob/living/basic/blob_minion/blobbernaut, /obj/structure/blob/normal, /turf/open/floor/engine, /area/awaymission/black_mesa/hecu_zone_test_chambers) @@ -9663,7 +9663,7 @@ /area/awaymission/black_mesa/hecu_zone_tunnel) "lEm" = ( /obj/structure/closet/crate/large, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/plating, /area/awaymission/black_mesa/science_tunnel) "lEu" = ( @@ -10093,8 +10093,8 @@ /area/awaymission/black_mesa/deep_sci_medbay) "mzJ" = ( /obj/structure/closet/crate/bin, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/carpet/blue, /area/awaymission/black_mesa/high_security_servers) "mzY" = ( @@ -10109,7 +10109,7 @@ "mEd" = ( /obj/structure/closet/crate, /obj/structure/alien/weeds/xen, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/textured_large, /area/awaymission/black_mesa/entrance_large_office) "mED" = ( @@ -10263,8 +10263,8 @@ "mVV" = ( /obj/machinery/light/broken/directional/north, /obj/structure/table, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/plating, /area/awaymission/black_mesa/equipment_room) "mWj" = ( @@ -10283,7 +10283,7 @@ /area/awaymission/black_mesa/entrance_large_office) "mYd" = ( /obj/structure/closet/crate/large, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/plating, /area/awaymission/black_mesa/dorm_tunnel) "mYF" = ( @@ -10371,7 +10371,7 @@ }, /obj/structure/closet/crate/bin, /obj/structure/alien/weeds/xen, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/textured_large, /area/awaymission/black_mesa/entrance_hall) "njp" = ( @@ -11088,7 +11088,7 @@ dir = 5 }, /obj/structure/lattice/catwalk, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/plating, /area/awaymission/black_mesa/resonant_chamber) "oBI" = ( @@ -12705,7 +12705,7 @@ "rDg" = ( /obj/structure/table, /obj/item/grenade/gas_crystal/nitrous_oxide_crystal, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/textured_large, /area/awaymission/black_mesa/genetics_sec) "rDq" = ( @@ -13005,7 +13005,7 @@ dir = 1 }, /obj/structure/closet/crate/bin, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/smooth_large, /area/awaymission/black_mesa/entrance_internal_hall) "sja" = ( @@ -13947,7 +13947,7 @@ /turf/open/floor/iron/smooth, /area/awaymission/black_mesa/hecu_zone_infirmary) "ugU" = ( -/obj/item/gun/ballistic/automatic/pistol/g17/mesa, +/obj/item/gun/ballistic/automatic/pistol/sol, /turf/open/misc/xen, /area/awaymission/black_mesa/xen/freeman_puzzle) "ugW" = ( @@ -14088,7 +14088,7 @@ /turf/open/floor/iron, /area/awaymission/black_mesa/entrance_lobby) "usi" = ( -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/space/basic, /area/space) "usA" = ( @@ -15075,7 +15075,7 @@ "wgs" = ( /obj/structure/railing, /obj/structure/table, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/textured_large, /area/awaymission/black_mesa/equipment_room) "wjB" = ( @@ -15258,7 +15258,7 @@ /area/awaymission/black_mesa/equipment_room) "wFj" = ( /obj/structure/table, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/wood/parquet, /area/awaymission/black_mesa/employee_dorm_room) "wGe" = ( @@ -15445,10 +15445,10 @@ "wVR" = ( /obj/structure/rack/shelf, /obj/machinery/light/warm, -/obj/item/gun/ballistic/automatic/pistol/g17/mesa, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/gun/ballistic/automatic/pistol/sol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/wood/parquet, /area/awaymission/black_mesa/employee_dorm_room) "wWc" = ( @@ -15631,9 +15631,9 @@ /area/awaymission/black_mesa/deep_sci_feesh) "xjK" = ( /obj/structure/closet/crate/secure/weapon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /obj/item/gun_maintenance_supplies, /obj/item/gun_maintenance_supplies, /obj/item/gun_maintenance_supplies, @@ -15641,7 +15641,7 @@ /obj/item/ammo_box/magazine/mp5, /obj/item/ammo_box/magazine/m16, /obj/item/ammo_box/magazine/m16, -/obj/item/gun/ballistic/automatic/pistol/g17/mesa{ +/obj/item/gun/ballistic/automatic/pistol/sol{ burst_size = 3; desc = "A weapon from bygone times, and this is the exact 21st century version. In fact, even more reliable, but it also can run full automatic fire mode. Chambered in 9mm."; firing_burst = 1; @@ -15961,7 +15961,7 @@ /turf/open/floor/iron/textured_large, /area/awaymission/black_mesa/science_decon_room) "xTE" = ( -/obj/item/ammo_box/magazine/multi_sprite/ladon, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/iron/smooth_large, /area/awaymission/black_mesa/deep_sci_medbay) "xUH" = ( diff --git a/_maps/RandomZLevels/mothership_astrum.dmm b/_maps/RandomZLevels/mothership_astrum.dmm index 26bebe36e5532a..b55e6e40141be7 100644 --- a/_maps/RandomZLevels/mothership_astrum.dmm +++ b/_maps/RandomZLevels/mothership_astrum.dmm @@ -1219,7 +1219,7 @@ /area/awaymission/mothership_astrum/halls) "uA" = ( /obj/structure/closet/abductor, -/obj/item/ammo_box/magazine/multi_sprite/mk58, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/mineral/abductor, /area/awaymission/mothership_astrum/halls) "uH" = ( @@ -1357,8 +1357,8 @@ /area/awaymission/mothership_astrum/halls) "wt" = ( /obj/structure/table/abductor, -/obj/item/ammo_box/magazine/multi_sprite/mk58, -/obj/item/ammo_box/magazine/multi_sprite/mk58, +/obj/item/ammo_box/magazine/c35sol_pistol, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/mineral/abductor, /area/awaymission/mothership_astrum/halls) "wz" = ( @@ -1715,7 +1715,7 @@ /area/awaymission/mothership_astrum/halls) "Ci" = ( /obj/structure/table/abductor, -/obj/item/ammo_box/magazine/multi_sprite/mk58, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/plating/abductor2, /area/awaymission/mothership_astrum/halls) "Cm" = ( @@ -1851,7 +1851,7 @@ /area/awaymission/mothership_astrum/deck5) "DR" = ( /obj/structure/table, -/obj/item/ammo_box/magazine/multi_sprite/mk58, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/wood, /area/awaymission/mothership_astrum/deck2) "DU" = ( @@ -1921,7 +1921,7 @@ /area/awaymission/mothership_astrum/deck2) "EJ" = ( /obj/structure/table/abductor, -/obj/item/gun/ballistic/automatic/pistol/mk58, +/obj/item/gun/ballistic/automatic/pistol/sol, /turf/open/floor/mineral/abductor, /area/awaymission/mothership_astrum/halls) "EL" = ( @@ -2196,7 +2196,7 @@ "Hn" = ( /obj/structure/table/abductor, /obj/structure/window/reinforced/spawner/directional/west, -/obj/item/gun/ballistic/automatic/pistol/mk58, +/obj/item/gun/ballistic/automatic/pistol/sol, /turf/open/floor/mineral/abductor, /area/awaymission/mothership_astrum/halls) "Hp" = ( @@ -2827,7 +2827,7 @@ /turf/open/floor/wood, /area/awaymission/mothership_astrum/deck2) "OF" = ( -/obj/item/ammo_box/magazine/multi_sprite/mk58, +/obj/item/ammo_box/magazine/c35sol_pistol, /turf/open/floor/wood, /area/awaymission/mothership_astrum/deck3) "Pb" = ( diff --git a/_maps/RandomZLevels/snowdin.dmm b/_maps/RandomZLevels/snowdin.dmm index a643bde9e4c463..af28c01f413059 100644 --- a/_maps/RandomZLevels/snowdin.dmm +++ b/_maps/RandomZLevels/snowdin.dmm @@ -9729,7 +9729,7 @@ /area/awaymission/snowdin/post/mining_main) "IV" = ( /obj/structure/table, -/obj/structure/showcase/machinery/microwave, +/obj/machinery/microwave/engineering/cell_included, /obj/effect/turf_decal/tile/neutral/half/contrasted, /turf/open/floor/iron, /area/awaymission/snowdin/post/mining_main) diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index 78590312a618cc..0895d18df5cb80 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -46,6 +46,10 @@ }, /turf/open/floor/iron, /area/station/security/tram) +"ach" = ( +/obj/machinery/netpod, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "acl" = ( /obj/effect/turf_decal/sand/plating, /obj/effect/decal/cleanable/dirt, @@ -534,6 +538,16 @@ }, /turf/open/floor/iron, /area/station/security) +"akY" = ( +/obj/machinery/door/airlock{ + name = "Maintenance" + }, +/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating/rust, +/area/station/maintenance/fore/greater) "akZ" = ( /turf/closed/mineral/random/stationside, /area/space) @@ -804,6 +818,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) +"aqV" = ( +/obj/machinery/door/airlock/glass, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/starboard/greater) "aqW" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/chair/sofa/bench/right{ @@ -872,12 +893,13 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/engineering/atmos/project) -"arU" = ( -/obj/effect/turf_decal/bot_white, -/obj/structure/rack, -/obj/item/electronics/apc, -/turf/open/floor/iron/smooth_large, -/area/station/cargo/warehouse) +"arV" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow/opposingcorners, +/obj/structure/table, +/obj/machinery/microwave/engineering/cell_included, +/turf/open/floor/iron, +/area/station/maintenance/department/engine/atmos) "asb" = ( /obj/effect/turf_decal/siding/white, /turf/open/floor/iron/dark/small, @@ -2095,6 +2117,7 @@ /turf/closed/wall/r_wall, /area/station/maintenance/department/engine) "aRw" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/chapel{ dir = 4 }, @@ -2292,6 +2315,8 @@ /area/station/engineering/supermatter/room) "aUA" = ( /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark/smooth_edge, /area/station/maintenance/starboard/greater) "aUQ" = ( @@ -2454,6 +2479,11 @@ }, /turf/open/floor/noslip/tram_platform, /area/station/security/tram) +"aYR" = ( +/obj/structure/broken_flooring/singular/directional/east, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/starboard/greater) "aYY" = ( /obj/structure/flora/bush/flowers_yw/style_random, /turf/open/misc/sandy_dirt, @@ -2576,11 +2606,6 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"bbP" = ( -/obj/structure/rack, -/obj/effect/spawner/random/maintenance/two, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "bbU" = ( /obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -3118,6 +3143,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/construction) "bmB" = ( @@ -3125,14 +3151,6 @@ /mob/living/simple_animal/bot/medbot/autopatrol, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) -"bmL" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/obj/structure/extinguisher_cabinet/directional/north, -/turf/open/floor/iron, -/area/station/cargo/storage) "bmM" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -3454,6 +3472,8 @@ }, /area/station/engineering/break_room) "bsI" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark/smooth_corner{ dir = 4 }, @@ -3711,6 +3731,10 @@ "bxT" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/navigate_destination/dockescpod, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, /turf/open/floor/plating, /area/station/maintenance/starboard/central) "byk" = ( @@ -3951,6 +3975,30 @@ }, /turf/open/floor/iron, /area/station/security/processing) +"bCh" = ( +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 8 + }, +/obj/machinery/door/airlock/mining{ + name = "Bitrunning Den" + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/turf/open/floor/iron/dark/smooth_half{ + dir = 1 + }, +/area/station/bitrunning/den) "bCi" = ( /obj/effect/turf_decal/tile/yellow/opposingcorners, /obj/machinery/atmospherics/components/binary/crystallizer{ @@ -4364,6 +4412,8 @@ "bJw" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/broken_flooring/singular/directional/south, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "bJL" = ( @@ -4539,6 +4589,7 @@ /obj/structure/broken_flooring/pile/directional/east, /obj/effect/decal/cleanable/dirt, /obj/structure/alien/weeds, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) "bNQ" = ( @@ -4666,6 +4717,24 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/noslip/tram_platform, /area/station/security/tram) +"bQF" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow/full, +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/machinery/door/window/right/directional/east{ + name = "Pharmacy Desk"; + req_access = list("pharmacy") + }, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 4; + id = "pharmacy_shutters"; + name = "Pharmacy Shutters" + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/medical/pharmacy) "bQU" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -4946,6 +5015,13 @@ /obj/effect/landmark/start/head_of_security, /turf/open/floor/iron/small, /area/station/security/office) +"bVR" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/maintenance/starboard/greater) "bWa" = ( /obj/effect/turf_decal/siding/white{ dir = 10 @@ -5869,6 +5945,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/port/lesser) +"cpJ" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/transit_tube/horizontal, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/starboard/greater) "cpP" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -6131,6 +6213,27 @@ "cvJ" = ( /turf/open/floor/plating, /area/station/maintenance/department/engine/atmos) +"cvP" = ( +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/holopad, +/turf/open/floor/iron/dark/smooth_half{ + dir = 1 + }, +/area/station/bitrunning/den) "cvZ" = ( /obj/structure/closet/secure_closet/evidence, /obj/effect/decal/cleanable/dirt, @@ -6244,6 +6347,8 @@ dir = 1 }, /obj/structure/broken_flooring/singular/directional/east, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/hallway/secondary/dock) "cxO" = ( @@ -6696,6 +6801,12 @@ }, /turf/open/floor/iron, /area/station/security) +"cFj" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/alien/weeds, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/iron, +/area/station/maintenance/starboard/greater) "cFq" = ( /obj/machinery/door/airlock{ name = "Maintenance" @@ -6740,6 +6851,7 @@ dir = 8 }, /obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/department/engine) "cFR" = ( @@ -7547,6 +7659,7 @@ /area/station/maintenance/department/engine) "cWh" = ( /obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/stairs{ dir = 4 }, @@ -8493,6 +8606,8 @@ /obj/structure/disposalpipe/segment, /obj/effect/decal/cleanable/dirt, /obj/structure/broken_flooring/singular/directional/east, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "doj" = ( @@ -8705,6 +8820,7 @@ "dtq" = ( /obj/effect/mapping_helpers/broken_floor, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) "dty" = ( @@ -8929,6 +9045,7 @@ /area/station/maintenance/department/medical/central) "dxz" = ( /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "dxG" = ( @@ -9449,6 +9566,8 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "dHT" = ( @@ -10078,6 +10197,8 @@ /obj/machinery/light/small/directional/south, /obj/structure/alien/weeds, /obj/structure/alien/weeds, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) "dTI" = ( @@ -10666,6 +10787,7 @@ "ecL" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/transit_tube/horizontal, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "ecQ" = ( @@ -10693,6 +10815,9 @@ "edD" = ( /obj/machinery/light/small/directional/west, /obj/item/kirbyplants/random, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "edJ" = ( @@ -10891,6 +11016,7 @@ /area/station/medical/storage) "egN" = ( /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/chapel, /area/station/maintenance/starboard/greater) "ehj" = ( @@ -10991,6 +11117,10 @@ /obj/structure/frame/computer, /turf/open/floor/eighties/red, /area/station/service/abandoned_gambling_den/gaming) +"ejq" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/bitrunning/den) "ejt" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -12004,6 +12134,12 @@ /obj/machinery/camera/autoname/directional/north, /turf/open/floor/iron/smooth_large, /area/station/science/robotics/mechbay) +"eAo" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/grimy, +/area/station/commons/vacant_room/office) "eAu" = ( /obj/structure/cable, /obj/machinery/power/tracker, @@ -12928,6 +13064,14 @@ /obj/machinery/computer/security/telescreen/entertainment/directional/south, /turf/open/floor/iron, /area/station/engineering/break_room) +"eQQ" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 1 + }, +/area/station/maintenance/starboard/greater) "eQR" = ( /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/iron/smooth, @@ -13740,6 +13884,7 @@ spawn_loot_chance = 50 }, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) "fik" = ( @@ -13917,6 +14062,8 @@ /obj/machinery/duct, /obj/effect/mapping_helpers/broken_floor, /obj/effect/decal/cleanable/glass/plastitanium, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "flM" = ( @@ -14390,6 +14537,18 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/stone, /area/station/command/heads_quarters/hos) +"fts" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/computer/order_console/bitrunning{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/end{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "ftv" = ( /obj/effect/turf_decal/tile/dark_red/opposingcorners, /obj/structure/table/reinforced, @@ -14514,6 +14673,11 @@ /obj/structure/disposalpipe/trunk, /turf/open/floor/iron, /area/station/hallway/primary/port) +"fvz" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/maintenance/starboard/greater) "fvC" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -15492,6 +15656,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/smooth, /area/station/ai_monitored/turret_protected/aisat_interior) +"fKx" = ( +/obj/structure/transit_tube/horizontal, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/space/basic, +/area/space/nearstation) "fKO" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -15694,6 +15864,7 @@ /obj/structure/broken_flooring/corner/directional/south, /obj/effect/spawner/random/trash/food_packaging, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) "fNA" = ( @@ -16971,6 +17142,8 @@ /turf/open/floor/iron/dark, /area/station/medical/medbay/aft) "gmm" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "gmn" = ( @@ -17626,6 +17799,8 @@ /obj/effect/mapping_helpers/broken_floor, /obj/machinery/duct, /obj/machinery/power/apc/auto_name/directional/west, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "gyd" = ( @@ -18386,6 +18561,7 @@ }, /obj/effect/mapping_helpers/airlock/abandoned, /obj/effect/mapping_helpers/airlock/access/any/command/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) "gMb" = ( @@ -19126,6 +19302,8 @@ /area/station/service/bar) "gYq" = ( /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/maintenance/starboard/greater) "gYy" = ( @@ -19424,6 +19602,8 @@ name = "Maintenance" }, /obj/effect/mapping_helpers/airlock/access/any/science/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "hdB" = ( @@ -19934,11 +20114,6 @@ /obj/structure/broken_flooring/singular/directional/east, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) -"hln" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/yellow/opposingcorners, -/turf/open/floor/iron, -/area/station/maintenance/department/engine/atmos) "hlo" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/camera/autoname/directional/north, @@ -20074,6 +20249,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/commons/storage/tools) +"hnF" = ( +/obj/structure/cable, +/obj/machinery/duct, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "hnO" = ( /obj/structure/disposalpipe/segment, /obj/structure/disposalpipe/segment{ @@ -20681,6 +20862,7 @@ }, /obj/structure/cable, /obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) "hyl" = ( @@ -20998,12 +21180,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/fore) -"hDn" = ( -/obj/effect/turf_decal/tile/yellow/opposingcorners, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron, -/area/station/maintenance/department/engine/atmos) "hDt" = ( /obj/structure/toilet{ pixel_y = 8 @@ -21097,6 +21273,7 @@ /area/station/maintenance/starboard/greater) "hFC" = ( /obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating/rust, /area/station/maintenance/fore/lesser) "hFG" = ( @@ -21473,6 +21650,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"hNv" = ( +/obj/machinery/netpod, +/obj/machinery/light_switch/directional/north, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "hNA" = ( /obj/effect/turf_decal/tile/brown/opposingcorners, /turf/open/floor/iron, @@ -22124,6 +22307,12 @@ }, /turf/open/floor/wood/tile, /area/station/command/meeting_room) +"iaJ" = ( +/obj/structure/transit_tube/crossing/horizontal, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/space/basic, +/area/space/nearstation) "iaK" = ( /obj/structure/table/wood, /obj/item/reagent_containers/cup/glass/bottle/wine{ @@ -22285,6 +22474,7 @@ /area/station/science/lower) "icW" = ( /obj/structure/transit_tube/horizontal, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) "ide" = ( @@ -22472,6 +22662,12 @@ }, /turf/open/floor/plating, /area/station/maintenance/hallway/abandoned_command) +"igr" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/plating, +/area/station/maintenance/fore/lesser) "ihc" = ( /obj/structure/cable, /obj/machinery/door/airlock/command/glass{ @@ -23270,6 +23466,8 @@ /area/station/engineering/supermatter) "iux" = ( /obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/fitness/recreation/entertainment) "iuH" = ( @@ -23288,6 +23486,9 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/directional/west, /obj/item/kirbyplants/random, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "iuZ" = ( @@ -23485,14 +23686,6 @@ /obj/effect/spawner/random/structure/girder, /turf/open/floor/noslip/tram_platform, /area/station/security/tram) -"iym" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/generic_maintenance_landmark, -/turf/open/floor/iron, -/area/station/engineering/storage/tech) "iyq" = ( /obj/machinery/atmospherics/pipe/smart/simple/green/hidden{ dir = 9 @@ -23868,6 +24061,7 @@ name = "Command Maintanence" }, /obj/effect/mapping_helpers/airlock/access/all/command/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) "iHs" = ( @@ -24417,6 +24611,8 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/mapping_helpers/broken_floor, /obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating/rust, /area/station/maintenance/fore/greater) "iQU" = ( @@ -24439,6 +24635,8 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/mapping_helpers/broken_floor, /obj/effect/decal/cleanable/glass/plastitanium, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "iRz" = ( @@ -24736,6 +24934,12 @@ }, /turf/open/floor/iron, /area/station/security) +"iWI" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/transit_tube/horizontal, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "iWQ" = ( /obj/effect/turf_decal/tile/yellow/opposingcorners, /obj/effect/landmark/start/chemist, @@ -24781,6 +24985,8 @@ dir = 4 }, /obj/structure/broken_flooring/corner/directional/south, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "iXi" = ( @@ -25225,6 +25431,8 @@ name = "Faded Door" }, /obj/effect/mapping_helpers/airlock/abandoned, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "jfX" = ( @@ -25995,6 +26203,7 @@ pixel_x = -32; spawn_loot_chance = 50 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) "jwi" = ( @@ -26357,6 +26566,14 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/station/security/interrogation) +"jCL" = ( +/obj/effect/turf_decal/tile/yellow/opposingcorners, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/light/small/directional/north, +/obj/structure/table, +/obj/effect/spawner/random/food_or_drink/donkpockets, +/turf/open/floor/iron, +/area/station/maintenance/department/engine/atmos) "jCP" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -26733,7 +26950,7 @@ }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/holopad, -/mob/living/simple_animal/sloth/citrus, +/mob/living/basic/sloth/citrus, /turf/open/floor/iron, /area/station/cargo/storage) "jHE" = ( @@ -26966,6 +27183,11 @@ /obj/effect/landmark/start/virologist, /turf/open/floor/iron/showroomfloor, /area/station/medical/virology) +"jLl" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/maintenance/starboard/greater) "jLr" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -27226,6 +27448,8 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/duct, /obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "jQo" = ( @@ -27241,12 +27465,19 @@ /obj/structure/chair{ pixel_y = -2 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, /turf/open/floor/wood, /area/station/maintenance/fore/greater) "jQL" = ( /obj/structure/window/reinforced/spawner/directional/west, /obj/effect/decal/cleanable/dirt, /obj/effect/landmark/blobstart, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, /turf/open/floor/iron, /area/station/maintenance/fore/greater) "jQW" = ( @@ -27283,6 +27514,9 @@ /obj/effect/mapping_helpers/broken_floor, /obj/structure/window/reinforced/spawner/directional/east, /obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "jRE" = ( @@ -27515,6 +27749,16 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/station/security/courtroom) +"jWA" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron, +/area/station/cargo/storage) "jWO" = ( /obj/effect/turf_decal/tile/blue, /obj/machinery/camera/autoname/directional/south, @@ -27822,7 +28066,6 @@ /area/station/service/abandoned_gambling_den) "kbW" = ( /obj/effect/mapping_helpers/broken_floor, -/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/carpet/orange, /area/station/service/abandoned_gambling_den) "kbY" = ( @@ -28787,6 +29030,7 @@ "ksN" = ( /obj/structure/transit_tube/station/dispenser, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) "ksP" = ( @@ -28801,7 +29045,6 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron, /area/station/engineering/gravity_generator) "ktc" = ( @@ -28954,6 +29197,12 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron, /area/station/security/execution/transfer) +"kwu" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/maintenance/starboard/greater) "kwz" = ( /obj/structure/closet/secure_closet/engineering_personal, /obj/effect/turf_decal/stripes/line{ @@ -29149,6 +29398,7 @@ "kzP" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/spawner/random/trash, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "kzX" = ( @@ -29159,6 +29409,7 @@ /obj/structure/transit_tube/station/dispenser/flipped{ dir = 1 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "kAk" = ( @@ -29453,6 +29704,9 @@ /turf/open/floor/plating, /area/station/maintenance/fore/greater) "kGB" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/station/hallway/secondary/construction) "kGC" = ( @@ -29630,6 +29884,7 @@ "kIY" = ( /obj/structure/broken_flooring/singular/directional/south, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) "kJb" = ( @@ -29797,10 +30052,6 @@ dir = 1 }, /area/station/medical/treatment_center) -"kLT" = ( -/obj/machinery/rnd/bepis, -/turf/open/floor/iron, -/area/station/cargo/storage) "kMm" = ( /obj/structure/chair/sofa/right/brown{ dir = 1 @@ -30353,6 +30604,10 @@ }, /turf/open/floor/iron/dark, /area/station/security/interrogation) +"kXJ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "kXM" = ( /obj/effect/spawner/random/structure/girder, /obj/structure/barricade/wooden, @@ -30453,6 +30708,8 @@ /obj/effect/spawner/random/trash, /obj/effect/decal/cleanable/dirt, /obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "kZx" = ( @@ -30463,6 +30720,15 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/showroomfloor, /area/station/medical/surgery/theatre) +"kZB" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/cable, +/obj/structure/extinguisher_cabinet/directional/north, +/obj/machinery/light/cold/directional/north, +/turf/open/floor/iron, +/area/station/cargo/storage) "kZF" = ( /obj/structure/closet/crate/secure{ desc = "A secure crate containing various materials for building a customised test-site."; @@ -30530,6 +30796,19 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/wood, /area/station/service/abandoned_gambling_den) +"lbF" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/effect/turf_decal/stripes, +/obj/effect/turf_decal/trimline/brown/line, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/obj/machinery/light/small/directional/east, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/smooth_half, +/area/station/bitrunning/den) "lbM" = ( /obj/structure/chair/sofa/bench/right{ dir = 1 @@ -31256,6 +31535,15 @@ /obj/structure/alien/weeds, /turf/open/misc/asteroid, /area/station/maintenance/starboard/greater) +"lko" = ( +/obj/machinery/door/airlock{ + name = "Maintenance" + }, +/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/starboard/greater) "lku" = ( /obj/structure/table, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -31629,6 +31917,7 @@ /obj/structure/disposalpipe/segment, /obj/structure/cable, /obj/structure/steam_vent, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) "ltp" = ( @@ -31908,6 +32197,8 @@ /obj/structure/disposalpipe/segment{ dir = 6 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "lxy" = ( @@ -32326,6 +32617,13 @@ "lEa" = ( /turf/open/floor/iron/half, /area/station/hallway/primary/central/fore) +"lEg" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/broken_flooring/pile/directional/east, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "lEu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -32482,6 +32780,8 @@ "lHS" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/chair/stool/directional/east, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "lHT" = ( @@ -32683,6 +32983,20 @@ /obj/effect/mapping_helpers/broken_floor, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) +"lKH" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/stripes, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/obj/machinery/airalarm/directional/west, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/smooth_half, +/area/station/bitrunning/den) "lKK" = ( /obj/effect/mapping_helpers/broken_floor, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -32698,6 +33012,13 @@ /obj/effect/mapping_helpers/airlock/access/any/security/general, /turf/open/floor/iron, /area/station/security/checkpoint/escape) +"lLq" = ( +/obj/machinery/firealarm/directional/east, +/obj/effect/decal/cleanable/oil, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "lLr" = ( /obj/machinery/porta_turret/ai{ dir = 4 @@ -32970,6 +33291,11 @@ }, /turf/open/floor/iron/white/small, /area/station/science/lobby) +"lOY" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/fore/lesser) "lPd" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -33117,6 +33443,8 @@ dir = 6 }, /obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "lSf" = ( @@ -33302,6 +33630,11 @@ /obj/structure/window/spawner/directional/west, /turf/open/floor/plating, /area/station/cargo/sorting) +"lVg" = ( +/obj/structure/transit_tube/horizontal, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/maintenance/starboard/aft) "lVy" = ( /obj/effect/turf_decal/tile/green/anticorner/contrasted{ dir = 8 @@ -33785,6 +34118,8 @@ /obj/structure/disposalpipe/segment{ dir = 9 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "mcl" = ( @@ -33870,6 +34205,11 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/white/side, /area/station/science/lower) +"meJ" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/starboard/greater) "meN" = ( /obj/structure/chair/sofa/bench{ dir = 8 @@ -34855,6 +35195,8 @@ }, /obj/effect/mapping_helpers/broken_floor, /obj/structure/broken_flooring/singular/directional/south, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "myt" = ( @@ -36065,6 +36407,7 @@ "mTU" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/transit_tube/horizontal, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) "mUg" = ( @@ -36196,6 +36539,15 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron, /area/station/security/processing) +"mXk" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/broken_flooring/singular/directional/east, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "mXo" = ( /obj/machinery/atmospherics/pipe/smart/manifold/general/visible{ dir = 1 @@ -36580,6 +36932,7 @@ "nfm" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/hallway/secondary/construction) "nfs" = ( @@ -37601,6 +37954,13 @@ }, /turf/open/floor/circuit/telecomms/mainframe, /area/station/science/xenobiology) +"nyf" = ( +/obj/machinery/camera/autoname/directional/east, +/obj/effect/decal/cleanable/dirt, +/obj/structure/table, +/obj/item/food/cornchips/green, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "nyi" = ( /turf/closed/wall/rust, /area/station/maintenance/hallway/abandoned_command) @@ -37951,6 +38311,22 @@ /obj/structure/falsewall, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) +"nEl" = ( +/obj/machinery/computer/quantum_console{ + dir = 4 + }, +/obj/machinery/computer/quantum_console{ + dir = 4 + }, +/obj/machinery/computer/quantum_console{ + dir = 4 + }, +/obj/machinery/computer/quantum_console{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "nEo" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -38012,6 +38388,9 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/smooth, /area/station/cargo/drone_bay) +"nFo" = ( +/turf/closed/wall, +/area/station/bitrunning/den) "nFp" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -38587,6 +38966,10 @@ }, /turf/open/floor/iron/white, /area/station/commons/dorms) +"nPX" = ( +/obj/structure/cable, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/warehouse) "nQa" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/cable, @@ -39142,6 +39525,10 @@ /obj/machinery/power/apc/auto_name/directional/east, /turf/open/floor/iron/white/small, /area/station/science/ordnance/storage) +"obv" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "obG" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -39201,7 +39588,7 @@ /area/station/maintenance/hallway/abandoned_command) "odk" = ( /obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/atmospheric_sanity/ignore_area, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/grimy, /area/station/commons/vacant_room/office) "odA" = ( @@ -39220,7 +39607,6 @@ /area/station/maintenance/fore/greater) "odP" = ( /obj/machinery/firealarm/directional/west, -/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron/dark/small, /area/station/medical/morgue) "odX" = ( @@ -39751,13 +40137,6 @@ /obj/item/radio/intercom/directional/east, /turf/open/floor/iron/dark/small, /area/station/medical/chemistry) -"onI" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Maintenance" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "onP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/door/firedoor, @@ -40141,6 +40520,8 @@ /obj/item/clothing/head/cone{ pixel_x = 7 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) "ouN" = ( @@ -40204,6 +40585,8 @@ "ovB" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/alien/weeds, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) "ovQ" = ( @@ -40382,6 +40765,14 @@ /obj/structure/mannequin/plastic, /turf/open/floor/carpet/blue, /area/station/cargo/boutique) +"ozV" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 8 + }, +/area/station/maintenance/starboard/greater) "oAc" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -40541,6 +40932,9 @@ /obj/machinery/camera/autoname/directional/east, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"oCG" = ( +/turf/closed/wall/rust, +/area/station/bitrunning/den) "oCM" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/broken_flooring/pile/directional/east, @@ -40650,6 +41044,9 @@ "oFf" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/directional/east, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, /turf/open/floor/iron/chapel{ dir = 4 }, @@ -41312,6 +41709,7 @@ /obj/machinery/door/airlock/grunge{ name = "St. Brendan's" }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/maintenance/starboard/greater) "oRZ" = ( @@ -41556,16 +41954,6 @@ /obj/machinery/atmospherics/pipe/heat_exchanging/simple, /turf/open/floor/iron/dark/small, /area/station/tcommsat/server) -"oXa" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/item/radio/intercom/directional/north, -/turf/open/floor/iron, -/area/station/cargo/storage) "oXe" = ( /obj/effect/mapping_helpers/broken_floor, /obj/machinery/duct, @@ -42192,6 +42580,8 @@ /obj/effect/mapping_helpers/airlock/unres{ dir = 1 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "piG" = ( @@ -42489,6 +42879,11 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron/white, /area/station/medical/treatment_center) +"pof" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/grimy, +/area/station/commons/vacant_room/office) "pog" = ( /obj/effect/turf_decal/siding/wood, /turf/open/floor/iron/freezer, @@ -43734,6 +44129,7 @@ "pHk" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/light/small/directional/east, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron/chapel, /area/station/maintenance/starboard/greater) "pHn" = ( @@ -44025,6 +44421,8 @@ /obj/structure/cable, /obj/effect/decal/cleanable/dirt, /obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "pLZ" = ( @@ -44049,6 +44447,7 @@ /area/station/maintenance/department/engine) "pMs" = ( /obj/structure/transit_tube/horizontal, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "pMu" = ( @@ -44224,6 +44623,8 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/mapping_helpers/broken_floor, /obj/effect/decal/cleanable/glass/plastitanium, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "pOX" = ( @@ -45050,6 +45451,7 @@ /area/station/command/heads_quarters/rd) "qcf" = ( /obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark/side, /area/station/hallway/secondary/construction) "qcl" = ( @@ -45341,6 +45743,8 @@ dir = 4 }, /obj/structure/broken_flooring/singular/directional/east, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "qgx" = ( @@ -46330,6 +46734,7 @@ "qwn" = ( /obj/structure/cable, /obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) "qwq" = ( @@ -46345,6 +46750,8 @@ }, /obj/effect/mapping_helpers/broken_floor, /obj/structure/steam_vent, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "qwz" = ( @@ -46387,13 +46794,6 @@ }, /turf/open/floor/iron/solarpanel/airless, /area/station/solars/port) -"qxf" = ( -/obj/machinery/cryo_cell, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/iron/small, -/area/station/medical/cryo) "qxh" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -47727,6 +48127,10 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/commons/vacant_room/commissary) +"qTz" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/fore/lesser) "qTD" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -48390,6 +48794,13 @@ /obj/structure/barricade/wooden/crude, /turf/open/floor/plating, /area/station/maintenance/hallway/abandoned_recreation) +"rdh" = ( +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/duct, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "rdo" = ( /obj/structure/window/spawner/directional/west, /obj/structure/flora/bush/jungle/a/style_random, @@ -49355,6 +49766,15 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/science/lower) +"ruC" = ( +/obj/structure/window/reinforced/spawner/directional/east, +/obj/effect/turf_decal/tile/green/anticorner/contrasted, +/obj/structure/table/glass, +/obj/effect/mapping_helpers/broken_floor, +/obj/item/radio/intercom/directional/south, +/obj/machinery/reagentgrinder, +/turf/open/floor/iron/white, +/area/station/medical/virology) "ruD" = ( /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) @@ -49521,6 +49941,10 @@ "rxu" = ( /obj/structure/table, /obj/machinery/airalarm/directional/south, +/obj/item/storage/box/bandages{ + pixel_y = 6; + pixel_x = -6 + }, /obj/item/clipboard{ pixel_x = 4; pixel_y = 4 @@ -50462,6 +50886,11 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/station/hallway/secondary/dock) +"rMb" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/iron/grimy, +/area/station/commons/vacant_room/office) "rMl" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -50689,6 +51118,26 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/orange/hidden/layer1, /turf/open/floor/catwalk_floor/iron_white, /area/station/engineering/atmos) +"rPx" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/corner, +/obj/effect/turf_decal/trimline/brown/corner, +/obj/effect/turf_decal/trimline/brown/corner{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 1 + }, +/area/station/bitrunning/den) "rPz" = ( /obj/structure/table/glass, /obj/item/flashlight/lamp/green{ @@ -50782,6 +51231,7 @@ "rRu" = ( /obj/structure/transit_tube/horizontal, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) "rRy" = ( @@ -51159,8 +51609,30 @@ "rWO" = ( /obj/structure/disposalpipe/segment, /obj/structure/broken_flooring/singular/directional/east, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"rWP" = ( +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 8 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/dark/smooth_half{ + dir = 1 + }, +/area/station/bitrunning/den) "rWW" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -51189,10 +51661,6 @@ /obj/structure/reagent_dispensers/watertank, /turf/open/floor/plating, /area/station/maintenance/port/greater) -"rXy" = ( -/obj/effect/spawner/random/structure/closet_maintenance, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "rXW" = ( /obj/structure/flora/bush/flowers_yw, /obj/machinery/door/window/left/directional/west{ @@ -51599,6 +52067,14 @@ /obj/structure/curtain/cloth, /turf/open/floor/carpet/purple, /area/station/commons/dorms) +"seI" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/turf/open/floor/wood, +/area/station/maintenance/fore/greater) "seM" = ( /obj/effect/turf_decal/stripes/red/line{ dir = 4 @@ -51608,6 +52084,7 @@ "seV" = ( /obj/structure/transit_tube/horizontal, /obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/space/basic, /area/space/nearstation) "sfb" = ( @@ -52529,6 +53006,13 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron/checker, /area/station/command/heads_quarters/hos) +"suF" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/maintenance/starboard/greater) "suK" = ( /obj/effect/spawner/random/vending/snackvend, /obj/effect/mapping_helpers/broken_floor, @@ -52613,25 +53097,6 @@ dir = 8 }, /area/station/commons/dorms) -"svU" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow/full, -/obj/structure/table/reinforced, -/obj/machinery/door/firedoor, -/obj/machinery/door/window/right/directional/east{ - dir = 8; - name = "Pharmacy Desk"; - req_access = list("pharmacy") - }, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 4; - id = "pharmacy_shutters"; - name = "Pharmacy Shutters" - }, -/turf/open/floor/iron/dark/textured_large, -/area/station/medical/pharmacy) "svZ" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/effect/decal/cleanable/dirt, @@ -53072,6 +53537,7 @@ /area/station/security/execution/transfer) "sCw" = ( /obj/structure/transit_tube/station/dispenser/flipped, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "sCB" = ( @@ -53141,10 +53607,6 @@ /obj/effect/turf_decal/tile/neutral/opposingcorners, /turf/open/floor/iron, /area/station/hallway/secondary/spacebridge) -"sEi" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "sEn" = ( /obj/item/clothing/head/cone, /obj/item/clothing/head/cone{ @@ -53703,6 +54165,9 @@ /area/station/engineering/gravity_generator) "sOF" = ( /obj/item/kirbyplants/random, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) "sON" = ( @@ -53733,6 +54198,15 @@ /obj/machinery/duct, /turf/open/floor/iron/freezer, /area/station/service/kitchen/coldroom) +"sPa" = ( +/obj/effect/mapping_helpers/airlock/access/any/service/maintenance, +/obj/machinery/door/airlock/grunge{ + name = "St. Brendan's" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/dark, +/area/station/maintenance/starboard/greater) "sPt" = ( /obj/effect/turf_decal/tile/blue, /obj/effect/turf_decal/tile/green{ @@ -53771,9 +54245,7 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, -/mob/living/simple_animal/hostile/retaliate/goat{ - name = "Pete" - }, +/mob/living/basic/goat/pete, /obj/machinery/duct, /turf/open/floor/iron/freezer, /area/station/service/kitchen/coldroom) @@ -54126,6 +54598,11 @@ /obj/structure/cable, /turf/open/floor/iron/textured_half, /area/station/security) +"sVk" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/maintenance/starboard/greater) "sVp" = ( /obj/structure/table, /obj/structure/sign/poster/official/corporate_perks_vacation/directional/east, @@ -54179,6 +54656,8 @@ /obj/effect/mapping_helpers/airlock/abandoned, /obj/effect/decal/cleanable/dirt, /obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/grimy, /area/station/maintenance/starboard/greater) "sWJ" = ( @@ -54770,6 +55249,13 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/wood/tile, /area/station/command/heads_quarters/hop) +"tgJ" = ( +/obj/machinery/cryo_cell, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/iron/small, +/area/station/medical/cryo) "tgR" = ( /obj/structure/disposalpipe/junction/flip{ dir = 1 @@ -55514,6 +56000,15 @@ }, /turf/open/misc/sandy_dirt, /area/station/security/tram) +"tvN" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/storage) "tvP" = ( /obj/machinery/suit_storage_unit/captain, /obj/machinery/light/small/directional/south, @@ -56297,11 +56792,6 @@ /obj/effect/turf_decal/tile/green/diagonal_centre, /turf/open/floor/iron/diagonal, /area/station/hallway/primary/central/aft) -"tIQ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/spawner/random/structure/crate, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "tJe" = ( /obj/effect/turf_decal/tile/dark_red/half/contrasted{ dir = 1 @@ -56723,6 +57213,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/hallway/primary/starboard) +"tPZ" = ( +/obj/machinery/netpod, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "tQx" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/reagent_dispensers/fueltank, @@ -58325,6 +58821,8 @@ /obj/effect/mapping_helpers/broken_floor, /obj/effect/spawner/random/trash, /obj/structure/broken_flooring/singular/directional/south, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "uqO" = ( @@ -58367,7 +58865,7 @@ "urm" = ( /obj/structure/table/glass, /obj/item/gun/energy/laser/practice, -/obj/item/gun/energy/laser/practice{ +/obj/item/gun/energy/laser/carbine/practice{ pixel_x = -2; pixel_y = 4 }, @@ -59114,6 +59612,12 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/maintenance/department/engine) +"uFc" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "uFk" = ( /obj/structure/flora/rock/pile/jungle/style_random, /obj/structure/window/reinforced/spawner/directional/east, @@ -59354,6 +59858,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/white/small, /area/station/science/ordnance/storage) +"uIj" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/fore/lesser) "uIn" = ( /obj/structure/window/spawner/directional/west, /obj/structure/window/spawner/directional/east, @@ -59407,6 +59917,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/hallway/primary/port) +"uJG" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/wood, +/area/station/maintenance/fore/greater) "uJR" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -59517,6 +60033,13 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/station/hallway/secondary/service) +"uMl" = ( +/obj/machinery/cryo_cell, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/iron/small, +/area/station/medical/cryo) "uMu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -60053,6 +60576,13 @@ /obj/item/food/cake/apple, /turf/open/floor/iron/cafeteria, /area/station/service/kitchen) +"uVO" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "uVT" = ( /turf/closed/wall/r_wall, /area/station/command/heads_quarters/hop) @@ -61068,6 +61598,13 @@ "vlV" = ( /turf/closed/wall, /area/station/maintenance/aft) +"vlX" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/chapel{ + dir = 4 + }, +/area/station/maintenance/starboard/greater) "vlY" = ( /obj/structure/chair/stool/bamboo{ dir = 8 @@ -61409,6 +61946,10 @@ /obj/effect/spawner/random/trash/graffiti{ pixel_y = -32 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) "vql" = ( @@ -62502,6 +63043,8 @@ name = "Maintenance" }, /obj/effect/mapping_helpers/airlock/access/any/science/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "vIJ" = ( @@ -62861,6 +63404,7 @@ pixel_y = 12 }, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) "vNv" = ( @@ -63389,6 +63933,7 @@ "vVT" = ( /obj/structure/transit_tube/crossing/horizontal, /obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/space/basic, /area/space/nearstation) "vVU" = ( @@ -63809,6 +64354,14 @@ }, /turf/open/floor/iron/cafeteria, /area/station/hallway/secondary/exit/departure_lounge) +"wcI" = ( +/obj/structure/cable, +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/duct, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/fore/greater) "wcP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/modular_computer/preset/cargochat/cargo, @@ -64271,14 +64824,9 @@ /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, /area/station/hallway/secondary/recreation) -"wkZ" = ( -/obj/machinery/cryo_cell, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/turf/open/floor/iron/small, -/area/station/medical/cryo) "wla" = ( +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/chapel, /area/station/maintenance/starboard/greater) "wlf" = ( @@ -64612,6 +65160,7 @@ "wqM" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating/rust, /area/station/maintenance/fore/lesser) "wqY" = ( @@ -64635,6 +65184,8 @@ /obj/structure/disposalpipe/segment{ dir = 9 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "wrF" = ( @@ -64899,6 +65450,9 @@ "wuH" = ( /obj/structure/broken_flooring/singular/directional/south, /obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "wuI" = ( @@ -65304,6 +65858,7 @@ /obj/machinery/door/airlock/engineering{ name = "Supplies Depot" }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/hallway/secondary/construction) "wBm" = ( @@ -65334,6 +65889,7 @@ /obj/machinery/light/small/broken/directional/east, /obj/effect/decal/cleanable/dirt, /obj/machinery/duct, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/fore/greater) "wBQ" = ( @@ -65717,14 +66273,6 @@ /obj/structure/window/reinforced/spawner/directional/north, /turf/open/space/basic, /area/space/nearstation) -"wIG" = ( -/obj/structure/window/reinforced/spawner/directional/east, -/obj/effect/turf_decal/tile/green/anticorner/contrasted, -/obj/structure/table/glass, -/obj/effect/mapping_helpers/broken_floor, -/obj/item/radio/intercom/directional/south, -/turf/open/floor/iron/white, -/area/station/medical/virology) "wII" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/orange/hidden/layer1, /turf/open/floor/iron/dark, @@ -66421,16 +66969,17 @@ dir = 8 }, /obj/structure/table, -/obj/item/stack/medical/gauze{ - pixel_x = -2; - pixel_y = 7 +/obj/item/radio/intercom/directional/south, +/obj/structure/extinguisher_cabinet/directional/west, +/obj/item/storage/box/bandages{ + pixel_y = 6; + pixel_x = 4 }, /obj/item/stack/medical/gauze{ - pixel_x = 2; - pixel_y = 1 + pixel_x = -2; + pixel_y = 8 }, -/obj/item/radio/intercom/directional/south, -/obj/structure/extinguisher_cabinet/directional/west, +/obj/item/stack/medical/gauze, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) "wSH" = ( @@ -67578,13 +68127,6 @@ "xia" = ( /turf/closed/wall, /area/station/science/cubicle) -"xic" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/sink/directional/south, -/obj/item/reagent_containers/cup/bucket, -/obj/item/mop, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "xif" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -67755,6 +68297,8 @@ /area/station/security/brig/entrance) "xkn" = ( /obj/structure/steam_vent, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) "xkt" = ( @@ -68055,6 +68599,7 @@ /obj/structure/transit_tube/station/dispenser{ dir = 1 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/maintenance/starboard/greater) "xpf" = ( @@ -68840,15 +69385,6 @@ }, /turf/open/floor/iron/dark, /area/station/security/interrogation) -"xyz" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/structure/cable, -/obj/machinery/light/cold/directional/north, -/obj/structure/sign/poster/official/random/directional/north, -/turf/open/floor/iron, -/area/station/cargo/storage) "xyJ" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/iron, @@ -69109,6 +69645,9 @@ /turf/open/floor/iron, /area/station/security/execution/transfer) "xCT" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, /turf/open/floor/iron/dark/smooth_edge{ dir = 8 }, @@ -69213,6 +69752,8 @@ /area/station/maintenance/starboard/central) "xEv" = ( /obj/structure/sign/departments/holy/directional/west, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/greater) "xEC" = ( @@ -70667,6 +71208,8 @@ dir = 4 }, /obj/effect/spawner/random/trash, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "xXr" = ( @@ -70816,6 +71359,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/tile/yellow/opposingcorners, /obj/effect/turf_decal/siding/white, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/construction) "xZx" = ( @@ -71745,6 +72289,12 @@ "ylD" = ( /turf/closed/wall, /area/station/maintenance/starboard/greater) +"ylH" = ( +/obj/machinery/quantum_server, +/obj/effect/turf_decal/delivery, +/obj/machinery/light/cold/directional/west, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "ylJ" = ( /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating, @@ -71775,6 +72325,12 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/station/science/ordnance/testlab) +"ymh" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/plating, +/area/station/maintenance/starboard/greater) (1,1,1) = {" dDB @@ -83191,7 +83747,7 @@ uzJ mQh nJU ppk -kLT +uzJ ovQ oRr poM @@ -83436,12 +83992,12 @@ slY ueX slY ueX -slY -ueX -slY -slY -slY -slY +nFo +oCG +nFo +nFo +nFo +nFo lxy hzm jTA @@ -83660,7 +84216,7 @@ yjE fPv dja bNq -hln +arV dIm dQY ecq @@ -83691,15 +84247,15 @@ slY gOK slY hfc -slY -xic jBb -kPW -kwY -sEi -rXy -slY -oXa +iNE +nFo +ach +lKH +ylH +nEl +ejq +tvN lRc moz kee @@ -83917,7 +84473,7 @@ yjE uYG djC bNq -hDn +jCL dIe dRE ecF @@ -83948,15 +84504,15 @@ slY gPN gZk iNE -ueX -bbP kwY -slY -slY -kwY -slY -slY -xyz +kPW +nFo +tPZ +rPx +cvP +rWP +bCh +jWA lTv oem oem @@ -84205,14 +84761,14 @@ slY gPN slY hff -jCo -hff -jCo -slY -tIQ -sEi kPW -onI +hfc +nFo +hNv +lbF +lLq +nyf +ejq jkS lTN mRD @@ -84464,13 +85020,13 @@ slY jCo slY slY -jCi -slY -slY -slY -slY -slY -bmL +nFo +nFo +nFo +nFo +nFo +nFo +kZB lUz ohj ohj @@ -84719,8 +85275,8 @@ sjq sNz hyO roi -slY -arU +jCi +nPX hAN jMb kzI @@ -84730,7 +85286,7 @@ iUN jlv sRR odX -odX +fts nyE uzJ axj @@ -98342,7 +98898,7 @@ hei hei vPP hxJ -jVe +gIb nsc vzt mnw @@ -98856,7 +99412,7 @@ iEQ hic azJ gcz -qtQ +lOY gcz ihl oVY @@ -99113,7 +99669,7 @@ ydj ykd qyz gcz -qtQ +lOY gcz ihq rHp @@ -99417,7 +99973,7 @@ qtl dDB dDB qIf -qxf +uMl aQr wCa ulb @@ -99931,7 +100487,7 @@ qtl dDB dDB qIf -wkZ +tgJ nQU bDj onP @@ -100136,12 +100692,12 @@ gDp gIj iRz wqM -iRz -iRz -iRz +uIj +uIj +uIj lto hyj -qtQ +lOY gcz lcs xQD @@ -100649,7 +101205,7 @@ aJq aJq xRH nts -ruY +qTz gXf ruY iSb @@ -100906,7 +101462,7 @@ tYT aJq nIY gJY -ruY +igr gXg iFE iSk @@ -103570,7 +104126,7 @@ gLb bXH vTY nqV -wIG +ruC wgL oiA kWs @@ -104060,7 +104616,7 @@ wfr nPd wfr nPd -svU +bQF uxJ wfr wfr @@ -106099,7 +106655,7 @@ qRO ssz bFW rwW -iym +vtB pGD wSH kJW @@ -107084,7 +107640,7 @@ bqy bqy tIE nFW -twN +akY nFW nFW nFW @@ -108115,8 +108671,8 @@ ivO iRv nFW sJR -sJR -nfc +obv +seI nfc nFW wqj @@ -108371,7 +108927,7 @@ tIE yju pOL jfP -nfc +uJG jQF spH klf @@ -109143,7 +109699,7 @@ kGz jPr gxZ dxz -sJR +kXJ xwy sJR nFW @@ -109398,7 +109954,7 @@ aJN tIE nFW iSW -njm +rdh liR jQL uwH @@ -109655,7 +110211,7 @@ pyt nvS nFW iUy -vtL +hnF iKN jRb kaL @@ -109912,7 +110468,7 @@ nvS pyt vcE vcE -njm +rdh fjN jRz sSV @@ -110169,9 +110725,9 @@ kbY pvA iIe vcE -njm +rdh wBO -bHA +wcI njm njm njm @@ -120518,7 +121074,7 @@ blb blb kQt lxo -hzK +uFc pil cxy cyf @@ -122054,7 +122610,7 @@ hyE oix hyE iZH -mME +mXk lKG scv hyE @@ -123083,8 +123639,8 @@ xap ieY kks dof -ieY -rWA +uVO +lEg rWO wrD bHs @@ -124109,7 +124665,7 @@ dDB dDB dDB hyE -pMs +lVg afF afF pMs @@ -124366,7 +124922,7 @@ dDB dDB dDB hyE -ecL +iWI hyE hyE ecL @@ -124623,7 +125179,7 @@ dDB dDB dDB dDB -seV +fKx blb blb seV @@ -124880,7 +125436,7 @@ dDB dDB dDB dDB -vVT +iaJ blb blb seV @@ -125137,7 +125693,7 @@ dDB dDB dDB dDB -vVT +iaJ blb blb vVT @@ -125394,7 +125950,7 @@ dDB dDB dDB dDB -seV +fKx blb blb seV @@ -125651,7 +126207,7 @@ ylD dDB dDB ylD -mTU +cpJ ylD ylD mTU @@ -126166,7 +126722,7 @@ wNK pnt ylD ksN -jxD +sVk dtq xpb ylD @@ -126180,7 +126736,7 @@ dDB ylD urn pHk -aRw +vlX wla aRw egN @@ -126417,13 +126973,13 @@ qkp rfZ sEB odk -sEB +pof eLn xlx sEn csI -xlx -jxD +bVR +jLl xlx sOF cFq @@ -126437,7 +126993,7 @@ dDB ylD ylD ylD -oRV +sPa ylD ylD oRV @@ -126673,14 +127229,14 @@ mMr ylD rhL rTq -rir -sEB +rMb +eAo sWA -xlx +kwu ouL -csI -dtq -xlx +aqV +suF +kwu vLs qeT ylD @@ -126693,7 +127249,7 @@ ylD ylD ylD mEq -xCT +ozV bsI ylD wBa @@ -126941,15 +127497,15 @@ xBF sVp oyR ylD -idq -xZy +ymh +meJ xkn xEv -xZy -xZy -xZy -oRV -sgO +meJ +meJ +meJ +sPa +eQQ gYq aUA ylD @@ -127198,7 +127754,7 @@ ylD ylD ylD ylD -idq +ymh ylD ylD ylD @@ -127449,13 +128005,13 @@ ylD mMr dOb ovB -cFq -xZy -xZy -xZy -xZy +lko +meJ +meJ +meJ +meJ xkn -idq +ymh ylD xqq xLY @@ -127696,13 +128252,13 @@ mwx wgF ylD rZG -ovB +cFj bNP fii fNv jwh -xlx -vlb +fvz +aYR vNt kIY vqb diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 41f0a2456425db..dc37382b41610a 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -1692,14 +1692,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/chemistry) -"atk" = ( -/obj/item/kirbyplants/random, -/obj/structure/sign/poster/official/random/directional/west, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "atl" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/components/binary/valve/digital{ @@ -2753,6 +2745,11 @@ /obj/item/toy/figure/chef, /turf/open/floor/iron/dark, /area/station/service/kitchen) +"aHw" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/port/aft) "aHC" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/status_display/evac/directional/east, @@ -3037,12 +3034,6 @@ /obj/structure/sign/warning/electric_shock/directional/west, /turf/open/space/basic, /area/space) -"aLg" = ( -/obj/structure/filingcabinet/chestdrawer, -/obj/effect/turf_decal/delivery, -/obj/machinery/airalarm/directional/south, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "aLv" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -3427,6 +3418,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/science/robotics/lab) +"aPD" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "aPO" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible, /obj/effect/turf_decal/tile/yellow{ @@ -3567,16 +3567,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/security/courtroom) -"aSj" = ( -/obj/structure/disposalpipe/trunk{ - dir = 1 - }, -/obj/machinery/disposal/bin, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery, -/obj/structure/sign/poster/official/random/directional/south, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "aSl" = ( /obj/machinery/door/firedoor, /obj/effect/mapping_helpers/airlock/cyclelink_helper_multi{ @@ -3818,16 +3808,6 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron, /area/station/engineering/supermatter/room) -"aWe" = ( -/obj/structure/table/reinforced, -/obj/effect/decal/cleanable/dirt, -/obj/item/flashlight/lamp, -/obj/structure/cable, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "aWk" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -5004,6 +4984,13 @@ }, /turf/open/floor/iron/grimy, /area/station/command/heads_quarters/hos) +"bkr" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/conveyor{ + id = "cargodisposals" + }, +/turf/open/floor/plating, +/area/station/cargo/sorting) "bkD" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, @@ -7307,6 +7294,28 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/department/science) +"bLN" = ( +/obj/structure/rack, +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/toolbox/emergency{ + pixel_x = -3; + pixel_y = 3 + }, +/obj/item/storage/toolbox/emergency, +/obj/item/shovel, +/obj/item/shovel, +/obj/item/pickaxe, +/obj/item/pickaxe, +/obj/effect/turf_decal/bot, +/obj/machinery/light/small/directional/south, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/machinery/light_switch/directional/west{ + pixel_x = -38 + }, +/obj/machinery/airalarm/directional/south, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "bLP" = ( /obj/machinery/camera/directional/east{ c_tag = "Permabrig - Kitchen Entrance"; @@ -7420,16 +7429,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/science/robotics/mechbay) -"bNi" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "bNr" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -9991,22 +9990,6 @@ /obj/machinery/status_display/evac/directional/north, /turf/open/floor/iron, /area/station/ai_monitored/command/storage/eva) -"ctR" = ( -/obj/structure/table, -/obj/effect/decal/cleanable/dirt, -/obj/item/clipboard, -/obj/item/toy/figure/miner, -/obj/machinery/light/directional/north, -/obj/machinery/light_switch/directional/west{ - pixel_x = -42 - }, -/obj/effect/turf_decal/bot, -/obj/machinery/firealarm/directional/west, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "ctU" = ( /obj/structure/chair/office{ dir = 1 @@ -10124,6 +10107,7 @@ }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/department/science) "cvo" = ( @@ -10166,6 +10150,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/hop) +"cwd" = ( +/obj/machinery/light/directional/south, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "cwe" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -10217,6 +10207,22 @@ /obj/structure/sign/warning/radiation/directional/south, /turf/open/floor/iron, /area/station/engineering/supermatter/room) +"cwK" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/effect/turf_decal/delivery, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/iron, +/area/station/maintenance/starboard/fore) "cwV" = ( /obj/effect/landmark/start/hangover, /obj/structure/disposalpipe/segment{ @@ -10326,6 +10332,11 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/medical/treatment_center) +"cyc" = ( +/obj/machinery/netpod, +/obj/machinery/airalarm/directional/east, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "cyq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -10401,13 +10412,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/engineering/atmos) -"cze" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "czf" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood/large, @@ -11087,6 +11091,9 @@ /obj/item/radio/intercom/directional/north, /turf/open/floor/iron/grimy, /area/station/tcommsat/computer) +"cGV" = ( +/turf/closed/wall, +/area/station/bitrunning/den) "cHb" = ( /obj/machinery/door/firedoor/heavy, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -11803,10 +11810,6 @@ }, /turf/open/floor/iron/large, /area/station/science/xenobiology) -"cQO" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "cQT" = ( /obj/structure/table/reinforced, /obj/machinery/computer/security/telescreen{ @@ -12689,12 +12692,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) -"dcA" = ( -/obj/effect/decal/cleanable/cobweb/cobweb2, -/obj/effect/decal/cleanable/dirt, -/obj/structure/reagent_dispensers/watertank, -/turf/open/floor/plating, -/area/station/maintenance/starboard/fore) "dcG" = ( /obj/effect/turf_decal/trimline/red/filled/line, /obj/effect/landmark/start/depsec/science, @@ -13098,10 +13095,6 @@ /obj/effect/turf_decal/siding/wood/corner, /turf/open/floor/iron/dark, /area/station/hallway/secondary/service) -"dih" = ( -/obj/effect/decal/cleanable/oil, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "din" = ( /obj/structure/table/wood, /obj/item/paper_bin, @@ -13715,19 +13708,6 @@ }, /turf/open/floor/iron, /area/station/maintenance/department/chapel) -"dri" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/maintenance/starboard/fore) "drj" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -13846,15 +13826,6 @@ /obj/machinery/rnd/server, /turf/open/floor/circuit/green/telecomms/mainframe, /area/station/science/server) -"dsq" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/brown{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "dsy" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -13972,13 +13943,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/security/detectives_office/private_investigators_office) -"dtp" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "dtJ" = ( /obj/machinery/power/apc/auto_name/directional/north, /obj/structure/cable, @@ -14048,6 +14012,18 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/xenobiology) +"dux" = ( +/obj/structure/table, +/obj/effect/turf_decal/tile/brown/half{ + dir = 4 + }, +/obj/item/clipboard, +/obj/item/toy/figure/miner, +/obj/machinery/light/directional/south, +/turf/open/floor/iron/half{ + dir = 1 + }, +/area/station/cargo/miningoffice) "duA" = ( /turf/closed/wall/r_wall, /area/station/command/corporate_showroom) @@ -15070,13 +15046,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/cryo) -"dIz" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "dIE" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -15710,6 +15679,12 @@ }, /turf/open/floor/plating, /area/station/engineering/supermatter/room) +"dPC" = ( +/obj/structure/closet/secure_closet/miner, +/obj/effect/turf_decal/delivery, +/obj/structure/extinguisher_cabinet/directional/north, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "dPD" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -15829,13 +15804,6 @@ dir = 8 }, /area/station/hallway/primary/fore) -"dRf" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "dRh" = ( /obj/machinery/telecomms/bus/preset_four, /obj/effect/turf_decal/tile/brown/anticorner/contrasted{ @@ -16095,10 +16063,6 @@ dir = 1 }, /area/station/hallway/primary/fore) -"dVe" = ( -/obj/effect/landmark/generic_maintenance_landmark, -/turf/open/floor/plating/airless, -/area/space/nearstation) "dVg" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -16261,6 +16225,14 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/maintenance/port) +"dXs" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/structure/table/reinforced, +/obj/item/flashlight/lamp, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "dXw" = ( /obj/structure/sign/painting/large/library_private{ dir = 1; @@ -17196,26 +17168,6 @@ }, /turf/open/floor/iron/dark/textured_large, /area/station/engineering/atmos/hfr_room) -"eld" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/machinery/requests_console/directional/south{ - department = "Mining"; - name = "Mining Requests Console" - }, -/obj/machinery/requests_console/directional/south{ - department = "Mining"; - name = "Mining Requests Console" - }, -/obj/machinery/camera/directional/south{ - c_tag = "Cargo - Mining Dock"; - name = "cargo camera" - }, -/obj/effect/turf_decal/tile/brown/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "eln" = ( /obj/effect/turf_decal/stripes/end{ dir = 4 @@ -17278,6 +17230,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/command/gateway) +"elO" = ( +/obj/effect/landmark/event_spawn, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "elP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/turf_decal/tile/yellow/fourcorners, @@ -18760,6 +18718,18 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"eFU" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "eGb" = ( /obj/effect/spawner/random/trash/mess, /turf/open/floor/wood, @@ -19030,14 +19000,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) -"eIA" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "eIQ" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -19199,11 +19161,6 @@ /obj/item/radio/intercom/directional/south, /turf/open/floor/iron, /area/station/engineering/supermatter/room) -"eKS" = ( -/obj/machinery/rnd/bepis, -/obj/effect/turf_decal/box/white, -/turf/open/floor/iron, -/area/station/cargo/storage) "eKU" = ( /obj/effect/turf_decal/tile/red/anticorner/contrasted{ dir = 1 @@ -20327,7 +20284,7 @@ /area/station/maintenance/space_hut/observatory) "eYo" = ( /obj/structure/table/reinforced, -/obj/item/gun/energy/laser/practice{ +/obj/item/gun/energy/laser/carbine/practice{ pixel_x = 3; pixel_y = -3 }, @@ -20339,6 +20296,15 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/security/range) +"eYt" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/computer/order_console/mining, +/obj/item/radio/intercom/directional/west, +/obj/machinery/firealarm/directional/west{ + pixel_y = -9 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "eYy" = ( /obj/structure/cable, /obj/structure/closet/secure_closet/atmospherics, @@ -20528,6 +20494,10 @@ /obj/effect/decal/cleanable/cobweb, /turf/open/floor/iron/smooth, /area/station/maintenance/department/science/xenobiology) +"fbu" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/bitrunning/den) "fbA" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -21567,23 +21537,6 @@ /obj/structure/chair/office, /turf/open/floor/iron/grimy, /area/station/tcommsat/computer) -"fnN" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/mining{ - name = "Mining Dock" - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "foh" = ( /obj/machinery/atmospherics/components/binary/volume_pump{ name = "Ports to Distro" @@ -21837,19 +21790,6 @@ }, /turf/open/floor/iron, /area/station/commons/locker) -"fsg" = ( -/obj/structure/disposalpipe/segment, -/obj/machinery/door/airlock/mining{ - name = "Mining Dock" - }, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "fsl" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -22031,6 +21971,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/grimy, /area/station/service/library) +"ftS" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/herringbone, +/area/station/cargo/miningoffice) "ftU" = ( /obj/structure/cable, /obj/effect/turf_decal/siding/yellow, @@ -22206,11 +22153,6 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/dark, /area/station/science/xenobiology) -"fwD" = ( -/obj/structure/table, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "fwK" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -22472,6 +22414,16 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/engineering/storage) +"fAj" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron/herringbone, +/area/station/cargo/miningoffice) "fAn" = ( /obj/machinery/holopad, /obj/effect/turf_decal/bot, @@ -22624,12 +22576,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) -"fCb" = ( -/obj/effect/turf_decal/loading_area{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "fCf" = ( /obj/machinery/door/poddoor/preopen{ id = "atmoslock"; @@ -22652,6 +22598,16 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) +"fCm" = ( +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 4; + id = "chemisttop"; + name = "Pharmacy Shutters" + }, +/obj/machinery/smartfridge/chemistry/preloaded, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/white, +/area/station/medical/pharmacy) "fCn" = ( /obj/machinery/door/airlock/medical{ name = "Medical Break Room" @@ -23154,11 +23110,6 @@ }, /turf/open/floor/iron/large, /area/station/security/checkpoint/escape) -"fJm" = ( -/obj/effect/landmark/start/shaft_miner, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "fJq" = ( /turf/closed/wall, /area/station/security/brig) @@ -23845,6 +23796,7 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners{ dir = 1 }, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron, /area/station/service/kitchen/abandoned) "fTw" = ( @@ -23932,13 +23884,6 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/iron/grimy, /area/station/service/abandoned_gambling_den) -"fUl" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/conveyor{ - id = "cargodisposals" - }, -/turf/open/floor/plating, -/area/station/cargo/sorting) "fUq" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line{ @@ -23962,6 +23907,12 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"fUr" = ( +/obj/machinery/cryo_cell{ + dir = 8 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/medical/cryo) "fUF" = ( /obj/structure/table/reinforced, /obj/structure/window/reinforced/spawner/directional/east, @@ -24403,14 +24354,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/atmos/project) -"fZz" = ( -/obj/effect/landmark/start/shaft_miner, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "fZG" = ( /obj/effect/turf_decal/stripes/corner, /obj/effect/turf_decal/stripes/corner{ @@ -24656,6 +24599,16 @@ }, /turf/open/floor/iron, /area/station/service/hydroponics) +"gco" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "gcr" = ( /obj/effect/turf_decal/tile/neutral/half/contrasted, /turf/open/floor/iron, @@ -24790,11 +24743,6 @@ /obj/machinery/light/small/dim/directional/north, /turf/open/floor/plating, /area/station/maintenance/department/security) -"gdD" = ( -/obj/structure/closet/secure_closet/miner, -/obj/effect/turf_decal/delivery, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "gdE" = ( /obj/structure/chair/office, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -25206,6 +25154,39 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) +"giO" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/structure/desk_bell{ + pixel_x = 7; + pixel_y = 6 + }, +/obj/item/folder/yellow{ + pixel_x = -3; + pixel_y = -6 + }, +/obj/item/pen{ + pixel_x = -3; + pixel_y = -2 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 4; + id = "chemisttop"; + name = "Pharmacy Shutters" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/door/window/left/directional/west{ + name = "Pharmacy Desk"; + req_access = list("pharmacy"); + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/medical/pharmacy) "giY" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/sign/poster/contraband/random/directional/north, @@ -26019,11 +26000,6 @@ }, /turf/open/floor/iron/dark/corner, /area/station/engineering/atmos/pumproom) -"grT" = ( -/obj/structure/cable, -/obj/effect/turf_decal/tile/brown/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "grV" = ( /obj/effect/turf_decal/arrows/red{ dir = 4; @@ -26206,6 +26182,14 @@ }, /turf/open/floor/iron, /area/station/commons/storage/primary) +"guj" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/machinery/disposal/bin, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "gum" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -26994,9 +26978,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/cafeteria, /area/station/security/prison/mess) -"gDE" = ( -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "gDP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -27248,12 +27229,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/aisat/exterior) -"gGM" = ( -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "gGT" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/toilet{ @@ -27834,6 +27809,7 @@ /area/station/security/prison) "gOH" = ( /obj/effect/landmark/blobstart, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/fore) "gOR" = ( @@ -28246,13 +28222,6 @@ }, /turf/open/floor/iron, /area/station/service/abandoned_gambling_den/gaming) -"gUe" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/maintenance/starboard/fore) "gUi" = ( /obj/effect/turf_decal/stripes/red/line{ dir = 10 @@ -29429,6 +29398,13 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron/white/smooth_large, /area/station/medical/medbay) +"hkn" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "hkt" = ( /obj/effect/spawner/random/engineering/tank, /turf/open/floor/plating, @@ -30142,6 +30118,7 @@ /obj/effect/spawner/random/engineering/tracking_beacon, /obj/effect/mapping_helpers/burnt_floor, /obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron, /area/station/maintenance/department/electrical) "huX" = ( @@ -30445,6 +30422,10 @@ }, /turf/open/floor/glass/reinforced, /area/station/maintenance/department/science/xenobiology) +"hzs" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "hzx" = ( /obj/machinery/firealarm/directional/west, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -33005,16 +32986,6 @@ /obj/item/stack/rods/fifty, /turf/open/floor/plating, /area/station/maintenance/department/eva/abandoned) -"ihc" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/effect/turf_decal/tile/brown/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "iho" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -33076,6 +33047,16 @@ }, /turf/open/floor/plating, /area/station/medical/virology) +"iio" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "iiy" = ( /obj/structure/easel, /turf/open/floor/iron, @@ -33899,7 +33880,6 @@ "itC" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/landmark/generic_maintenance_landmark, /obj/effect/mapping_helpers/broken_floor, /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, @@ -34326,6 +34306,14 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/hallway/secondary/entry) +"izj" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron/herringbone, +/area/station/cargo/miningoffice) "izo" = ( /obj/structure/table/wood, /obj/item/gavelblock, @@ -36018,13 +36006,6 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"iWJ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/loading_area{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "iWR" = ( /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 8 @@ -36059,6 +36040,15 @@ }, /turf/open/floor/iron, /area/station/engineering/lobby) +"iXd" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/start/shaft_miner, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "iXj" = ( /obj/effect/landmark/start/hangover, /obj/effect/turf_decal/bot, @@ -36881,6 +36871,13 @@ /obj/structure/sign/warning/secure_area/directional/west, /turf/open/floor/plating, /area/station/engineering/atmos/mix) +"jfO" = ( +/obj/structure/closet/wardrobe/miner, +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/backpack/satchel/explorer, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "jfP" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -37181,21 +37178,6 @@ dir = 8 }, /area/station/hallway/primary/port) -"jjK" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/structure/sign/nanotrasen{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "jjU" = ( /obj/effect/turf_decal/tile/neutral/half/contrasted, /turf/open/floor/iron, @@ -38053,19 +38035,6 @@ "jtC" = ( /turf/open/floor/plating, /area/station/service/abandoned_gambling_den) -"jtE" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/machinery/firealarm/directional/east, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/machinery/light/small/directional/east, -/turf/open/floor/iron, -/area/station/hallway/primary/central/fore) "jtV" = ( /obj/structure/sign/warning/electric_shock, /turf/closed/wall/r_wall, @@ -38614,6 +38583,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/science/lobby) +"jBM" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "jCb" = ( /obj/machinery/computer/records/security{ dir = 8 @@ -38697,6 +38671,13 @@ /obj/item/pen, /turf/open/floor/wood, /area/station/service/library/abandoned) +"jCu" = ( +/obj/structure/closet/secure_closet/miner, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/delivery, +/obj/machinery/light/directional/north, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "jCv" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/hydroponics/constructable, @@ -38739,17 +38720,6 @@ /obj/effect/mapping_helpers/airlock/access/all/service/lawyer, /turf/open/floor/iron, /area/station/service/lawoffice) -"jCR" = ( -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/conveyor{ - id = "cargodisposals" - }, -/obj/effect/mapping_helpers/burnt_floor, -/turf/open/floor/plating, -/area/station/cargo/sorting) "jCS" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -39355,6 +39325,18 @@ /obj/effect/turf_decal/tile/blue/opposingcorners, /turf/open/floor/iron/white, /area/station/command/heads_quarters/cmo) +"jKY" = ( +/obj/effect/decal/cleanable/oil/streak, +/obj/machinery/camera/directional/south, +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 7 + }, +/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind{ + pixel_x = 5 + }, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "jLa" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/railing{ @@ -39937,6 +39919,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/medical/medbay) +"jRc" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "jRg" = ( /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, @@ -40171,23 +40166,6 @@ "jUx" = ( /turf/open/floor/plating, /area/station/maintenance/department/science) -"jUy" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/door/airlock/mining/glass{ - name = "Delivery Office" - }, -/obj/effect/mapping_helpers/airlock/access/any/supply/shipping, -/obj/effect/mapping_helpers/airlock/access/any/supply/mining, -/turf/open/floor/iron, -/area/station/cargo/sorting) "jUC" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -42043,11 +42021,6 @@ "ksK" = ( /turf/closed/wall/r_wall, /area/station/command/gateway) -"ksL" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "ksP" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible{ dir = 4 @@ -42525,13 +42498,6 @@ /obj/effect/turf_decal/tile/neutral/full, /turf/open/floor/iron/large, /area/station/ai_monitored/command/storage/eva) -"kzi" = ( -/obj/structure/closet/secure_closet/miner, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery, -/obj/machinery/status_display/evac/directional/north, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "kzm" = ( /obj/structure/disposalpipe/sorting/mail/flip{ dir = 4; @@ -43261,6 +43227,15 @@ /obj/structure/sign/warning/pods, /turf/closed/wall, /area/station/hallway/secondary/entry) +"kKx" = ( +/obj/effect/turf_decal/tile/brown/half{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/iron/half{ + dir = 1 + }, +/area/station/cargo/miningoffice) "kKy" = ( /obj/machinery/airalarm/directional/east, /obj/machinery/rnd/production/techfab/department/medical, @@ -43887,6 +43862,18 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron/dark, /area/station/engineering/main) +"kTs" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 1 + }, +/obj/effect/landmark/start/shaft_miner, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "kTy" = ( /obj/structure/chair/office{ dir = 8 @@ -44028,6 +44015,7 @@ dir = 8 }, /obj/effect/turf_decal/tile/red/fourcorners, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron, /area/station/service/kitchen/abandoned) "kVx" = ( @@ -44804,11 +44792,15 @@ dir = 4 }, /obj/structure/table/reinforced, -/obj/item/storage/toolbox/mechanical, -/obj/item/storage/belt/utility, /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 1 }, +/obj/item/storage/box/bandages{ + pixel_y = 6; + pixel_x = 4 + }, +/obj/item/storage/toolbox/mechanical, +/obj/item/storage/belt/utility, /turf/open/floor/iron, /area/station/cargo/storage) "lfD" = ( @@ -45186,6 +45178,15 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/general, /turf/open/floor/iron, /area/station/maintenance/solars/starboard/fore) +"ljQ" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "ljS" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/reinforced, @@ -45325,6 +45326,16 @@ /obj/machinery/light/directional/west, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"llj" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/turf/open/floor/iron/herringbone, +/area/station/cargo/miningoffice) "llm" = ( /obj/structure/chair/office/tactical{ dir = 8 @@ -45859,6 +45870,7 @@ }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/department/chapel) "ltr" = ( @@ -45902,16 +45914,6 @@ /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/iron, /area/station/medical/treatment_center) -"ltB" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/purple{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "ltD" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, @@ -46583,22 +46585,6 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/engineering/storage) -"lBB" = ( -/obj/structure/rack, -/obj/effect/decal/cleanable/dirt, -/obj/item/storage/toolbox/emergency{ - pixel_x = -3; - pixel_y = 3 - }, -/obj/item/storage/toolbox/emergency, -/obj/item/shovel, -/obj/item/shovel, -/obj/item/pickaxe, -/obj/item/pickaxe, -/obj/effect/turf_decal/bot, -/obj/machinery/light/small/directional/south, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "lBG" = ( /obj/structure/cable, /obj/effect/spawner/structure/window/reinforced, @@ -48148,6 +48134,12 @@ /obj/effect/turf_decal/tile/neutral/full, /turf/open/floor/iron/large, /area/station/medical/paramedic) +"lUW" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/tile/red/fourcorners, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/iron, +/area/station/service/kitchen/abandoned) "lVi" = ( /obj/structure/closet/l3closet/virology, /obj/effect/turf_decal/bot, @@ -48613,16 +48605,6 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/carpet/orange, /area/station/commons/dorms) -"mcK" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "mcV" = ( /obj/machinery/door/airlock/engineering/glass{ name = "Supermatter Engine Room" @@ -49224,6 +49206,11 @@ "mlE" = ( /turf/closed/wall/r_wall, /area/station/ai_monitored/command/storage/eva) +"mlF" = ( +/obj/machinery/computer/quantum_console, +/obj/structure/extinguisher_cabinet/directional/west, +/turf/open/floor/iron/dark/smooth_corner, +/area/station/bitrunning/den) "mlM" = ( /obj/structure/table/wood, /obj/machinery/computer/records/medical/laptop, @@ -49770,6 +49757,11 @@ /obj/effect/turf_decal/tile/yellow/fourcorners, /turf/open/floor/iron, /area/station/engineering/storage) +"mtL" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/status_display/evac/directional/north, +/turf/open/floor/plating, +/area/station/cargo/miningoffice) "mtO" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/yellow{ @@ -50523,6 +50515,13 @@ /obj/structure/cable, /turf/open/floor/engine, /area/station/maintenance/disposal/incinerator) +"mDm" = ( +/obj/machinery/quantum_server, +/obj/effect/turf_decal/bot/left, +/turf/open/floor/iron/dark/smooth_corner{ + dir = 4 + }, +/area/station/bitrunning/den) "mDo" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -52755,6 +52754,17 @@ /obj/effect/spawner/random/trash/hobo_squat, /turf/open/floor/plating, /area/station/maintenance/department/chapel) +"nhj" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/table, +/obj/machinery/microwave{ + desc = "Cooks and boils stuff, somehow."; + pixel_x = -3; + pixel_y = 5 + }, +/obj/structure/sign/poster/official/random/directional/west, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "nhm" = ( /turf/closed/wall/r_wall, /area/station/maintenance/starboard/lesser) @@ -53281,11 +53291,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/security/courtroom) -"nos" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/starboard/fore) "not" = ( /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -53498,11 +53503,6 @@ }, /turf/open/floor/iron, /area/station/security/warden) -"nro" = ( -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/turf/open/floor/plating, -/area/station/maintenance/starboard/fore) "nry" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, @@ -53583,16 +53583,6 @@ }, /turf/open/floor/iron/dark, /area/station/maintenance/port) -"nsI" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "nsV" = ( /obj/structure/table/reinforced, /obj/structure/reagent_dispensers/wall/peppertank/directional/west, @@ -53662,12 +53652,6 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/dark, /area/station/commons/fitness/recreation) -"ntU" = ( -/obj/structure/table/reinforced, -/obj/machinery/microwave, -/obj/structure/sign/poster/random/directional/west, -/turf/open/floor/wood, -/area/station/engineering/break_room) "ntX" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 @@ -54495,6 +54479,12 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/station/maintenance/port) +"nEE" = ( +/obj/machinery/netpod, +/obj/structure/sign/poster/random/directional/north, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "nEJ" = ( /obj/structure/cable, /obj/effect/turf_decal/trimline/yellow/line, @@ -55604,12 +55594,6 @@ /obj/item/storage/medkit/regular, /turf/open/floor/iron, /area/station/commons/fitness/recreation) -"nTw" = ( -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/purple/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "nTz" = ( /obj/item/stack/sheet/plasteel/twenty, /obj/item/stack/sheet/rglass{ @@ -55819,22 +55803,6 @@ /obj/effect/turf_decal/tile/red/fourcorners, /turf/open/floor/iron/dark, /area/station/security/lockers) -"nXf" = ( -/obj/machinery/door/firedoor, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/door/airlock/mining/glass{ - name = "Delivery Office" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/access/any/supply/mining, -/obj/effect/mapping_helpers/airlock/access/any/supply/shipping, -/turf/open/floor/iron, -/area/station/cargo/sorting) "nXj" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -56373,14 +56341,6 @@ /obj/structure/closet, /turf/open/floor/plating, /area/station/maintenance/fore) -"oea" = ( -/obj/structure/closet/wardrobe/miner, -/obj/effect/decal/cleanable/dirt, -/obj/item/storage/backpack/satchel/explorer, -/obj/effect/turf_decal/bot, -/obj/item/radio/intercom/directional/south, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "oec" = ( /obj/effect/spawner/structure/window/reinforced/tinted, /turf/open/floor/plating/airless, @@ -56500,12 +56460,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos/mix) -"ofM" = ( -/obj/effect/turf_decal/tile/purple/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "ofN" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/conveyor{ @@ -56657,14 +56611,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"ohR" = ( -/obj/structure/cable, -/obj/structure/extinguisher_cabinet/directional/west, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "ohZ" = ( /obj/structure/rack, /obj/effect/spawner/random/techstorage/service_all, @@ -56905,6 +56851,24 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/security/prison/garden) +"okN" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 8 + }, +/obj/effect/decal/cleanable/generic, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/landmark/start/bitrunner, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "okV" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/reagent_dispensers/plumbed{ @@ -57058,10 +57022,6 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) -"oml" = ( -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "omv" = ( /obj/structure/table, /obj/item/flashlight/lamp, @@ -57768,6 +57728,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/port) +"owZ" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/table, +/obj/item/storage/medkit/regular, +/obj/machinery/light/directional/west, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "oxb" = ( /obj/machinery/duct, /obj/effect/turf_decal/siding/white, @@ -58011,6 +57978,28 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/grimy, /area/station/command/heads_quarters/captain/private) +"oAV" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/corner{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "oAW" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -59562,9 +59551,6 @@ /obj/machinery/newscaster/directional/east, /turf/open/floor/wood, /area/station/hallway/secondary/service) -"oWV" = ( -/turf/closed/wall, -/area/station/cargo/miningoffice) "oXi" = ( /obj/effect/turf_decal/bot_white/left, /obj/effect/turf_decal/tile/neutral{ @@ -61577,6 +61563,21 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/hallway/secondary/exit/departure_lounge) +"pxS" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown/half{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/half{ + dir = 1 + }, +/area/station/cargo/miningoffice) "pxT" = ( /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, @@ -62042,6 +62043,13 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) +"pDy" = ( +/obj/machinery/cryo_cell{ + dir = 8 + }, +/obj/machinery/status_display/ai/directional/south, +/turf/open/floor/iron/dark/textured_large, +/area/station/medical/cryo) "pDE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -63275,6 +63283,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/mapping_helpers/broken_floor, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/port/fore) "pRy" = ( @@ -63484,38 +63493,6 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/grimy, /area/station/command/heads_quarters/hos) -"pTz" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/firedoor, -/obj/structure/desk_bell{ - pixel_x = 7; - pixel_y = 6 - }, -/obj/item/folder/yellow{ - pixel_x = -3; - pixel_y = -6 - }, -/obj/item/pen{ - pixel_x = -3; - pixel_y = -2 - }, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 4; - id = "chemisttop"; - name = "Pharmacy Shutters" - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/door/window/left/directional/west{ - name = "Pharmacy Desk"; - req_access = list("pharmacy") - }, -/turf/open/floor/iron/dark, -/area/station/medical/pharmacy) "pTB" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -63636,6 +63613,17 @@ }, /turf/open/floor/iron/dark/corner, /area/station/engineering/atmos/pumproom) +"pUs" = ( +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/obj/machinery/door/airlock/mining/glass{ + name = "Bitrunning Den" + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "pUw" = ( /obj/machinery/holopad, /obj/effect/turf_decal/bot, @@ -64855,6 +64843,18 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/command/bridge) +"qko" = ( +/obj/item/kirbyplants/random, +/obj/effect/turf_decal/tile/brown/half{ + dir = 8 + }, +/obj/machinery/light/directional/west, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/sign/poster/official/random/directional/west, +/turf/open/floor/iron/half{ + dir = 1 + }, +/area/station/cargo/miningoffice) "qkv" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -65011,6 +65011,21 @@ }, /turf/open/floor/plating, /area/station/engineering/supermatter/room) +"qmT" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/maintenance/starboard/fore) "qnc" = ( /obj/machinery/firealarm/directional/south, /obj/effect/turf_decal/tile/blue{ @@ -65438,6 +65453,22 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/science/xenobiology) +"qsF" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 + }, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "qsN" = ( /obj/structure/chair{ dir = 4 @@ -65865,13 +65896,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/security/execution/transfer) -"qyO" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "qyX" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -68363,6 +68387,13 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"rgC" = ( +/obj/structure/table/reinforced, +/obj/item/folder/yellow, +/obj/item/gps/mining, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "rgG" = ( /obj/structure/closet/secure_closet/engineering_personal, /obj/effect/decal/cleanable/dirt, @@ -68572,15 +68603,6 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron/white, /area/station/medical/medbay) -"riZ" = ( -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 4; - id = "chemisttop"; - name = "Pharmacy Shutters" - }, -/obj/machinery/smartfridge/chemistry/preloaded, -/turf/open/floor/iron/white, -/area/station/medical/pharmacy) "rjd" = ( /obj/structure/table/wood, /obj/item/flashlight/lamp/green, @@ -68995,6 +69017,19 @@ /obj/machinery/light/dim/directional/east, /turf/open/floor/iron/dark, /area/station/tcommsat/computer) +"rmH" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "rmI" = ( /obj/structure/table/reinforced, /obj/item/electronics/apc, @@ -69279,6 +69314,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 }, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/port) "rqV" = ( @@ -69973,6 +70009,16 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/station/cargo/storage) +"rAl" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/machinery/conveyor{ + id = "cargodisposals" + }, +/turf/open/floor/plating, +/area/station/cargo/sorting) "rAm" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/turf_decal/tile/yellow/half/contrasted{ @@ -70677,15 +70723,6 @@ /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, /turf/open/floor/plating, /area/station/engineering/atmos/mix) -"rKu" = ( -/obj/structure/cable, -/obj/structure/table/reinforced, -/obj/effect/decal/cleanable/dirt, -/obj/item/folder/yellow, -/obj/item/gps/mining, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "rKA" = ( /obj/machinery/firealarm/directional/east, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -71280,6 +71317,11 @@ /obj/structure/mirror/directional/west, /turf/open/floor/wood, /area/station/maintenance/port/aft) +"rQF" = ( +/obj/machinery/netpod, +/obj/effect/decal/cleanable/robot_debris, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "rQI" = ( /obj/machinery/airlock_sensor/incinerator_atmos{ pixel_x = 24 @@ -71581,6 +71623,14 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/xenobiology) +"rUi" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "rUj" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/preopen{ @@ -72578,6 +72628,15 @@ }, /turf/open/space/basic, /area/space) +"sgK" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "sgZ" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable, @@ -72780,6 +72839,12 @@ }, /turf/open/floor/iron, /area/station/maintenance/port) +"sjJ" = ( +/obj/structure/table/reinforced, +/obj/machinery/microwave/engineering/cell_included, +/obj/structure/sign/poster/random/directional/west, +/turf/open/floor/wood, +/area/station/engineering/break_room) "ske" = ( /obj/effect/spawner/random/entertainment/arcade, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -73055,13 +73120,6 @@ }, /turf/open/floor/iron/white, /area/station/science/research) -"snh" = ( -/obj/machinery/computer/order_console/mining, -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/directional/north, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "snj" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/decal/cleanable/dirt, @@ -73462,6 +73520,10 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/medical/pharmacy) +"stf" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron/herringbone, +/area/station/cargo/miningoffice) "stp" = ( /obj/machinery/airalarm/directional/west, /obj/effect/turf_decal/trimline/brown/filled/line{ @@ -73840,14 +73902,6 @@ /obj/item/papercutter, /turf/open/floor/iron/grimy, /area/station/command/bridge) -"sxu" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/effect/turf_decal/tile/purple/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "sxD" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -74278,6 +74332,23 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/half, /area/station/service/hydroponics) +"sCW" = ( +/obj/machinery/door/firedoor, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/door/airlock/mining/glass{ + name = "Delivery Office" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/access/any/supply/mining, +/obj/effect/mapping_helpers/airlock/access/any/supply/shipping, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/turf/open/floor/iron, +/area/station/cargo/sorting) "sCY" = ( /obj/structure/cable, /obj/machinery/power/tracker, @@ -74961,6 +75032,9 @@ /obj/structure/sign/poster/official/build/directional/north, /turf/open/floor/iron, /area/station/science/robotics/mechbay) +"sLg" = ( +/turf/open/floor/iron, +/area/station/cargo/storage) "sLx" = ( /obj/effect/decal/cleanable/generic, /turf/open/floor/iron/grimy, @@ -75137,6 +75211,7 @@ /obj/effect/decal/cleanable/dirt, /obj/machinery/duct, /obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron, /area/station/maintenance/department/chapel) "sOi" = ( @@ -75475,6 +75550,12 @@ /obj/effect/spawner/random/trash/graffiti, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"sSx" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/delivery, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/iron, +/area/station/science/research/abandoned) "sSH" = ( /obj/effect/turf_decal/tile/green/half/contrasted{ dir = 8 @@ -76094,12 +76175,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/service/chapel) -"taR" = ( -/obj/machinery/cryo_cell{ - dir = 8 - }, -/turf/open/floor/iron/dark/textured_large, -/area/station/medical/cryo) "tbd" = ( /obj/item/radio/intercom/directional/west, /obj/effect/turf_decal/tile/yellow/half/contrasted{ @@ -76231,6 +76306,14 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron, /area/station/engineering/supermatter/room) +"tcB" = ( +/obj/machinery/door/airlock/mining{ + name = "Mining Dock" + }, +/obj/effect/mapping_helpers/airlock/access/all/supply/mining, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "tcG" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -76931,6 +77014,13 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/hallway/primary/central/aft) +"toy" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron/herringbone, +/area/station/cargo/miningoffice) "toB" = ( /obj/machinery/light/directional/west, /obj/effect/turf_decal/stripes/line{ @@ -78985,6 +79075,16 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/server) +"tNn" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "tNq" = ( /obj/effect/turf_decal/stripes/line{ dir = 1 @@ -79299,17 +79399,6 @@ dir = 1 }, /area/station/service/bar) -"tQr" = ( -/obj/structure/table, -/obj/machinery/microwave{ - desc = "Cooks and boils stuff, somehow."; - pixel_x = -3; - pixel_y = 5 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "tQt" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -80044,9 +80133,7 @@ /obj/structure/disposalpipe/segment, /obj/effect/decal/cleanable/dirt, /obj/machinery/duct, -/mob/living/simple_animal/hostile/retaliate/goat{ - name = "Pete" - }, +/mob/living/basic/goat/pete, /turf/open/floor/iron/freezer, /area/station/service/kitchen/coldroom) "uaE" = ( @@ -81241,6 +81328,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "upv" = ( @@ -81497,6 +81585,13 @@ }, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) +"usJ" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "usZ" = ( /obj/item/flashlight/lamp, /obj/machinery/airalarm/directional/east, @@ -82128,15 +82223,6 @@ /obj/effect/turf_decal/tile/red, /turf/open/floor/iron, /area/station/security/execution/transfer) -"uAH" = ( -/obj/structure/cable, -/obj/structure/chair/office{ - dir = 4 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/purple/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "uAI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/landmark/start/depsec/engineering, @@ -82181,6 +82267,21 @@ dir = 1 }, /area/station/medical/morgue) +"uBd" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/sign/nanotrasen{ + pixel_y = 32 + }, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "uBf" = ( /obj/machinery/atmospherics/pipe/smart/manifold/purple/visible{ dir = 4 @@ -83170,6 +83271,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/commons/storage/primary) +"uND" = ( +/obj/effect/turf_decal/tile/brown/half{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/machinery/computer/order_console/bitrunning, +/obj/effect/turf_decal/stripes/end, +/turf/open/floor/iron/half{ + dir = 1 + }, +/area/station/cargo/miningoffice) "uNE" = ( /obj/machinery/atmospherics/components/unary/passive_vent{ dir = 4 @@ -83216,6 +83330,15 @@ }, /turf/open/floor/iron/white, /area/station/science/ordnance/office) +"uOk" = ( +/obj/structure/chair/office{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown/half/contrasted, +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/start/shaft_miner, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "uOn" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -84342,7 +84465,7 @@ /area/station/maintenance/port/fore) "vbT" = ( /obj/structure/rack, -/obj/item/gun/energy/laser/practice{ +/obj/item/gun/energy/laser/carbine/practice{ pixel_x = 3; pixel_y = -3 }, @@ -84755,6 +84878,7 @@ /area/station/service/bar/backroom) "vhK" = ( /obj/effect/landmark/blobstart, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/aft) "vhW" = ( @@ -85038,11 +85162,15 @@ /area/station/service/cafeteria) "vmo" = ( /obj/structure/table/glass, -/obj/item/reagent_containers/cup/bottle/morphine, -/obj/item/reagent_containers/syringe, /obj/machinery/status_display/ai/directional/west, /obj/machinery/newscaster/directional/north, /obj/effect/turf_decal/siding/dark_red, +/obj/item/storage/box/bandages{ + pixel_y = 6; + pixel_x = -6 + }, +/obj/item/reagent_containers/cup/bottle/morphine, +/obj/item/reagent_containers/syringe, /turf/open/floor/iron/dark, /area/station/security/execution/transfer) "vmr" = ( @@ -86026,13 +86154,6 @@ }, /turf/open/floor/wood, /area/station/service/library/abandoned) -"vyF" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/start/shaft_miner, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "vyG" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -86109,18 +86230,6 @@ /obj/structure/sign/warning/secure_area/directional/north, /turf/open/space, /area/space/nearstation) -"vzy" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 9 - }, -/obj/effect/decal/cleanable/dirt, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/delivery, -/turf/open/floor/iron, -/area/station/maintenance/starboard/fore) "vzA" = ( /obj/effect/turf_decal/trimline/purple/filled/line, /turf/open/floor/iron/white, @@ -86454,6 +86563,21 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted, /turf/open/floor/iron, /area/station/command/heads_quarters/hos) +"vDj" = ( +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/machinery/holopad, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "vDm" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -86838,6 +86962,23 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/department/security) +"vId" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 8 + }, +/obj/item/radio/intercom/directional/south, +/obj/effect/decal/cleanable/oil, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "vIq" = ( /obj/structure/cable, /obj/structure/disposalpipe/junction{ @@ -87175,6 +87316,22 @@ }, /turf/open/floor/iron, /area/station/security/checkpoint/engineering) +"vNV" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/tile/brown/half{ + dir = 8 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/half{ + dir = 1 + }, +/area/station/cargo/miningoffice) "vOh" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -87408,12 +87565,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron/dark, /area/station/service/bar) -"vQT" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "vRn" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /obj/structure/railing/corner, @@ -88521,6 +88672,24 @@ /obj/effect/landmark/start/depsec/medical, /turf/open/floor/iron/large, /area/station/security/checkpoint/medical/medsci) +"whb" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/structure/disposalpipe/segment, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/door/airlock/mining/glass{ + name = "Delivery Office" + }, +/obj/effect/mapping_helpers/airlock/access/any/supply/shipping, +/obj/effect/mapping_helpers/airlock/access/any/supply/mining, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/turf/open/floor/iron, +/area/station/cargo/sorting) "whc" = ( /obj/structure/sign/poster/official/fruit_bowl/directional/west, /obj/effect/turf_decal/stripes/line{ @@ -88926,13 +89095,6 @@ }, /turf/open/floor/glass, /area/station/maintenance/space_hut/observatory) -"wml" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "wmn" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -89178,14 +89340,6 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"woJ" = ( -/obj/effect/decal/cleanable/dirt, -/obj/structure/cable, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "woK" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -89559,13 +89713,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/starboard) -"wsJ" = ( -/obj/machinery/cryo_cell{ - dir = 8 - }, -/obj/machinery/status_display/ai/directional/south, -/turf/open/floor/iron/dark/textured_large, -/area/station/medical/cryo) "wsN" = ( /obj/machinery/door/airlock/command{ name = "Research Division Server Room" @@ -89736,6 +89883,19 @@ }, /turf/open/floor/iron/white, /area/station/science/ordnance/storage) +"wuU" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/firealarm/directional/east, +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/machinery/light/small/directional/east, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/iron, +/area/station/hallway/primary/central/fore) "wuV" = ( /obj/structure/fireaxecabinet/directional/south, /obj/effect/turf_decal/tile/blue/half/contrasted, @@ -89964,11 +90124,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central/fore) -"wxL" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "wyh" = ( /obj/structure/disposalpipe/segment{ dir = 10 @@ -90346,14 +90501,6 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/department/engine/atmos) -"wCA" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "wCB" = ( /obj/machinery/atmospherics/pipe/smart/simple/scrubbers/visible, /obj/effect/turf_decal/stripes/line{ @@ -91932,14 +92079,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/security/lockers) -"xaN" = ( -/obj/structure/cable, -/obj/effect/turf_decal/bot, -/obj/structure/table, -/obj/item/storage/medkit/regular, -/obj/machinery/power/apc/auto_name/directional/west, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "xaP" = ( /obj/effect/turf_decal/tile/neutral{ dir = 8 @@ -93982,6 +94121,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 }, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/port) "xzO" = ( @@ -95071,6 +95211,13 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/ai) +"xMZ" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/cargo/sorting) "xNe" = ( /obj/structure/lattice, /obj/structure/grille/broken, @@ -95230,7 +95377,7 @@ /obj/structure/disposalpipe/segment{ dir = 10 }, -/mob/living/simple_animal/sloth/citrus, +/mob/living/basic/sloth/citrus, /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, /area/station/command/heads_quarters/qm) @@ -95626,6 +95773,13 @@ /obj/structure/barricade/wooden, /turf/open/floor/plating, /area/station/service/abandoned_gambling_den) +"xVv" = ( +/obj/effect/turf_decal/tile/purple/half/contrasted{ + dir = 4 + }, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "xVI" = ( /obj/structure/rack, /obj/item/analyzer, @@ -96173,15 +96327,6 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron, /area/station/science/robotics/mechbay) -"ydr" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "ydE" = ( /obj/structure/chair/stool/directional/south, /obj/effect/decal/cleanable/dirt, @@ -96571,14 +96716,6 @@ }, /turf/open/floor/iron/white, /area/station/science/lab) -"yiG" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/obj/effect/turf_decal/tile/purple/half/contrasted, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "yiK" = ( /obj/item/kirbyplants/organic/plant21, /obj/effect/turf_decal/delivery, @@ -119009,7 +119146,7 @@ uiP vkg wlS vQj -ntU +sjJ cJX fhr kTd @@ -121640,7 +121777,7 @@ vSX nEc tFP oMV -nVQ +sSx cHU eKz qel @@ -127565,7 +127702,7 @@ bvd wJJ wEI dnV -tTg +aHw gFO qQM isR @@ -136786,8 +136923,8 @@ uNY squ pEU cwh -riZ -pTz +fCm +giO cwh cwh udd @@ -138788,7 +138925,7 @@ hoC yfI bGf kGo -nXf +sCW xhW ygL xhW @@ -139541,7 +139678,7 @@ kRn kjl lDi lDi -eKS +sLg bqv hDZ bfT @@ -139629,9 +139766,9 @@ cwe ltS cwe oDE -taR +fUr bcj -wsJ +pDy oDE ajY tJh @@ -139811,7 +139948,7 @@ mOe yhh liD mZU -jUy +whb uBZ pso sqW @@ -140328,8 +140465,8 @@ gLz xhW axz fOz -fUl -jCR +rAl +bkr yfo qLp pcx @@ -140585,14 +140722,14 @@ ohH xhW xhW nPo -kGo -nPo -xhW -xhW -xhW -xhW -jjK -jtE +xMZ +cGV +cGV +cGV +cGV +cGV +uBd +wuU vPp tJT qzY @@ -140840,14 +140977,14 @@ uSp oSv cFz rWo -ctR -ydr -gDE -dsq -atk -ohR -xaN -tpZ +qko +vNV +pxS +fbu +mlF +qsF +jKY +cGV lDY tpZ kOj @@ -141063,7 +141200,7 @@ fTh egs vno rJN -tLW +lUW pGy vno kvs @@ -141096,16 +141233,16 @@ qaF tQW hQj uzM -fsg -eIA -dtp -cQO -wml -cQO -nTw -lBB -tpZ -dri +aPD +stf +llj +ftS +fbu +mDm +vDj +cwd +cGV +qmT tpZ aaa aad @@ -141353,16 +141490,16 @@ rbV qLg uTu tQP -fnN -mcK -ltB -wCA -nsI -cze -ihc -bNi -qyX -vzy +rmH +toy +izj +fAj +pUs +okN +oAV +vId +cGV +eFU tpZ aaa lhY @@ -141611,15 +141748,15 @@ fya cSK pok rWo -llJ -fCb -vyF -dih -vQT -yiG -oea -tpZ -nos +uND +kKx +dux +cGV +nEE +cyc +rQF +cGV +eFU tpZ aad lhY @@ -141868,15 +142005,15 @@ fKA krp krp aJE -kzi -fCb -fZz -oml -qyO -eld -oWV -tpZ -nro +mtL +tcB +rWo +cGV +cGV +cGV +cGV +cGV +jRc tpZ aaa lhY @@ -142125,15 +142262,15 @@ jmp iWR gkP krp -gdD -iWJ -fJm -oml -ksL -sxu -aSj +llJ +ljQ +guj +eYt +nhj +owZ +bLN tpZ -gUe +eFU tpZ aaa lhY @@ -142382,15 +142519,15 @@ xPf xZC aiF aJE -snh -dIz -cQO -wxL -cQO -grT -aLg -tpZ -dcA +jCu +rUi +kTs +sgK +iio +gco +hkn +qyX +cwK tpZ aaa lhY @@ -142639,12 +142776,12 @@ osw qZD qrG aJE -tQr -gGM -ksL -cQO -cQO -uAH +dPC +usJ +iXd +elO +hzs +uOk bhJ tpZ tpZ @@ -142896,12 +143033,12 @@ uQZ xhJ vMd tgX -fwD -dRf -ofM -woJ -aWe -rKu +jfO +jBM +tNn +xVv +dXs +rgC tDD rWo aad @@ -153248,7 +153385,7 @@ aaa aaa qYo kUH -dVe +yhJ yhJ vVc vVc diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 5ae6d741a2a02b..bdde1b185ee3cc 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -1,4 +1,12 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aaf" = ( +/obj/structure/table/glass, +/obj/machinery/microwave/engineering/cell_included, +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/white, +/area/station/medical/break_room) "aak" = ( /obj/structure/stairs/south, /obj/structure/railing{ @@ -237,6 +245,13 @@ /obj/structure/cable, /turf/open/floor/iron, /area/mine/production) +"afn" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "afp" = ( /obj/machinery/air_sensor/nitrogen_tank, /turf/open/floor/engine/n2, @@ -968,6 +983,12 @@ }, /turf/open/floor/iron, /area/station/command/bridge) +"aqK" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/turf/open/floor/plating, +/area/station/maintenance/aft/lesser) "aqQ" = ( /obj/structure/table, /obj/item/stack/package_wrap, @@ -1032,6 +1053,12 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"arO" = ( +/obj/effect/turf_decal/tile/blue, +/obj/machinery/light/directional/south, +/obj/structure/extinguisher_cabinet/directional/south, +/turf/open/floor/iron, +/area/station/hallway/primary/starboard) "arT" = ( /obj/machinery/computer/security/labor{ dir = 4 @@ -1292,6 +1319,14 @@ }, /turf/open/floor/wood, /area/station/hallway/secondary/service) +"auX" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/maintenance/department/chapel) "avb" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, @@ -1697,11 +1732,14 @@ "aBx" = ( /obj/effect/decal/cleanable/plasma, /obj/effect/landmark/blobstart, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) "aBQ" = ( /obj/effect/landmark/blobstart, /obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron, /area/station/maintenance/port/aft) "aBR" = ( @@ -2789,15 +2827,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/primary/central) -"aTJ" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 4; - id = "pharmacy_shutters"; - name = "Pharmacy Shutters" - }, -/turf/open/floor/plating, -/area/station/medical/pharmacy) "aTT" = ( /obj/structure/closet/toolcloset, /obj/effect/turf_decal/tile/yellow/half/contrasted, @@ -2960,6 +2989,13 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) +"aVE" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 4 + }, +/obj/item/radio/intercom/directional/east, +/turf/open/floor/iron/dark, +/area/station/cargo/miningdock) "aVF" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /obj/effect/turf_decal/tile/red{ @@ -3385,6 +3421,7 @@ dir = 4 }, /obj/effect/mapping_helpers/airlock/access/any/science/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "bcT" = ( @@ -3912,6 +3949,14 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/aisat/service) +"bkw" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/maintenance/starboard/upper) "bkC" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -4450,6 +4495,9 @@ }, /turf/open/floor/iron/dark, /area/mine/storage) +"bsx" = ( +/turf/closed/wall, +/area/station/bitrunning/den) "bsG" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/research/glass{ @@ -5212,20 +5260,6 @@ /obj/item/storage/box/monkeycubes, /turf/open/floor/iron, /area/station/science/xenobiology) -"bCM" = ( -/obj/machinery/requests_console/directional/north{ - department = "Cargo Bay"; - name = "Cargo Bay Requests Console" - }, -/obj/effect/mapping_helpers/requests_console/supplies, -/obj/structure/table, -/obj/item/hand_labeler, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/item/folder/yellow, -/turf/open/floor/iron, -/area/station/cargo/storage) "bCQ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, @@ -5677,6 +5711,11 @@ /obj/effect/turf_decal/tile/blue/half/contrasted, /turf/open/floor/iron, /area/station/command/bridge) +"bIS" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "bIU" = ( /obj/structure/table, /obj/item/stack/sheet/glass/fifty, @@ -6159,6 +6198,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/construction) +"bPy" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "bPz" = ( /obj/effect/landmark/blobstart, /turf/open/floor/plating, @@ -6813,6 +6858,11 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"cat" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/solars/port/fore) "caC" = ( /obj/machinery/door/window/right/directional/south{ dir = 8; @@ -7184,12 +7234,6 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) -"cfR" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "cfS" = ( /obj/item/clothing/suit/costume/snowman{ name = "Man of Snow" @@ -8209,31 +8253,6 @@ }, /turf/open/floor/circuit, /area/station/ai_monitored/turret_protected/ai) -"cvp" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/firedoor, -/obj/machinery/door/window/right/directional/east{ - dir = 8; - name = "Pharmacy Desk"; - req_access = list("pharmacy") - }, -/obj/item/folder/white{ - pixel_x = -5 - }, -/obj/item/pen{ - pixel_x = -5 - }, -/obj/structure/desk_bell{ - pixel_x = 7 - }, -/obj/effect/turf_decal/tile/yellow/fourcorners, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 4; - id = "pharmacy_shutters"; - name = "Pharmacy Shutters" - }, -/turf/open/floor/iron, -/area/station/medical/pharmacy) "cvq" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /obj/effect/turf_decal/tile/red/half/contrasted{ @@ -8558,6 +8577,13 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) +"czx" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "czz" = ( /obj/machinery/computer/pod/old/mass_driver_controller/trash{ pixel_x = -24; @@ -8755,6 +8781,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/aft/greater) +"cBw" = ( +/obj/effect/spawner/random/structure/steam_vent, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/department/medical/morgue) "cBD" = ( /obj/effect/turf_decal/siding/wood/corner{ dir = 4 @@ -8772,7 +8803,7 @@ /turf/open/floor/iron, /area/station/security/prison/workout) "cBJ" = ( -/obj/item/gun/energy/laser/practice{ +/obj/item/gun/energy/laser/carbine/practice{ pixel_y = 5 }, /obj/item/gun/energy/laser/practice, @@ -9403,16 +9434,6 @@ /obj/effect/mapping_helpers/airlock/access/all/security/brig, /turf/open/floor/iron/dark/textured, /area/station/security/lockers) -"cLI" = ( -/obj/structure/rack, -/obj/item/shovel{ - pixel_x = -5 - }, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "cLJ" = ( /obj/structure/table/wood, /obj/item/paper{ @@ -9575,6 +9596,10 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) +"cNG" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/plating, +/area/station/maintenance/aft/lesser) "cNI" = ( /obj/machinery/door/poddoor/preopen{ id = "xenobio7"; @@ -10044,6 +10069,14 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/mine/laborcamp) +"cWa" = ( +/obj/machinery/light_switch/directional/west, +/obj/effect/decal/cleanable/cobweb, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "cWq" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /obj/effect/turf_decal/tile/green/half/contrasted{ @@ -10051,11 +10084,6 @@ }, /turf/open/floor/iron, /area/station/security/prison/garden) -"cWr" = ( -/obj/effect/landmark/start/shaft_miner, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "cWG" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -10686,6 +10714,30 @@ }, /turf/open/floor/glass/reinforced, /area/station/science/xenobiology) +"dff" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/machinery/door/window/right/directional/east{ + name = "Pharmacy Desk"; + req_access = list("pharmacy") + }, +/obj/item/folder/white{ + pixel_x = -5 + }, +/obj/item/pen{ + pixel_x = -5 + }, +/obj/structure/desk_bell{ + pixel_x = 7 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "pharmacy_shutters"; + name = "Pharmacy Shutters"; + dir = 4 + }, +/turf/open/floor/iron, +/area/station/medical/pharmacy) "dfq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/cyan/visible, /turf/closed/wall/r_wall, @@ -10720,6 +10772,12 @@ }, /turf/open/floor/plating/snowed/smoothed/icemoon, /area/icemoon/underground/explored) +"dgf" = ( +/obj/machinery/firealarm/directional/north, +/obj/structure/chair, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron, +/area/station/cargo/storage) "dgl" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 @@ -11701,6 +11759,12 @@ dir = 1 }, /area/mine/eva) +"dva" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "dvf" = ( /obj/machinery/light/directional/south, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -12020,6 +12084,20 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/engineering/lobby) +"dAq" = ( +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/plating, +/area/station/maintenance/aft/lesser) +"dAt" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/light_switch/directional/west, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "dAx" = ( /obj/machinery/hydroponics/soil{ pixel_y = 8 @@ -12280,11 +12358,6 @@ /obj/effect/turf_decal/tile/blue/half/contrasted, /turf/open/floor/iron, /area/station/command/bridge) -"dEJ" = ( -/obj/machinery/light_switch/directional/north, -/obj/machinery/light/directional/north, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "dEQ" = ( /obj/machinery/camera/directional/east{ c_tag = "Public Mining Ladder" @@ -12914,6 +12987,16 @@ /obj/effect/turf_decal/tile/dark_blue/diagonal_edge, /turf/open/floor/iron/dark/diagonal, /area/station/engineering/atmos/storage) +"dPn" = ( +/obj/structure/rack, +/obj/item/pickaxe{ + pixel_x = 5 + }, +/obj/item/shovel{ + pixel_x = -5 + }, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "dPy" = ( /obj/machinery/camera/directional/west{ c_tag = "Xenobiology Kill Chamber"; @@ -12936,6 +13019,20 @@ /obj/effect/mapping_helpers/airlock/access/any/service/maintenance, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"dPW" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/effect/landmark/start/bitrunner, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "dPX" = ( /obj/structure/sign/warning/docking/directional/east, /obj/effect/turf_decal/weather/snow/corner{ @@ -13191,6 +13288,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/freezer, /area/mine/laborcamp) +"dUK" = ( +/obj/machinery/netpod, +/obj/machinery/light/small/directional/south, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "dUL" = ( /obj/machinery/door/poddoor/preopen{ id = "maint1" @@ -13219,6 +13321,15 @@ /obj/structure/sign/poster/random/directional/east, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) +"dVs" = ( +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/machinery/quantum_server, +/obj/effect/decal/cleanable/oil/streak, +/turf/open/floor/iron/dark/smooth_corner{ + dir = 4 + }, +/area/station/bitrunning/den) "dVt" = ( /obj/structure/chair/stool/directional/west, /turf/open/floor/iron/checker, @@ -13538,6 +13649,7 @@ "eae" = ( /obj/structure/sign/poster/contraband/random/directional/north, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/port/greater) "eag" = ( @@ -13615,6 +13727,7 @@ /obj/effect/turf_decal/trimline/green/filled/line{ dir = 8 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "ebB" = ( @@ -14619,6 +14732,7 @@ "erU" = ( /obj/effect/landmark/generic_maintenance_landmark, /obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/plating, /area/station/maintenance/department/crew_quarters/bar) "erY" = ( @@ -14879,6 +14993,12 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/station/maintenance/department/medical/central) +"ewq" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/cargo/storage) "ewz" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/structure/window/reinforced/spawner/directional/north, @@ -15078,6 +15198,10 @@ /obj/item/toy/sword, /turf/open/floor/iron/checker, /area/station/maintenance/port/fore) +"eAe" = ( +/obj/structure/chair, +/turf/open/floor/iron, +/area/station/cargo/storage) "eAg" = ( /obj/effect/spawner/structure/window/reinforced/tinted, /turf/closed/wall, @@ -15926,13 +16050,6 @@ }, /turf/open/floor/iron/white, /area/station/science/research) -"eNM" = ( -/obj/machinery/cryo_cell, -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/iron/dark/textured, -/area/station/medical/cryo) "eNQ" = ( /obj/structure/sign/warning/vacuum/directional/south, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -16118,6 +16235,8 @@ /turf/open/floor/iron, /area/station/command/heads_quarters/hop) "eSg" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/solars/port/fore) "eSn" = ( @@ -16757,6 +16876,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/science/ordnance) +"fcs" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/solars/port/aft) "fcu" = ( /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/chair, @@ -16833,6 +16957,24 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/department/chapel) +"fdO" = ( +/obj/structure/table/glass, +/obj/item/stack/cable_coil, +/obj/item/stack/cable_coil, +/obj/item/screwdriver{ + pixel_x = 2; + pixel_y = 11 + }, +/obj/item/grenade/chem_grenade, +/obj/item/grenade/chem_grenade, +/obj/item/grenade/chem_grenade, +/obj/item/grenade/chem_grenade, +/obj/effect/turf_decal/tile/yellow/half/contrasted{ + dir = 1 + }, +/obj/structure/extinguisher_cabinet/directional/north, +/turf/open/floor/iron/white, +/area/station/medical/pharmacy) "fdP" = ( /obj/structure/bonfire, /obj/item/melee/roastingstick, @@ -16864,6 +17006,11 @@ /obj/item/seeds/apple, /turf/open/floor/iron, /area/mine/laborcamp) +"feB" = ( +/obj/machinery/airalarm/directional/east, +/obj/effect/landmark/event_spawn, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "feJ" = ( /turf/closed/wall/r_wall, /area/station/ai_monitored/security/armory/upper) @@ -17026,6 +17173,16 @@ }, /turf/open/floor/iron, /area/station/engineering/lobby) +"fib" = ( +/obj/machinery/smartfridge/chemistry/preloaded, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "pharmacy_shutters2"; + name = "Pharmacy Shutters"; + dir = 4 + }, +/turf/open/floor/iron/white, +/area/station/medical/pharmacy) "fij" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -17421,6 +17578,13 @@ }, /turf/open/floor/iron/dark, /area/station/medical/storage) +"foo" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/aft/lesser) "foy" = ( /obj/item/radio/intercom/directional/south, /obj/machinery/vending/wardrobe/science_wardrobe, @@ -17576,6 +17740,10 @@ dir = 8 }, /area/station/medical/chem_storage) +"fqY" = ( +/obj/machinery/light/small/directional/north, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "frd" = ( /obj/structure/railing/corner{ dir = 1 @@ -17662,6 +17830,19 @@ }, /turf/open/floor/iron/dark/textured, /area/station/security/range) +"fss" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "fsv" = ( /turf/open/floor/iron, /area/station/hallway/secondary/entry) @@ -17716,6 +17897,28 @@ /obj/item/storage/box/prisoner, /turf/open/floor/iron/showroomfloor, /area/station/security/processing) +"ftB" = ( +/obj/machinery/camera{ + c_tag = "Medbay Pharmacy"; + dir = 9; + network = list("ss13","medbay") + }, +/obj/effect/turf_decal/tile/yellow/half/contrasted{ + dir = 1 + }, +/obj/machinery/shower/directional/south, +/obj/structure/railing{ + dir = 4 + }, +/obj/structure/fluff{ + desc = "What, you think the water just magically soaks into the metallic flooring?"; + icon = 'icons/obj/mining_zones/survival_pod.dmi'; + icon_state = "fan_tiny"; + name = "shower drain" + }, +/obj/effect/turf_decal/stripes/white/end, +/turf/open/floor/iron/white, +/area/station/medical/pharmacy) "ftJ" = ( /obj/structure/table/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ @@ -17983,7 +18186,7 @@ /area/station/maintenance/starboard/aft) "fya" = ( /obj/structure/cable, -/mob/living/simple_animal/sloth/paperwork, +/mob/living/basic/sloth/paperwork, /turf/open/floor/iron, /area/station/cargo/storage) "fyc" = ( @@ -18067,6 +18270,9 @@ "fzA" = ( /obj/effect/spawner/random/maintenance, /obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, /turf/open/floor/plating, /area/station/maintenance/port/aft) "fzD" = ( @@ -18233,6 +18439,13 @@ }, /turf/open/floor/cult, /area/station/service/chapel/office) +"fCA" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/solars/port/aft) "fCM" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -18605,6 +18818,7 @@ /obj/effect/mapping_helpers/airlock/abandoned, /obj/effect/mapping_helpers/airlock/unres, /obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance/departmental, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/aft) "fJd" = ( @@ -18952,6 +19166,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/green/visible, /turf/open/floor/engine, /area/station/engineering/supermatter/room) +"fNx" = ( +/obj/structure/cable, +/obj/machinery/computer/quantum_console, +/turf/open/floor/iron/dark/smooth_corner, +/area/station/bitrunning/den) "fNy" = ( /obj/structure/rack, /obj/item/clothing/suit/hooded/wintercoat{ @@ -19074,6 +19293,13 @@ /obj/structure/cable/layer3, /turf/open/floor/iron/grimy, /area/station/ai_monitored/turret_protected/aisat_interior) +"fQx" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 8 + }, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "fQz" = ( /obj/effect/landmark/start/hangover, /turf/open/floor/carpet, @@ -19711,6 +19937,11 @@ }, /turf/open/floor/iron, /area/station/command/gateway) +"gbf" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "gbh" = ( /obj/machinery/light/small/directional/south, /turf/open/floor/engine, @@ -19964,6 +20195,13 @@ /obj/effect/turf_decal/siding/yellow, /turf/open/floor/iron, /area/station/engineering/storage) +"gfu" = ( +/obj/machinery/light/small/directional/east, +/obj/machinery/computer/order_console/bitrunning{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "gfw" = ( /obj/machinery/light/small/directional/west, /obj/structure/table, @@ -20945,13 +21183,6 @@ /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/iron, /area/station/science/xenobiology) -"gvZ" = ( -/obj/machinery/rnd/bepis, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "gwm" = ( /obj/machinery/door/firedoor/heavy, /turf/open/floor/iron/white/side{ @@ -20992,17 +21223,6 @@ }, /turf/open/floor/iron/cafeteria, /area/station/commons/dorms/laundry) -"gwB" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/mining{ - name = "Mining Dock" - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "gwJ" = ( /obj/effect/turf_decal/stripes/asteroid/line{ dir = 5 @@ -21127,6 +21347,11 @@ }, /turf/open/floor/grass, /area/station/service/hydroponics) +"gyC" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/aft/lesser) "gyH" = ( /obj/machinery/light/directional/north, /obj/machinery/vending/coffee, @@ -21706,6 +21931,8 @@ /turf/open/floor/iron/white, /area/station/medical/treatment_center) "gHv" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/fore) "gHA" = ( @@ -21989,6 +22216,10 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/wood, /area/station/maintenance/aft/greater) +"gMV" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/bitrunning/den) "gMZ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -22023,6 +22254,25 @@ /obj/item/reagent_containers/dropper, /turf/open/floor/iron/cafeteria, /area/station/science/lab) +"gNA" = ( +/obj/structure/table/reinforced, +/obj/item/folder/white, +/obj/item/pen, +/obj/machinery/door/firedoor, +/obj/machinery/door/window/right/directional/east{ + base_state = "left"; + icon_state = "left"; + name = "Pharmacy Desk"; + req_access = list("pharmacy") + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "pharmacy_shutters2"; + name = "Pharmacy Shutters"; + dir = 4 + }, +/turf/open/floor/iron, +/area/station/medical/pharmacy) "gNH" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 @@ -23136,6 +23386,11 @@ /obj/effect/turf_decal/tile/blue/half/contrasted, /turf/open/floor/iron, /area/station/command/bridge) +"heW" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "heX" = ( /obj/structure/cable, /turf/open/floor/wood, @@ -24204,13 +24459,6 @@ /obj/effect/turf_decal/tile/blue/full, /turf/open/floor/iron/large, /area/station/medical/treatment_center) -"hxC" = ( -/obj/structure/rack, -/obj/item/pickaxe{ - pixel_x = 5 - }, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "hxE" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -24753,6 +25001,7 @@ /obj/structure/cable, /obj/structure/sign/warning/gas_mask/directional/south, /obj/machinery/light/small/dim/directional/south, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/aft) "hHu" = ( @@ -26666,6 +26915,12 @@ /obj/effect/spawner/random/structure/steam_vent, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) +"imu" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/plating, +/area/station/maintenance/aft/lesser) "imy" = ( /obj/machinery/airalarm/directional/east, /turf/open/floor/iron/dark, @@ -26716,6 +26971,7 @@ }, /obj/structure/cable, /obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/solars/port/fore) "inE" = ( @@ -27292,11 +27548,6 @@ "iwC" = ( /turf/closed/wall/r_wall, /area/station/hallway/primary/central/fore) -"iwD" = ( -/obj/structure/cable, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "iwO" = ( /obj/structure/closet/secure_closet/personal{ anchored = 1 @@ -28368,15 +28619,6 @@ dir = 1 }, /area/station/service/hydroponics) -"iNu" = ( -/obj/structure/table, -/obj/item/paper_bin{ - pixel_x = 1; - pixel_y = 9 - }, -/obj/machinery/mining_weather_monitor/directional/west, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "iNy" = ( /obj/structure/chair{ dir = 4 @@ -28610,6 +28852,7 @@ /obj/effect/mapping_helpers/airlock/unres{ dir = 4 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) "iRo" = ( @@ -29407,6 +29650,7 @@ /area/station/hallway/secondary/exit/departure_lounge) "jdP" = ( /obj/machinery/duct, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) "jdQ" = ( @@ -29620,12 +29864,6 @@ /obj/structure/tank_holder/extinguisher, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) -"jiK" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "jjk" = ( /obj/structure/lattice/catwalk, /obj/structure/railing{ @@ -30690,6 +30928,11 @@ /obj/structure/flora/bush/jungle/a/style_random, /turf/open/floor/grass, /area/station/service/hydroponics) +"jBr" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "jBB" = ( /obj/structure/kitchenspike, /turf/open/floor/plating/snowed/coldroom, @@ -31468,6 +31711,11 @@ }, /turf/open/floor/carpet/blue, /area/station/hallway/secondary/entry) +"jNS" = ( +/obj/effect/mapping_helpers/burnt_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "jNZ" = ( /obj/effect/turf_decal/weather/snow/corner{ dir = 9 @@ -33352,6 +33600,15 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/ai_monitored/turret_protected/aisat/maint) +"kpb" = ( +/obj/machinery/disposal/bin, +/obj/structure/disposalpipe/trunk, +/obj/effect/turf_decal/tile/yellow/half/contrasted{ + dir = 1 + }, +/obj/machinery/firealarm/directional/north, +/turf/open/floor/iron/white, +/area/station/medical/pharmacy) "kpf" = ( /obj/effect/turf_decal/tile/neutral/diagonal_edge, /obj/machinery/oven/range, @@ -33374,6 +33631,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 }, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/port/fore) "kpC" = ( @@ -33571,6 +33829,13 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/central) +"krx" = ( +/obj/machinery/cryo_cell, +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/turf/open/floor/iron/dark/textured, +/area/station/medical/cryo) "kry" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -33755,6 +34020,8 @@ /area/station/maintenance/department/medical/central) "ktC" = ( /obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/smooth, /area/station/maintenance/fore/lesser) "ktD" = ( @@ -34168,14 +34435,6 @@ /obj/effect/spawner/random/structure/grille, /turf/open/floor/plating, /area/station/maintenance/department/chapel) -"kAq" = ( -/obj/machinery/cryo_cell, -/obj/effect/turf_decal/stripes/line{ - dir = 6 - }, -/obj/item/radio/intercom/directional/east, -/turf/open/floor/iron/dark/textured, -/area/station/medical/cryo) "kAC" = ( /obj/structure/reagent_dispensers/watertank, /obj/effect/decal/cleanable/cobweb/cobweb2, @@ -34482,6 +34741,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/security/prison/visit) +"kEo" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/plating, +/area/station/maintenance/fore) "kEq" = ( /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, @@ -34800,10 +35064,6 @@ /obj/structure/sign/poster/official/random/directional/north, /turf/open/floor/iron/smooth, /area/mine/laborcamp/security) -"kJz" = ( -/obj/machinery/firealarm/directional/east, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "kJI" = ( /obj/structure/transit_tube/station/reverse, /turf/open/floor/plating, @@ -35019,6 +35279,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/medical/cryo) +"kNg" = ( +/obj/machinery/smartfridge/chemistry/preloaded, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "pharmacy_shutters"; + name = "Pharmacy Shutters"; + dir = 4 + }, +/turf/open/floor/iron/white, +/area/station/medical/pharmacy) "kNi" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -35041,6 +35311,13 @@ /obj/structure/cable, /turf/open/floor/iron/dark/telecomms, /area/station/tcommsat/server) +"kNz" = ( +/obj/structure/cable, +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/fore) "kNA" = ( /obj/structure/disposalpipe/segment, /obj/structure/girder, @@ -35260,6 +35537,12 @@ /obj/structure/sign/warning/bodysposal/directional/south, /turf/open/floor/iron/white, /area/station/medical/surgery/aft) +"kQL" = ( +/obj/structure/cable, +/obj/structure/chair, +/obj/effect/landmark/start/shaft_miner, +/turf/open/floor/iron, +/area/station/cargo/storage) "kQM" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 5 @@ -35333,6 +35616,7 @@ }, /obj/structure/cable, /obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/solars/port/aft) "kRw" = ( @@ -35543,6 +35827,8 @@ /area/mine/eva) "kUG" = ( /obj/item/trash/popcorn, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/plating, /area/station/maintenance/fore) "kUJ" = ( @@ -35606,6 +35892,12 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/station/engineering/lobby) +"kVW" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/plating, +/area/station/maintenance/department/medical/central) "kWa" = ( /obj/structure/fireplace, /turf/open/floor/plating, @@ -35894,6 +36186,14 @@ "kZu" = ( /turf/closed/wall, /area/mine/production) +"kZw" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "kZz" = ( /obj/machinery/computer/order_console/cook{ dir = 1 @@ -36247,6 +36547,7 @@ "lge" = ( /obj/structure/sign/poster/contraband/random/directional/east, /obj/machinery/light/small/dim/directional/west, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/aft) "lgk" = ( @@ -36587,6 +36888,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/science/xenobiology) +"llC" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/wood, +/area/station/maintenance/port/aft) "llD" = ( /obj/structure/table/wood, /obj/item/paper_bin/carbon, @@ -36709,6 +37015,11 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/commons/storage/tools) +"lnd" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/port/greater) "lnk" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -36826,6 +37137,10 @@ "loQ" = ( /obj/effect/turf_decal/trimline/green/filled/corner, /obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "loV" = ( @@ -36920,13 +37235,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"lqt" = ( -/obj/structure/table, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "lqz" = ( /obj/structure/cable, /turf/closed/wall, @@ -36971,6 +37279,7 @@ /obj/effect/decal/cleanable/insectguts, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/port/aft) "lqU" = ( @@ -37058,6 +37367,18 @@ }, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/aisat/service) +"lti" = ( +/obj/structure/table, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/machinery/requests_console/directional/west{ + department = "Mining"; + name = "Mining Requests Console" + }, +/obj/effect/mapping_helpers/requests_console/supplies, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "ltk" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 8 @@ -37066,11 +37387,13 @@ /obj/effect/mapping_helpers/airlock/access/all/engineering/external, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) -"lts" = ( -/obj/structure/extinguisher_cabinet/directional/south, -/obj/effect/turf_decal/tile/blue, -/turf/open/floor/iron, -/area/station/hallway/primary/starboard) +"ltl" = ( +/obj/machinery/airalarm/directional/west, +/obj/effect/landmark/start/bitrunner, +/obj/machinery/light/small/directional/south, +/obj/effect/decal/cleanable/robot_debris, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "ltE" = ( /obj/structure/closet/crate/freezer, /obj/item/reagent_containers/blood/random, @@ -37123,6 +37446,10 @@ /turf/open/floor/iron/white/side, /area/station/science/ordnance/office) "luK" = ( +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/aft) "lva" = ( @@ -38927,6 +39254,9 @@ /area/station/maintenance/starboard/aft) "lXm" = ( /obj/item/trash/pistachios, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, /turf/open/floor/plating, /area/station/maintenance/aft/greater) "lXn" = ( @@ -39308,14 +39638,6 @@ /obj/structure/cable, /turf/open/floor/wood/parquet, /area/station/service/bar/atrium) -"meF" = ( -/obj/machinery/chem_dispenser, -/obj/structure/window/reinforced/spawner/directional/west, -/obj/machinery/light/directional/north, -/obj/structure/sign/warning/no_smoking/directional/north, -/obj/effect/turf_decal/tile/yellow/full, -/turf/open/floor/iron/white/smooth_large, -/area/station/medical/pharmacy) "meG" = ( /obj/item/kirbyplants/random, /obj/structure/cable, @@ -40178,6 +40500,11 @@ /obj/machinery/requests_console/auto_name/directional/south, /turf/open/floor/plating, /area/station/engineering/storage/tech) +"mtm" = ( +/obj/effect/spawner/random/structure/steam_vent, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/aft/lesser) "mtn" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -40278,6 +40605,7 @@ /obj/machinery/door/airlock/maintenance, /obj/effect/mapping_helpers/airlock/abandoned, /obj/effect/mapping_helpers/airlock/access/any/science/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "mvl" = ( @@ -40286,6 +40614,7 @@ "mvp" = ( /obj/machinery/space_heater, /obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) "mvv" = ( @@ -40354,11 +40683,6 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) -"mwF" = ( -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "mwQ" = ( /obj/structure/tank_holder/extinguisher, /turf/open/floor/plating, @@ -40770,19 +41094,6 @@ /obj/structure/cable/layer3, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/aisat/hallway) -"mEi" = ( -/obj/machinery/firealarm/directional/north, -/obj/structure/tank_holder/extinguisher, -/obj/machinery/camera{ - c_tag = "Medbay Pharmacy"; - dir = 9; - network = list("ss13","medbay") - }, -/obj/effect/turf_decal/tile/yellow/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/medical/pharmacy) "mEv" = ( /obj/structure/rack, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -41050,10 +41361,6 @@ dir = 4 }, /area/station/service/chapel) -"mJv" = ( -/obj/item/paper/fluff/ids_for_dummies, -/turf/open/genturf, -/area/icemoon/underground/unexplored/rivers/deep) "mJD" = ( /obj/structure/cable, /obj/effect/turf_decal/tile/neutral{ @@ -41443,10 +41750,7 @@ /obj/structure/railing{ dir = 1 }, -/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4{ - color = "#0000ff"; - name = "Supply multi deck pipe adapter" - }, +/obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) "mRG" = ( @@ -41583,6 +41887,7 @@ /obj/effect/mapping_helpers/airlock/abandoned, /obj/effect/mapping_helpers/airlock/unres, /obj/effect/mapping_helpers/airlock/access/any/science/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "mUz" = ( @@ -41803,6 +42108,7 @@ dir = 4 }, /obj/effect/mapping_helpers/airlock/access/any/medical/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) "mXi" = ( @@ -41827,7 +42133,7 @@ "mXq" = ( /obj/structure/table, /obj/machinery/recharger, -/obj/item/gun/energy/laser/practice, +/obj/item/gun/energy/laser/carbine/practice, /obj/item/gun/energy/laser/practice, /obj/machinery/newscaster/directional/south, /turf/open/floor/iron, @@ -41878,6 +42184,11 @@ }, /turf/open/floor/plating, /area/station/hallway/secondary/entry) +"mYc" = ( +/obj/effect/mapping_helpers/burnt_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/port/aft) "mYd" = ( /obj/machinery/air_sensor/ordnance_burn_chamber, /turf/open/floor/engine/vacuum, @@ -41981,15 +42292,6 @@ /obj/machinery/light/built/directional/east, /turf/open/floor/iron/white, /area/station/maintenance/port/fore) -"mZt" = ( -/obj/structure/closet/crate, -/obj/item/radio/intercom/directional/east, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/machinery/light/small/directional/north, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "mZu" = ( /obj/structure/table/glass, /obj/item/cultivator, @@ -42077,6 +42379,15 @@ /obj/machinery/light/directional/north, /turf/open/floor/iron, /area/station/engineering/storage) +"naO" = ( +/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ + dir = 8 + }, +/obj/machinery/computer/security/mining{ + dir = 1 + }, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "naP" = ( /obj/structure/chair/comfy/black{ dir = 4 @@ -42095,15 +42406,6 @@ "naX" = ( /turf/closed/wall/mineral/iron, /area/station/engineering/atmos/mix) -"nbd" = ( -/obj/machinery/disposal/bin, -/obj/structure/disposalpipe/trunk, -/obj/item/radio/intercom/directional/north, -/obj/effect/turf_decal/tile/yellow/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/medical/pharmacy) "nbi" = ( /obj/item/radio/intercom/directional/west, /obj/effect/turf_decal/tile/yellow{ @@ -42674,6 +42976,7 @@ name = "Blast Door Control A"; pixel_y = -6 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) "niC" = ( @@ -42746,6 +43049,14 @@ /obj/effect/spawner/random/trash/mess, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) +"njP" = ( +/obj/machinery/chem_mass_spec, +/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ + dir = 8 + }, +/obj/structure/sign/warning/no_smoking/directional/west, +/turf/open/floor/iron/white, +/area/station/medical/pharmacy) "njT" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -43795,6 +44106,18 @@ }, /turf/closed/wall/r_wall, /area/station/engineering/transit_tube) +"nyB" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 + }, +/obj/machinery/holopad, +/obj/effect/decal/cleanable/oil, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "nyC" = ( /turf/open/floor/iron/dark/smooth_half, /area/station/service/chapel) @@ -44540,7 +44863,6 @@ /turf/open/floor/iron/white, /area/station/medical/medbay/aft) "nIa" = ( -/obj/effect/landmark/generic_maintenance_landmark, /obj/structure/cable, /obj/machinery/light/floor, /turf/open/floor/plating, @@ -44825,6 +45147,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/science/research) +"nMB" = ( +/obj/machinery/door/firedoor, +/obj/machinery/door/airlock/mining{ + name = "Mining Dock" + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, +/turf/open/floor/iron, +/area/station/cargo/storage) "nME" = ( /obj/item/clothing/head/utility/hardhat, /turf/open/floor/plating/snowed/icemoon, @@ -45755,6 +46088,7 @@ /area/station/science/robotics/lab) "oef" = ( /obj/structure/grille/broken, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/aft) "oeh" = ( @@ -45932,6 +46266,10 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/surface/outdoors/nospawn) +"ohM" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/department/medical/morgue) "ohS" = ( /obj/structure/railing{ dir = 8 @@ -46026,6 +46364,7 @@ /area/station/hallway/secondary/entry) "oiH" = ( /obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "oiK" = ( @@ -46154,6 +46493,11 @@ }, /turf/open/floor/iron/dark, /area/station/medical/morgue) +"okg" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/aft) "okk" = ( /obj/structure/cable, /obj/structure/sign/departments/aisat/directional/east, @@ -46775,6 +47119,7 @@ /obj/effect/mapping_helpers/airlock/unres{ dir = 1 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) "osr" = ( @@ -47392,6 +47737,12 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/fore) +"oCl" = ( +/obj/structure/cable, +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/fore) "oCs" = ( /obj/structure/table, /obj/item/toy/figure/virologist{ @@ -48116,6 +48467,7 @@ dir = 9 }, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/starboard/aft) "oNA" = ( @@ -48153,14 +48505,6 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) -"oOa" = ( -/obj/structure/table, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 8 - }, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "oOb" = ( /obj/structure/sign/warning/fire/directional/north, /turf/open/floor/glass/reinforced, @@ -48267,8 +48611,12 @@ /area/station/engineering/lobby) "oQa" = ( /obj/structure/table, -/obj/item/food/cheesiehonkers, /obj/effect/turf_decal/tile/brown/half/contrasted, +/obj/item/storage/box/bandages{ + pixel_y = 6; + pixel_x = -6 + }, +/obj/item/food/cheesiehonkers, /turf/open/floor/iron, /area/station/cargo/office) "oQn" = ( @@ -48611,6 +48959,17 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron/freezer, /area/station/commons/toilet) +"oVf" = ( +/obj/machinery/door/airlock/mining/glass{ + id_tag = "innercargo"; + name = "Bitrunning Den" + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/turf/open/floor/iron, +/area/station/bitrunning/den) "oVt" = ( /obj/machinery/power/apc/auto_name/directional/south, /obj/structure/cable, @@ -48875,6 +49234,7 @@ /obj/effect/mapping_helpers/airlock/unres{ dir = 1 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/crew_quarters/bar) "oYH" = ( @@ -49557,6 +49917,13 @@ }, /turf/open/floor/iron/smooth_large, /area/station/cargo/warehouse) +"piX" = ( +/obj/machinery/camera/directional/north{ + c_tag = "Cargo Bay North" + }, +/obj/machinery/light/directional/north, +/turf/open/floor/iron, +/area/station/cargo/storage) "pja" = ( /obj/structure/rack, /obj/item/pickaxe, @@ -49782,13 +50149,6 @@ /obj/structure/flora/grass/brown/style_random, /turf/open/misc/asteroid/snow/standard_air, /area/station/science/research) -"pnr" = ( -/obj/structure/chair/office{ - dir = 8 - }, -/obj/effect/landmark/start/shaft_miner, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "pnz" = ( /obj/item/radio/intercom/directional/west, /turf/open/floor/iron, @@ -51058,6 +51418,7 @@ "pGM" = ( /obj/structure/girder, /obj/structure/grille, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "pGQ" = ( @@ -51096,6 +51457,7 @@ }, /obj/structure/cable, /obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/fore) "pHy" = ( @@ -51525,6 +51887,12 @@ }, /turf/open/floor/iron/large, /area/station/commons/storage/tools) +"pNM" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/port/aft) "pNO" = ( /obj/machinery/duct, /obj/structure/disposalpipe/segment, @@ -51962,6 +52330,17 @@ }, /turf/open/floor/iron, /area/station/tcommsat/computer) +"pVC" = ( +/obj/machinery/requests_console/directional/north{ + department = "Cargo Bay"; + name = "Cargo Bay Requests Console" + }, +/obj/effect/mapping_helpers/requests_console/supplies, +/obj/structure/table, +/obj/item/hand_labeler, +/obj/item/folder/yellow, +/turf/open/floor/iron, +/area/station/cargo/storage) "pVH" = ( /turf/closed/wall/mineral/wood, /area/station/maintenance/aft/lesser) @@ -52488,6 +52867,8 @@ dir = 1 }, /obj/effect/decal/cleanable/blood/splatter, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron, /area/station/maintenance/starboard/fore) "qeL" = ( @@ -53246,6 +53627,7 @@ /area/station/maintenance/starboard/fore) "qqC" = ( /obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/crew_quarters/bar) "qqJ" = ( @@ -53414,6 +53796,21 @@ /obj/machinery/light/directional/north, /turf/open/misc/asteroid/snow/icemoon, /area/icemoon/underground/explored) +"qtT" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/trimline/brown/corner{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "que" = ( /obj/machinery/camera/directional/south{ c_tag = "Chapel South" @@ -53633,6 +54030,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/chair/stool/directional/south, /obj/effect/mapping_helpers/broken_floor, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) "qxb" = ( @@ -54412,6 +54810,17 @@ /obj/item/cigbutt, /turf/open/floor/wood/large, /area/mine/eva/lower) +"qJJ" = ( +/obj/machinery/firealarm/directional/east, +/obj/structure/table, +/obj/item/paper_bin{ + pixel_x = 1; + pixel_y = 9 + }, +/obj/item/folder/yellow, +/obj/item/pen, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "qJT" = ( /obj/machinery/light/small/directional/south, /turf/open/floor/plating/snowed/icemoon, @@ -54881,12 +55290,6 @@ "qPL" = ( /turf/closed/wall/r_wall, /area/station/hallway/secondary/exit/departure_lounge) -"qPR" = ( -/obj/effect/turf_decal/stripes/corner{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "qPX" = ( /obj/structure/sink/directional/west, /obj/structure/mirror/directional/east, @@ -54973,6 +55376,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/command/meeting_room) +"qRt" = ( +/obj/effect/spawner/random/trash/mess, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/starboard/fore) "qRv" = ( /obj/structure/railing, /obj/structure/marker_beacon/cerulean, @@ -55113,9 +55521,8 @@ /turf/open/floor/plating, /area/station/maintenance/port/aft) "qTe" = ( -/obj/structure/reagent_dispensers/fueltank, -/obj/structure/railing{ - dir = 1 +/obj/structure/railing/corner/end/flip{ + dir = 4 }, /turf/open/floor/plating, /area/station/maintenance/department/medical/central) @@ -55402,6 +55809,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/maintenance/fore/lesser) +"qYc" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/light/small/directional/north, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "qYh" = ( /obj/structure/chair/pew{ dir = 1 @@ -55413,6 +55827,14 @@ /obj/effect/turf_decal/tile/bar/opposingcorners, /turf/open/floor/iron, /area/station/service/bar) +"qYp" = ( +/obj/machinery/chem_dispenser, +/obj/structure/window/reinforced/spawner/directional/west, +/obj/machinery/light/directional/north, +/obj/effect/turf_decal/tile/yellow/full, +/obj/item/radio/intercom/directional/north, +/turf/open/floor/iron/white/smooth_large, +/area/station/medical/pharmacy) "qYw" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -55519,12 +55941,6 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/textured, /area/mine/mechbay) -"qZY" = ( -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/cargo/miningdock) "rab" = ( /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plating, @@ -56290,6 +56706,11 @@ /obj/structure/sign/warning/no_smoking/circle/directional/west, /turf/open/floor/iron/white, /area/station/maintenance/port/fore) +"rmh" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/showroomfloor, +/area/station/maintenance/department/medical/morgue) "rmn" = ( /obj/structure/chair/stool/directional/north, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -56885,8 +57306,9 @@ /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) "rwG" = ( +/obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 1 + dir = 8 }, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) @@ -57193,14 +57615,6 @@ /obj/item/stack/license_plates/empty/fifty, /turf/open/floor/iron/dark/smooth_half, /area/station/security/prison/work) -"rBz" = ( -/obj/machinery/door/airlock/mining/glass{ - name = "Mining Dock" - }, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "rBL" = ( /obj/machinery/light/directional/west, /turf/open/openspace, @@ -57662,11 +58076,6 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/aft) -"rIw" = ( -/obj/effect/landmark/generic_maintenance_landmark, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/starboard/aft) "rIF" = ( /obj/effect/turf_decal/trimline/dark_blue/line, /obj/machinery/camera/directional/south{ @@ -58014,6 +58423,10 @@ /area/station/engineering/lobby) "rOX" = ( /obj/structure/chair, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/port/aft) "rPe" = ( @@ -58908,6 +59321,13 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted, /turf/open/floor/iron/dark, /area/station/ai_monitored/command/storage/eva) +"sez" = ( +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/turf/open/floor/plating, +/area/station/maintenance/aft/greater) "seA" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/cable, @@ -59154,6 +59574,7 @@ id = "maint3" }, /obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/fore) "siu" = ( @@ -59416,6 +59837,14 @@ /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos/project) +"slK" = ( +/obj/machinery/cryo_cell, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/item/radio/intercom/directional/east, +/turf/open/floor/iron/dark/textured, +/area/station/medical/cryo) "slX" = ( /obj/structure/fans/tiny, /obj/effect/turf_decal/stripes/red/box, @@ -60412,13 +60841,6 @@ "sAS" = ( /turf/closed/wall, /area/station/commons/storage/art) -"sAT" = ( -/obj/machinery/chem_mass_spec, -/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron/white, -/area/station/medical/pharmacy) "sBi" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, @@ -61732,6 +62154,10 @@ /obj/item/screwdriver, /turf/open/floor/plating/snowed/icemoon, /area/icemoon/underground/explored) +"sVW" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "sWl" = ( /obj/machinery/door/airlock/command{ name = "Chief Medical Officer" @@ -61765,6 +62191,8 @@ /obj/structure/disposalpipe/segment{ dir = 6 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/catwalk_floor/iron_smooth, /area/station/maintenance/fore/lesser) "sWB" = ( @@ -62206,11 +62634,6 @@ /obj/machinery/power/apc/auto_name/directional/west, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/aft) -"tfp" = ( -/obj/machinery/smartfridge/chemistry/preloaded, -/obj/machinery/door/firedoor, -/turf/open/floor/iron/white, -/area/station/medical/pharmacy) "tfu" = ( /obj/structure/sign/warning/electric_shock, /turf/closed/wall, @@ -62281,6 +62704,7 @@ dir = 1 }, /obj/effect/mapping_helpers/airlock/access/any/science/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "tgx" = ( @@ -62308,7 +62732,7 @@ "thc" = ( /obj/structure/table/reinforced, /obj/structure/extinguisher_cabinet/directional/south, -/obj/item/gun/energy/laser/practice{ +/obj/item/gun/energy/laser/carbine/practice{ pixel_x = 3; pixel_y = -3 }, @@ -62400,6 +62824,11 @@ dir = 8 }, /area/mine/eva) +"tip" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/solars/starboard/fore) "tis" = ( /obj/structure/window/reinforced/fulltile, /obj/structure/transit_tube/horizontal, @@ -62852,26 +63281,6 @@ /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/iron/white/textured, /area/station/security/medical) -"tpY" = ( -/obj/structure/table/reinforced, -/obj/item/folder/white, -/obj/item/pen, -/obj/machinery/door/firedoor, -/obj/machinery/door/window/right/directional/east{ - base_state = "left"; - dir = 8; - icon_state = "left"; - name = "Pharmacy Desk"; - req_access = list("pharmacy") - }, -/obj/effect/turf_decal/tile/yellow/fourcorners, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 4; - id = "pharmacy_shutters2"; - name = "Pharmacy Shutters" - }, -/turf/open/floor/iron, -/area/station/medical/pharmacy) "tqk" = ( /obj/structure/table, /obj/item/paper_bin{ @@ -62882,6 +63291,11 @@ /obj/item/key/janitor, /turf/open/floor/iron, /area/station/service/janitor) +"tqC" = ( +/obj/machinery/netpod, +/obj/machinery/camera/directional/south, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "tqQ" = ( /obj/effect/turf_decal/stripes/corner{ dir = 1 @@ -63319,7 +63733,6 @@ "txe" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/generic_maintenance_landmark, /obj/effect/landmark/blobstart, /obj/effect/turf_decal/tile/yellow/opposingcorners, /turf/open/floor/iron/white, @@ -63401,6 +63814,17 @@ /obj/structure/chair/office, /turf/open/floor/wood, /area/station/service/library) +"tyH" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/door/airlock/mining{ + name = "Mining Dock" + }, +/obj/effect/mapping_helpers/airlock/access/all/supply/mining, +/obj/machinery/door/firedoor, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "tyK" = ( /obj/item/mop, /obj/item/reagent_containers/cup/bucket, @@ -64455,10 +64879,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/engineering/atmos/mix) -"tOz" = ( -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "tOF" = ( /obj/structure/chair/comfy/black{ dir = 8 @@ -64834,13 +65254,6 @@ /obj/structure/table, /turf/open/floor/plating/snowed/coldroom, /area/station/service/kitchen/coldroom) -"tWF" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/landmark/event_spawn, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "tWK" = ( /obj/structure/cable, /turf/open/floor/plating/snowed/icemoon, @@ -65428,23 +65841,6 @@ /obj/structure/beebox, /turf/open/floor/grass, /area/station/service/hydroponics) -"uhn" = ( -/obj/structure/table/glass, -/obj/item/stack/cable_coil, -/obj/item/stack/cable_coil, -/obj/item/screwdriver{ - pixel_x = 2; - pixel_y = 11 - }, -/obj/item/grenade/chem_grenade, -/obj/item/grenade/chem_grenade, -/obj/item/grenade/chem_grenade, -/obj/item/grenade/chem_grenade, -/obj/effect/turf_decal/tile/yellow/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron/white, -/area/station/medical/pharmacy) "uhs" = ( /obj/structure/railing/corner, /obj/machinery/camera/directional/south{ @@ -66113,17 +66509,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/white, /area/station/science/research) -"use" = ( -/obj/structure/table, -/obj/item/folder/yellow, -/obj/item/pen, -/obj/machinery/requests_console/directional/west{ - department = "Mining"; - name = "Mining Requests Console" - }, -/obj/effect/mapping_helpers/requests_console/supplies, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "uso" = ( /obj/structure/closet/crate/trashcart, /obj/effect/spawner/random/contraband/prison, @@ -66539,6 +66924,11 @@ /obj/structure/cable, /turf/open/floor/iron/dark/textured, /area/station/security/range) +"uAF" = ( +/obj/effect/decal/cleanable/oil, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/port/aft) "uAJ" = ( /obj/machinery/space_heater, /turf/open/floor/plating, @@ -68310,6 +68700,10 @@ }, /turf/open/floor/iron/grimy, /area/station/security/prison/work) +"veh" = ( +/obj/machinery/vending/wardrobe/cargo_wardrobe, +/turf/open/floor/iron, +/area/station/cargo/storage) "vek" = ( /obj/effect/turf_decal/weather/snow/corner, /obj/machinery/light/small/directional/north, @@ -68464,6 +68858,11 @@ /obj/effect/turf_decal/trimline/blue/filled/line, /turf/open/floor/iron/white, /area/station/medical/medbay/aft) +"vgC" = ( +/obj/machinery/netpod, +/obj/item/radio/intercom/directional/south, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "vgD" = ( /obj/structure/rack, /obj/item/stack/sheet/iron/fifty, @@ -68490,6 +68889,8 @@ /area/station/maintenance/port/greater) "vhg" = ( /obj/structure/sign/poster/random/directional/east, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron/smooth, /area/station/maintenance/fore/lesser) "vhm" = ( @@ -68497,15 +68898,11 @@ /obj/machinery/firealarm/directional/north, /turf/open/floor/iron/dark, /area/station/service/chapel) -"vhn" = ( -/obj/machinery/firealarm/directional/north, -/turf/open/floor/iron, -/area/station/cargo/storage) "vhr" = ( -/mob/living/simple_animal/hostile/retaliate/goat{ - atmos_requirements = list("min_oxy"=1,"max_oxy"=0,"min_plas"=0,"max_plas"=1,"min_co2"=0,"max_co2"=5,"min_n2"=0,"max_n2"=0); +/mob/living/basic/goat/pete{ desc = "Not known for their pleasant disposition. This one seems a bit more hardy to the cold."; - minbodytemp = 150; + habitable_atmos = list("min_oxy"=1,"max_oxy"=0,"min_plas"=0,"max_plas"=1,"min_co2"=0,"max_co2"=5,"min_n2"=0,"max_n2"=0); + minimum_survivable_temperature = 150; name = "Snowy Pete" }, /turf/open/misc/asteroid/snow/coldroom, @@ -68700,10 +69097,6 @@ /obj/structure/sign/poster/random/directional/west, /turf/open/floor/iron/large, /area/station/service/kitchen/diner) -"vlu" = ( -/obj/machinery/airalarm/directional/east, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "vlI" = ( /obj/effect/turf_decal/siding/white{ dir = 4 @@ -70238,10 +70631,6 @@ /turf/open/floor/iron, /area/station/hallway/secondary/service) "vKo" = ( -/obj/machinery/atmospherics/pipe/multiz/supply/visible/layer4{ - color = "#0000ff"; - name = "Supply multi deck pipe adapter" - }, /obj/structure/railing{ dir = 1 }, @@ -70325,6 +70714,7 @@ dir = 1 }, /obj/effect/mapping_helpers/airlock/access/any/medical/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) "vMa" = ( @@ -70478,6 +70868,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/spawner/random/trash/grille_or_waste, /obj/machinery/duct, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) "vPh" = ( @@ -70760,6 +71151,7 @@ }, /obj/structure/cable, /obj/effect/mapping_helpers/airlock/access/all/engineering/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/solars/starboard/aft) "vTo" = ( @@ -70961,6 +71353,13 @@ /obj/item/book/bible, /turf/open/floor/iron/chapel, /area/station/service/chapel) +"vWV" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/power/apc/auto_name/directional/west, +/turf/open/floor/iron, +/area/station/cargo/miningdock) "vWW" = ( /obj/effect/turf_decal/tile/neutral/opposingcorners, /turf/open/floor/iron, @@ -71155,6 +71554,7 @@ dir = 8 }, /obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/department/cargo) "vZt" = ( @@ -72107,7 +72507,7 @@ /area/station/security/brig) "wog" = ( /obj/item/food/fried_chicken, -/turf/open/floor/plating/snowed/smoothed/icemoon, +/turf/open/floor/plating/snowed/smoothed, /area/station/maintenance/fore/lesser) "wol" = ( /obj/effect/decal/cleanable/dirt, @@ -72702,14 +73102,6 @@ /obj/effect/mapping_helpers/airlock/access/all/service/lawyer, /turf/open/floor/wood, /area/station/service/lawoffice) -"wxd" = ( -/obj/machinery/camera/directional/north{ - c_tag = "Cargo Bay North" - }, -/obj/machinery/vending/wardrobe/cargo_wardrobe, -/obj/machinery/light/directional/north, -/turf/open/floor/iron, -/area/station/cargo/storage) "wxg" = ( /turf/open/floor/iron/freezer, /area/mine/laborcamp) @@ -72792,13 +73184,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/greater) -"wyv" = ( -/obj/machinery/camera/directional/west{ - c_tag = "Mining Dock" - }, -/obj/machinery/computer/security/mining, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "wyB" = ( /obj/machinery/conveyor{ dir = 1; @@ -72875,8 +73260,12 @@ /area/mine/laborcamp) "wzz" = ( /obj/structure/rack, -/obj/item/healthanalyzer, /obj/machinery/light/cold/directional/north, +/obj/item/storage/box/bandages{ + pixel_y = 6; + pixel_x = -6 + }, +/obj/item/healthanalyzer, /turf/open/floor/iron/white/textured, /area/station/security/medical) "wAq" = ( @@ -74368,10 +74757,19 @@ /area/station/maintenance/port/fore) "wWm" = ( /obj/item/trash/raisins, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"wWn" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "pharmacy_shutters"; + name = "Pharmacy Shutters"; + dir = 4 + }, +/turf/open/floor/plating, +/area/station/medical/pharmacy) "wWJ" = ( -/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron/dark, /area/station/medical/morgue) "wWM" = ( @@ -74406,8 +74804,15 @@ "wXc" = ( /obj/structure/sign/warning/cold_temp/directional/east, /obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"wXf" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "wXh" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/flipped/co2{ dir = 8 @@ -74434,6 +74839,7 @@ "wXW" = ( /obj/structure/sign/warning/gas_mask/directional/south, /obj/effect/spawner/random/trash/grille_or_waste, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/medical/morgue) "wXX" = ( @@ -75165,6 +75571,7 @@ /obj/effect/mapping_helpers/burnt_floor, /obj/machinery/airalarm/directional/north, /obj/effect/decal/cleanable/dirt/dust, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/port/lesser) "xgO" = ( @@ -75183,6 +75590,14 @@ }, /turf/open/floor/iron/smooth_large, /area/station/cargo/drone_bay) +"xgQ" = ( +/obj/effect/landmark/generic_maintenance_landmark, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/aft) "xgX" = ( /obj/structure/table/wood, /obj/effect/spawner/random/entertainment/deck{ @@ -75393,9 +75808,9 @@ "xkG" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/generic_maintenance_landmark, /obj/effect/decal/cleanable/confetti, /obj/effect/turf_decal/tile/yellow/opposingcorners, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron/white, /area/station/maintenance/port/fore) "xkH" = ( @@ -75839,6 +76254,7 @@ "xsm" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron/cafeteria{ dir = 5 }, @@ -75929,12 +76345,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/port/aft) -"xuh" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/miningdock) "xun" = ( /obj/machinery/door/poddoor/massdriver_chapel, /obj/structure/fans/tiny, @@ -77865,14 +78275,6 @@ }, /turf/open/floor/iron/dark/smooth_large, /area/station/engineering/main) -"xZo" = ( -/obj/structure/table/glass, -/obj/machinery/microwave, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron/white, -/area/station/medical/break_room) "xZA" = ( /turf/open/floor/iron/checker, /area/station/science/lab) @@ -78075,6 +78477,7 @@ "ycc" = ( /obj/structure/plasticflaps, /obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/fore) "ych" = ( @@ -78456,6 +78859,8 @@ /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/west, /obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/smooth, /area/station/maintenance/fore/lesser) "ykw" = ( @@ -81634,7 +82039,7 @@ oSU oSU oSU oSU -mJv +oSU oSU oSU oSU @@ -179484,9 +179889,9 @@ jKG hjM xDU aBx -sBJ +rmh vLY -qck +ohM bHF eos jol @@ -181288,7 +181693,7 @@ nxM jdP jdP jdP -cFJ +cBw oiT xUe hjM @@ -181802,7 +182207,7 @@ nxM wEU jtD rBv -owG +qHl hRX oiT smw @@ -182058,7 +182463,7 @@ xMq nxM bvS vKo -qHl +owG rwG cmQ skJ @@ -184647,9 +185052,9 @@ nsp fWO tRd tRd -jOp -oxO -oxO +mtm +tRd +tRd alM alM oxO @@ -184906,7 +185311,7 @@ tRd alM alM iry -oxO +tRd lms alM oxO @@ -185163,7 +185568,7 @@ tRd alM alM fuD -oxO +dAq eEY oxO fWO @@ -185917,9 +186322,9 @@ oxO oxO oxO oxO -oxO -oxO -oxO +gyC +tRd +tRd nPI wjy nPI @@ -188176,7 +188581,7 @@ tBs nHQ oik oFl -vGJ +auX uDl feQ tBs @@ -190014,7 +190419,7 @@ alM alM alM oxO -oxO +cNG tNJ tNJ nyJ @@ -190276,11 +190681,11 @@ oLa pvh oxO oxO +aqK oxO +foo oxO -iKG -oxO -oxO +imu oxO oxO oxO @@ -225937,11 +226342,11 @@ pVN kJe pVN eSg -pVN +cat inw -iwD -anl -anl +rgs +eUf +eUf eUf hjI lJO @@ -226977,7 +227382,7 @@ qDI lJO lJO lJO -eUf +dva lFq dix lJO @@ -229058,11 +229463,11 @@ uKO juq tKI xqX -bCQ +lnd wBb tKI -gvZ -jiK +veh +ajw ajw ajw mmi @@ -229104,7 +229509,7 @@ qAI snw mNY kkp -ipE +fCA ipE glh bln @@ -229318,8 +229723,8 @@ sIM yjn wBb tKI -bCM -qPR +pVC +ajw kXs ajw mmi @@ -229361,7 +229766,7 @@ mXN vUz mNY qIf -smj +fcs czR glh bln @@ -229832,7 +230237,7 @@ nAr nAr wNR tKI -wxd +piX ajw ajw ajw @@ -229875,7 +230280,7 @@ aPV gFH apj cqL -eAj +xHe ptf bln bln @@ -230132,7 +230537,7 @@ ukA hUI apj daS -eAj +xHe ptf bln bln @@ -230359,11 +230764,11 @@ irD irD pzX gdN -pYT +gfu maT bln qjQ -qZY +aVE qxb nrm hoD @@ -230388,7 +230793,7 @@ tKV cjL gfC pRj -eAj +daS hHs pRj pRj @@ -230616,11 +231021,11 @@ iaF ajw ajw ajw -kXr -kXr -bln -qjQ -qjQ +bsx +bsx +gMV +bsx +bsx ojk bVJ dSO @@ -230630,7 +231035,7 @@ bln pRj jzk kYF -csE +llC qzM pRj dOH @@ -230873,12 +231278,12 @@ qqJ gjP ajw ajw -maT -bln -bln -bln -qjQ -mZt +gMV +cWa +sVW +ltl +bsx +qYc hxE xtr qjQ @@ -231128,13 +231533,13 @@ kXr kXr kXr kXr -vhn -ajw -kXr -bln -bln -qjQ -qjQ +dgf +eMa +oVf +fss +qtT +tqC +bsx qjQ rVe qjQ @@ -231384,17 +231789,17 @@ mAN vra lZQ wXR -qjQ -aOd -rBz -aOd -qjQ -qjQ -qjQ -lqt -oOa +kXr +eAe +eMa +bsx +fNx +dPW +vgC +bsx +lti jBf -cLI +naO qjQ sEB sEB @@ -231641,17 +232046,17 @@ kXA oDt kRU oQa -qjQ -mwF -tOz -hoD -iNu -use -wyv -hoD -hoD +kXr +kQL +ewq +bsx +dVs +nyB +dUK +bsx +fqY hxE -hxC +dPn aOd bln bln @@ -231898,14 +232303,14 @@ cXl uxl oRy aHC -qjQ -dEJ -cWr -hoD -hoD -pnr -cfR -hoD +kXr +ghl +ewq +bsx +gMV +gMV +bsx +bsx iVA hxE aCh @@ -232155,14 +232560,14 @@ mOA cHb psW psW -gwB -hxE -hxE -tWF -hxE -hxE +nMB +ewq +ewq +tyH hxE hxE +vWV +dAt hxE hxE wBV @@ -232171,7 +232576,7 @@ bln bln ptf jYS -jSe +pNM jSe oxB jQC @@ -232412,13 +232817,13 @@ ljl kXA rLu nRq +maT +ajw +eMa aOd -hoD -xuh -hoD -kJz +qJJ hxE -hoD +iVA hoD hoD abz @@ -232672,10 +233077,10 @@ uuP tue nZh lNG -nZh tue +qjQ hxE -vlu +feB lis aud lis @@ -233475,14 +233880,14 @@ pRj poc oef wWm -fSj -daS +uAF +pXv lge -daS -rlj -daS +pXv +mYc +pXv fIL -daS +pXv rOX nkO ptf @@ -233732,7 +234137,7 @@ blO xHe pRj glX -daS +xgQ kNZ pRj lDF @@ -242958,7 +243363,7 @@ cvS sxu kwX pNq -pNq +kVW gDp rxa qgm @@ -243155,9 +243560,9 @@ bln fsm bUx cCC -jOQ -ykA -ykA +kEo +kNz +oCl skl iHz jOQ @@ -243414,10 +243819,10 @@ bUx wnq dqv cKn -ykA +oCl skl kUG -ykA +oCl skl gmW gmW @@ -243453,7 +243858,7 @@ bai azw jqE kZb -sAT +njP azw fMg fqW @@ -244220,9 +244625,9 @@ sIm hmb lso dEV -lts +bai azw -uhn +fdO fTC xSu azw @@ -244477,9 +244882,9 @@ exw exw cwh dEV -jyp +arO azw -mEi +ftB eyc qPt uTc @@ -244997,8 +245402,8 @@ cJw dip bHO azw -tpY -tfp +gNA +fib azw eiY tZm @@ -245250,7 +245655,7 @@ vwO hHg bai azw -nbd +kpb uTk sJA sHc @@ -245507,7 +245912,7 @@ lso aAa bai azw -meF +qYp vYH nah azw @@ -246021,9 +246426,9 @@ mqq kjK bai azw -aTJ -cvp -tfp +wWn +dff +kNg azw gIY iBj @@ -250147,7 +250552,7 @@ oyy amE wyj klc -eNM +krx ufN vCz ufN @@ -250661,7 +251066,7 @@ qhN amE lei klc -kAq +slK hXU oRu hIe @@ -250869,12 +251274,12 @@ kxv fIs kxv gHv -kxv +tip pHd -tvZ -tvZ -tvZ -tvZ +gbf +gbf +gbf +gbf kKL gAt orf @@ -250932,7 +251337,7 @@ xMM nqd ttO mFE -xZo +aaf pWY rQI phj @@ -251131,7 +251536,7 @@ pDQ xBL wJM wJM -tvZ +gbf kKL dnL orf @@ -251199,7 +251604,7 @@ sZF sZF hEZ mlo -sKf +sez sKf sZF sZF @@ -251388,7 +251793,7 @@ mHB pVl kKL bqe -tvZ +gbf kKL hOu orf @@ -251645,7 +252050,7 @@ cvF lli kKL mwu -tvZ +gbf kKL kKL lAG @@ -251902,7 +252307,7 @@ oCv gGF kKL qqB -tvZ +gbf kKL weF orf @@ -252416,7 +252821,7 @@ rSq raH kKL lli -tvZ +gbf kKL kKL orf @@ -252673,7 +253078,7 @@ kKL kKL kKL xcp -tvZ +gbf sin niB iOc @@ -252930,7 +253335,7 @@ sRI jwF kKL lli -sRI +jNS paT lli lli @@ -253184,10 +253589,10 @@ bln kKL cjO qeJ -lRs +heW osq -lli -gGF +tDy +qRt kKL kKL kKL @@ -254736,7 +255141,7 @@ wsO bcC bcC bcC -bcC +czx unu kKL hno @@ -254993,7 +255398,7 @@ bcC lli hJx weF -lli +bPy aME kKL qLf @@ -255332,7 +255737,7 @@ vzD vzD vzD uZc -uZc +kZw sGZ gQw bln @@ -255580,16 +255985,16 @@ eBz eBz eBz fxV -jCl -jCl -jCl -rIw -jCl -nuj -jCl +rEU +rEU +rEU +bIS +rEU +bIS +rEU mUt -uZc -uZc +wXf +wXf fNa gQw bln @@ -258655,7 +259060,7 @@ rDZ rDZ bgx qUY -jCl +afn juQ vzD geJ @@ -258912,7 +259317,7 @@ uaT oTd bgx jCl -jCl +rEU jCl vzD geJ @@ -259169,8 +259574,8 @@ rDZ rDZ bgx vzb -jCl -nuj +rEU +bIS tgw pTW vzD @@ -259689,7 +260094,7 @@ jCl geJ oiH vTl -xCz +okg luK xCz qYP @@ -260170,7 +260575,7 @@ elw elw elw rft -dbw +bkw idt fMq pSz @@ -260183,7 +260588,7 @@ hyV bgx gti bhk -jCl +fQx jCl jCl jCl @@ -260454,7 +260859,7 @@ ibw iQT qob rZa -jCl +rEU vzD sDr twZ @@ -260710,8 +261115,8 @@ tKN qZh vzD twZ -jCl -jCl +jBr +rEU vXd jCl mwQ diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index bfda66d10db3d1..18fb519e73d047 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -261,6 +261,16 @@ name = "Holodeck Projector Floor" }, /area/station/holodeck/rec_center) +"afF" = ( +/obj/structure/table/reinforced, +/obj/machinery/microwave/engineering/cell_included, +/obj/effect/turf_decal/stripes/corner, +/obj/effect/turf_decal/tile/yellow{ + dir = 8 + }, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron/checker, +/area/station/engineering/storage_shared) "afZ" = ( /obj/machinery/vending/coffee, /obj/structure/disposalpipe/segment, @@ -2133,6 +2143,14 @@ /obj/effect/turf_decal/tile/blue, /turf/open/floor/iron/dark, /area/station/command/bridge) +"aNL" = ( +/obj/effect/spawner/random/trash/garbage, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 1 + }, +/turf/open/floor/plating, +/area/station/maintenance/aft/lesser) "aNN" = ( /obj/machinery/airalarm/directional/south, /obj/machinery/disposal/bin, @@ -3334,6 +3352,12 @@ /obj/structure/extinguisher_cabinet/directional/north, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"bje" = ( +/obj/effect/decal/cleanable/oil/streak, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/structure/extinguisher_cabinet/directional/north, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "bjl" = ( /obj/machinery/rnd/production/techfab/department/service, /obj/effect/turf_decal/trimline/brown/warning{ @@ -4153,13 +4177,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/grimy, /area/station/service/chapel/office) -"bwj" = ( -/obj/effect/decal/cleanable/blood/tracks{ - dir = 4 - }, -/obj/effect/spawner/random/structure/grille, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "bwr" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -4526,7 +4543,6 @@ "bDS" = ( /obj/structure/chair/office/light, /obj/structure/cable, -/obj/item/stamp/head/cmo, /turf/open/floor/iron/white, /area/station/command/heads_quarters/cmo) "bDW" = ( @@ -4674,6 +4690,18 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) +"bGM" = ( +/obj/machinery/door/airlock/mining{ + name = "Mining Office" + }, +/obj/machinery/door/firedoor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/mapping_helpers/airlock/access/any/supply/mining, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "bHb" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -4685,6 +4713,10 @@ /obj/effect/turf_decal/tile/brown/anticorner/contrasted{ dir = 1 }, +/obj/item/storage/box/bandages{ + pixel_y = 6; + pixel_x = 4 + }, /turf/open/floor/iron, /area/station/cargo/miningoffice) "bHr" = ( @@ -4856,12 +4888,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) -"bKK" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "bKT" = ( /obj/machinery/door/airlock/grunge{ name = "Prison Forestry" @@ -6046,13 +6072,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/treatment_center) -"ckG" = ( -/obj/effect/landmark/generic_maintenance_landmark, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/landmark/start/hangover, -/turf/open/floor/carpet, -/area/station/commons/dorms) "ckI" = ( /obj/effect/turf_decal/stripes/line{ dir = 6 @@ -6079,6 +6098,15 @@ "clq" = ( /turf/open/floor/carpet, /area/station/security/detectives_office) +"cly" = ( +/obj/machinery/computer/quantum_console, +/obj/effect/turf_decal/siding/thinplating_new/dark, +/obj/effect/decal/cleanable/cobweb, +/obj/machinery/camera/directional/north{ + c_tag = "Mining Dock" + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "clA" = ( /obj/structure/sign/departments/cargo, /turf/closed/wall, @@ -6235,6 +6263,30 @@ /obj/effect/decal/cleanable/blood/old, /turf/open/floor/wood, /area/station/maintenance/port/aft) +"cph" = ( +/obj/structure/table/reinforced, +/obj/item/folder/white{ + pixel_x = 4; + pixel_y = -3 + }, +/obj/machinery/door/firedoor, +/obj/item/folder/white{ + pixel_x = 4; + pixel_y = -3 + }, +/obj/item/pen, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 4; + id = "pharmacy_shutters_2"; + name = "Pharmacy Shutters" + }, +/obj/machinery/door/window/right/directional/east{ + name = "Pharmacy Desk"; + req_access = list("pharmacy") + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/floor/iron/white, +/area/station/medical/pharmacy) "cpi" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/circuit/green{ @@ -7186,6 +7238,15 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/station/security/brig) +"cGL" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "cGV" = ( /obj/machinery/air_sensor/plasma_tank, /turf/open/floor/engine/plasma, @@ -8252,7 +8313,7 @@ /obj/item/bedsheet/red, /obj/machinery/airalarm/directional/east, /obj/machinery/flasher/directional/north{ - id = "IsolationCell" + id = "IsolationFlash" }, /obj/effect/turf_decal/tile/red/fourcorners, /turf/open/floor/iron/white, @@ -8847,6 +8908,13 @@ /obj/structure/window/spawner/directional/south, /turf/open/floor/iron, /area/station/engineering/atmos) +"dob" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/machinery/computer/order_console/bitrunning, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "dox" = ( /obj/structure/rack, /obj/item/screwdriver{ @@ -9279,6 +9347,15 @@ }, /turf/open/floor/iron/cafeteria, /area/station/engineering/atmos) +"dwA" = ( +/obj/effect/spawner/random/maintenance, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "dwJ" = ( /obj/structure/lattice, /obj/effect/spawner/random/structure/grille, @@ -9371,6 +9448,16 @@ }, /turf/open/floor/plating, /area/station/science/lab) +"dzh" = ( +/obj/machinery/quantum_server, +/obj/effect/turf_decal/bot/left, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 6 + }, +/obj/machinery/light/directional/north, +/obj/item/radio/intercom/directional/north, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "dzw" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -10949,6 +11036,9 @@ /obj/item/clipboard, /obj/item/toy/figure/cmo, /obj/structure/cable, +/obj/item/stamp/head/cmo{ + pixel_x = -9 + }, /turf/open/floor/iron/white, /area/station/command/heads_quarters/cmo) "edq" = ( @@ -11007,6 +11097,17 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/plating, /area/station/cargo/sorting) +"edP" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "edQ" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -11916,6 +12017,7 @@ /turf/open/floor/iron, /area/station/maintenance/starboard/greater) "esK" = ( +/obj/machinery/firealarm/directional/east, /obj/structure/cable, /obj/machinery/light/small/directional/east, /turf/open/floor/iron/dark, @@ -12431,6 +12533,22 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/aft) +"eEb" = ( +/obj/effect/turf_decal/trimline/brown/corner{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/corner{ + dir = 8 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/door/airlock/mining{ + name = "Bitrunning Den" + }, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/turf/open/floor/iron/dark/textured_half, +/area/station/bitrunning/den) "eEf" = ( /obj/machinery/camera/directional/north{ c_tag = "Bar - Backroom" @@ -12898,6 +13016,7 @@ dir = 4 }, /obj/effect/mapping_helpers/broken_floor, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/port/aft) "eNR" = ( @@ -14938,11 +15057,10 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/iron, /area/station/engineering/atmos) -"fBi" = ( -/obj/effect/landmark/generic_maintenance_landmark, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/maintenance/disposal/incinerator) +"fBl" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/bitrunning/den) "fBo" = ( /obj/machinery/door/window/left/directional/north{ dir = 8; @@ -15209,13 +15327,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, /turf/open/floor/plating, /area/station/maintenance/department/science/xenobiology) -"fGB" = ( -/obj/item/clothing/gloves/color/rainbow, -/obj/item/clothing/shoes/sneakers/rainbow, -/obj/item/clothing/under/color/rainbow, -/obj/item/clothing/head/soft/rainbow, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "fGC" = ( /obj/machinery/door/airlock/maintenance{ name = "Detective Maintenance" @@ -15465,6 +15576,15 @@ /obj/effect/mapping_helpers/airlock/access/all/medical/general, /turf/open/floor/plating, /area/station/maintenance/port/aft) +"fLn" = ( +/obj/effect/spawner/random/decoration/microwave{ + dir = 1; + pixel_y = 2 + }, +/obj/structure/table/wood, +/obj/machinery/light/small/directional/south, +/turf/open/floor/carpet, +/area/station/command/corporate_showroom) "fLp" = ( /obj/structure/disposalpipe/junction{ dir = 8 @@ -15592,6 +15712,15 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/white, /area/station/science/explab) +"fNH" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Mining Dock Maintenance" + }, +/obj/structure/cable, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/obj/effect/mapping_helpers/airlock/access/any/supply/mining, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "fNI" = ( /obj/structure/sign/poster/contraband/random/directional/east, /turf/open/floor/wood, @@ -16101,9 +16230,6 @@ /obj/structure/cable, /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, /turf/open/floor/iron/white, /area/station/medical/medbay/central) "fYC" = ( @@ -16497,6 +16623,12 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"ghJ" = ( +/obj/machinery/netpod, +/obj/machinery/light/directional/west, +/obj/machinery/airalarm/directional/south, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "ghK" = ( /obj/structure/rack, /obj/item/tank/internals/oxygen, @@ -17281,6 +17413,10 @@ "guX" = ( /turf/closed/wall, /area/station/commons/storage/primary) +"guZ" = ( +/obj/machinery/netpod, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "gva" = ( /obj/effect/turf_decal/delivery, /turf/open/floor/iron, @@ -17341,6 +17477,10 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/iron, /area/station/science/explab) +"gvZ" = ( +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/aft/lesser) "gwc" = ( /obj/structure/chair/stool/bar/directional/south, /obj/effect/turf_decal/siding/wood{ @@ -17777,15 +17917,6 @@ /obj/machinery/rnd/production/protolathe/department/science, /turf/open/floor/iron/dark, /area/station/science/lab) -"gFz" = ( -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "gFL" = ( /obj/effect/turf_decal/tile/green{ dir = 4 @@ -18139,9 +18270,7 @@ /area/station/science/xenobiology/hallway) "gLF" = ( /obj/structure/sink/kitchen/directional/west, -/mob/living/simple_animal/hostile/retaliate/goat{ - name = "Pete" - }, +/mob/living/basic/goat/pete, /turf/open/floor/iron/kitchen_coldroom/freezerfloor, /area/station/service/kitchen/coldroom) "gLI" = ( @@ -18178,14 +18307,18 @@ /area/station/medical/abandoned) "gMg" = ( /obj/structure/table, -/obj/item/storage/medkit/regular, -/obj/item/reagent_containers/cup/bottle/epinephrine, -/obj/item/reagent_containers/cup/bottle/multiver, -/obj/item/reagent_containers/syringe, /obj/structure/extinguisher_cabinet/directional/west, /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 8 }, +/obj/item/storage/box/bandages{ + pixel_y = 6; + pixel_x = -6 + }, +/obj/item/storage/medkit/regular, +/obj/item/reagent_containers/cup/bottle/multiver, +/obj/item/reagent_containers/cup/bottle/epinephrine, +/obj/item/reagent_containers/syringe, /turf/open/floor/iron/white, /area/station/security/medical) "gMt" = ( @@ -18400,6 +18533,15 @@ /obj/machinery/atmospherics/pipe/smart/simple/yellow/visible, /turf/open/space/basic, /area/space/nearstation) +"gQv" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/sorting/mail/flip{ + dir = 1 + }, +/obj/effect/mapping_helpers/mail_sorting/supply/disposals, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "gQw" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/white/line, @@ -19969,7 +20111,6 @@ }, /obj/item/mod/module/plasma_stabilizer, /obj/item/mod/module/thermal_regulator, -/obj/item/mod/module/signlang_radio, /turf/open/floor/iron/dark, /area/station/medical/storage) "hwg" = ( @@ -20413,6 +20554,23 @@ /obj/effect/turf_decal/tile/neutral, /turf/open/floor/iron, /area/station/hallway/primary/starboard) +"hDd" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark/corner{ + dir = 8 + }, +/obj/machinery/firealarm/directional/south, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/dark/textured_half, +/area/station/bitrunning/den) "hDe" = ( /obj/machinery/portable_atmospherics/canister/plasma, /turf/open/floor/engine/plasma, @@ -20987,6 +21145,10 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/service/chapel) +"hPG" = ( +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "hPK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/duct, @@ -21200,13 +21362,6 @@ /obj/effect/landmark/navigate_destination, /turf/open/floor/iron, /area/station/command/gateway) -"hTi" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 4 - }, -/obj/machinery/cryo_cell, -/turf/open/floor/iron/dark/textured, -/area/station/medical/cryo) "hTn" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -21348,13 +21503,6 @@ /obj/effect/landmark/navigate_destination, /turf/open/floor/iron/white, /area/station/medical/virology) -"hVW" = ( -/obj/effect/landmark/generic_maintenance_landmark, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/landmark/start/hangover, -/turf/open/floor/wood, -/area/station/commons/dorms) "hVX" = ( /obj/structure/toilet{ pixel_y = 8 @@ -21456,13 +21604,6 @@ /obj/machinery/door/firedoor/heavy, /turf/open/floor/iron/dark/textured, /area/station/engineering/atmos) -"hXA" = ( -/obj/structure/closet/emcloset, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "hXC" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -22361,17 +22502,6 @@ }, /turf/open/floor/engine, /area/station/science/xenobiology) -"imy" = ( -/obj/structure/table/reinforced, -/obj/machinery/microwave{ - pixel_y = 6 - }, -/obj/effect/turf_decal/tile/neutral/opposingcorners{ - dir = 1 - }, -/obj/machinery/digital_clock/directional/south, -/turf/open/floor/iron/dark, -/area/station/medical/break_room) "imU" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -22770,6 +22900,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 }, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/port/aft) "itr" = ( @@ -23050,11 +23181,6 @@ /obj/machinery/portable_atmospherics/canister/plasma, /turf/open/floor/iron/dark, /area/station/science/ordnance/storage) -"iyj" = ( -/obj/effect/landmark/generic_maintenance_landmark, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/starboard/aft) "iym" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -23522,7 +23648,6 @@ /turf/open/floor/iron, /area/station/engineering/atmos) "iGy" = ( -/obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 }, @@ -24483,6 +24608,21 @@ /obj/machinery/duct, /turf/open/floor/iron/white, /area/station/medical/treatment_center) +"iUV" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/start/bitrunner, +/obj/machinery/holopad, +/turf/open/floor/iron/dark/textured_half, +/area/station/bitrunning/den) "iVi" = ( /obj/machinery/door/airlock{ id_tag = "Cabin6"; @@ -24492,13 +24632,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/commons/dorms) -"iVm" = ( -/obj/structure/reagent_dispensers/watertank, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "iVs" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment, @@ -25228,7 +25361,7 @@ dir = 4 }, /obj/structure/disposalpipe/segment, -/mob/living/simple_animal/sloth/citrus, +/mob/living/basic/sloth/citrus, /turf/open/floor/iron, /area/station/cargo/storage) "jhD" = ( @@ -25882,6 +26015,13 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/engineering/storage/tech) +"jty" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/machinery/light/small/directional/west, +/turf/open/floor/iron, +/area/station/cargo/storage) "jtA" = ( /obj/structure/table/glass, /obj/effect/turf_decal/siding/white{ @@ -26850,14 +26990,14 @@ /turf/open/floor/plating, /area/station/maintenance/starboard/aft) "jJp" = ( +/obj/machinery/button/flasher{ + id = "IsolationFlash"; + pixel_x = -23; + pixel_y = 8 + }, /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/machinery/status_display/door_timer{ - id = "IsolationCell"; - name = "Isolation Cell"; - pixel_x = -32 - }, /turf/open/floor/iron, /area/station/security/execution/transfer) "jJC" = ( @@ -26996,6 +27136,13 @@ /obj/structure/railing/corner, /turf/open/floor/plating/airless, /area/space/nearstation) +"jLI" = ( +/obj/effect/spawner/random/trash/garbage{ + spawn_scatter_radius = 1 + }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "jMo" = ( /obj/structure/chair/stool/directional/north, /turf/open/floor/iron, @@ -27163,7 +27310,7 @@ /area/station/medical/chemistry) "jOF" = ( /obj/structure/rack, -/obj/item/gun/energy/laser/practice{ +/obj/item/gun/energy/laser/carbine/practice{ pixel_x = 2; pixel_y = 5 }, @@ -27399,11 +27546,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood, /area/station/commons/lounge) -"jSg" = ( -/obj/structure/cable, -/obj/effect/landmark/event_spawn, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "jSj" = ( /obj/machinery/door/airlock/research{ glass = 1; @@ -28077,14 +28219,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/hallway/primary/central) -"kdy" = ( -/obj/machinery/vending/wardrobe/cargo_wardrobe, -/obj/effect/turf_decal/tile/brown/half/contrasted{ - dir = 8 - }, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron, -/area/station/cargo/storage) "kdA" = ( /obj/machinery/door/airlock/mining{ name = "Warehouse" @@ -29534,6 +29668,8 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 }, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/port/aft) "kGs" = ( @@ -29600,6 +29736,14 @@ /obj/structure/window/reinforced/spawner/directional/west, /turf/open/floor/engine, /area/station/science/explab) +"kHU" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light_switch/directional/north, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "kIG" = ( /obj/structure/rack, /obj/effect/spawner/random/maintenance/two, @@ -30045,6 +30189,11 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/commons/locker) +"kQZ" = ( +/obj/effect/spawner/random/structure/grille, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "kRc" = ( /obj/structure/table, /obj/item/multitool{ @@ -31111,7 +31260,6 @@ /area/station/engineering/storage/tech) "lkZ" = ( /obj/structure/cable, -/obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 }, @@ -32013,7 +32161,6 @@ /turf/open/floor/plating, /area/station/maintenance/port) "lEB" = ( -/obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet, @@ -32771,6 +32918,14 @@ /obj/vehicle/sealed/mecha/ripley/cargo, /turf/open/floor/plating, /area/station/cargo/warehouse) +"lUe" = ( +/obj/structure/reagent_dispensers/fueltank, +/obj/structure/sign/poster/contraband/random/directional/north, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "lUj" = ( /obj/structure/table, /obj/item/book/manual/wiki/security_space_law{ @@ -34530,6 +34685,15 @@ /obj/structure/window/spawner/directional/south, /turf/open/floor/iron/white, /area/station/security/prison/mess) +"mzs" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/mapping_helpers/broken_floor, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "mzu" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -34585,6 +34749,12 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/iron/dark, /area/station/hallway/primary/port) +"mAy" = ( +/obj/effect/turf_decal/tile/brown{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "mAJ" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -35780,13 +35950,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/engineering/atmospherics_engine) -"mVd" = ( -/obj/machinery/rnd/bepis, -/obj/effect/turf_decal/stripes/end{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "mVf" = ( /obj/structure/table/glass, /obj/item/reagent_containers/dropper, @@ -35829,7 +35992,6 @@ /turf/open/floor/plating, /area/station/engineering/atmos) "mVS" = ( -/obj/effect/landmark/generic_maintenance_landmark, /obj/effect/decal/cleanable/cobweb, /obj/effect/spawner/random/trash/janitor_supplies, /turf/open/floor/plating, @@ -37196,11 +37358,6 @@ }, /turf/open/floor/iron, /area/station/security/execution/transfer) -"nsT" = ( -/obj/structure/reagent_dispensers/fueltank, -/obj/structure/sign/poster/contraband/random/directional/north, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "nsZ" = ( /obj/structure/disposalpipe/segment{ dir = 5 @@ -37713,14 +37870,6 @@ /obj/structure/extinguisher_cabinet/directional/south, /turf/open/floor/wood, /area/station/service/bar/backroom) -"nBo" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Mining Dock Maintenance" - }, -/obj/structure/cable, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "nBp" = ( /obj/structure/sink/directional/east, /obj/effect/spawner/random/trash/mess, @@ -37963,12 +38112,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/security/execution/education) -"nEO" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "nET" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 1 @@ -38192,7 +38335,6 @@ dir = 4 }, /obj/structure/sign/poster/official/random/directional/north, -/obj/item/mod/module/signlang_radio, /turf/open/floor/iron/dark/corner{ dir = 1 }, @@ -38315,6 +38457,16 @@ /obj/effect/turf_decal/tile/neutral/opposingcorners, /turf/open/floor/iron, /area/station/commons/vacant_room/commissary) +"nME" = ( +/obj/structure/rack, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/item/storage/toolbox/emergency, +/obj/effect/spawner/random/maintenance, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "nMF" = ( /obj/machinery/light/small/directional/east, /obj/machinery/firealarm/directional/east, @@ -38506,13 +38658,6 @@ /obj/structure/bookcase/random/fiction, /turf/open/floor/wood, /area/station/service/library) -"nPC" = ( -/obj/structure/cable, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "nPJ" = ( /obj/structure/reagent_dispensers/watertank, /obj/effect/mapping_helpers/broken_floor, @@ -38705,7 +38850,6 @@ /turf/open/floor/plating, /area/station/maintenance/port/fore) "nTU" = ( -/obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 }, @@ -39316,12 +39460,6 @@ /obj/effect/mapping_helpers/airlock/access/all/service/hydroponics, /turf/open/floor/iron, /area/station/service/hydroponics) -"oee" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "oet" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on{ dir = 1 @@ -39488,6 +39626,14 @@ /obj/item/toy/cattoy, /turf/open/floor/plating, /area/station/medical/abandoned) +"oif" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "oip" = ( /obj/machinery/door/firedoor, /obj/structure/disposalpipe/segment, @@ -39531,6 +39677,12 @@ }, /turf/open/floor/engine/plasma, /area/station/engineering/atmos) +"okd" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/plating, +/area/station/maintenance/starboard/aft) "okP" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -40493,33 +40645,6 @@ /obj/machinery/light/small/directional/south, /turf/open/floor/plating, /area/station/cargo/storage) -"oDH" = ( -/obj/structure/table/reinforced, -/obj/item/folder/white{ - pixel_x = 4; - pixel_y = -3 - }, -/obj/machinery/door/firedoor, -/obj/item/folder/white{ - pixel_x = 4; - pixel_y = -3 - }, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 1; - id = "pharmacy_shutters"; - name = "Pharmacy Shutters" - }, -/obj/structure/desk_bell{ - pixel_x = -8 - }, -/obj/machinery/door/window/left/directional/north{ - dir = 2; - name = "Pharmacy Desk"; - req_access = list("pharmacy") - }, -/obj/effect/turf_decal/tile/yellow/fourcorners, -/turf/open/floor/iron/white, -/area/station/medical/pharmacy) "oDJ" = ( /obj/structure/sign/warning/vacuum/external, /turf/closed/wall, @@ -40993,18 +41118,6 @@ "oKU" = ( /turf/open/floor/circuit/green/telecomms/mainframe, /area/station/tcommsat/server) -"oKX" = ( -/obj/machinery/door/airlock/mining{ - name = "Mining Office" - }, -/obj/machinery/door/firedoor, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/obj/effect/landmark/navigate_destination, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "oLD" = ( /obj/structure/chair/comfy/beige, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -41278,7 +41391,6 @@ /turf/open/floor/iron, /area/station/science/xenobiology) "oQN" = ( -/obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 }, @@ -41390,6 +41502,32 @@ }, /turf/open/floor/iron, /area/station/engineering/atmos) +"oTp" = ( +/obj/structure/table/reinforced, +/obj/item/folder/white{ + pixel_x = 4; + pixel_y = -3 + }, +/obj/machinery/door/firedoor, +/obj/item/folder/white{ + pixel_x = 4; + pixel_y = -3 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 1; + id = "pharmacy_shutters"; + name = "Pharmacy Shutters" + }, +/obj/structure/desk_bell{ + pixel_x = -8 + }, +/obj/machinery/door/window/left/directional/north{ + name = "Pharmacy Desk"; + req_access = list("pharmacy") + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/floor/iron/white, +/area/station/medical/pharmacy) "oTD" = ( /obj/structure/frame/computer, /turf/open/floor/plating/airless, @@ -41914,7 +42052,6 @@ /obj/effect/mapping_helpers/airlock/access/all/medical/coroner, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment, /turf/open/floor/iron/dark, /area/station/medical/morgue) "pdX" = ( @@ -43265,15 +43402,6 @@ /obj/machinery/power/apc/auto_name/directional/east, /turf/open/floor/iron/grimy, /area/station/tcommsat/computer) -"pDh" = ( -/obj/structure/showcase/machinery/microwave{ - dir = 1; - pixel_y = 2 - }, -/obj/structure/table/wood, -/obj/machinery/light/small/directional/south, -/turf/open/floor/carpet, -/area/station/command/corporate_showroom) "pDl" = ( /obj/effect/turf_decal/delivery, /obj/machinery/door/window/left/directional/north{ @@ -43701,11 +43829,6 @@ }, /turf/open/floor/iron, /area/station/security/execution/transfer) -"pKe" = ( -/obj/structure/cable, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "pKs" = ( /obj/structure/table/wood, /obj/item/paper_bin/carbon{ @@ -44116,16 +44239,6 @@ /obj/effect/decal/cleanable/blood/old, /turf/open/floor/plating, /area/station/maintenance/starboard/lesser) -"pRG" = ( -/obj/machinery/door/airlock/maintenance{ - name = "Mining Dock Maintenance" - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "pRM" = ( /obj/machinery/disposal/bin, /obj/machinery/camera/directional/east{ @@ -45138,6 +45251,12 @@ }, /turf/open/floor/iron/dark, /area/station/command/bridge) +"qlr" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "qlG" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 @@ -46170,6 +46289,21 @@ /obj/structure/sign/warning/docking, /turf/closed/wall, /area/station/hallway/secondary/entry) +"qHC" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/textured_half, +/area/station/bitrunning/den) "qHK" = ( /obj/effect/spawner/random/structure/grille, /turf/open/floor/plating, @@ -46248,6 +46382,13 @@ /obj/structure/window/reinforced/spawner/directional/south, /turf/open/floor/iron/dark, /area/station/ai_monitored/aisat/exterior) +"qIP" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/cryo_cell, +/turf/open/floor/iron/dark/textured, +/area/station/medical/cryo) "qIS" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, @@ -47446,6 +47587,13 @@ /obj/machinery/portable_atmospherics/canister/nitrous_oxide, /turf/open/floor/iron/dark, /area/station/science/ordnance/storage) +"raL" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/machinery/computer/order_console/mining, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "raT" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -47470,15 +47618,6 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) -"rbu" = ( -/obj/machinery/door/airlock/mining{ - name = "Mining Office" - }, -/obj/structure/cable, -/obj/machinery/door/firedoor, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "rbw" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -49250,13 +49389,6 @@ /obj/item/paper/fluff/ids_for_dummies, /turf/open/floor/wood, /area/station/command/heads_quarters/hop) -"rJu" = ( -/obj/structure/rack, -/obj/effect/decal/cleanable/cobweb/cobweb2, -/obj/item/storage/toolbox/emergency, -/obj/effect/spawner/random/maintenance, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "rJA" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -49552,6 +49684,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/plating, /area/station/maintenance/port/fore) +"rNV" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Mining Dock Maintenance" + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/obj/effect/mapping_helpers/airlock/access/any/supply/mining, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "rOz" = ( /obj/effect/spawner/random/structure/crate, /turf/open/floor/plating, @@ -49787,6 +49930,9 @@ }, /turf/open/floor/plating, /area/station/service/chapel) +"rSa" = ( +/turf/closed/wall, +/area/station/bitrunning/den) "rSi" = ( /obj/effect/landmark/start/chief_engineer, /obj/structure/chair/office/light{ @@ -50585,6 +50731,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 1 }, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/fore) "shl" = ( @@ -53095,6 +53242,24 @@ /obj/effect/mapping_helpers/burnt_floor, /turf/open/floor/plating, /area/station/maintenance/port) +"taq" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 4 + }, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/textured_half, +/area/station/bitrunning/den) "tar" = ( /obj/machinery/medical_kiosk, /obj/effect/turf_decal/tile/blue/half/contrasted, @@ -53180,13 +53345,6 @@ /obj/structure/bookcase/random/nonfiction, /turf/open/floor/wood, /area/station/service/library) -"tcf" = ( -/obj/machinery/computer/order_console/mining, -/obj/effect/turf_decal/tile/brown/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/miningoffice) "tck" = ( /obj/structure/extinguisher_cabinet/directional/north, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -54086,6 +54244,11 @@ /obj/structure/cable, /turf/open/floor/iron/cafeteria, /area/station/service/kitchen) +"ttG" = ( +/obj/machinery/netpod, +/obj/effect/decal/cleanable/robot_debris, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "ttM" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -54585,17 +54748,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/white, /area/station/medical/abandoned) -"tDv" = ( -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) -"tDD" = ( -/obj/effect/spawner/random/structure/crate, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "tDN" = ( /obj/structure/chair{ dir = 8 @@ -54920,9 +55072,6 @@ /obj/item/mod/module/plasma_stabilizer{ pixel_x = 16 }, -/obj/item/mod/module/signlang_radio{ - pixel_x = 16 - }, /obj/item/mod/module/thermal_regulator{ pixel_x = 16 }, @@ -55611,14 +55760,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, /turf/open/floor/iron, /area/station/security/prison/garden) -"tVq" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/sorting/mail/flip{ - dir = 1 - }, -/obj/effect/mapping_helpers/mail_sorting/supply/disposals, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "tVr" = ( /obj/machinery/disposal/delivery_chute{ dir = 4 @@ -55706,6 +55847,16 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/port) +"tWj" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/brown{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "tWq" = ( /obj/effect/spawner/random/trash/janitor_supplies, /obj/effect/mapping_helpers/broken_floor, @@ -56253,18 +56404,6 @@ }, /turf/open/floor/iron, /area/station/security/office) -"uew" = ( -/obj/structure/table/reinforced, -/obj/machinery/microwave{ - pixel_y = 6 - }, -/obj/effect/turf_decal/stripes/corner, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron/checker, -/area/station/engineering/storage_shared) "ueB" = ( /obj/machinery/airalarm/directional/south, /obj/effect/turf_decal/tile/yellow/half/contrasted, @@ -56631,7 +56770,6 @@ /turf/open/floor/iron/white, /area/station/medical/chemistry) "unw" = ( -/obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 }, @@ -56834,7 +56972,6 @@ /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 }, -/obj/machinery/firealarm/directional/east, /turf/open/floor/iron/dark, /area/station/security/execution/education) "urs" = ( @@ -57083,7 +57220,6 @@ /turf/open/floor/iron, /area/station/ai_monitored/command/storage/eva) "uuz" = ( -/obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 8 }, @@ -57292,6 +57428,13 @@ /obj/effect/turf_decal/tile/red/half/contrasted, /turf/open/floor/iron/dark, /area/station/security/execution/education) +"uyj" = ( +/obj/machinery/vending/wardrobe/cargo_wardrobe, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "uyr" = ( /obj/item/radio/intercom/directional/east, /obj/structure/disposalpipe/segment, @@ -57585,9 +57728,7 @@ dir = 4; id = "garbage" }, -/obj/machinery/recycler{ - dir = 8 - }, +/obj/machinery/recycler, /turf/open/floor/plating, /area/station/maintenance/disposal) "uEO" = ( @@ -59602,6 +59743,7 @@ "vmY" = ( /obj/structure/sign/poster/contraband/busty_backdoor_xeno_babes_6/directional/east, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/port/aft) "vnk" = ( @@ -59779,6 +59921,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/primary/central) +"vpU" = ( +/obj/effect/spawner/random/structure/crate, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/plating, +/area/station/maintenance/port/fore) "vpX" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -59885,13 +60034,6 @@ /obj/effect/turf_decal/tile/red/half/contrasted, /turf/open/floor/iron, /area/station/security/checkpoint/customs) -"vrS" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/cryo_cell, -/turf/open/floor/iron/dark/textured, -/area/station/medical/cryo) "vsr" = ( /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -60379,7 +60521,6 @@ /turf/open/floor/iron, /area/station/science/robotics/lab) "vzX" = ( -/obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 }, @@ -63214,13 +63355,6 @@ }, /turf/open/floor/iron, /area/station/security/brig) -"wxY" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/turf/open/floor/plating, -/area/station/maintenance/port/fore) "wyn" = ( /obj/machinery/hydroponics/soil, /obj/item/shovel/spade, @@ -63767,6 +63901,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) +"wKe" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/cryo_cell, +/turf/open/floor/iron/dark/textured, +/area/station/medical/cryo) "wKu" = ( /obj/structure/cable, /turf/open/floor/wood, @@ -64418,31 +64559,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/disposal) -"wVc" = ( -/obj/structure/table/reinforced, -/obj/item/folder/white{ - pixel_x = 4; - pixel_y = -3 - }, -/obj/machinery/door/firedoor, -/obj/item/folder/white{ - pixel_x = 4; - pixel_y = -3 - }, -/obj/item/pen, -/obj/machinery/door/poddoor/shutters/preopen{ - dir = 4; - id = "pharmacy_shutters_2"; - name = "Pharmacy Shutters" - }, -/obj/machinery/door/window/right/directional/east{ - dir = 8; - name = "Pharmacy Desk"; - req_access = list("pharmacy") - }, -/obj/effect/turf_decal/tile/yellow/fourcorners, -/turf/open/floor/iron/white, -/area/station/medical/pharmacy) "wVd" = ( /obj/structure/cable, /obj/effect/decal/cleanable/dirt, @@ -64875,6 +64991,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white/side, /area/station/science/lobby) +"xdY" = ( +/obj/machinery/door/airlock/mining{ + name = "Mining Office" + }, +/obj/structure/cable, +/obj/machinery/door/firedoor, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/obj/effect/mapping_helpers/airlock/access/any/supply/mining, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "xel" = ( /obj/structure/closet/firecloset, /turf/open/floor/plating, @@ -65420,6 +65546,16 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/science/genetics) +"xoc" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/miningoffice) "xor" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/cable, @@ -66712,6 +66848,15 @@ }, /turf/open/floor/iron, /area/station/construction/mining/aux_base) +"xMk" = ( +/obj/structure/table/reinforced, +/obj/machinery/microwave/engineering/cell_included, +/obj/effect/turf_decal/tile/neutral/opposingcorners{ + dir = 1 + }, +/obj/machinery/digital_clock/directional/south, +/turf/open/floor/iron/dark, +/area/station/medical/break_room) "xMl" = ( /obj/machinery/navbeacon{ codes_txt = "patrol;next_patrol=15-Court"; @@ -84439,10 +84584,10 @@ nmg vEV jPp jXu -aaa -aaa -aaa -pnI +rSa +rSa +rSa +hKg bUm kRe qRa @@ -84696,9 +84841,9 @@ jXu kXA ufv jXu -aaa -aaa -aaa +cly +taq +ghJ hKg hKg fQW @@ -84953,10 +85098,10 @@ jXu jXu hWS jXu -jXu -jXu -jXu -jXu +dzh +iUV +guZ +fBl qvY kRe wxh @@ -84975,8 +85120,8 @@ hxo hxo hxo cbz -mVd -kdy +uyj +jty jLb tTa kQP @@ -85208,12 +85353,12 @@ gYE lBm qKy ybN -gFz -tDv -hXA -jXu -fGB +edP jXu +bje +qHC +ttG +fBl pPh aFd nVG @@ -85465,12 +85610,12 @@ iPE vfv cTQ xte -nEO -sHu -iVm -jXu -jXu +mzs jXu +kHU +hDd +rSa +rSa jpG kRe nVG @@ -85722,18 +85867,18 @@ gYE uEC wgw twr -uuD -jSg -nPC -pKe +bSm jXu +fBl +eEb +rSa ouc dSG cLj xYl cLj mUz -rbu +xdY rgN mmR mmR @@ -85978,19 +86123,19 @@ wvR pQu vEH jXu -nsT -uuD -wxY -tVq -oee -pRG -xyz +lUe +gQv +rNV +cGL +xoc +xoc +tWj xyz kdC btt aqx shx -oKX +bGM fiC dAk rhn @@ -86235,13 +86380,13 @@ vhU eNU aQE jXu -rJu -iUE -bKK +nME +dwA jXu -jXu -jXu -tcf +dob +qlr +raL +mAy cLj kRe aFd @@ -86493,10 +86638,10 @@ jXu jXu jXu jXu -uuD -bKK +bSm +jXu +jXu jXu -fhn jXu lJo xJV @@ -86750,13 +86895,13 @@ mVS xxp twr sxn -uuD -tDD +oif +vpU twr -bwj +fhn jXu jXu -nBo +fNH jXu jXu jXu @@ -88864,7 +89009,7 @@ sQx kir vXH pOa -vrS +wKe aez ajK aSe @@ -89151,7 +89296,7 @@ nGr aST tBs vRN -imy +xMk rOF ryf vnV @@ -89378,7 +89523,7 @@ vXH sQY tWq pOa -hTi +qIP jkT gdp eRc @@ -94522,7 +94667,7 @@ bKB eAL xQY kcF -oDH +oTp oar keK lXA @@ -94786,7 +94931,7 @@ hYA jsh rvE tZJ -wVc +cph tZJ eIO wKC @@ -95025,7 +95170,7 @@ jzN sUy dkL uOd -pDh +fLn jzN qyI qaP @@ -96610,7 +96755,7 @@ jxW svS tjE rDB -nFa +gvZ lqh dKC mHK @@ -100982,7 +101127,7 @@ rxG dpN dpN egk -oEx +aNL bIa vYl nFa @@ -102510,7 +102655,7 @@ oWk xuD fFa xdF -fPD +qkl fPD fPD xZx @@ -102767,7 +102912,7 @@ oWk xuD sip bLd -clj +kQZ bLd bLd bLd @@ -103024,8 +103169,8 @@ oWk lPc qZg bLd -fPD -fPD +qkl +qkl fPD uGX oWk @@ -103282,7 +103427,7 @@ xuD qZg bLd yeI -fPD +okd fPD nYU oWk @@ -103713,10 +103858,10 @@ lOU nmI lnc sBa -hVW +obw lnc avU -ckG +cKC lnc crL wcr @@ -104314,7 +104459,7 @@ fPD fPD bLd ojt -iyj +eQY bLd tjf tjf @@ -104828,7 +104973,7 @@ vXO qkl bLd ias -fPD +hPG nMj pPN fPD @@ -105592,7 +105737,7 @@ yhu rnn oWk nPJ -jJm +jLI fwP fwP fwP @@ -107628,7 +107773,7 @@ fWA fWA dRj lWq -fBi +lWq lWq tLg pnH @@ -109907,7 +110052,7 @@ qjl wlx qPT jRb -uew +afF qsv sKD lUz diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm index 5f7a19198bbe91..e26ac494a0f872 100644 --- a/_maps/map_files/Mining/Lavaland.dmm +++ b/_maps/map_files/Mining/Lavaland.dmm @@ -1508,6 +1508,13 @@ /obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance, /turf/open/floor/plating, /area/mine/maintenance/public/north) +"jk" = ( +/obj/structure/table, +/obj/item/storage/box/bandages{ + pixel_y = 6 + }, +/turf/open/floor/iron/white, +/area/mine/laborcamp/production) "jm" = ( /obj/machinery/door/airlock/public/glass{ name = "Showers" @@ -1932,6 +1939,17 @@ }, /turf/open/lava/smooth/lava_land_surface, /area/lavaland/surface/outdoors) +"lA" = ( +/obj/machinery/recycler{ + dir = 8 + }, +/obj/machinery/conveyor{ + dir = 4; + id = "mining_disposals" + }, +/obj/effect/turf_decal/sand/plating/volcanic, +/turf/open/floor/plating/lavaland_atmos, +/area/mine/maintenance/service/disposals) "lC" = ( /obj/structure/stone_tile/block/cracked{ dir = 1 @@ -2170,19 +2188,6 @@ }, /turf/open/indestructible/boss, /area/lavaland/surface/outdoors) -"mu" = ( -/obj/structure/table, -/obj/item/storage/pill_bottle/epinephrine{ - pixel_x = -2; - pixel_y = 4 - }, -/obj/effect/turf_decal/trimline/blue/filled/line{ - dir = 10 - }, -/turf/open/floor/iron/white/smooth_corner{ - dir = 8 - }, -/area/mine/medical) "mv" = ( /obj/structure/stone_tile{ dir = 4 @@ -5391,10 +5396,6 @@ }, /turf/open/floor/iron/dark, /area/mine/laborcamp/security) -"HE" = ( -/obj/structure/table, -/turf/open/floor/iron/white, -/area/mine/laborcamp/production) "HF" = ( /obj/structure/stone_tile{ dir = 1 @@ -5809,6 +5810,23 @@ dir = 1 }, /area/mine/living_quarters) +"JQ" = ( +/obj/structure/table, +/obj/effect/turf_decal/trimline/blue/filled/line{ + dir = 10 + }, +/obj/item/storage/box/bandages{ + pixel_y = 6; + pixel_x = 4 + }, +/obj/item/storage/pill_bottle/epinephrine{ + pixel_x = -6; + pixel_y = 4 + }, +/turf/open/floor/iron/white/smooth_corner{ + dir = 8 + }, +/area/mine/medical) "JR" = ( /obj/structure/stone_tile, /obj/structure/stone_tile{ @@ -6772,17 +6790,6 @@ }, /turf/open/floor/plating, /area/mine/production) -"PL" = ( -/obj/machinery/recycler{ - dir = 8 - }, -/obj/machinery/conveyor{ - dir = 4; - id = "mining_disposals" - }, -/obj/effect/turf_decal/sand/plating/volcanic, -/turf/open/floor/plating/lavaland_atmos, -/area/mine/maintenance/service/disposals) "PR" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/carpet/executive, @@ -23744,7 +23751,7 @@ aj aj eR Kw -HE +jk ff mU Fv @@ -36321,7 +36328,7 @@ pU mA su xG -PL +lA Sd pU aj @@ -39439,7 +39446,7 @@ yp yp Dz LG -mu +JQ It Xp Ss diff --git a/_maps/map_files/NorthStar/north_star.dmm b/_maps/map_files/NorthStar/north_star.dmm index 53e9e0a8d549f9..b43c9c7acfc394 100644 --- a/_maps/map_files/NorthStar/north_star.dmm +++ b/_maps/map_files/NorthStar/north_star.dmm @@ -185,6 +185,10 @@ "abJ" = ( /obj/machinery/light_switch/directional/north, /obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, /turf/open/floor/wood, /area/station/maintenance/floor3/starboard/aft) "abP" = ( @@ -318,12 +322,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/catwalk_floor/iron_dark, /area/station/maintenance/floor2/port) -"ads" = ( -/obj/effect/turf_decal/stripes{ - dir = 9 - }, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "adB" = ( /obj/structure/closet/crate/bin{ name = "biowaste bin" @@ -577,7 +575,6 @@ dir = 8 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron/dark, /area/station/medical/morgue) "ahd" = ( @@ -1736,22 +1733,6 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/wood, /area/station/medical/psychology) -"avu" = ( -/obj/effect/turf_decal/siding/thinplating_new/dark{ - dir = 4 - }, -/obj/machinery/door/airlock/hatch{ - name = "Maintenance Access" - }, -/obj/effect/mapping_helpers/airlock/access/any/supply/general, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/pod/dark, -/area/station/maintenance/floor1/starboard/fore) "avH" = ( /obj/structure/table/glass, /obj/item/experi_scanner, @@ -1988,6 +1969,17 @@ }, /turf/open/floor/catwalk_floor, /area/station/maintenance/floor3/port/fore) +"azj" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, +/obj/effect/turf_decal/arrows{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/disposalpipe/trunk/multiz, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "azu" = ( /obj/structure/table/wood, /obj/item/gun/ballistic/shotgun/doublebarrel, @@ -2537,6 +2529,7 @@ dir = 4 }, /obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/pod/light, /area/station/maintenance/solars/port/aft) "aHk" = ( @@ -2997,13 +2990,6 @@ }, /turf/open/floor/iron/dark/textured, /area/station/commons/fitness) -"aOv" = ( -/obj/effect/turf_decal/stripes{ - dir = 10 - }, -/obj/effect/mapping_helpers/broken_floor, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "aOx" = ( /obj/machinery/griddle, /obj/machinery/airalarm/directional/west, @@ -3492,11 +3478,6 @@ /obj/effect/mapping_helpers/airlock/access/any/medical/psychology, /turf/open/floor/catwalk_floor, /area/station/hallway/floor2/fore) -"aUn" = ( -/obj/effect/spawner/random/structure/table_or_rack, -/obj/effect/spawner/random/trash/soap, -/turf/open/floor/pod/light, -/area/station/maintenance/floor1/starboard/fore) "aUG" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/spawner/random/structure/table_or_rack, @@ -3750,12 +3731,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/carpet/purple, /area/station/maintenance/floor1/port/aft) -"aXl" = ( -/obj/machinery/cryo_cell{ - dir = 4 - }, -/turf/open/floor/iron/dark/textured, -/area/station/medical/cryo) "aXq" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -5438,18 +5413,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron/white, /area/station/science/xenobiology/hallway) -"bqm" = ( -/obj/machinery/door/firedoor/border_only{ - dir = 1 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/turf/open/floor/catwalk_floor, -/area/station/maintenance/floor1/starboard/fore) "bqn" = ( /obj/structure/closet/crate, /obj/item/reagent_containers/cup/bowl, @@ -5596,6 +5559,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/white, /area/station/science/robotics/lab) +"brL" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/extinguisher_cabinet/directional/west, +/turf/open/floor/iron/stairs{ + dir = 1 + }, +/area/station/bitrunning/den) +"brM" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/floor4/port/fore) "brN" = ( /obj/effect/spawner/structure/window/hollow/reinforced/directional, /obj/structure/disposalpipe/segment, @@ -5616,6 +5592,15 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/medical/abandoned) +"bsq" = ( +/obj/machinery/computer/order_console/bitrunning{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/end{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "bsu" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -6387,6 +6372,11 @@ dir = 4 }, /area/station/hallway/floor3/aft) +"bAh" = ( +/obj/effect/spawner/random/structure/table_or_rack, +/obj/effect/spawner/random/trash/soap, +/turf/open/floor/plating, +/area/station/maintenance/floor1/starboard/fore) "bAj" = ( /obj/machinery/conveyor{ dir = 9; @@ -8942,14 +8932,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/smooth, /area/station/construction) -"cjz" = ( -/obj/machinery/door/firedoor/border_only{ - dir = 8 - }, -/obj/machinery/firealarm/directional/east, -/obj/machinery/firealarm/directional/east, -/turf/open/floor/pod/light, -/area/station/maintenance/floor1/starboard/fore) "cjB" = ( /obj/effect/turf_decal/stripes/line, /obj/effect/decal/cleanable/dirt, @@ -10003,17 +9985,6 @@ }, /turf/open/floor/engine, /area/station/engineering/atmos/hfr_room) -"cxp" = ( -/obj/machinery/exoscanner, -/obj/effect/turf_decal/stripes{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/obj/structure/extinguisher_cabinet/directional/west, -/turf/open/floor/iron/corner, -/area/station/cargo/drone_bay) "cxx" = ( /obj/effect/turf_decal/tile/green/half{ dir = 4 @@ -10256,6 +10227,21 @@ }, /turf/open/floor/engine/vacuum, /area/station/science/ordnance/freezerchamber) +"cBT" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, +/obj/effect/turf_decal/arrows{ + dir = 4 + }, +/obj/structure/railing{ + layer = 3.1 + }, +/obj/effect/decal/cleanable/robot_debris, +/obj/structure/disposalpipe/segment, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "cBU" = ( /obj/structure/window/reinforced/spawner/directional/west, /obj/structure/flora/bush/sunny/style_random, @@ -10364,6 +10350,12 @@ /obj/machinery/chem_master, /turf/open/floor/iron/dark/textured, /area/station/medical/pharmacy) +"cDe" = ( +/obj/machinery/computer/quantum_console{ + dir = 4 + }, +/turf/open/floor/iron/dark/smooth_corner, +/area/station/bitrunning/den) "cDh" = ( /obj/item/broken_bottle, /turf/open/floor/carpet/neon/simple/pink/nodots, @@ -11658,6 +11650,7 @@ /obj/effect/mapping_helpers/airlock/unres{ dir = 8 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/pod/light, /area/station/maintenance/floor3/starboard/aft) "cVX" = ( @@ -12053,11 +12046,11 @@ "dad" = ( /obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance, /obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/door/airlock/hatch{ name = "Emergency Power" }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/pod/dark, /area/station/maintenance/floor4/port/fore) "daf" = ( @@ -13089,6 +13082,7 @@ "dqJ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/pod/light, /area/station/maintenance/floor2/port/aft) "dqQ" = ( @@ -13204,6 +13198,7 @@ /obj/structure/chair/office{ dir = 8 }, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/wood, /area/station/maintenance/floor2/starboard) "dsz" = ( @@ -14681,15 +14676,6 @@ /obj/effect/landmark/start/captain, /turf/open/floor/wood/tile, /area/station/command/heads_quarters/captain/private) -"dNf" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/disposalpipe/segment{ - dir = 4 - }, -/turf/open/floor/catwalk_floor, -/area/station/maintenance/floor1/starboard/fore) "dNm" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 1 @@ -15313,6 +15299,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 1 }, +/obj/item/storage/medkit/regular, /turf/open/floor/iron/white, /area/station/security/medical) "dVt" = ( @@ -15544,10 +15531,6 @@ dir = 4 }, /area/station/hallway/floor2/fore) -"dXP" = ( -/obj/machinery/computer/exodrone_control_console, -/turf/open/floor/iron/dark, -/area/station/cargo/drone_bay) "dXX" = ( /obj/structure/window/reinforced/spawner/directional/west, /obj/machinery/rnd/production/techfab/department/security, @@ -15583,19 +15566,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/iron, /area/station/engineering/atmos/project) -"dYm" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 10 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/cargo/storage) "dYq" = ( /obj/structure/reagent_dispensers/watertank, /obj/effect/turf_decal/stripes{ @@ -15771,6 +15741,10 @@ }, /turf/open/floor/engine/hull, /area/space/nearstation) +"ebC" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/catwalk_floor, +/area/station/maintenance/floor1/starboard) "ebE" = ( /obj/structure/disposalpipe/segment{ dir = 9 @@ -16845,6 +16819,22 @@ /obj/machinery/duct, /turf/open/floor/iron/showroomfloor, /area/station/commons/toilet) +"eoo" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/structure/railing/corner/end{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "eop" = ( /obj/structure/disposalpipe/segment{ dir = 6 @@ -17018,6 +17008,20 @@ /obj/structure/cable, /turf/open/floor/catwalk_floor, /area/station/maintenance/floor1/starboard) +"erV" = ( +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/effect/turf_decal/stripes, +/obj/effect/turf_decal/trimline/brown/line, +/turf/open/floor/iron/dark/smooth_half, +/area/station/bitrunning/den) "erY" = ( /obj/machinery/vending/wardrobe/bar_wardrobe, /turf/open/floor/wood, @@ -17148,6 +17152,21 @@ }, /turf/open/floor/pod/dark, /area/station/maintenance/floor3/starboard) +"eul" = ( +/obj/structure/table/reinforced, +/obj/item/storage/toolbox/mechanical{ + pixel_x = -2; + pixel_y = 8 + }, +/obj/item/cigbutt/cigarbutt{ + pixel_x = 7 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/iron/dark/smooth_half, +/area/station/bitrunning/den) "euu" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, @@ -18557,10 +18576,6 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/wood/tile, /area/station/service/library) -"ePI" = ( -/obj/effect/turf_decal/stripes, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "ePJ" = ( /obj/effect/turf_decal/trimline/red/line{ dir = 1 @@ -18784,11 +18799,6 @@ /obj/machinery/newscaster/directional/west, /turf/open/floor/wood, /area/station/hallway/secondary/entry) -"eTD" = ( -/obj/effect/turf_decal/bot, -/obj/structure/sign/poster/random/directional/north, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) "eTH" = ( /obj/structure/flora/bush/sparsegrass/style_random, /mob/living/carbon/human/species/monkey, @@ -20969,12 +20979,6 @@ dir = 1 }, /area/station/command/bridge) -"fBB" = ( -/obj/effect/turf_decal/stripes{ - dir = 5 - }, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "fBM" = ( /obj/effect/turf_decal/delivery, /turf/open/floor/iron/dark, @@ -21014,6 +21018,14 @@ "fCp" = ( /turf/open/floor/plating/airless, /area/space) +"fCw" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 8 + }, +/obj/machinery/holopad, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "fCx" = ( /obj/structure/rack, /turf/open/floor/pod/dark, @@ -23141,11 +23153,6 @@ /obj/machinery/light/small/directional/east, /turf/open/floor/wood/tile, /area/station/service/library) -"gex" = ( -/obj/structure/rack, -/obj/effect/spawner/random/maintenance/two, -/turf/open/floor/pod/light, -/area/station/maintenance/floor1/starboard/fore) "geA" = ( /obj/effect/turf_decal/tile/blue/opposingcorners, /obj/item/kirbyplants/random, @@ -23674,6 +23681,7 @@ "gmg" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/stripes/line, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/pod/light, /area/station/maintenance/floor4/port/fore) "gmj" = ( @@ -24121,6 +24129,19 @@ /obj/structure/chair/stool/bar/directional/east, /turf/open/floor/iron/white, /area/station/science/circuits) +"gso" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/storage) "gsp" = ( /obj/machinery/door/airlock/medical{ id_tag = "asylum_airlock_exterior"; @@ -24343,10 +24364,6 @@ }, /turf/open/floor/iron/dark/textured, /area/station/medical/medbay/lobby) -"gvu" = ( -/obj/effect/spawner/random/structure/crate, -/turf/open/floor/pod/light, -/area/station/maintenance/floor1/starboard/fore) "gvx" = ( /obj/effect/turf_decal/trimline/blue/filled/corner, /turf/open/floor/iron/white, @@ -24892,12 +24909,6 @@ /obj/structure/extinguisher_cabinet/directional/west, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) -"gCn" = ( -/obj/effect/decal/cleanable/dirt, -/obj/machinery/light/broken/directional/north, -/obj/item/radio/intercom/directional/north, -/turf/open/floor/catwalk_floor/iron_smooth, -/area/station/cargo/warehouse) "gCv" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -25138,6 +25149,11 @@ /obj/machinery/door/firedoor/border_only, /turf/open/floor/pod/dark, /area/station/maintenance/floor2/starboard/aft) +"gFU" = ( +/obj/machinery/computer/exodrone_control_console, +/obj/structure/extinguisher_cabinet/directional/west, +/turf/open/floor/iron/dark, +/area/station/cargo/drone_bay) "gGe" = ( /obj/machinery/telecomms/bus/preset_one, /turf/open/floor/circuit/telecomms, @@ -27631,7 +27647,7 @@ /turf/open/floor/iron/white, /area/station/science/ordnance/testlab) "hnH" = ( -/obj/machinery/microwave, +/obj/machinery/microwave/engineering/cell_included, /obj/structure/table/reinforced/rglass, /obj/effect/turf_decal/tile/blue/fourcorners, /turf/open/floor/iron/white/textured, @@ -28092,6 +28108,13 @@ }, /turf/open/floor/pod/dark, /area/station/maintenance/floor2/port/fore) +"htK" = ( +/obj/machinery/netpod, +/obj/structure/railing{ + layer = 3.1 + }, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "htW" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/catwalk_floor/iron, @@ -28687,6 +28710,10 @@ /obj/effect/spawner/random/maintenance, /turf/open/floor/pod/light, /area/station/maintenance/floor2/port/aft) +"hBR" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/catwalk_floor/iron_smooth, +/area/station/cargo/warehouse) "hBT" = ( /obj/structure/table, /obj/structure/bedsheetbin, @@ -30504,6 +30531,16 @@ }, /turf/open/floor/iron/dark, /area/station/commons/dorms/room4) +"iaJ" = ( +/obj/machinery/netpod, +/obj/effect/decal/cleanable/vomit/old{ + pixel_x = -12; + pixel_y = -13 + }, +/obj/item/radio/intercom/directional/north, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "iaO" = ( /obj/structure/rack, /obj/structure/sign/nanotrasen{ @@ -30596,10 +30633,6 @@ dir = 4 }, /area/station/commons/storage/primary) -"icf" = ( -/obj/effect/spawner/random/maintenance, -/turf/open/floor/pod/light, -/area/station/maintenance/floor1/starboard/fore) "ick" = ( /obj/effect/turf_decal/trimline/brown/warning{ dir = 8 @@ -30675,7 +30708,7 @@ /turf/open/floor/plating, /area/station/maintenance/floor3/starboard/fore) "idf" = ( -/mob/living/simple_animal/sloth/paperwork, +/mob/living/basic/sloth/paperwork, /obj/effect/turf_decal/tile/yellow, /obj/effect/turf_decal/tile/brown{ dir = 4 @@ -31484,6 +31517,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) +"ioi" = ( +/obj/machinery/quantum_server, +/obj/effect/turf_decal/bot/left, +/turf/open/floor/iron/dark/smooth_corner{ + dir = 4 + }, +/area/station/bitrunning/den) "iom" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -31751,7 +31791,6 @@ /turf/open/floor/engine, /area/station/engineering/supermatter/room) "irp" = ( -/obj/effect/landmark/generic_maintenance_landmark, /obj/effect/baseturf_helper/reinforced_plating/ceiling, /turf/open/floor/iron, /area/station/maintenance/disposal/incinerator) @@ -32678,6 +32717,11 @@ /obj/machinery/firealarm/directional/east, /turf/open/floor/catwalk_floor, /area/station/maintenance/floor3/starboard/fore) +"iDJ" = ( +/obj/structure/rack, +/obj/item/stack/sheet/leather, +/turf/open/floor/plating, +/area/station/maintenance/floor1/starboard/fore) "iDP" = ( /obj/structure/cable/multilayer/multiz, /turf/open/floor/plating, @@ -33362,12 +33406,6 @@ /obj/effect/mapping_helpers/mail_sorting/service/bar, /turf/open/floor/iron/dark/side, /area/station/hallway/floor3/fore) -"iOl" = ( -/obj/machinery/modular_computer/preset/civilian, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/cable, -/turf/open/floor/iron/dark, -/area/station/cargo/drone_bay) "iOp" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -33685,6 +33723,7 @@ /area/station/service/library/lounge) "iRo" = ( /obj/machinery/firealarm/directional/north, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/catwalk_floor, /area/station/maintenance/floor1/starboard) "iRr" = ( @@ -34801,6 +34840,13 @@ /obj/structure/cable, /turf/open/floor/pod/light, /area/station/maintenance/floor1/starboard/fore) +"jhP" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/turf_decal/stripes{ + dir = 8 + }, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "jhU" = ( /turf/open/floor/iron/white, /area/station/science/robotics/lab) @@ -35449,6 +35495,12 @@ /obj/structure/reagent_dispensers/watertank, /turf/open/floor/iron, /area/station/maintenance/floor1/starboard/fore) +"jsb" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/mapping_helpers/broken_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/wood, +/area/station/maintenance/floor3/starboard/aft) "jse" = ( /obj/machinery/door/airlock{ name = "Bartender's Backroom" @@ -36150,6 +36202,22 @@ }, /turf/open/floor/carpet/royalblack, /area/station/service/kitchen/diner) +"jAr" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/obj/machinery/door/airlock/mining/glass{ + name = "Bitrunning Den" + }, +/turf/open/floor/pod/dark, +/area/station/bitrunning/den) "jAB" = ( /obj/machinery/light/floor, /turf/open/floor/iron/dark/side{ @@ -37739,6 +37807,13 @@ /obj/effect/turf_decal/trimline/purple/warning, /turf/open/floor/iron/dark, /area/station/hallway/floor2/fore) +"jWJ" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "jWR" = ( /obj/structure/railing/corner, /obj/effect/turf_decal/siding/wood/corner{ @@ -38120,6 +38195,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/mapping_helpers/airlock/access/all/engineering/maintenance, /obj/structure/barricade/wooden/crude, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/pod/light, /area/station/maintenance/floor1/starboard) "kca" = ( @@ -41268,19 +41344,6 @@ /obj/effect/spawner/random/engineering/flashlight, /turf/open/floor/pod/light, /area/station/maintenance/floor2/port/aft) -"kQL" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "kQN" = ( /obj/effect/mapping_helpers/airlock/access/any/engineering/maintenance, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -41912,13 +41975,6 @@ /obj/structure/rack, /turf/open/floor/pod/light, /area/station/maintenance/floor2/port/fore) -"kYs" = ( -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/structure/disposalpipe/trunk/multiz, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "kYt" = ( /obj/structure/chair/comfy/carp, /turf/open/floor/carpet/neon/simple/pink/nodots, @@ -42578,6 +42634,15 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"lgs" = ( +/obj/structure/sign/poster/random/directional/north, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/decal/cleanable/oil, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 8 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "lgv" = ( /obj/structure/rack, /obj/item/book/manual/nuclear, @@ -42879,7 +42944,13 @@ /area/station/medical/chemistry) "lkI" = ( /obj/structure/table, -/obj/item/storage/box/donkpockets, +/obj/item/storage/box/bandages{ + pixel_y = 6; + pixel_x = -6 + }, +/obj/item/storage/box/donkpockets{ + pixel_x = 6 + }, /turf/open/floor/catwalk_floor/iron, /area/station/cargo/storage) "lkP" = ( @@ -43338,6 +43409,7 @@ /area/station/maintenance/floor2/port) "lrM" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/pod/light, /area/station/maintenance/solars/starboard/aft) "lrN" = ( @@ -43948,13 +44020,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/checker, /area/station/cargo/miningdock) -"lAv" = ( -/obj/machinery/cryo_cell{ - dir = 8 - }, -/obj/structure/sign/poster/official/random/directional/east, -/turf/open/floor/iron/dark/textured, -/area/station/medical/cryo) "lAD" = ( /obj/effect/turf_decal/trimline/green/filled/arrow_cw{ dir = 10 @@ -44593,12 +44658,6 @@ /obj/structure/reagent_dispensers/fueltank, /turf/open/floor/pod/light, /area/station/maintenance/floor1/port) -"lJl" = ( -/obj/machinery/door/firedoor/border_only{ - dir = 8 - }, -/turf/open/floor/pod/light, -/area/station/maintenance/floor1/starboard/fore) "lJn" = ( /obj/item/radio/intercom/directional/west, /turf/open/floor/iron/dark/side{ @@ -48412,18 +48471,6 @@ /obj/effect/landmark/start/assistant, /turf/open/floor/carpet/red, /area/station/commons/dorms/apartment1) -"mFK" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/structure/cable, -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/structure/railing{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/turf/open/floor/iron, -/area/station/cargo/storage) "mFP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -50154,17 +50201,6 @@ }, /turf/open/floor/iron/white/herringbone, /area/station/medical/patients_rooms) -"ncf" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron, -/area/station/cargo/storage) "ncl" = ( /obj/structure/dresser, /turf/open/floor/carpet/red, @@ -50928,6 +50964,25 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/dark, /area/station/hallway/floor3/aft) +"nkT" = ( +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/trimline/brown/line, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/smooth_corner{ + dir = 8 + }, +/area/station/bitrunning/den) "nla" = ( /obj/structure/table/wood, /obj/effect/turf_decal/siding/wood{ @@ -51172,6 +51227,7 @@ "noF" = ( /obj/effect/spawner/random/trash/grime, /obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/medical/abandoned) "noM" = ( @@ -51426,6 +51482,7 @@ /obj/effect/turf_decal/stripes/corner{ dir = 8 }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/pod/light, /area/station/maintenance/floor4/port/fore) "nrB" = ( @@ -54596,6 +54653,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/command/heads_quarters/hos) +"oiv" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/pod/light, +/area/station/maintenance/floor1/starboard) "oiw" = ( /obj/structure/cable, /obj/machinery/door/airlock/grunge{ @@ -55568,6 +55631,24 @@ }, /turf/open/floor/iron/dark/side, /area/station/security/checkpoint) +"owk" = ( +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 + }, +/obj/effect/turf_decal/stripes{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/effect/turf_decal/trimline/brown/line, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/turf/open/floor/iron/dark/smooth_half, +/area/station/bitrunning/den) "owo" = ( /obj/effect/decal/cleanable/dirt, /obj/structure/cable, @@ -55752,6 +55833,9 @@ /obj/structure/sign/warning/biohazard/directional/west, /turf/open/floor/iron/white, /area/station/hallway/floor2/aft) +"oyT" = ( +/turf/closed/wall, +/area/station/bitrunning/den) "oyW" = ( /obj/structure/chair{ dir = 8 @@ -55844,15 +55928,6 @@ /obj/effect/spawner/random/structure/closet_maintenance, /turf/open/floor/pod/dark, /area/station/maintenance/floor3/port/aft) -"ozY" = ( -/obj/machinery/door/firedoor/border_only{ - dir = 1 - }, -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/catwalk_floor, -/area/station/maintenance/floor1/starboard/fore) "oAc" = ( /obj/effect/turf_decal/trimline/purple/line, /obj/machinery/door/firedoor/border_only{ @@ -58518,9 +58593,7 @@ "pmG" = ( /obj/machinery/power/apc/auto_name/directional/west, /obj/structure/cable, -/mob/living/simple_animal/hostile/retaliate/goat{ - name = "Pete" - }, +/mob/living/basic/goat/pete, /turf/open/floor/iron/kitchen_coldroom/freezerfloor, /area/station/service/kitchen/coldroom) "pmO" = ( @@ -58894,6 +58967,19 @@ /obj/effect/decal/cleanable/blood/drip, /turf/open/misc/dirt/jungle, /area/station/service/hydroponics/garden/abandoned) +"prm" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/cargo/storage) "pro" = ( /obj/effect/turf_decal/stripes, /obj/effect/decal/cleanable/dirt, @@ -59585,6 +59671,11 @@ /obj/effect/mapping_helpers/airlock/unres, /turf/open/floor/pod/light, /area/station/maintenance/floor3/starboard/aft) +"pAv" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/pod/light, +/area/station/maintenance/floor4/port/fore) "pAy" = ( /obj/structure/window/reinforced/spawner/directional/south, /obj/structure/flora/bush/snow/style_random, @@ -59638,6 +59729,14 @@ /obj/effect/spawner/random/structure/crate, /turf/open/floor/pod/light, /area/station/maintenance/floor1/port/aft) +"pBA" = ( +/obj/machinery/netpod, +/obj/machinery/airalarm/directional/east, +/obj/machinery/airalarm/directional/east, +/obj/machinery/airalarm/directional/east, +/obj/machinery/airalarm/directional/east, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "pBJ" = ( /obj/machinery/navbeacon{ codes_txt = "patrol;next_patrol=1-7"; @@ -59756,6 +59855,11 @@ /obj/effect/turf_decal/trimline/green/filled/line, /turf/open/floor/iron/dark, /area/station/medical/virology) +"pCW" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "pDd" = ( /obj/structure/table/reinforced/plasmarglass, /obj/item/reagent_containers/pill/epinephrine{ @@ -59793,6 +59897,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/airalarm/directional/east, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/wood/parquet, /area/station/maintenance/floor2/port/aft) "pDK" = ( @@ -62185,6 +62290,10 @@ /obj/structure/cable, /turf/open/floor/carpet/neon/simple/white, /area/station/commons/dorms/room3) +"qna" = ( +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/plating, +/area/station/medical/abandoned) "qnc" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -64296,6 +64405,19 @@ /obj/machinery/light_switch/directional/east, /turf/open/floor/iron/dark, /area/station/command/bridge) +"qOr" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/structure/railing{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "qOs" = ( /obj/structure/table/wood/fancy/red, /obj/item/paper_bin, @@ -65409,6 +65531,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/catwalk_floor/iron, /area/station/engineering/lobby) +"rce" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, +/turf/open/floor/pod/light, +/area/station/maintenance/floor4/starboard/fore) "rci" = ( /obj/structure/closet/emcloset, /obj/effect/turf_decal/trimline/purple/filled/line{ @@ -66018,6 +66145,12 @@ }, /turf/open/floor/iron/dark, /area/station/medical/psychology) +"rku" = ( +/obj/machinery/cryo_cell{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured, +/area/station/medical/cryo) "rkE" = ( /obj/structure/disposalpipe/trunk/multiz{ dir = 1 @@ -66473,6 +66606,21 @@ /obj/machinery/duct, /turf/open/floor/iron/dark/textured, /area/station/medical/cryo) +"rqB" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/cargo/storage) "rqK" = ( /obj/effect/turf_decal/stripes/full, /obj/structure/window/reinforced/spawner/directional/west, @@ -66732,6 +66880,7 @@ /area/station/cargo/storage) "rvh" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/plating, /area/station/maintenance/floor2/starboard/aft) "rvD" = ( @@ -67491,6 +67640,11 @@ }, /turf/open/floor/plating, /area/station/medical/abandoned) +"rGF" = ( +/obj/effect/turf_decal/bot, +/obj/machinery/light/broken/directional/north, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "rGI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -69877,6 +70031,16 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/hallway/floor4/aft) +"sqK" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "srz" = ( /obj/machinery/door/airlock/atmos{ name = "Atmospherics" @@ -70836,7 +71000,7 @@ "sEq" = ( /obj/structure/rack, /obj/effect/turf_decal/stripes, -/obj/item/gun/energy/laser/practice{ +/obj/item/gun/energy/laser/carbine/practice{ pixel_x = 3; pixel_y = -3 }, @@ -71315,6 +71479,12 @@ /obj/machinery/light/cold/directional/east, /turf/open/floor/iron/dark/textured, /area/station/medical/office) +"sKg" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/pod/light, +/area/station/maintenance/floor4/port) "sKm" = ( /turf/closed/wall, /area/station/medical/virology/isolation) @@ -71432,6 +71602,17 @@ /obj/structure/sign/warning/xeno_mining/directional/north, /turf/open/floor/iron/white, /area/station/science/xenobiology/hallway) +"sLq" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, +/obj/effect/turf_decal/arrows{ + dir = 4 + }, +/obj/machinery/light/directional/north, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "sLE" = ( /obj/machinery/door/airlock/security/glass{ name = "Security Entrance" @@ -71750,7 +71931,7 @@ pixel_x = 3; pixel_y = -3 }, -/obj/item/gun/energy/laser/practice, +/obj/item/gun/energy/laser/carbine/practice, /obj/machinery/light/directional/north, /turf/open/floor/iron/dark, /area/station/security/range) @@ -73167,6 +73348,7 @@ "tiC" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/oil, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/pod/light, /area/station/maintenance/floor1/port/fore) "tiX" = ( @@ -74795,6 +74977,7 @@ /area/station/medical/treatment_center) "tEb" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron/textured_large, /area/station/maintenance/solars/starboard/fore) "tEc" = ( @@ -75038,6 +75221,7 @@ /area/station/security/prison) "tIa" = ( /obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/floor4/port/fore) "tIc" = ( @@ -75440,13 +75624,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/textured_large, /area/station/engineering/lobby) -"tNh" = ( -/obj/effect/turf_decal/stripes{ - dir = 6 - }, -/obj/structure/disposalpipe/segment, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "tNi" = ( /obj/structure/table/wood, /obj/effect/spawner/random/entertainment/cigar, @@ -76081,15 +76258,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark, /area/station/service/chapel/funeral) -"tWc" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "tWn" = ( /obj/machinery/portable_atmospherics/canister/oxygen, /obj/effect/turf_decal/bot, @@ -76599,11 +76767,6 @@ /obj/structure/cable, /turf/open/floor/iron/textured_large, /area/station/maintenance/disposal/incinerator) -"udV" = ( -/obj/effect/spawner/structure/window, -/obj/effect/spawner/structure/window, -/turf/open/floor/plating, -/area/station/maintenance/floor2/port/aft) "udZ" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -78074,6 +78237,7 @@ "uyS" = ( /obj/machinery/airalarm/directional/south, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/catwalk_floor/iron_dark, /area/station/maintenance/floor3/starboard) "uyX" = ( @@ -78112,12 +78276,6 @@ /obj/structure/closet, /turf/open/floor/pod/light, /area/station/maintenance/floor2/port/fore) -"uzr" = ( -/obj/effect/turf_decal/stripes{ - dir = 1 - }, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "uzB" = ( /obj/structure/table/reinforced, /obj/item/screwdriver, @@ -78354,6 +78512,14 @@ }, /turf/open/floor/iron, /area/station/hallway/floor2/aft) +"uDm" = ( +/obj/machinery/firealarm/directional/south, +/obj/machinery/light/directional/south, +/obj/effect/decal/cleanable/oil/streak, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "uDr" = ( /obj/machinery/light/small/directional/north, /obj/effect/decal/cleanable/dirt, @@ -78363,6 +78529,7 @@ /area/station/maintenance/floor1/port) "uDx" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron/kitchen, /area/station/service/kitchen/abandoned) "uDA" = ( @@ -79830,12 +79997,6 @@ /obj/machinery/light/small/directional/north, /turf/open/floor/iron/dark/smooth_large, /area/station/science/robotics/lab) -"uVb" = ( -/obj/effect/turf_decal/stripes{ - dir = 8 - }, -/turf/open/floor/plating, -/area/station/maintenance/floor1/starboard/fore) "uVh" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -80480,6 +80641,12 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/service/kitchen/diner) +"vej" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/turf/open/floor/pod/light, +/area/station/maintenance/floor4/port/fore) "veA" = ( /obj/structure/railing{ dir = 8 @@ -81981,9 +82148,12 @@ /area/station/science/explab) "vxL" = ( /obj/structure/table/glass, -/obj/item/storage/medkit/regular, -/obj/item/reagent_containers/syringe, /obj/item/radio/intercom/directional/south, +/obj/item/storage/box/bandages{ + pixel_y = 6; + pixel_x = -6 + }, +/obj/item/storage/medkit/regular, /turf/open/floor/iron/white, /area/station/security/medical) "vxT" = ( @@ -82143,10 +82313,6 @@ /obj/effect/turf_decal/trimline/brown/arrow_ccw, /turf/open/floor/iron/dark/side, /area/station/cargo/lobby) -"vzo" = ( -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/storage) "vzu" = ( /obj/effect/landmark/start/psychologist, /obj/structure/sign/poster/official/random/directional/south, @@ -83261,6 +83427,11 @@ /obj/effect/spawner/structure/window/hollow/reinforced/directional, /turf/open/floor/plating, /area/station/service/chapel/office) +"vPC" = ( +/obj/effect/decal/cleanable/dirt, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/pod/light, +/area/station/maintenance/floor1/starboard) "vPE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -83289,17 +83460,6 @@ /obj/machinery/atmospherics/pipe/heat_exchanging/simple/layer2, /turf/open/floor/engine/vacuum, /area/station/science/ordnance/freezerchamber) -"vPU" = ( -/obj/structure/railing{ - dir = 4 - }, -/obj/effect/turf_decal/stripes{ - dir = 4 - }, -/obj/structure/disposalpipe/segment, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron, -/area/station/cargo/storage) "vQb" = ( /obj/effect/turf_decal/siding/wood{ dir = 6 @@ -83380,6 +83540,16 @@ /obj/machinery/light/red/dim/directional/west, /turf/open/floor/catwalk_floor, /area/station/maintenance/floor4/port/aft) +"vRb" = ( +/obj/effect/turf_decal/trimline/red/filled/line{ + dir = 8 + }, +/obj/effect/landmark/generic_maintenance_landmark, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/pod/light, +/area/station/maintenance/floor3/starboard/fore) "vRj" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood, @@ -84077,6 +84247,13 @@ /obj/machinery/firealarm/directional/west, /turf/open/floor/iron, /area/station/hallway/floor2/aft) +"waA" = ( +/obj/machinery/cryo_cell{ + dir = 8 + }, +/obj/structure/sign/poster/official/random/directional/east, +/turf/open/floor/iron/dark/textured, +/area/station/medical/cryo) "waI" = ( /obj/effect/turf_decal/stripes, /obj/machinery/atmospherics/components/binary/pump/off{ @@ -84646,6 +84823,10 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/hallway/floor4/aft) +"whN" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/bitrunning/den) "whR" = ( /turf/closed/wall, /area/station/service/bar) @@ -85707,21 +85888,6 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/service) -"wuE" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/obj/structure/disposalpipe/segment{ - dir = 5 - }, -/obj/structure/railing/corner/end{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "wuJ" = ( /obj/effect/turf_decal/tile/dark_red/fourcorners, /turf/open/floor/iron, @@ -86741,6 +86907,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/item/reagent_containers/syringe, /turf/open/floor/iron/white, /area/station/security/medical) "wHP" = ( @@ -87146,6 +87313,7 @@ /area/station/science/auxlab) "wLy" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/pod, /area/station/maintenance/floor4/starboard/aft) "wLC" = ( @@ -89286,12 +89454,6 @@ "xpI" = ( /turf/closed/wall, /area/station/maintenance/solars/starboard/fore) -"xpK" = ( -/obj/effect/decal/cleanable/cobweb/cobweb2, -/obj/machinery/rnd/bepis, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "xpL" = ( /obj/machinery/door/airlock/research/glass/incinerator/ordmix_exterior{ name = "Burn Chamber Exterior Airlock" @@ -90691,6 +90853,7 @@ "xHf" = ( /obj/structure/chair/wood, /obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/carpet/green, /area/station/service/abandoned_gambling_den) "xHg" = ( @@ -91158,6 +91321,16 @@ /obj/structure/cable, /turf/open/floor/catwalk_floor, /area/station/maintenance/floor2/starboard/fore) +"xOd" = ( +/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/siding/thinplating_new{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/shieldgen, +/obj/item/radio/intercom/directional/north, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "xOe" = ( /obj/machinery/light/cold/no_nightlight/directional/north, /turf/open/floor/engine, @@ -92568,6 +92741,7 @@ /area/station/service/library/artgallery) "yiV" = ( /obj/effect/landmark/blobstart, +/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/grass/fairy, /area/station/maintenance/floor2/port/fore) "yiZ" = ( @@ -115256,13 +115430,13 @@ owI owI owI owI -oic -oic -ads -uVb -aOv -ozY -oic +oyT +oyT +oyT +oyT +oyT +bAh +iDJ oic oic oic @@ -115513,14 +115687,14 @@ owI owI owI owI -oic -oic -uzr -oic -ePI -ozY -icf -oic +oyT +oyT +cDe +ioi +oyT +oyT +oyT +oyT gUS nOj dzo @@ -115770,15 +115944,15 @@ owI owI owI owI -oic -oic -fBB -kYs -tNh -bqm -aUn -oic -eTD +oyT +oyT +lgs +fCw +brL +erV +uDm +oyT +rGF yiZ yiZ bUC @@ -116027,15 +116201,15 @@ owI owI owI owI -oic -oic -lJl -lJl -cjz -dNf -gvu -oic -gCn +oyT +oyT +sLq +azj +cBT +owk +jhP +whN +hBR qWJ qWJ imO @@ -116284,14 +116458,14 @@ owI owI owI owI -oic -oic -gex -oic -oic -avu -oic -oic +oyT +oyT +iaJ +pBA +htK +nkT +eul +whN rYA eEB lUY @@ -116541,15 +116715,15 @@ owI owI owI owI -oic -oic -oic -oic -iOl -xxQ -cxp -aQK -fve +oyT +oyT +oyT +oyT +oyT +jAr +whN +oyT +xOd fve aSL iCn @@ -116802,7 +116976,7 @@ uYl pFb gHw yef -dXP +gFU kHQ hIj aQK @@ -117063,7 +117237,7 @@ wZu vTt hai aQK -xpK +pCW rhs eaW lSJ @@ -117578,8 +117752,8 @@ fuJ aQK aQK cfO -vzo -mnR +jWJ +bsq mnk mnR aHb @@ -117830,13 +118004,13 @@ cUL cUL oKT xsL -tWc -dYm -ncf -kQL -vPU -mFK -wuE +sqK +rqB +prm +gso +gso +qOr +eoo myW myW myW @@ -126827,10 +127001,10 @@ bdC ddv mST dui -tRj -tRj +oiv +vPC kbW -jJm +ebC wsE whV lYR @@ -127087,7 +127261,7 @@ dui rxJ jVW whV -jJm +ebC jFT whV whV @@ -127344,7 +127518,7 @@ whV whV whV whV -jJm +ebC yfi wJB eFY @@ -127858,7 +128032,7 @@ nho qKt aqd whV -jJm +ebC yfi vqN eFY @@ -128115,7 +128289,7 @@ whV whV whV whV -jJm +ebC bCT nSv vWS @@ -194971,7 +195145,7 @@ gHO yba lfW wdd -aXl +rku nqM qQM dHR @@ -196513,7 +196687,7 @@ dXy bND aHK wdd -lAv +waA wat mVm tfX @@ -205251,7 +205425,7 @@ aGI xui ijX xui -udV +aGI cWo nlN nlN @@ -241974,7 +242148,7 @@ kVp wRJ wRJ eCP -wPF +vRb wPF xkX ooF @@ -254078,7 +254252,7 @@ eDe xGx diU ufs -xGx +qna dDu ufs uZc @@ -268707,7 +268881,7 @@ xJM hCJ vXH kRw -sBE +jsb iMM kRw cpa @@ -307767,7 +307941,7 @@ ucA xHe xHe ioM -uxw +rce xjQ iqD euv @@ -311655,7 +311829,7 @@ xFo lBG gmg tIa -wkF +brM dad qlh nDu @@ -311908,8 +312082,8 @@ xMF kBi uIx rao -rao -rao +vej +pAv nry eiO wkF @@ -314226,7 +314400,7 @@ owb fXs dIh wtL -wtL +sKg bAG wtL fXs diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 4bae39e99008bd..c0df28a28aa230 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -3127,13 +3127,21 @@ /turf/open/floor/iron/dark, /area/station/security/brig) "alx" = ( -/obj/machinery/door/airlock/mining/glass{ - name = "Comissary Back Room" +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 }, +/obj/machinery/power/apc/auto_name/directional/west, /obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/cargo/office) +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "aly" = ( /obj/machinery/light/small/directional/south, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ @@ -10179,6 +10187,7 @@ /obj/effect/spawner/random/structure/crate, /obj/structure/cable, /obj/effect/mapping_helpers/burnt_floor, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/cargo) "aKn" = ( @@ -10792,6 +10801,7 @@ id = "Commissary"; name = "Commissary Shutters" }, +/obj/item/flashlight/lantern, /turf/open/floor/iron, /area/station/cargo/office) "aMB" = ( @@ -11136,6 +11146,7 @@ name = "Quartermaster Maintenance" }, /obj/effect/mapping_helpers/airlock/access/all/supply/qm, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/cargo) "aNQ" = ( @@ -11449,6 +11460,7 @@ /area/station/maintenance/department/cargo) "aOZ" = ( /obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/wood, /area/station/command/heads_quarters/qm) "aPb" = ( @@ -13051,9 +13063,7 @@ /turf/open/floor/iron/showroomfloor, /area/station/service/kitchen) "aUZ" = ( -/mob/living/simple_animal/hostile/retaliate/goat{ - name = "Pete" - }, +/mob/living/basic/goat/pete, /turf/open/floor/iron/showroomfloor, /area/station/service/kitchen) "aVa" = ( @@ -22976,7 +22986,6 @@ /turf/open/floor/plating, /area/station/medical/surgery) "bFP" = ( -/obj/structure/closet/secure_closet/smartgun, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "bFS" = ( @@ -33411,6 +33420,10 @@ /obj/structure/disposalpipe/junction/flip{ dir = 8 }, +/obj/machinery/power/apc/auto_name/directional/east, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, /turf/open/floor/iron, /area/station/cargo/office) "cDB" = ( @@ -37951,6 +37964,8 @@ /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/effect/mapping_helpers/airlock/access/any/supply/maintenance, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/maintenance/department/cargo) "gmA" = ( @@ -38166,7 +38181,7 @@ /area/station/hallway/secondary/exit/departure_lounge) "gvi" = ( /obj/effect/turf_decal/bot, -/mob/living/simple_animal/sloth/paperwork{ +/mob/living/basic/sloth/paperwork{ name = "Taxes" }, /turf/open/floor/iron, @@ -39481,15 +39496,10 @@ /turf/open/floor/iron/dark, /area/station/commons/dorms/barracks) "huJ" = ( -/obj/structure/table/reinforced, -/obj/item/clothing/shoes/laceup, -/obj/item/clothing/under/suit/navy, -/obj/item/clothing/neck/tie/blue, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/office) +/obj/machinery/netpod, +/obj/effect/decal/cleanable/robot_debris, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "hvm" = ( /obj/structure/window/reinforced/fulltile, /obj/structure/flora/bush/pointy/style_random, @@ -39761,12 +39771,20 @@ /turf/open/floor/iron/dark, /area/station/security/execution/education) "hDh" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 }, -/turf/open/floor/iron, -/area/station/cargo/office) +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/obj/machinery/holopad, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "hDG" = ( /obj/machinery/door/airlock/engineering{ name = "Auxiliary Base Construction" @@ -40553,6 +40571,11 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/lobby) +"igy" = ( +/obj/machinery/computer/quantum_console, +/obj/structure/extinguisher_cabinet/directional/west, +/turf/open/floor/iron/dark/smooth_corner, +/area/station/bitrunning/den) "igC" = ( /obj/effect/turf_decal/stripes/corner{ dir = 8 @@ -41280,12 +41303,11 @@ /turf/open/floor/iron/white, /area/station/medical/virology) "iMJ" = ( -/obj/structure/table/reinforced, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/office) +/obj/machinery/light/directional/south, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "iNN" = ( /obj/machinery/airalarm/directional/north, /obj/structure/table, @@ -41725,15 +41747,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/engineering/atmos/hfr_room) -"jhw" = ( -/obj/structure/rack, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 9 - }, -/obj/machinery/power/apc/auto_name/directional/east, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/office) "jhz" = ( /obj/machinery/modular_computer/preset/id, /obj/machinery/computer/security/telescreen/entertainment{ @@ -42043,20 +42056,9 @@ /turf/open/floor/wood, /area/station/command/heads_quarters/hos) "jvs" = ( -/obj/structure/table/reinforced, -/obj/item/flashlight/lantern, -/obj/machinery/door/window/right/directional/west{ - dir = 1; - name = "Comissary Desk"; - req_access = list("cargo") - }, -/obj/machinery/door/poddoor/preopen{ - id = "Commissary"; - name = "Commissary Shutters" - }, /obj/structure/disposalpipe/segment, -/turf/open/floor/iron, -/area/station/cargo/office) +/turf/closed/wall, +/area/station/bitrunning/den) "jvF" = ( /obj/machinery/atmospherics/components/unary/thermomachine/freezer{ dir = 8; @@ -42150,6 +42152,9 @@ /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 1 }, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, /turf/open/floor/iron, /area/station/cargo/office) "jyo" = ( @@ -45709,13 +45714,11 @@ /turf/open/floor/iron/white, /area/station/science/xenobiology) "mqp" = ( -/obj/structure/cable, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/disposalpipe/segment{ dir = 9 }, -/turf/open/floor/iron, -/area/station/cargo/office) +/turf/closed/wall, +/area/station/bitrunning/den) "mqD" = ( /obj/machinery/cryopod{ dir = 8 @@ -46093,6 +46096,7 @@ }, /obj/effect/mapping_helpers/airlock/abandoned, /obj/effect/mapping_helpers/airlock/access/any/supply/maintenance, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/plating, /area/station/maintenance/department/cargo) "mBo" = ( @@ -47052,6 +47056,28 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/primary/aft) +"nnF" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/corner{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "noM" = ( /turf/open/floor/iron/white, /area/station/science/genetics) @@ -47661,6 +47687,9 @@ /obj/structure/window/reinforced/spawner/directional/north, /turf/open/floor/grass, /area/station/medical/storage) +"nOV" = ( +/turf/closed/wall, +/area/station/bitrunning/den) "nOY" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -49011,22 +49040,6 @@ /obj/machinery/firealarm/directional/south, /turf/open/floor/iron/white, /area/station/commons/toilet/restrooms) -"oMv" = ( -/obj/machinery/button/door{ - id = "Commissary"; - name = "Commissary Shutter Control"; - pixel_x = 24; - pixel_y = 6 - }, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ - dir = 8 - }, -/obj/structure/disposalpipe/segment, -/turf/open/floor/iron, -/area/station/cargo/office) "oMH" = ( /obj/structure/table, /obj/item/airlock_painter/decal, @@ -49682,12 +49695,21 @@ /turf/open/floor/iron/dark, /area/station/security/prison) "plW" = ( -/obj/structure/rack, -/obj/effect/spawner/random/maintenance/three, -/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 8 + }, +/obj/effect/decal/cleanable/generic, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/landmark/start/bitrunner, /obj/machinery/airalarm/directional/north, -/turf/open/floor/iron, -/area/station/cargo/office) +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "pmc" = ( /turf/closed/wall, /area/station/service/jadedragon) @@ -49845,9 +49867,15 @@ /area/station/commons/dorms/barracks) "puX" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 + dir = 5 }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/button/door{ + id = "Commissary"; + name = "Commissary Shutter Control"; + pixel_x = 24; + pixel_y = 6 + }, /turf/open/floor/iron, /area/station/cargo/office) "pvv" = ( @@ -50002,7 +50030,7 @@ /area/station/engineering/main) "pAs" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 8 + dir = 10 }, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 @@ -50375,7 +50403,6 @@ /turf/open/floor/iron/dark, /area/station/commons/dorms/barracks) "pMg" = ( -/obj/machinery/rnd/bepis, /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 10 }, @@ -50471,6 +50498,18 @@ /obj/item/food/grown/wheat, /turf/open/floor/iron/dark, /area/station/security/prison) +"pPv" = ( +/obj/effect/decal/cleanable/oil/streak, +/obj/machinery/camera/directional/south, +/obj/structure/table, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 7 + }, +/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind{ + pixel_x = 5 + }, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "pPI" = ( /obj/structure/table, /obj/machinery/camera/directional/north{ @@ -50873,7 +50912,6 @@ "qgK" = ( /obj/effect/turf_decal/bot_blue, /obj/structure/rack/gunrack, -/obj/effect/spawner/armory_spawn/cmg, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "qgM" = ( @@ -52692,17 +52730,11 @@ /turf/open/floor/iron/dark, /area/station/commons/dorms) "rxv" = ( -/obj/structure/rack, -/obj/item/sales_tagger{ - pixel_x = 7; - pixel_y = 5 - }, -/obj/item/sales_tagger{ - pixel_x = 6 - }, -/obj/effect/turf_decal/trimline/brown/filled/line, -/turf/open/floor/iron, -/area/station/cargo/office) +/obj/machinery/netpod, +/obj/structure/sign/poster/random/directional/north, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "rxA" = ( /obj/structure/table, /obj/item/stack/sheet/glass/fifty, @@ -53570,11 +53602,12 @@ /turf/open/floor/iron, /area/station/cargo/sorting) "seY" = ( -/obj/structure/rack, -/obj/effect/spawner/random/maintenance/two, -/obj/effect/turf_decal/trimline/brown/filled/line, -/turf/open/floor/iron, -/area/station/cargo/office) +/obj/machinery/quantum_server, +/obj/effect/turf_decal/bot/left, +/turf/open/floor/iron/dark/smooth_corner{ + dir = 4 + }, +/area/station/bitrunning/den) "sfo" = ( /obj/item/kirbyplants/random, /turf/open/floor/iron, @@ -57004,11 +57037,10 @@ /area/station/maintenance/department/engine) "uMv" = ( /obj/structure/cable, -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/office) +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "uMY" = ( /obj/structure/disposalpipe/segment, /obj/effect/turf_decal/trimline/blue/filled/corner{ @@ -57165,13 +57197,22 @@ /turf/open/floor/engine, /area/station/engineering/supermatter/room) "uUf" = ( -/obj/machinery/vending/assist, -/obj/effect/turf_decal/trimline/brown/filled/line{ +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/line{ + dir = 8 + }, +/obj/item/radio/intercom/directional/south, +/obj/effect/decal/cleanable/oil, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 1 }, -/obj/machinery/light/directional/south, -/turf/open/floor/iron, -/area/station/cargo/office) +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "uUr" = ( /obj/structure/cable, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, @@ -60676,6 +60717,12 @@ /obj/structure/cable, /turf/open/floor/engine, /area/station/science/xenobiology) +"xuu" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/plating, +/area/station/maintenance/department/cargo) "xuv" = ( /obj/item/broken_bottle, /turf/open/floor/plating, @@ -61414,6 +61461,9 @@ /obj/structure/disposalpipe/trunk{ dir = 1 }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 6 + }, /turf/open/floor/iron, /area/station/cargo/office) "xVD" = ( @@ -101482,10 +101532,10 @@ xlX cot kUq jvs -oMv +jvs mqp -jhw -aRl +nOV +nOV bcI wDZ abh @@ -101738,12 +101788,12 @@ aGF aGF vpv qCS -aRl -aRl +nOV +igy alx -aRl -aRl -bcI +pPv +nOV +fwI aNO aOZ aTl @@ -101995,12 +102045,12 @@ cBp vpv osW hxQ -aRl +nOV seY hDh iMJ -aRl -bcI +nOV +fwI wDZ hsN aRp @@ -102252,12 +102302,12 @@ nCF nCF owj rrd -aRl +nOV plW -aVp +nnF uUf -aRl -bcI +nOV +fwI wDZ aPb bcS @@ -102509,12 +102559,12 @@ sFN pdK tfI sfo -aRl +nOV rxv uMv huJ -aRl -bcI +nOV +fwI wDZ wDZ aTo @@ -102766,12 +102816,12 @@ aFd rmc itC bfu -aRl -aRl +nOV +nOV gma -aRl -aRl -bcI +nOV +nOV +fwI aQk cDa aQf @@ -103025,10 +103075,10 @@ epJ aFi aFi aFi -oEL +xuu aKk mAV -bcI +fwI aNQ cDa aTq diff --git a/_maps/map_files/VoidRaptor/VoidRaptor.dmm b/_maps/map_files/VoidRaptor/VoidRaptor.dmm index a68a80d0d40b88..eedc9a22ce0c76 100644 --- a/_maps/map_files/VoidRaptor/VoidRaptor.dmm +++ b/_maps/map_files/VoidRaptor/VoidRaptor.dmm @@ -1531,6 +1531,10 @@ /obj/structure/trash_pile, /turf/open/floor/iron/smooth, /area/station/maintenance/department/engine) +"awG" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/miningdock) "awP" = ( /obj/machinery/mech_bay_recharge_port, /obj/effect/turf_decal/bot, @@ -1869,7 +1873,6 @@ "aAN" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ - dir = 8; id = "chemistry_shutters"; name = "Pharmacy Shutters" }, @@ -3260,6 +3263,9 @@ /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 }, +/obj/item/storage/box/bandages{ + pixel_y = 8 + }, /turf/open/floor/iron/dark/smooth_edge{ dir = 8 }, @@ -3365,7 +3371,7 @@ anchored = 1; name = "Citrus's bed" }, -/mob/living/simple_animal/sloth/citrus, +/mob/living/basic/sloth/citrus, /turf/open/floor/iron/dark/smooth_large, /area/station/command/heads_quarters/qm) "aWY" = ( @@ -3477,9 +3483,9 @@ pixel_y = 16 }, /obj/machinery/door/poddoor/shutters/window/preopen{ - dir = 4; id = "paramed_dispatch_desk"; - name = "Desk Shutters" + name = "Desk Shutters"; + dir = 8 }, /obj/item/paper_bin{ pixel_y = 4 @@ -3689,16 +3695,6 @@ }, /turf/open/floor/iron/smooth_large, /area/station/hallway/primary/aft) -"baW" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 4 - }, -/obj/structure/closet/secure_closet/miner, -/obj/effect/turf_decal/delivery, -/turf/open/floor/iron/smooth_edge{ - dir = 8 - }, -/area/station/cargo/miningdock) "bbh" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -8461,6 +8457,9 @@ dir = 1 }, /area/station/science/explab) +"cBk" = ( +/turf/closed/wall, +/area/station/bitrunning/den) "cBU" = ( /obj/structure/chair/comfy/beige{ dir = 1 @@ -8731,8 +8730,8 @@ pixel_y = 5 }, /obj/machinery/light_switch/directional/east{ - pixel_y = 6; - pixel_x = 23 + pixel_x = 23; + pixel_y = 6 }, /obj/effect/turf_decal/trimline/blue/filled/warning{ dir = 5 @@ -9780,8 +9779,8 @@ /area/station/hallway/primary/fore) "cWB" = ( /obj/machinery/digital_clock{ - pixel_y = 7; - pixel_x = -1 + pixel_x = -1; + pixel_y = 7 }, /turf/closed/wall/r_wall, /area/station/engineering/supermatter/room) @@ -10031,6 +10030,10 @@ /obj/item/multitool, /obj/machinery/airalarm/directional/south, /obj/machinery/atmospherics/pipe/smart/manifold4w/general/hidden, +/obj/item/storage/box/bandages{ + pixel_x = 4; + pixel_y = 5 + }, /turf/open/floor/engine, /area/station/tcommsat/computer) "day" = ( @@ -10348,6 +10351,12 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron/smooth_large, /area/station/engineering/atmos/pumproom) +"deu" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ + dir = 1 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "dex" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, /turf/open/floor/carpet, @@ -11103,6 +11112,14 @@ }, /turf/open/floor/engine/vacuum, /area/station/science/ordnance/freezerchamber) +"dpw" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/obj/structure/closet/secure_closet/miner, +/obj/effect/turf_decal/delivery, +/turf/open/floor/iron/smooth_edge, +/area/station/cargo/miningdock) "dpx" = ( /obj/structure/table/wood, /obj/item/storage/crayons, @@ -11902,12 +11919,19 @@ "dAP" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ - dir = 4; id = "genetics_shutters"; name = "Genetics Shutters" }, /turf/open/floor/plating, /area/station/science/genetics) +"dAV" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 9 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/textured, +/area/station/bitrunning/den) "dAX" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -13918,7 +13942,6 @@ /obj/item/reagent_containers/syringe/epinephrine, /obj/effect/turf_decal/tile/yellow/fourcorners, /obj/machinery/door/poddoor/shutters/preopen{ - dir = 8; id = "chemistry_shutters"; name = "Pharmacy Shutters" }, @@ -14573,12 +14596,6 @@ dir = 8 }, /area/station/cargo/lobby) -"ejt" = ( -/obj/machinery/cryo_cell, -/obj/effect/turf_decal/bot, -/obj/effect/turf_decal/tile/dark_blue/fourcorners, -/turf/open/floor/iron/dark, -/area/station/medical/medbay/central) "eju" = ( /obj/structure/rack, /obj/effect/spawner/random/clothing/costume, @@ -15951,10 +15968,10 @@ /turf/open/floor/iron/smooth_large, /area/station/hallway/secondary/service) "eEi" = ( -/obj/structure/closet/secure_closet/smartgun, /obj/effect/turf_decal/tile/dark_red/anticorner, /obj/structure/sign/poster/official/twelve_gauge/directional/east, /obj/effect/turf_decal/bot, +/obj/structure/closet/secure_closet/armory_kiboko, /turf/open/floor/engine, /area/station/ai_monitored/security/armory) "eEp" = ( @@ -18239,9 +18256,9 @@ req_access = list("medical") }, /obj/machinery/door/poddoor/shutters/window/preopen{ - dir = 4; id = "paramed_dispatch_desk"; - name = "Desk Shutters" + name = "Desk Shutters"; + dir = 8 }, /turf/open/floor/iron/white/smooth_large, /area/station/medical/medbay/lobby) @@ -18708,6 +18725,16 @@ /obj/machinery/atmospherics/pipe/smart/simple/dark/visible, /turf/open/floor/iron/smooth, /area/station/maintenance/disposal/incinerator) +"fth" = ( +/obj/machinery/byteforge, +/obj/effect/turf_decal/box/corners{ + dir = 8 + }, +/obj/effect/turf_decal/box/corners{ + dir = 1 + }, +/turf/open/floor/engine, +/area/station/bitrunning/den) "ftr" = ( /obj/machinery/power/shuttle_engine/heater, /obj/effect/turf_decal/stripes/line{ @@ -18923,12 +18950,6 @@ /obj/structure/table/glass, /turf/open/floor/iron/white/smooth_large, /area/station/medical/medbay/central) -"fxJ" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ - dir = 8 - }, -/turf/open/floor/iron/smooth_large, -/area/station/cargo/miningdock) "fxO" = ( /obj/structure/displaycase/trophy, /obj/effect/turf_decal/siding/wood{ @@ -19689,6 +19710,12 @@ }, /turf/open/floor/iron/large, /area/station/commons/fitness/recreation/entertainment) +"fKN" = ( +/obj/machinery/cryo_cell, +/obj/effect/turf_decal/bot, +/obj/effect/turf_decal/tile/dark_blue/fourcorners, +/turf/open/floor/iron/dark, +/area/station/medical/medbay/central) "fKU" = ( /obj/effect/turf_decal/trimline/brown/filled/warning{ dir = 4 @@ -20501,13 +20528,6 @@ "fXP" = ( /turf/closed/wall/r_wall, /area/station/engineering/atmos/storage/gas) -"fXS" = ( -/obj/machinery/cryo_cell, -/obj/effect/turf_decal/bot, -/obj/structure/disposalpipe/segment, -/obj/effect/turf_decal/tile/dark_blue/fourcorners, -/turf/open/floor/iron/dark, -/area/station/medical/medbay/central) "fXZ" = ( /obj/effect/turf_decal/siding/red{ dir = 1 @@ -21279,17 +21299,10 @@ /area/station/command/heads_quarters/rd) "gjk" = ( /obj/structure/table/reinforced, -/obj/item/storage/medkit/fire{ - pixel_x = -2; - pixel_y = 4 - }, -/obj/item/radio/off{ - pixel_x = 6; - pixel_y = 6 - }, /obj/effect/turf_decal/trimline/yellow/filled/warning{ dir = 10 }, +/obj/machinery/microwave/engineering/cell_included, /turf/open/floor/iron/smooth, /area/station/engineering/lobby) "gjl" = ( @@ -21691,6 +21704,17 @@ /obj/structure/sign/poster/official/wtf_is_co2, /turf/closed/wall, /area/station/engineering/atmos) +"goP" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/smooth_edge{ + dir = 4 + }, +/area/station/bitrunning/den) "goS" = ( /turf/open/floor/iron/freezer, /area/station/medical/chemistry) @@ -21976,11 +22000,7 @@ }, /obj/structure/table, /obj/machinery/status_display/evac/directional/west, -/obj/machinery/microwave{ - desc = "Cooks and boils stuff, somehow."; - pixel_x = -2; - pixel_y = 5 - }, +/obj/machinery/microwave/engineering/cell_included, /turf/open/floor/iron/dark, /area/station/medical/break_room) "gtq" = ( @@ -22789,12 +22809,12 @@ /area/station/ai_monitored/turret_protected/ai_upload) "gEO" = ( /obj/structure/rack/gunrack, -/obj/effect/spawner/armory_spawn/cmg, /obj/effect/turf_decal/tile/dark_red/anticorner{ dir = 4 }, /obj/structure/sign/poster/official/ion_rifle/directional/east, /obj/effect/turf_decal/delivery, +/obj/effect/spawner/armory_spawn/smg, /turf/open/floor/engine, /area/station/ai_monitored/security/armory) "gEV" = ( @@ -22872,7 +22892,7 @@ }, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/mob/living/simple_animal/hostile/retaliate/goat{ +/mob/living/basic/goat/pete{ name = "Pete" }, /obj/effect/turf_decal/weather/snow, @@ -24092,6 +24112,13 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron/freezer, /area/station/medical/chemistry) +"gWT" = ( +/obj/machinery/computer/quantum_console{ + dir = 8 + }, +/obj/machinery/light/small/red/directional/east, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "gWV" = ( /obj/effect/turf_decal/trimline/yellow/filled/warning{ dir = 4 @@ -24342,7 +24369,6 @@ /area/station/engineering/atmos) "haE" = ( /obj/machinery/door/poddoor/shutters/preopen{ - dir = 8; id = "hop"; name = "Privacy Shutters" }, @@ -24976,6 +25002,17 @@ /obj/structure/window/spawner/directional/east, /turf/open/misc/beach/sand, /area/station/science/research) +"hjg" = ( +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/table, +/obj/item/plate, +/obj/effect/spawner/random/trash/food_packaging, +/obj/machinery/camera/directional/north{ + c_tag = "Mining Dock" + }, +/obj/structure/cable, +/turf/open/floor/iron/smooth_edge, +/area/station/bitrunning/den) "hji" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 1 @@ -25092,6 +25129,9 @@ /obj/item/storage/medkit/regular, /obj/item/storage/backpack/satchel/explorer, /obj/machinery/light/directional/south, +/obj/item/storage/box/bandages{ + pixel_y = 8 + }, /turf/open/floor/iron/smooth_edge{ dir = 1 }, @@ -26702,6 +26742,15 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/pod/dark, /area/station/service/chapel) +"hJg" = ( +/obj/structure/table, +/obj/item/modular_computer/laptop/preset/civilian{ + pixel_y = 5; + pixel_x = 2 + }, +/obj/structure/cable, +/turf/open/floor/iron/smooth_large, +/area/station/bitrunning/den) "hJx" = ( /obj/machinery/atmospherics/components/unary/outlet_injector/monitored/ordnance_burn_chamber_input{ dir = 4 @@ -26772,6 +26821,18 @@ dir = 8 }, /area/station/engineering/atmos) +"hKK" = ( +/obj/structure/chair/plastic{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 5 + }, +/obj/machinery/computer/security/telescreen/entertainment/directional/east, +/obj/structure/sign/poster/contraband/random/directional/north, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/smooth, +/area/station/bitrunning/den) "hKP" = ( /obj/item/reagent_containers/cup/bucket, /obj/effect/decal/cleanable/cobweb/cobweb2, @@ -26864,14 +26925,14 @@ "hMN" = ( /obj/structure/table/glass, /obj/effect/turf_decal/bot, -/obj/item/storage/box{ - pixel_x = 3; - pixel_y = 3 - }, /obj/item/radio/headset/headset_eng{ pixel_x = -4; pixel_y = 3 }, +/obj/item/storage/box/bandages{ + pixel_x = 4; + pixel_y = 5 + }, /turf/open/floor/iron/smooth_large, /area/station/engineering/lobby) "hMQ" = ( @@ -27225,6 +27286,13 @@ }, /turf/open/floor/iron/white, /area/station/hallway/primary/fore) +"hSf" = ( +/obj/effect/landmark/start/shaft_miner, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/miningdock) "hSn" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 @@ -27570,22 +27638,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/smooth_large, /area/station/maintenance/department/engine/atmos/lesser) -"hWA" = ( -/obj/machinery/door/airlock/mining{ - name = "Mining Dock" - }, -/obj/effect/mapping_helpers/airlock/access/all/supply/mining, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/structure/cable, -/obj/machinery/door/firedoor, -/obj/effect/turf_decal/stripes/line, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/obj/structure/disposalpipe/segment, -/turf/open/floor/iron/smooth, -/area/station/cargo/miningdock) "hWF" = ( /obj/effect/turf_decal/trimline/brown/filled/line{ dir = 1 @@ -28114,6 +28166,13 @@ "ifq" = ( /turf/closed/wall/r_wall, /area/station/medical/pharmacy) +"ifS" = ( +/obj/machinery/cryo_cell, +/obj/effect/turf_decal/bot, +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/dark_blue/fourcorners, +/turf/open/floor/iron/dark, +/area/station/medical/medbay/central) "igd" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -28158,13 +28217,6 @@ dir = 4 }, /area/station/commons/fitness/recreation/entertainment) -"ihv" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 9 - }, -/obj/machinery/rnd/bepis, -/turf/open/floor/iron/smooth, -/area/station/cargo/warehouse) "ihy" = ( /obj/machinery/atmospherics/pipe/bridge_pipe/green/visible, /obj/structure/window/reinforced/plasma/spawner/directional/west, @@ -29211,7 +29263,8 @@ /obj/effect/turf_decal/caution/stand_clear, /obj/machinery/door/poddoor/shutters{ id = "mechbay"; - name = "Mech Bay Shutters" + name = "Mech Bay Shutters"; + dir = 4 }, /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -30164,6 +30217,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/item/storage/box/bandages{ + pixel_y = 8 + }, /turf/open/floor/iron/freezer, /area/station/medical/treatment_center) "iHi" = ( @@ -30398,6 +30454,13 @@ dir = 8 }, /area/station/engineering/atmos/hfr_room) +"iLb" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/dark/textured_edge, +/area/station/bitrunning/den) "iLH" = ( /obj/effect/turf_decal/trimline/purple/filled/warning{ dir = 4 @@ -31341,7 +31404,6 @@ pixel_x = -4; pixel_y = 10 }, -/obj/item/storage/box/gunset, /obj/item/storage/medkit/tactical/blueshield, /obj/effect/turf_decal/stripes/line{ dir = 10 @@ -32973,6 +33035,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/edge, /area/station/hallway/primary/central) +"jvw" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/textured_edge{ + dir = 8 + }, +/area/station/bitrunning/den) "jvx" = ( /obj/structure/table/wood, /obj/item/food/breadslice/plain, @@ -35349,6 +35420,14 @@ }, /turf/open/floor/iron/dark/smooth_large, /area/station/security/warden) +"kdS" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 10 + }, +/obj/machinery/light_switch/directional/west, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/smooth, +/area/station/bitrunning/den) "kek" = ( /obj/effect/turf_decal/trimline/neutral/filled/warning{ dir = 1 @@ -35856,6 +35935,15 @@ }, /turf/open/floor/pod/dark, /area/station/service/chapel/funeral) +"kkC" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/obj/structure/extinguisher_cabinet/directional/north, +/obj/structure/closet/secure_closet/miner, +/obj/effect/turf_decal/delivery, +/turf/open/floor/iron/smooth_edge, +/area/station/cargo/miningdock) "kkI" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -36252,6 +36340,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/smooth_large, /area/station/hallway/secondary/construction) +"krz" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/trimline/brown/filled/corner{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/miningdock) "krA" = ( /obj/effect/turf_decal/trimline/brown/filled/corner{ dir = 1 @@ -36284,6 +36381,15 @@ /obj/effect/spawner/random/trash/mess, /turf/open/floor/iron/smooth, /area/station/maintenance/department/science/xenobiology) +"ksB" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/textured_edge{ + dir = 4 + }, +/area/station/bitrunning/den) "ksD" = ( /obj/effect/turf_decal/trimline/brown/filled/warning{ dir = 6 @@ -36813,7 +36919,6 @@ req_access = list("pharmacy") }, /obj/machinery/door/poddoor/shutters/preopen{ - dir = 4; id = "chemistry_shutters"; name = "Pharmacy Shutters" }, @@ -37411,6 +37516,15 @@ }, /turf/open/floor/iron/white, /area/station/medical/medbay/central) +"kFL" = ( +/obj/effect/spawner/random/trash/grime, +/obj/effect/turf_decal/trimline/brown/filled/corner{ + dir = 4 + }, +/turf/open/floor/iron/smooth_corner{ + dir = 4 + }, +/area/station/bitrunning/den) "kFS" = ( /obj/effect/mapping_helpers/airlock/access/all/science/rd, /obj/machinery/door/airlock/rd/glass{ @@ -39184,6 +39298,11 @@ }, /turf/open/floor/iron/smooth_large, /area/station/engineering/power_room) +"ldU" = ( +/obj/machinery/netpod, +/obj/machinery/light/small/blacklight/directional/west, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "leb" = ( /obj/structure/cable, /turf/open/floor/iron/smooth_large, @@ -39206,6 +39325,11 @@ }, /turf/open/floor/catwalk_floor/iron_smooth, /area/station/maintenance/department/crew_quarters/bar) +"leF" = ( +/obj/machinery/quantum_server, +/obj/structure/extinguisher_cabinet/directional/east, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "leI" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 5 @@ -39307,7 +39431,6 @@ /area/station/hallway/primary/fore) "lfY" = ( /obj/machinery/door/poddoor/shutters/preopen{ - dir = 8; id = "hopqueue"; name = "HoP Queue Shutters" }, @@ -39674,6 +39797,9 @@ dir = 10 }, /obj/machinery/firealarm/directional/south, +/obj/item/storage/box/bandages{ + pixel_y = 8 + }, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) "llF" = ( @@ -40458,7 +40584,6 @@ pixel_y = 9 }, /obj/machinery/door/poddoor/shutters/preopen{ - dir = 4; id = "genetics_shutters"; name = "Genetics Shutters" }, @@ -40734,6 +40859,10 @@ }, /obj/effect/turf_decal/bot, /obj/item/clothing/glasses/meson/engine, +/obj/item/storage/box/bandages{ + pixel_x = 4; + pixel_y = 5 + }, /turf/open/floor/iron/dark/smooth_large, /area/station/engineering/main) "lAS" = ( @@ -44319,9 +44448,9 @@ /obj/item/stack/medical/mesh, /obj/item/stack/medical/suture, /obj/machinery/door/poddoor/shutters/window/preopen{ - dir = 4; id = "paramed_dispatch_desk"; - name = "Desk Shutters" + name = "Desk Shutters"; + dir = 8 }, /turf/open/floor/iron/white/smooth_large, /area/station/medical/medbay/lobby) @@ -45708,6 +45837,12 @@ /obj/effect/turf_decal/box, /turf/open/floor/plating/airless, /area/space/nearstation) +"mTY" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 5 + }, +/turf/open/floor/iron/dark/textured, +/area/station/bitrunning/den) "mUp" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/spawner/random/trash/mess, @@ -47279,6 +47414,15 @@ }, /turf/open/floor/wood/large, /area/station/hallway/primary/fore) +"nqU" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/turf_decal/trimline/brown/filled/warning{ + dir = 1 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/miningdock) "nrb" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -47341,13 +47485,6 @@ }, /turf/open/floor/wood/large, /area/station/commons/fitness/recreation/entertainment) -"nsm" = ( -/obj/effect/turf_decal/loading_area{ - dir = 4 - }, -/obj/effect/landmark/start/shaft_miner, -/turf/open/floor/iron/smooth_large, -/area/station/cargo/miningdock) "nsp" = ( /obj/effect/turf_decal/trimline/purple/filled/line{ dir = 1 @@ -47582,7 +47719,8 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/structure/table, +/obj/structure/closet/l3closet/security, +/obj/effect/turf_decal/bot, /turf/open/floor/iron/dark, /area/station/security/office) "nvc" = ( @@ -48010,6 +48148,12 @@ dir = 4 }, /area/station/engineering/power_room) +"nAD" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 9 + }, +/turf/open/floor/iron/smooth, +/area/station/cargo/warehouse) "nAH" = ( /turf/closed/wall/r_wall, /area/station/ai_monitored/turret_protected/aisat/atmos) @@ -48040,6 +48184,17 @@ }, /turf/closed/wall/r_wall, /area/station/science/ordnance/burnchamber) +"nBO" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/smooth_edge{ + dir = 8 + }, +/area/station/cargo/miningdock) "nCl" = ( /obj/structure/chair/office/light{ dir = 4 @@ -48315,6 +48470,19 @@ /obj/effect/spawner/random/trash/grille_or_waste, /turf/open/floor/catwalk_floor/iron_smooth, /area/station/science/research/abandoned) +"nGR" = ( +/obj/structure/chair/sofa/corp/right{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/machinery/light/small/directional/west, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/smooth_edge{ + dir = 4 + }, +/area/station/bitrunning/den) "nGX" = ( /obj/structure/chair/sofa/right/brown{ dir = 8 @@ -50180,6 +50348,11 @@ "ogb" = ( /obj/machinery/smartfridge, /obj/effect/turf_decal/bot, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "kitchen_service"; + name = "Service Shutter" + }, /turf/open/floor/iron/large, /area/station/service/kitchen) "ogc" = ( @@ -50463,6 +50636,13 @@ /obj/machinery/status_display/ai/directional/south, /turf/open/floor/carpet/black, /area/station/service/chapel/office) +"oky" = ( +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/machinery/computer/order_console/bitrunning, +/turf/open/floor/iron/dark/textured_edge{ + dir = 1 + }, +/area/station/bitrunning/den) "okG" = ( /obj/effect/turf_decal/tile/neutral{ dir = 8 @@ -50505,7 +50685,8 @@ }, /obj/machinery/door/poddoor/shutters/preopen{ id = "roboticsprivacy"; - name = "Robotics Shutters" + name = "Robotics Shutters"; + dir = 4 }, /turf/open/floor/iron/dark/smooth_large, /area/station/science/robotics/lab) @@ -51379,6 +51560,13 @@ dir = 4 }, /area/station/hallway/secondary/command) +"oxn" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 10 + }, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/textured, +/area/station/bitrunning/den) "oxv" = ( /obj/effect/spawner/structure/window/reinforced, /obj/structure/disposalpipe/segment{ @@ -52052,6 +52240,16 @@ /obj/machinery/light/cold/directional/west, /turf/open/floor/iron/dark/small, /area/station/security/prison/garden) +"oGX" = ( +/obj/structure/table, +/obj/machinery/microwave, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 5 + }, +/obj/machinery/light/small/directional/east, +/obj/structure/sign/poster/contraband/random/directional/east, +/turf/open/floor/iron/smooth, +/area/station/bitrunning/den) "oHc" = ( /obj/machinery/atmospherics/pipe/smart/simple/cyan/visible, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -52912,6 +53110,11 @@ /obj/machinery/firealarm/directional/east, /turf/open/floor/circuit/green, /area/station/ai_monitored/command/nuke_storage) +"oUb" = ( +/obj/machinery/firealarm/directional/west, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron/stairs, +/area/station/bitrunning/den) "oUl" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -54690,6 +54893,19 @@ "pqh" = ( /turf/closed/wall, /area/station/cargo/warehouse) +"pqk" = ( +/obj/structure/chair/sofa/corp/left{ + desc = "Looks like someone threw it out. Covered in donut crumbs."; + dir = 4; + name = "couch" + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 9 + }, +/obj/structure/sign/poster/contraband/random/directional/west, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/smooth, +/area/station/bitrunning/den) "pql" = ( /obj/machinery/power/apc/auto_name/directional/east, /obj/structure/cable, @@ -54998,9 +55214,12 @@ req_access = list("medical") }, /obj/machinery/door/poddoor/shutters/window/preopen{ - dir = 4; id = "paramed_dispatch_desk"; - name = "Desk Shutters" + name = "Desk Shutters"; + dir = 8 + }, +/obj/item/storage/box/bandages{ + pixel_y = 15 }, /turf/open/floor/iron/white/smooth_large, /area/station/medical/medbay/lobby) @@ -55081,6 +55300,13 @@ /obj/machinery/atmospherics/pipe/layer_manifold/supply/hidden, /turf/closed/wall/r_wall, /area/station/maintenance/disposal/incinerator) +"pws" = ( +/obj/effect/landmark/start/shaft_miner, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/miningdock) "pwB" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/item/radio{ @@ -55698,6 +55924,15 @@ /obj/machinery/light_switch/directional/east, /turf/open/floor/iron/smooth, /area/station/engineering/atmos/storage/gas) +"pFJ" = ( +/obj/item/storage/cans/sixsoda, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 6 + }, +/obj/structure/railing, +/obj/item/radio/intercom/directional/east, +/turf/open/floor/iron/smooth, +/area/station/bitrunning/den) "pGh" = ( /turf/open/floor/iron/white/smooth_large, /area/station/hallway/primary/fore) @@ -56454,17 +56689,6 @@ /obj/structure/cable, /turf/open/floor/iron/smooth, /area/station/maintenance/department/electrical) -"pRu" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 4 - }, -/obj/structure/closet/secure_closet/miner, -/obj/effect/turf_decal/delivery, -/obj/machinery/light/directional/east, -/turf/open/floor/iron/smooth_edge{ - dir = 8 - }, -/area/station/cargo/miningdock) "pRv" = ( /obj/effect/spawner/random/trash/moisture_trap, /turf/open/floor/iron/smooth, @@ -57824,6 +58048,13 @@ "qgT" = ( /turf/open/floor/iron/white, /area/station/hallway/primary/fore) +"qgY" = ( +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/structure/railing, +/turf/open/floor/iron/smooth_edge{ + dir = 1 + }, +/area/station/bitrunning/den) "qha" = ( /obj/machinery/chem_heater/withbuffer, /obj/effect/turf_decal/trimline/yellow/filled/line, @@ -57867,7 +58098,6 @@ req_access = list("hop") }, /obj/machinery/door/poddoor/shutters/preopen{ - dir = 8; id = "hop"; name = "Privacy Shutters" }, @@ -57928,6 +58158,26 @@ }, /turf/open/floor/catwalk_floor, /area/station/hallway/secondary/exit/departure_lounge) +"qhU" = ( +/obj/structure/table, +/obj/item/food/cornchips/blue{ + pixel_x = 9; + pixel_y = 4 + }, +/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind{ + pixel_x = -7; + pixel_y = -1 + }, +/obj/effect/turf_decal/box/corners, +/obj/effect/turf_decal/box/corners{ + dir = 4 + }, +/obj/item/food/cornchips/red{ + pixel_x = 3; + pixel_y = 6 + }, +/turf/open/floor/engine, +/area/station/bitrunning/den) "qhX" = ( /obj/effect/landmark/start/medical_doctor, /obj/structure/curtain, @@ -58068,7 +58318,6 @@ }, /obj/machinery/door/firedoor, /obj/machinery/door/poddoor/shutters/preopen{ - dir = 4; id = "rndlab1"; name = "Research and Development Shutter" }, @@ -58401,10 +58650,6 @@ pixel_x = 5; pixel_y = 2 }, -/obj/item/stock_parts/cell/blueshield{ - pixel_x = -5; - pixel_y = 10 - }, /obj/machinery/newscaster/directional/north, /obj/machinery/light_switch/directional/north{ pixel_x = 16 @@ -58508,6 +58753,12 @@ }, /turf/open/floor/iron/dark/smooth_large, /area/station/medical/morgue) +"qpX" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/structure/cable, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/miningdock) "qqa" = ( /obj/effect/spawner/random/structure/barricade, /turf/open/floor/iron/smooth, @@ -58808,17 +59059,6 @@ /obj/item/seeds/watermelon/holy, /turf/open/floor/grass, /area/station/service/chapel) -"quF" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/loading_area{ - dir = 4 - }, -/obj/structure/extinguisher_cabinet/directional/north, -/obj/effect/landmark/start/shaft_miner, -/turf/open/floor/iron/smooth_edge, -/area/station/cargo/miningdock) "quG" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -59213,6 +59453,23 @@ }, /turf/open/floor/carpet/blue, /area/station/command/bridge) +"qBe" = ( +/obj/machinery/door/airlock/mining{ + name = "Mining Dock" + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/airlock/access/any/supply/mining, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/turf/open/floor/iron/smooth, +/area/station/cargo/miningdock) "qBh" = ( /obj/effect/spawner/random/trash/mopbucket, /obj/effect/decal/cleanable/dirt, @@ -59229,6 +59486,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/dark/smooth_large, /area/station/command/gateway) +"qBt" = ( +/obj/machinery/netpod, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "qBA" = ( /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, @@ -59346,7 +59607,6 @@ "qDW" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ - dir = 4; id = "rndlab1"; name = "Research and Development Shutter" }, @@ -60876,6 +61136,11 @@ /area/station/maintenance/aft/upper) "qZl" = ( /obj/machinery/smartfridge/chemistry/preloaded, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemistry_shutters"; + name = "Pharmacy Shutters" + }, /turf/open/floor/iron/freezer, /area/station/medical/pharmacy) "qZz" = ( @@ -61796,6 +62061,18 @@ }, /turf/open/floor/iron/dark/smooth_large, /area/station/security/prison) +"rnb" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 6 + }, +/obj/structure/trash_pile, +/obj/item/clothing/suit/costume/wellworn_shirt/messy/graphic{ + pixel_x = -5; + pixel_y = 5 + }, +/obj/structure/sign/poster/contraband/random/directional/east, +/turf/open/floor/iron/dark/textured, +/area/station/bitrunning/den) "rne" = ( /obj/structure/cable, /obj/machinery/power/apc/auto_name/directional/north, @@ -63094,10 +63371,6 @@ dir = 8 }, /area/station/service/hydroponics) -"rGR" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/turf/open/floor/iron/smooth_large, -/area/station/cargo/miningdock) "rHc" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 @@ -63954,7 +64227,6 @@ /area/station/service/cafeteria) "rUf" = ( /obj/machinery/door/poddoor/shutters/preopen{ - dir = 1; id = "chemistry_shutters"; name = "Pharmacy Shutters" }, @@ -65419,6 +65691,18 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/catwalk_floor/iron_smooth, /area/station/maintenance/department/engine/atmos) +"sqL" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/obj/machinery/light/directional/east, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/turf/open/floor/iron/smooth_edge{ + dir = 8 + }, +/area/station/cargo/miningdock) "sqQ" = ( /obj/machinery/power/solar{ id = "aftport"; @@ -66162,7 +66446,6 @@ req_access = list("pharmacy") }, /obj/machinery/door/poddoor/shutters/preopen{ - dir = 1; id = "chemistry_shutters"; name = "Pharmacy Shutters" }, @@ -68876,7 +69159,8 @@ /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ id = "roboticsprivacy"; - name = "Robotics Shutters" + name = "Robotics Shutters"; + dir = 8 }, /turf/open/floor/plating/airless, /area/station/science/robotics/lab) @@ -70497,6 +70781,25 @@ }, /turf/open/floor/iron/smooth_edge, /area/station/cargo/storage) +"tEI" = ( +/obj/structure/table, +/obj/item/food/ready_donk/mac_n_cheese{ + pixel_y = 3; + pixel_x = 2 + }, +/obj/item/food/ready_donk/nachos_grandes{ + pixel_y = 7 + }, +/obj/item/food/ready_donk/donkhiladas{ + pixel_y = 11; + pixel_x = 1 + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 6 + }, +/obj/machinery/airalarm/directional/east, +/turf/open/floor/iron/smooth, +/area/station/bitrunning/den) "tEK" = ( /obj/machinery/atmospherics/pipe/smart/simple/dark/hidden{ dir = 10 @@ -71107,6 +71410,15 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron/white/diagonal, /area/station/medical/medbay/central) +"tOa" = ( +/obj/structure/chair/plastic, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/obj/effect/landmark/start/bitrunner, +/obj/structure/cable, +/turf/open/floor/iron/smooth_large, +/area/station/bitrunning/den) "tOr" = ( /obj/effect/spawner/liquids_spawner, /obj/machinery/light/cold/directional/south, @@ -72023,6 +72335,12 @@ }, /turf/open/floor/iron/smooth_large, /area/station/engineering/atmos) +"ucK" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/smooth_large, +/area/station/cargo/miningdock) "ucR" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -72323,6 +72641,10 @@ /obj/effect/turf_decal/siding/wood{ dir = 9 }, +/obj/item/storage/box/bandages{ + pixel_y = 16; + pixel_x = -6 + }, /turf/open/floor/iron/dark/smooth_large, /area/station/cargo/storage) "uhv" = ( @@ -75333,6 +75655,10 @@ }, /turf/open/floor/catwalk_floor, /area/station/hallway/primary/aft) +"uVw" = ( +/obj/structure/trash_pile, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "uVG" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -76285,13 +76611,6 @@ /obj/machinery/light/small/directional/west, /turf/open/floor/pod/dark, /area/station/service/chapel) -"vkO" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/trimline/brown/filled/corner{ - dir = 1 - }, -/turf/open/floor/iron/smooth_large, -/area/station/cargo/miningdock) "vkT" = ( /obj/structure/table/glass, /obj/effect/turf_decal/tile/blue/full, @@ -76340,20 +76659,23 @@ dir = 6 }, /obj/structure/table/reinforced, -/obj/machinery/microwave{ - desc = "Cooks and boils stuff, somehow."; - pixel_x = -2; - pixel_y = 5 - }, /obj/machinery/requests_console/directional/south{ department = "Engineering"; - name = "Engineering Requests Console"; dir = 4; - pixel_y = 0; - pixel_x = 30 + name = "Engineering Requests Console"; + pixel_x = 30; + pixel_y = 0 }, /obj/effect/mapping_helpers/requests_console/supplies, /obj/effect/mapping_helpers/requests_console/assistance, +/obj/item/storage/medkit/fire{ + pixel_x = -2; + pixel_y = 4 + }, +/obj/item/radio/off{ + pixel_x = 6; + pixel_y = 6 + }, /turf/open/floor/iron/smooth, /area/station/engineering/lobby) "vlS" = ( @@ -76451,7 +76773,8 @@ /obj/effect/turf_decal/caution/stand_clear, /obj/machinery/door/poddoor/shutters{ id = "mechbay"; - name = "Mech Bay Shutters" + name = "Mech Bay Shutters"; + dir = 4 }, /obj/machinery/button/door/directional/north{ id = "mechbay"; @@ -76818,6 +77141,22 @@ dir = 8 }, /area/station/hallway/primary/fore) +"vte" = ( +/obj/machinery/door/airlock/mining{ + name = "Bitrunning Den" + }, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/structure/cable, +/turf/open/floor/iron/smooth, +/area/station/cargo/miningdock) "vti" = ( /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/preopen{ @@ -77197,6 +77536,11 @@ /obj/structure/cable, /turf/open/floor/plating, /area/station/maintenance/aft/greater) +"vxf" = ( +/obj/machinery/holopad, +/obj/effect/turf_decal/trimline/brown/filled/corner, +/turf/open/floor/iron/smooth_corner, +/area/station/bitrunning/den) "vxv" = ( /mob/living/basic/butterfly, /turf/closed/wall/mineral/iron, @@ -79820,13 +80164,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron/smooth, /area/station/science/robotics/mechbay) -"wjo" = ( -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/trimline/brown/filled/warning{ - dir = 1 - }, -/turf/open/floor/iron/smooth_large, -/area/station/cargo/miningdock) "wjq" = ( /obj/machinery/camera/directional/east{ c_tag = "Security - Detective's Office" @@ -80873,8 +81210,8 @@ /obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/shutters/preopen{ dir = 1; - name = "Exam Room Shutters"; - id = "medexamshutter" + id = "medexamshutter"; + name = "Exam Room Shutters" }, /turf/open/floor/plating, /area/station/medical/exam_room) @@ -82700,6 +83037,11 @@ /obj/machinery/light/cold/directional/west, /turf/open/floor/iron/freezer, /area/station/medical/chemistry) +"wYd" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/curtain/bounty/start_closed, +/turf/open/floor/plating, +/area/station/bitrunning/den) "wYo" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/public/glass{ @@ -83530,6 +83872,7 @@ layer = 2.9; pixel_x = 4 }, +/obj/item/gun/energy/laser/carbine/practice, /turf/open/floor/engine, /area/station/security/range) "xmO" = ( @@ -83590,6 +83933,11 @@ /area/station/security/checkpoint/engineering) "xnP" = ( /obj/machinery/smartfridge/chemistry/preloaded, +/obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemistry_shutters"; + name = "Pharmacy Shutters" + }, /turf/open/floor/iron/dark/smooth_large, /area/station/medical/pharmacy) "xnR" = ( @@ -85638,6 +85986,10 @@ /obj/structure/extinguisher_cabinet/directional/north{ pixel_x = 6 }, +/obj/item/gun/energy/laser/carbine/practice{ + pixel_x = -13; + pixel_y = -5 + }, /obj/machinery/firealarm/directional/north{ pixel_x = -7 }, @@ -86243,6 +86595,14 @@ dir = 8 }, /obj/effect/turf_decal/delivery, +/obj/item/storage/box/flashbangs{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/item/storage/box/teargas{ + pixel_x = 6; + pixel_y = -6 + }, /turf/open/floor/engine, /area/station/ai_monitored/security/armory) "ybE" = ( @@ -86860,13 +87220,13 @@ /turf/open/floor/iron/smooth_large, /area/station/engineering/atmos) "ykT" = ( -/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/smartfridge/chemistry/preloaded, /obj/machinery/door/poddoor/shutters/preopen{ - dir = 1; id = "chemistry_shutters"; name = "Pharmacy Shutters" }, -/turf/open/floor/plating/airless, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/dark/smooth_large, /area/station/medical/pharmacy) "ylg" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ @@ -113302,7 +113662,7 @@ ePK kUZ dYR lxm -fXS +ifS eux iAl wjR @@ -113816,7 +114176,7 @@ qiD kUZ dYR uYT -ejt +fKN pEQ bKZ cUH @@ -118948,7 +119308,7 @@ rFl xgy uQf jLi -ykT +aAN gut uMt sLk @@ -119205,7 +119565,7 @@ gLN dRX jQm tJU -xnP +ykT vVO twU wwr @@ -125902,7 +126262,7 @@ onP onP onP onP -ihv +nAD vwJ wKg fdP @@ -128980,7 +129340,7 @@ fNX iNa bkF hQq -hWA +qBe odX ipj ekQ @@ -129235,7 +129595,7 @@ xMq oXI ihS cvp -wjo +nqU bcW njG xCF @@ -129492,7 +129852,7 @@ xMq oXI iFV lmY -vkO +krz lon cbP szk @@ -129749,7 +130109,7 @@ xMq oXI oCm jAS -rGR +qpX pmM oXI pjT @@ -130006,7 +130366,7 @@ cbP cbP qtr jAS -rGR +qpX lFU oXI jBq @@ -130262,8 +130622,8 @@ ruV jBM ruV aUO -jAS -fxJ +awG +ucK hkN oXI mXQ @@ -130518,9 +130878,9 @@ ttw cbP cbP cbP -qtr -jAS -jAS +dpw +pws +ucK hwL oXI hwR @@ -130775,9 +131135,9 @@ ttw odJ xMq oXI -quF -nsm -nsm +kkC +pws +hSf llf oXI emO @@ -131033,8 +131393,8 @@ odJ xMq oXI xqM -pRu -baW +sqL +nBO afo oXI pjT @@ -131291,13 +131651,13 @@ xMq oXI oXI oXI +vte oXI oXI -oXI -ttw -ttw -ttw -ttw +qBt +ldU +qBt +cBk ttw ttw xMq @@ -131545,18 +131905,18 @@ xMq xMq xMq xMq -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw +cBk +pqk +nGR +goP +kdS +oUb +dAV +ksB +oxn +wYd +xMq +xMq xMq odJ ttw @@ -131801,17 +132161,17 @@ ttw ttw ttw ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw +xMq +cBk +hjg +hJg +tOa +qgY +fth +iLb +deu +oky +wYd ttw ttw xMq @@ -132056,19 +132416,19 @@ ttw ttw ttw ttw +kUb ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw +xMq +cBk +hKK +kFL +vxf +pFJ +qhU +mTY +jvw +rnb +wYd ttw ttw xMq @@ -132313,21 +132673,21 @@ ttw ttw ttw ttw +kUb ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw +xMq +cBk +cBk +oGX +tEI +cBk +uVw +leF +gWT +cBk +cBk +xMq +xMq xMq odJ ttw @@ -132568,21 +132928,21 @@ ttw ttw ttw ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw +smE +xMq +kUb +xMq +xMq +xMq +cBk +cBk +cBk +cBk +cBk +cBk +cBk +cBk +xMq ttw ttw xMq @@ -132827,21 +133187,21 @@ ttw ttw ttw ttw +kUb ttw ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw +xMq +xMq +xMq +xMq +xMq +xMq +xMq +xMq +xMq +xMq +xMq +xMq xMq odJ ttw @@ -133084,19 +133444,19 @@ ttw ttw ttw ttw +kUb +kUb ttw +xMq ttw ttw +xMq ttw ttw +xMq ttw ttw -ttw -ttw -ttw -ttw -ttw -ttw +xMq ttw ttw xMq @@ -133342,19 +133702,19 @@ ttw ttw ttw ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw -ttw +kUb +kUb +kUb +kUb +kUb +kUb +kUb +kUb +kUb +kUb +kUb +kUb +kUb ttw xMq xqO @@ -133601,16 +133961,16 @@ ttw ttw ttw ttw +xMq ttw ttw +xMq ttw ttw +xMq ttw ttw -ttw -ttw -ttw -ttw +xMq ttw ttw xMq @@ -133858,16 +134218,16 @@ ttw ttw ttw ttw +smE ttw ttw +smE ttw ttw +smE ttw ttw -ttw -ttw -ttw -ttw +smE ttw ttw ttw diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm index a475bd6401385c..b287fefce3ea4a 100644 --- a/_maps/map_files/debug/runtimestation.dmm +++ b/_maps/map_files/debug/runtimestation.dmm @@ -1763,6 +1763,10 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/science) +"js" = ( +/obj/machinery/quantum_server, +/turf/open/floor/iron, +/area/station/bitrunning/den) "jE" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 8 @@ -1985,6 +1989,10 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/medical/chemistry) +"vZ" = ( +/obj/machinery/byteforge, +/turf/open/floor/circuit/green, +/area/station/bitrunning/den) "wb" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 4 @@ -2008,6 +2016,10 @@ "wU" = ( /turf/closed/wall/r_wall, /area/station/science/explab) +"yn" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/bitrunning/den) "yA" = ( /obj/docking_port/stationary/laborcamp_home{ dir = 8 @@ -2036,12 +2048,21 @@ /obj/machinery/airalarm/directional/north, /turf/open/floor/iron, /area/station/science) +"Ai" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, +/obj/machinery/light/directional/north, +/turf/open/floor/iron, +/area/station/hallway/secondary/entry) "AP" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 8 }, /turf/open/floor/iron, /area/station/science) +"AR" = ( +/turf/open/floor/circuit/green, +/area/station/bitrunning/den) "BD" = ( /obj/structure/closet/secure_closet/chief_medical{ locked = 0 @@ -2058,6 +2079,12 @@ "Ce" = ( /turf/open/floor/iron, /area/station/medical/chemistry) +"Cq" = ( +/obj/machinery/door/airlock, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, +/turf/open/floor/iron, +/area/station/bitrunning/den) "Ct" = ( /obj/structure/closet/syndicate/resources/everything, /turf/open/floor/iron, @@ -2155,6 +2182,10 @@ /obj/effect/mapping_helpers/airalarm/unlocked, /turf/open/floor/iron, /area/station/command/bridge) +"Fk" = ( +/obj/machinery/netpod, +/turf/open/floor/iron, +/area/station/bitrunning/den) "HW" = ( /obj/machinery/airalarm/directional/east, /obj/effect/mapping_helpers/airalarm/unlocked, @@ -2235,6 +2266,9 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"Ma" = ( +/turf/open/floor/iron, +/area/station/bitrunning/den) "Mh" = ( /obj/structure/cable, /turf/open/floor/iron, @@ -2262,11 +2296,23 @@ /obj/machinery/chem_recipe_debug, /turf/open/floor/iron, /area/station/medical/chemistry) +"Nk" = ( +/obj/structure/table/reinforced, +/obj/machinery/light/directional/south, +/turf/open/floor/iron, +/area/station/bitrunning/den) "Ns" = ( /obj/machinery/door/airlock/public/glass, /obj/structure/cable, /turf/open/floor/iron, /area/station/medical/medbay) +"NQ" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 4 + }, +/obj/item/storage/part_replacer/bluespace/tier4, +/turf/open/floor/iron, +/area/station/bitrunning/den) "NZ" = ( /obj/machinery/rnd/production/protolathe/department, /turf/open/floor/iron, @@ -2320,6 +2366,10 @@ }, /turf/open/floor/iron, /area/station/hallway/secondary/entry) +"Qs" = ( +/obj/structure/cable, +/turf/open/floor/iron, +/area/station/bitrunning/den) "Qt" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper{ dir = 4 @@ -2350,6 +2400,11 @@ /obj/effect/turf_decal/tile/blue/half/contrasted, /turf/open/floor/iron, /area/station/command/bridge) +"RS" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, +/turf/open/floor/iron, +/area/station/bitrunning/den) "Sg" = ( /obj/machinery/power/apc/auto_name/directional/west, /obj/effect/turf_decal/stripes/corner, @@ -2425,6 +2480,11 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/main) +"VX" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, +/turf/open/floor/iron, +/area/station/hallway/secondary/entry) "We" = ( /obj/machinery/newscaster/directional/west, /turf/open/floor/iron, @@ -2517,6 +2577,9 @@ }, /turf/open/floor/iron/dark, /area/station/science/explab) +"Yn" = ( +/turf/closed/wall/r_wall, +/area/station/bitrunning/den) "Yy" = ( /obj/machinery/light/directional/north, /obj/machinery/rnd/production/circuit_imprinter/department, @@ -2536,6 +2599,13 @@ /obj/effect/mapping_helpers/airalarm/unlocked, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) +"Zp" = ( +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/cable, +/obj/machinery/airalarm/directional/east, +/obj/machinery/computer/quantum_console, +/turf/open/floor/iron, +/area/station/bitrunning/den) "Zz" = ( /obj/machinery/power/apc/auto_name/directional/west, /obj/effect/turf_decal/stripes/line, @@ -3033,12 +3103,12 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa +Yn +Yn +Yn +Yn +Yn +Yn aa aa aa @@ -3125,12 +3195,12 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa +Yn +AR +AR +Ma +Fk +Yn aa aa aa @@ -3217,12 +3287,12 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa +Yn +AR +vZ +Ma +Fk +Yn aa aa aa @@ -3309,12 +3379,12 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa +Yn +js +Ma +NQ +Fk +Yn aa aa aa @@ -3401,12 +3471,12 @@ aa aa aa aa -aa -aa -aa -aa -aa -aa +Yn +Zp +Qs +RS +Nk +Yn aa aa aa @@ -3493,12 +3563,12 @@ em em em em -em -em -em -dY -en -dY +Yn +Yn +Yn +Cq +yn +Yn Tj Tj Tj @@ -3588,7 +3658,7 @@ rK rK vy em -eh +VX eh LW lc @@ -3680,7 +3750,7 @@ qQ qQ ME em -eh +VX eh LW lc @@ -3772,7 +3842,7 @@ qQ qQ ME em -eh +VX eh LW lc @@ -3864,7 +3934,7 @@ qQ qQ CQ em -eh +Ai eh LW lc @@ -3956,7 +4026,7 @@ qQ qQ ME em -eh +VX eh LW lc @@ -4048,7 +4118,7 @@ qQ qQ YL em -eh +VX eh LW lc @@ -4140,7 +4210,7 @@ II gl gD kj -wM +VX wM LW lc diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 9b6c1b6d5d5187..b0de40dcde263a 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -2,6 +2,15 @@ "aa" = ( /turf/open/space/basic, /area/space) +"ab" = ( +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 1 + }, +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 1 + }, +/turf/open/floor/iron/white/side, +/area/centcom/central_command_areas/evacuation) "ad" = ( /turf/open/space, /area/space) @@ -313,6 +322,21 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/control) +"bu" = ( +/obj/effect/turf_decal/siding/dark_blue{ + dir = 9 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) +"bv" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/siding/dark_blue{ + dir = 8 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "bx" = ( /turf/open/floor/iron/goonplaque{ desc = "This is a plaque commemorating the thunderdome and all those who have died at its pearly blast doors." @@ -422,6 +446,10 @@ /obj/effect/light_emitter/thunderdome, /turf/open/floor/iron, /area/centcom/tdome/arena) +"bS" = ( +/obj/structure/sign/poster/contraband/syndicate_recruitment/directional/north, +/turf/open/indestructible/dark, +/area/centcom/central_command_areas/admin) "bV" = ( /obj/structure/table/reinforced, /obj/machinery/computer/records/medical/laptop, @@ -656,15 +684,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/tdome/observation) -"cX" = ( -/obj/structure/table/reinforced, -/turf/open/floor/iron, -/area/centcom/central_command_areas/supplypod) -"cY" = ( -/obj/machinery/icecream_vat, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/tdome/observation) "cZ" = ( /obj/effect/turf_decal/tile/green/half/contrasted{ dir = 1 @@ -679,6 +698,13 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) +"dc" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/yellow/corner{ + dir = 8 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supply) "dd" = ( /obj/structure/reagent_dispensers/watertank, /obj/effect/turf_decal/stripes/line{ @@ -690,13 +716,6 @@ /obj/effect/landmark/start/new_player, /turf/closed/indestructible/start_area, /area/misc/start) -"dh" = ( -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 8 - }, -/obj/machinery/light/floor, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "di" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, @@ -726,6 +745,16 @@ /obj/effect/light_emitter/thunderdome, /turf/open/floor/iron, /area/centcom/tdome/arena) +"dm" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/bot, +/obj/item/food/mint{ + pixel_x = 6; + pixel_y = -4 + }, +/turf/open/floor/iron, +/area/centcom/tdome/observation) "dn" = ( /obj/effect/turf_decal/siding/wood{ dir = 4 @@ -975,6 +1004,19 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) +"eC" = ( +/obj/structure/table, +/obj/item/toy/sword{ + pixel_y = 8; + pixel_x = 14 + }, +/obj/item/gun/ballistic/shotgun/toy/crossbow{ + pixel_y = 11; + pixel_x = -2 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "eD" = ( /obj/machinery/door/airlock/centcom{ name = "Administrative Office" @@ -997,6 +1039,28 @@ "eF" = ( /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/briefing) +"eG" = ( +/obj/machinery/computer/auxiliary_base/directional/north, +/obj/structure/table/reinforced, +/obj/item/clipboard{ + pixel_y = 4; + pixel_x = 2 + }, +/obj/item/folder/yellow{ + pixel_y = 7; + pixel_x = 5 + }, +/obj/item/pen/red{ + pixel_y = 2; + pixel_x = 3 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/item/paper_bin{ + pixel_x = -15; + pixel_y = 7 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/supply) "eH" = ( /obj/structure/flora/bush/sparsegrass/style_random, /obj/structure/flora/bush/lavendergrass/style_random, @@ -1142,6 +1206,27 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/centcom/central_command_areas/evacuation) +"fs" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/siding/dark_blue/corner, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) +"ft" = ( +/obj/structure/table/wood, +/obj/item/lighter{ + pixel_x = -6; + pixel_y = -2 + }, +/obj/item/crowbar/power{ + pixel_y = 15 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/supplypod) "fw" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron, @@ -1206,6 +1291,17 @@ }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/evacuation/ship) +"fJ" = ( +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 4 + }, +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 4 + }, +/turf/open/floor/iron/white/side{ + dir = 8 + }, +/area/centcom/central_command_areas/evacuation) "fM" = ( /obj/structure/filingcabinet/medical, /obj/machinery/firealarm/directional/west, @@ -1422,9 +1518,30 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron, /area/centcom/central_command_areas/control) +"gM" = ( +/obj/structure/table, +/obj/item/paper_bin{ + pixel_y = 7; + pixel_x = -4 + }, +/obj/item/pen{ + pixel_x = -5; + pixel_y = 9 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "gO" = ( /turf/closed/indestructible/riveted, /area/centcom/central_command_areas/briefing) +"gQ" = ( +/obj/effect/turf_decal/siding/dark_blue{ + dir = 6 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "gR" = ( /obj/item/wrench, /obj/item/restraints/handcuffs, @@ -1515,17 +1632,23 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) -"hv" = ( -/obj/structure/table/reinforced, -/obj/machinery/microwave{ - desc = "Cooks and boils stuff, somehow."; - pixel_x = -3; - pixel_y = 5 - }, -/obj/machinery/barsign/all_access/directional/south, +"hq" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/tdome/observation) +/obj/effect/turf_decal/siding/yellow{ + dir = 1 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supply) +"hs" = ( +/obj/item/kirbyplants/organic/plant22, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/siding/dark_blue{ + dir = 4 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "hx" = ( /obj/machinery/photocopier, /turf/open/floor/iron/grimy, @@ -2005,13 +2128,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/centcom/central_command_areas/supply) -"jq" = ( -/obj/item/stack/package_wrap, -/obj/item/hand_labeler, -/obj/structure/table, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/centcom/central_command_areas/supply) "jr" = ( /obj/machinery/door/airlock/external/ruin{ name = "Supply Shuttle" @@ -2186,12 +2302,17 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/supply) -"jQ" = ( -/obj/structure/closet/secure_closet/quartermaster, -/obj/machinery/airalarm/directional/east, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/centcom/central_command_areas/supply) +"jS" = ( +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 8 + }, +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 8 + }, +/turf/open/floor/iron/white/side{ + dir = 4 + }, +/area/centcom/central_command_areas/evacuation) "jU" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/computer, @@ -2205,10 +2326,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/tdome/administration) -"kh" = ( -/obj/machinery/telecomms/allinone/nuclear, -/turf/open/indestructible/hierophant, -/area/centcom/central_command_areas/admin) "ki" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/filingcabinet{ @@ -2481,6 +2598,26 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/supplypod) +"lH" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/table/reinforced, +/obj/machinery/reagentgrinder{ + desc = "Used to grind things up into raw materials and liquids."; + pixel_y = 5 + }, +/obj/item/reagent_containers/condiment/saltshaker{ + pixel_x = -8; + pixel_y = 5 + }, +/obj/item/reagent_containers/condiment/peppermill{ + pixel_x = -8 + }, +/obj/item/knife/kitchen{ + pixel_x = 11; + pixel_y = -12 + }, +/turf/open/floor/iron/dark, +/area/centcom/tdome/observation) "lJ" = ( /obj/machinery/door/airlock/centcom{ name = "Shuttle Control Office" @@ -2578,10 +2715,6 @@ }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/courtroom) -"lZ" = ( -/obj/machinery/light/floor, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "mc" = ( /obj/effect/light_emitter/podbay, /turf/open/floor/iron, @@ -2645,11 +2778,27 @@ /obj/structure/table/wood, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/courtroom) +"mr" = ( +/obj/effect/turf_decal/tile/dark_blue/fourcorners, +/obj/effect/turf_decal/tile/dark_blue/fourcorners, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "ms" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/machinery/light/floor, /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/ert) +"mv" = ( +/obj/machinery/airalarm/directional/east, +/obj/effect/turf_decal/bot, +/obj/structure/closet/wardrobe/cargotech, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supply) +"mB" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/yellow, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supply) "mC" = ( /obj/structure/window/reinforced/spawner/directional/east, /obj/machinery/computer/operating, @@ -3019,6 +3168,17 @@ /obj/effect/spawner/structure/window/reinforced, /turf/open/floor/plating, /area/centcom/central_command_areas/ferry) +"og" = ( +/obj/machinery/status_display/evac/directional/west, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/table/reinforced, +/obj/machinery/microwave{ + desc = "Cooks and boils stuff, somehow."; + pixel_x = -3; + pixel_y = 5 + }, +/turf/open/floor/iron/dark, +/area/centcom/tdome/observation) "oh" = ( /obj/structure/table/wood, /obj/item/paper_bin, @@ -3259,17 +3419,6 @@ /obj/structure/sign/nanotrasen, /turf/closed/indestructible/riveted, /area/centcom/central_command_areas/courtroom) -"pd" = ( -/obj/item/clipboard, -/obj/item/stamp/denied{ - pixel_x = 3; - pixel_y = 3 - }, -/obj/item/stamp, -/obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/central_command_areas/supply) "pf" = ( /obj/structure/table/reinforced, /obj/item/crowbar/red, @@ -3639,6 +3788,18 @@ /obj/effect/mapping_helpers/airlock/access/all/admin/captain, /turf/open/floor/iron, /area/centcom/central_command_areas/prison) +"qN" = ( +/obj/structure/table/wood, +/obj/item/storage/box/drinkingglasses{ + pixel_y = 14; + pixel_x = -4 + }, +/obj/item/reagent_containers/cup/glass/shaker{ + pixel_y = -8; + pixel_x = -10 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/supplypod) "qO" = ( /obj/effect/turf_decal/tile/red{ dir = 8 @@ -3707,6 +3868,11 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/prison) +"rj" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/closet/secure_closet/quartermaster, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/supply) "rk" = ( /turf/open/floor/wood, /area/centcom/central_command_areas/courtroom) @@ -3724,11 +3890,6 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) -"rq" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, -/obj/machinery/light/floor, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "rs" = ( /obj/effect/landmark/prisonwarp, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -3780,6 +3941,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) +"rC" = ( +/obj/effect/turf_decal/siding/dark_blue/corner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "rF" = ( /obj/structure/flora/bush/sparsegrass/style_random, /obj/structure/flora/bush/grassy/style_random, @@ -3891,12 +4058,6 @@ }, /turf/open/floor/iron/white, /area/centcom/tdome/observation) -"sa" = ( -/obj/structure/table/wood, -/obj/item/lighter, -/obj/item/crowbar/power, -/turf/open/floor/iron/dark, -/area/centcom/central_command_areas/supplypod) "sb" = ( /obj/machinery/vending/snack, /turf/open/floor/iron, @@ -3928,6 +4089,10 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/tdome/administration) +"sl" = ( +/obj/effect/turf_decal/siding/dark_blue/corner, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "sn" = ( /obj/machinery/door/airlock/centcom{ name = "CentCom Security" @@ -4086,15 +4251,6 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) -"sP" = ( -/obj/structure/table, -/obj/item/paper_bin, -/obj/item/pen, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "sQ" = ( /obj/structure/chair, /obj/effect/turf_decal/stripes/line{ @@ -4110,15 +4266,6 @@ /obj/machinery/light/directional/north, /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) -"sS" = ( -/obj/structure/table, -/obj/item/toy/katana, -/obj/item/toy/plush/carpplushie, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "sT" = ( /obj/effect/turf_decal/stripes/line{ dir = 5 @@ -4228,6 +4375,14 @@ /obj/effect/mapping_helpers/airlock/access/all/admin/general, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) +"tx" = ( +/obj/structure/table/reinforced, +/obj/item/paper_bin{ + pixel_y = 8; + pixel_x = -4 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supplypod) "ty" = ( /obj/structure/filingcabinet/security, /obj/machinery/status_display/evac/directional/south, @@ -4303,12 +4458,6 @@ /obj/machinery/status_display/evac/directional/west, /turf/open/floor/iron, /area/centcom/central_command_areas/prison) -"tT" = ( -/obj/effect/turf_decal/siding/yellow{ - dir = 1 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "tU" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -4319,9 +4468,9 @@ /obj/effect/turf_decal/delivery, /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) -"tW" = ( -/turf/open/indestructible/hierophant/two, -/area/centcom/central_command_areas/admin) +"tY" = ( +/turf/open/floor/iron/white, +/area/centcom/central_command_areas/evacuation) "ub" = ( /obj/machinery/door/firedoor, /obj/machinery/door/airlock/centcom{ @@ -4389,10 +4538,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/control) -"us" = ( -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "ut" = ( /obj/docking_port/stationary{ dir = 8; @@ -4428,15 +4573,6 @@ }, /turf/open/space, /area/space) -"uA" = ( -/obj/structure/chair{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "uE" = ( /obj/effect/light_emitter/thunderdome, /turf/closed/indestructible/fakeglass, @@ -4451,10 +4587,6 @@ /obj/machinery/light/directional/east, /turf/open/floor/grass, /area/centcom/tdome/observation) -"uG" = ( -/obj/effect/turf_decal/siding/yellow, -/turf/open/floor/iron, -/area/centcom/central_command_areas/supply) "uM" = ( /obj/machinery/chem_master/condimaster{ name = "HoochMaster 2000" @@ -4489,6 +4621,18 @@ /obj/machinery/light/floor, /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation/ship) +"uS" = ( +/obj/structure/table/reinforced, +/obj/item/reagent_containers/cup/glass/bottle/whiskey{ + pixel_y = 19; + pixel_x = 7 + }, +/obj/item/clothing/mask/cigarette/cigar/havana{ + pixel_x = -6; + pixel_y = 5 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supplypod) "uX" = ( /obj/machinery/shower/directional/east, /obj/effect/turf_decal/tile/green{ @@ -4557,20 +4701,6 @@ /obj/effect/turf_decal/bot, /turf/open/floor/iron, /area/centcom/central_command_areas/control) -"ve" = ( -/obj/effect/turf_decal/tile/blue, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) -"vf" = ( -/obj/effect/turf_decal/tile/blue/half/contrasted, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) -"vg" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "vm" = ( /obj/effect/turf_decal/delivery, /obj/machinery/light/directional/south, @@ -4729,18 +4859,6 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) -"vW" = ( -/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) -"vX" = ( -/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "vY" = ( /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 4 @@ -4748,18 +4866,6 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron, /area/centcom/central_command_areas/supply) -"vZ" = ( -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 4 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) -"wa" = ( -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "wb" = ( /obj/effect/turf_decal/tile/green/half/contrasted{ dir = 1 @@ -4829,6 +4935,13 @@ /obj/effect/light_emitter/thunderdome, /turf/open/floor/iron, /area/centcom/tdome/arena) +"wn" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/yellow{ + dir = 8 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supply) "wq" = ( /obj/structure/chair/comfy/black{ dir = 1 @@ -4954,16 +5067,6 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) -"wK" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) -"wL" = ( -/obj/effect/turf_decal/tile/blue/anticorner/contrasted, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "wN" = ( /obj/effect/turf_decal/siding/wood{ dir = 6 @@ -5074,20 +5177,10 @@ /obj/effect/turf_decal/tile/green, /turf/open/floor/iron, /area/centcom/central_command_areas/control) -"xr" = ( -/obj/structure/chair{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/status_display/evac/directional/west, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) -"xt" = ( -/obj/effect/turf_decal/tile/neutral/anticorner/contrasted{ - dir = 4 - }, +"xq" = ( +/obj/effect/turf_decal/tile/dark_blue/fourcorners, +/obj/effect/turf_decal/tile/dark_blue/fourcorners, +/obj/machinery/light/floor, /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) "xv" = ( @@ -5112,6 +5205,24 @@ /obj/structure/cable, /turf/open/floor/iron, /area/centcom/central_command_areas/admin/storage) +"xA" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/item/reagent_containers/condiment/saltshaker{ + pixel_x = -8; + pixel_y = 5 + }, +/obj/item/reagent_containers/condiment/peppermill{ + pixel_x = -8 + }, +/obj/item/reagent_containers/cup/glass/mug/britcup, +/obj/effect/turf_decal/bot, +/obj/item/clothing/head/utility/chefhat{ + pixel_y = 11; + pixel_x = 5 + }, +/turf/open/floor/iron, +/area/centcom/tdome/observation) "xD" = ( /obj/machinery/computer/security{ dir = 1 @@ -5187,18 +5298,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/courtroom) -"xY" = ( -/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) -"xZ" = ( -/obj/effect/turf_decal/tile/blue/anticorner/contrasted{ - dir = 8 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "yb" = ( /obj/item/kirbyplants/organic/plant21, /obj/effect/turf_decal/tile/green{ @@ -5313,12 +5412,6 @@ /obj/effect/light_emitter/thunderdome, /turf/open/floor/iron, /area/centcom/tdome/arena) -"yB" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 4 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "yC" = ( /obj/structure/filingcabinet/security, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -5342,6 +5435,27 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) +"yN" = ( +/obj/machinery/keycard_auth/directional/south, +/obj/structure/table/reinforced, +/obj/item/stack/package_wrap{ + pixel_y = 11; + pixel_x = -16 + }, +/obj/item/stack/cable_coil{ + pixel_y = 4; + pixel_x = -10 + }, +/obj/item/hand_labeler{ + pixel_y = 1 + }, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/item/hand_labeler_refill{ + pixel_x = 8; + pixel_y = 12 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/supply) "yO" = ( /obj/machinery/computer/communications, /obj/machinery/status_display/evac/directional/north, @@ -5462,18 +5576,6 @@ /obj/effect/mapping_helpers/airlock/access/all/admin/medical, /turf/open/floor/iron, /area/centcom/central_command_areas/control) -"zl" = ( -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) -"zm" = ( -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 1 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "zn" = ( /obj/machinery/light/directional/north, /obj/structure/table/reinforced, @@ -5513,6 +5615,11 @@ }, /turf/open/floor/iron, /area/centcom/tdome/observation) +"zv" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/griddle, +/turf/open/floor/iron/dark, +/area/centcom/tdome/observation) "zw" = ( /obj/structure/sign/nanotrasen, /turf/closed/indestructible/riveted, @@ -5629,6 +5736,16 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/two) +"zN" = ( +/obj/effect/turf_decal/siding/dark_blue, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) +"zP" = ( +/obj/effect/turf_decal/siding/dark_blue{ + dir = 10 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "zR" = ( /obj/structure/closet/secure_closet/personal, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -5644,6 +5761,22 @@ /obj/machinery/light/directional/south, /turf/open/misc/asteroid, /area/centcom/tdome/administration) +"zT" = ( +/obj/item/clipboard{ + pixel_y = 4; + pixel_x = -2 + }, +/obj/item/stamp/denied{ + pixel_x = -2; + pixel_y = 12 + }, +/obj/item/stamp{ + pixel_y = 7 + }, +/obj/structure/table/reinforced, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/supply) "zU" = ( /obj/item/kirbyplants/organic/plant22, /obj/machinery/light_switch/directional/south, @@ -5748,10 +5881,6 @@ }, /turf/open/floor/iron/white, /area/centcom/central_command_areas/control) -"At" = ( -/obj/effect/turf_decal/siding/yellow, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "Av" = ( /obj/item/kirbyplants/organic/plant21, /obj/effect/turf_decal/tile/green{ @@ -5861,13 +5990,6 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) -"AX" = ( -/obj/structure/table, -/obj/item/toy/sword, -/obj/item/gun/ballistic/shotgun/toy/crossbow, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "AY" = ( /obj/structure/chair{ dir = 1 @@ -5940,14 +6062,6 @@ }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) -"Bs" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/firedoor, -/obj/item/storage/bag/tray, -/obj/item/kitchen/fork, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/centcom/tdome/observation) "Bu" = ( /obj/item/kirbyplants/organic/plant21, /obj/machinery/status_display/evac/directional/west, @@ -6178,6 +6292,19 @@ /obj/machinery/light/directional/south, /turf/open/floor/grass, /area/centcom/central_command_areas/evacuation) +"Ce" = ( +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 8 + }, +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 8 + }, +/obj/effect/turf_decal/tile/dark_blue, +/obj/effect/turf_decal/tile/dark_blue, +/turf/open/floor/iron/white/corner{ + dir = 4 + }, +/area/centcom/central_command_areas/evacuation) "Cf" = ( /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 @@ -6193,19 +6320,6 @@ }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/evacuation) -"Ci" = ( -/obj/structure/table/reinforced, -/obj/item/surgery_tray/full{ - pixel_y = 10; - pixel_x = 2 - }, -/obj/item/storage/box/masks{ - pixel_x = -6; - pixel_y = 4 - }, -/obj/effect/turf_decal/stripes/line, -/turf/open/floor/iron/white, -/area/centcom/central_command_areas/evacuation/ship) "Co" = ( /obj/effect/turf_decal/tile/brown/half/contrasted{ dir = 4 @@ -6243,6 +6357,26 @@ }, /turf/open/floor/iron, /area/centcom/tdome/observation) +"CB" = ( +/obj/effect/turf_decal/tile/dark_blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/dark_blue{ + dir = 4 + }, +/turf/open/floor/iron/white/side{ + dir = 10 + }, +/area/centcom/central_command_areas/evacuation) +"CC" = ( +/obj/machinery/light/directional/north, +/obj/structure/table/wood, +/obj/structure/reagent_dispensers/beerkeg{ + pixel_y = 6; + pixel_x = 5 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/supplypod) "CE" = ( /obj/item/clipboard, /obj/item/folder/red, @@ -6374,6 +6508,12 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/control) +"Dg" = ( +/obj/machinery/light/floor, +/obj/effect/turf_decal/tile/dark_blue/fourcorners, +/obj/effect/turf_decal/tile/dark_blue/fourcorners, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "Di" = ( /turf/closed/indestructible/riveted, /area/centcom/ai_multicam_room) @@ -6394,6 +6534,32 @@ /obj/machinery/light/directional/east, /turf/open/floor/iron, /area/centcom/central_command_areas/control) +"Dn" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/siding/dark_blue/corner{ + dir = 4 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) +"Do" = ( +/obj/structure/table/reinforced, +/obj/machinery/status_display/evac/directional/west, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/item/clothing/suit/apron/chef, +/obj/item/kitchen/rollingpin{ + pixel_y = 2 + }, +/obj/item/reagent_containers/condiment/enzyme{ + pixel_y = 15; + pixel_x = -7 + }, +/turf/open/floor/iron/dark, +/area/centcom/tdome/observation) "Dp" = ( /obj/machinery/status_display/evac/directional/west, /obj/effect/turf_decal/tile/green{ @@ -6409,6 +6575,17 @@ /obj/effect/mapping_helpers/airlock/access/all/admin/general, /turf/open/floor/iron, /area/centcom/central_command_areas/control) +"Dr" = ( +/obj/effect/turf_decal/tile/dark_blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/dark_blue{ + dir = 8 + }, +/turf/open/floor/iron/white/side{ + dir = 5 + }, +/area/centcom/central_command_areas/evacuation) "Ds" = ( /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 4 @@ -6827,6 +7004,13 @@ /obj/effect/light_emitter/thunderdome, /turf/open/floor/iron, /area/centcom/tdome/arena) +"FM" = ( +/obj/effect/turf_decal/tile/brown/half/contrasted{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supply) "FO" = ( /obj/structure/table/reinforced, /obj/item/computer_disk/quartermaster, @@ -6838,6 +7022,15 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/supply) +"FP" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/siding/dark_blue/corner{ + dir = 8 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "FR" = ( /obj/effect/light_emitter/podbay, /turf/open/floor/iron, @@ -6867,6 +7060,13 @@ /obj/effect/light_emitter/thunderdome, /turf/closed/indestructible/fakeglass, /area/centcom/tdome/observation) +"Gc" = ( +/obj/structure/table/reinforced, +/obj/item/storage/fancy/donut_box{ + pixel_y = 13 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supplypod) "Gf" = ( /obj/machinery/firealarm/directional/east, /obj/machinery/atmospherics/components/unary/vent_pump{ @@ -6921,6 +7121,15 @@ /obj/machinery/light/directional/north, /turf/open/floor/iron, /area/centcom/central_command_areas/admin/storage) +"Gw" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/siding/dark_blue{ + dir = 4 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "GB" = ( /obj/machinery/power/apc/auto_name/directional/west, /obj/effect/turf_decal/stripes/line, @@ -6994,6 +7203,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/courtroom) +"GU" = ( +/obj/effect/turf_decal/siding/dark_blue/corner{ + dir = 4 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "GX" = ( /obj/item/kirbyplants/organic/plant22, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -7135,6 +7350,15 @@ /obj/machinery/status_display/evac/directional/south, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/courtroom) +"HQ" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/effect/turf_decal/siding/dark_blue/corner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "HR" = ( /obj/structure/bed/medical/emergency, /obj/machinery/iv_drip, @@ -7182,6 +7406,9 @@ }, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/evacuation/ship) +"Ib" = ( +/turf/closed/indestructible/riveted, +/area/space) "Ic" = ( /obj/machinery/door/poddoor{ id = "thunderdomehea"; @@ -7191,24 +7418,6 @@ /obj/effect/light_emitter/thunderdome, /turf/open/floor/iron, /area/centcom/tdome/arena) -"Id" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/firedoor, -/obj/item/reagent_containers/condiment/saltshaker{ - pixel_x = -8; - pixel_y = 5 - }, -/obj/item/reagent_containers/condiment/peppermill{ - pixel_x = -8 - }, -/obj/item/reagent_containers/cup/glass/mug/britcup, -/obj/effect/turf_decal/bot, -/turf/open/floor/iron, -/area/centcom/tdome/observation) -"Ie" = ( -/obj/structure/sign/poster/contraband/syndicate_recruitment, -/turf/closed/indestructible/riveted, -/area/centcom/central_command_areas/admin) "If" = ( /obj/machinery/newscaster{ pixel_x = -32 @@ -7246,6 +7455,13 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/ferry) +"Iu" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/yellow{ + dir = 4 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supply) "Iv" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -7283,6 +7499,32 @@ /obj/machinery/light/directional/south, /turf/open/floor/grass, /area/centcom/tdome/administration) +"IW" = ( +/obj/item/stack/package_wrap, +/obj/item/hand_labeler{ + pixel_y = 13; + pixel_x = 1 + }, +/obj/structure/table, +/obj/effect/turf_decal/bot, +/obj/item/hand_labeler_refill{ + pixel_x = -8; + pixel_y = 6 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supply) +"Ja" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor, +/obj/structure/noticeboard/directional/south, +/obj/effect/turf_decal/bot, +/obj/item/storage/bag/tray, +/obj/item/kitchen/fork{ + pixel_x = -7; + pixel_y = 2 + }, +/turf/open/floor/iron, +/area/centcom/tdome/observation) "Jb" = ( /turf/closed/indestructible/riveted, /area/centcom/central_command_areas/prison/cells) @@ -7338,6 +7580,17 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/tdome/administration) +"JK" = ( +/obj/structure/table/wood, +/obj/item/storage/box/donkpockets{ + pixel_y = 19; + pixel_x = 5 + }, +/obj/item/storage/fancy/cigarettes/cigars/cohiba{ + pixel_y = 6 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/supplypod) "JO" = ( /obj/machinery/modular_computer/preset/id/centcom, /obj/machinery/computer/security/telescreen{ @@ -7348,16 +7601,6 @@ }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) -"JU" = ( -/obj/structure/chair{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/machinery/light/directional/west, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "JV" = ( /obj/structure/table/wood, /obj/machinery/chem_dispenser/drinks/beer{ @@ -7372,6 +7615,9 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) +"JX" = ( +/turf/open/indestructible/dark, +/area/centcom/central_command_areas/admin) "Kd" = ( /obj/effect/turf_decal/tile/red/opposingcorners, /obj/effect/turf_decal/tile/yellow/opposingcorners{ @@ -7440,6 +7686,11 @@ "KH" = ( /turf/closed/wall/mineral/titanium, /area/centcom/central_command_areas/evacuation/ship) +"KJ" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/yellow/corner, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supply) "KK" = ( /obj/structure/reagent_dispensers/fueltank, /obj/effect/turf_decal/stripes/line{ @@ -7482,6 +7733,19 @@ /obj/machinery/vending/cigarette, /turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/evacuation/ship) +"KP" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/light/directional/west, +/obj/effect/turf_decal/siding/dark_blue{ + dir = 4 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "KQ" = ( /turf/open/floor/plating, /area/centcom/central_command_areas/evacuation/ship) @@ -7519,6 +7783,13 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/evacuation/ship) +"La" = ( +/obj/effect/turf_decal/tile/dark_blue/half/contrasted, +/obj/effect/turf_decal/tile/dark_blue/half/contrasted, +/turf/open/floor/iron/white/side{ + dir = 1 + }, +/area/centcom/central_command_areas/evacuation) "Lb" = ( /obj/effect/turf_decal/tile/neutral/opposingcorners, /obj/effect/turf_decal/tile/neutral/opposingcorners, @@ -7556,6 +7827,21 @@ /obj/structure/marker_beacon/burgundy, /turf/open/floor/catwalk_floor, /area/centcom/central_command_areas/evacuation/ship) +"Lh" = ( +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 8 + }, +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 8 + }, +/obj/effect/turf_decal/tile/dark_blue{ + dir = 4 + }, +/obj/effect/turf_decal/tile/dark_blue{ + dir = 4 + }, +/turf/open/floor/iron/white/corner, +/area/centcom/central_command_areas/evacuation) "Li" = ( /obj/effect/turf_decal/tile/neutral/opposingcorners, /obj/effect/turf_decal/tile/neutral/opposingcorners, @@ -7888,12 +8174,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/dark/herringbone, /area/centcom/central_command_areas/evacuation/ship) -"MI" = ( -/obj/machinery/light/directional/north, -/obj/structure/table/wood, -/obj/structure/reagent_dispensers/beerkeg, -/turf/open/floor/iron/dark, -/area/centcom/central_command_areas/supplypod) "MJ" = ( /obj/structure/chair/office, /obj/effect/landmark/ert_spawn, @@ -7966,16 +8246,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/control) -"Nh" = ( -/obj/structure/table/wood, -/obj/item/storage/box/drinkingglasses, -/obj/item/reagent_containers/cup/glass/shaker, -/turf/open/floor/iron/dark, -/area/centcom/central_command_areas/supplypod) -"Nk" = ( -/obj/structure/sign/poster/contraband/syndicate_pistol, -/turf/closed/indestructible/riveted, -/area/centcom/central_command_areas/admin) "Nm" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -8050,15 +8320,6 @@ /obj/effect/mapping_helpers/airlock/access/all/admin/general, /turf/open/floor/iron, /area/centcom/central_command_areas/control) -"NH" = ( -/obj/structure/table/reinforced, -/obj/item/food/mint, -/obj/item/reagent_containers/condiment/enzyme{ - pixel_y = 5 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/tdome/observation) "NI" = ( /obj/effect/turf_decal/siding/wood{ dir = 8 @@ -8198,6 +8459,13 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin/storage) +"Os" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/yellow/corner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supply) "Ot" = ( /obj/structure/table/reinforced, /obj/machinery/door/firedoor, @@ -8299,20 +8567,6 @@ /obj/item/kirbyplants/organic/plant21, /turf/open/floor/iron/dark/herringbone, /area/centcom/central_command_areas/evacuation/ship) -"OM" = ( -/obj/structure/table/reinforced, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/central_command_areas/supply) -"OO" = ( -/obj/structure/table/reinforced, -/obj/machinery/reagentgrinder{ - desc = "Used to grind things up into raw materials and liquids."; - pixel_y = 5 - }, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/tdome/observation) "OP" = ( /obj/effect/turf_decal/delivery, /turf/open/floor/iron, @@ -8379,6 +8633,10 @@ /obj/machinery/light/directional/north, /turf/open/misc/asteroid, /area/centcom/tdome/observation) +"Pa" = ( +/obj/machinery/light/floor, +/turf/open/floor/iron/white, +/area/centcom/central_command_areas/evacuation) "Pc" = ( /obj/structure/fans/tiny, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -8408,15 +8666,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/courtroom) -"Pg" = ( -/obj/machinery/computer/auxiliary_base/directional/north, -/obj/structure/table/reinforced, -/obj/item/clipboard, -/obj/item/folder/yellow, -/obj/item/pen/red, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/central_command_areas/supply) "Pk" = ( /obj/structure/table/wood, /obj/item/storage/fancy/donut_box, @@ -8522,13 +8771,6 @@ /obj/structure/sign/nanotrasen, /turf/closed/indestructible/riveted, /area/centcom/central_command_areas/admin) -"PG" = ( -/obj/effect/turf_decal/tile/blue/half/contrasted{ - dir = 4 - }, -/obj/machinery/light/floor, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "PH" = ( /obj/machinery/firealarm/directional/south, /obj/structure/closet/crate/bin, @@ -8715,12 +8957,6 @@ }, /turf/open/floor/iron, /area/centcom/tdome/observation) -"Qx" = ( -/obj/effect/turf_decal/siding/yellow{ - dir = 1 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/supply) "Qy" = ( /obj/machinery/shower/directional/west, /obj/effect/turf_decal/tile/green/anticorner/contrasted{ @@ -8767,6 +9003,11 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark/textured_large, /area/centcom/central_command_areas/evacuation/ship) +"QL" = ( +/obj/machinery/telecomms/allinone/nuclear, +/obj/structure/sign/poster/contraband/syndicate_pistol/directional/north, +/turf/open/indestructible/dark, +/area/centcom/central_command_areas/admin) "QM" = ( /obj/effect/turf_decal/tile/brown/anticorner/contrasted{ dir = 8 @@ -8779,6 +9020,23 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod) +"QQ" = ( +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 4 + }, +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 4 + }, +/obj/effect/turf_decal/tile/dark_blue{ + dir = 8 + }, +/obj/effect/turf_decal/tile/dark_blue{ + dir = 8 + }, +/turf/open/floor/iron/white/corner{ + dir = 1 + }, +/area/centcom/central_command_areas/evacuation) "QR" = ( /obj/structure/chair/office/light{ dir = 8 @@ -8861,10 +9119,9 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/briefing) -"Rf" = ( -/obj/item/kirbyplants/organic/plant22, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +"Re" = ( +/obj/effect/turf_decal/siding/dark_blue{ + dir = 5 }, /turf/open/floor/iron, /area/centcom/central_command_areas/evacuation) @@ -8921,14 +9178,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) -"Ro" = ( -/obj/structure/table/wood, -/obj/item/storage/box/donkpockets, -/obj/item/storage/fancy/cigarettes/cigars/cohiba{ - pixel_y = 3 - }, -/turf/open/floor/iron/dark, -/area/centcom/central_command_areas/supplypod) "Rp" = ( /obj/machinery/computer/communications, /turf/open/floor/iron/dark/herringbone, @@ -8956,20 +9205,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/tdome/administration) -"Rx" = ( -/obj/structure/table/reinforced, -/obj/item/reagent_containers/condiment/saltshaker{ - pixel_x = -8; - pixel_y = 5 - }, -/obj/item/reagent_containers/condiment/peppermill{ - pixel_x = -8 - }, -/obj/item/knife/kitchen, -/obj/machinery/newscaster/directional/west, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/tdome/observation) "Ry" = ( /obj/item/storage/medkit/fire, /obj/item/storage/medkit/regular{ @@ -9220,6 +9455,15 @@ /obj/machinery/computer/shuttle, /turf/open/floor/iron/dark/herringbone, /area/centcom/central_command_areas/evacuation/ship) +"SZ" = ( +/obj/structure/table/reinforced, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/item/papercutter{ + pixel_y = 6; + pixel_x = 2 + }, +/turf/open/floor/iron/dark, +/area/centcom/central_command_areas/supply) "Tb" = ( /obj/structure/railing/corner{ dir = 8 @@ -9265,16 +9509,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) -"Tj" = ( -/obj/structure/table/reinforced, -/obj/item/reagent_containers/cup/glass/bottle/whiskey{ - pixel_y = 5 - }, -/obj/item/clothing/mask/cigarette/cigar/havana{ - pixel_x = 2 - }, -/turf/open/floor/iron, -/area/centcom/central_command_areas/supplypod) "Tl" = ( /obj/structure/table/wood, /obj/structure/plaque/static_plaque/thunderdome{ @@ -9297,14 +9531,6 @@ }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) -"Tp" = ( -/obj/structure/table/reinforced, -/obj/item/clothing/suit/apron/chef, -/obj/item/kitchen/rollingpin, -/obj/machinery/status_display/evac/directional/west, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/tdome/observation) "Tq" = ( /obj/structure/filingcabinet/filingcabinet, /obj/machinery/status_display/evac/directional/south, @@ -9324,6 +9550,13 @@ }, /turf/open/floor/iron, /area/centcom/tdome/administration) +"Tu" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/siding/yellow/corner{ + dir = 4 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/supply) "Tv" = ( /obj/structure/table/wood, /obj/structure/window/spawner/directional/south, @@ -9392,15 +9625,6 @@ /obj/effect/light_emitter/thunderdome, /turf/open/floor/iron, /area/centcom/tdome/arena) -"TO" = ( -/obj/machinery/keycard_auth/directional/south, -/obj/structure/table/reinforced, -/obj/item/stack/package_wrap, -/obj/item/stack/cable_coil, -/obj/item/hand_labeler, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/central_command_areas/supply) "TS" = ( /obj/structure/table/wood, /obj/item/dice/d20{ @@ -9415,11 +9639,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/admin) -"TT" = ( -/obj/structure/table/reinforced, -/obj/item/storage/fancy/donut_box, -/turf/open/floor/iron, -/area/centcom/central_command_areas/supplypod) "TU" = ( /obj/machinery/computer/security{ dir = 8 @@ -9461,6 +9680,12 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/evacuation) +"Ug" = ( +/obj/machinery/barsign/all_access/directional/south, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/griddle, +/turf/open/floor/iron/dark, +/area/centcom/tdome/observation) "Uh" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ dir = 8 @@ -9547,9 +9772,6 @@ /obj/machinery/light/directional/west, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/supplypod) -"Ux" = ( -/turf/open/indestructible/hierophant, -/area/centcom/central_command_areas/admin) "Uz" = ( /obj/effect/turf_decal/stripes/line{ dir = 8 @@ -9650,10 +9872,6 @@ /obj/effect/decal/cleanable/vomit/old, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/control) -"Vd" = ( -/obj/effect/turf_decal/tile/blue/fourcorners, -/turf/open/floor/iron, -/area/centcom/central_command_areas/evacuation) "Vf" = ( /obj/item/kirbyplants/organic/plant21{ pixel_x = -3; @@ -9679,6 +9897,19 @@ }, /turf/open/floor/iron, /area/centcom/central_command_areas/armory) +"Vh" = ( +/obj/structure/table/reinforced, +/obj/item/surgery_tray/full{ + pixel_y = 10; + pixel_x = 2 + }, +/obj/item/storage/box/masks{ + pixel_x = -6; + pixel_y = 4 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron/white, +/area/centcom/central_command_areas/evacuation/ship) "Vi" = ( /obj/item/book/manual/wiki/security_space_law, /obj/structure/table/wood, @@ -9786,6 +10017,17 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/control) +"VE" = ( +/obj/structure/table, +/obj/item/toy/katana{ + pixel_y = 8 + }, +/obj/item/toy/plush/carpplushie, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "VF" = ( /obj/machinery/computer/crew{ dir = 4 @@ -9827,15 +10069,6 @@ /obj/effect/turf_decal/tile/brown/anticorner/contrasted, /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/four) -"VT" = ( -/obj/structure/rack, -/obj/item/storage/box/donkpockets, -/obj/item/storage/box/donkpockets, -/obj/item/clothing/head/utility/chefhat, -/obj/machinery/status_display/evac/directional/west, -/obj/effect/turf_decal/tile/neutral/fourcorners, -/turf/open/floor/iron/dark, -/area/centcom/tdome/observation) "VY" = ( /obj/machinery/computer/records/security{ dir = 8 @@ -9893,6 +10126,12 @@ /obj/effect/turf_decal/tile/red/fourcorners, /turf/open/floor/iron, /area/centcom/tdome/observation) +"Wi" = ( +/obj/machinery/newscaster/directional/west, +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/icecream_vat, +/turf/open/floor/iron/dark, +/area/centcom/tdome/observation) "Wl" = ( /obj/structure/table/wood, /obj/machinery/recharger, @@ -9917,6 +10156,12 @@ /obj/effect/turf_decal/tile/brown/half/contrasted, /turf/open/floor/iron, /area/centcom/central_command_areas/supplypod/loading/four) +"Wu" = ( +/obj/effect/turf_decal/siding/dark_blue/corner{ + dir = 8 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "Wv" = ( /obj/structure/chair, /obj/effect/landmark/thunderdome/observe, @@ -10353,6 +10598,19 @@ /obj/effect/mapping_helpers/airlock/access/all/admin/general, /turf/open/floor/iron/dark, /area/centcom/central_command_areas/control) +"YD" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/machinery/status_display/evac/directional/west, +/obj/effect/turf_decal/siding/dark_blue{ + dir = 4 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "YG" = ( /obj/structure/closet/emcloset, /obj/item/tank/internals/emergency_oxygen/engi, @@ -10408,6 +10666,12 @@ }, /turf/open/floor/iron/grimy, /area/centcom/central_command_areas/admin) +"YS" = ( +/obj/effect/turf_decal/siding/dark_blue{ + dir = 1 + }, +/turf/open/floor/iron, +/area/centcom/central_command_areas/evacuation) "YT" = ( /obj/structure/table/wood, /obj/structure/plaque/static_plaque/thunderdome{ @@ -10454,6 +10718,28 @@ /obj/structure/sign/nanotrasen, /turf/closed/indestructible/riveted, /area/centcom/central_command_areas/fore) +"Zc" = ( +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 4 + }, +/obj/effect/turf_decal/tile/dark_blue/half/contrasted{ + dir = 4 + }, +/obj/effect/turf_decal/tile/dark_blue{ + dir = 1 + }, +/obj/effect/turf_decal/tile/dark_blue{ + dir = 1 + }, +/turf/open/floor/iron/white/corner{ + dir = 8 + }, +/area/centcom/central_command_areas/evacuation) +"Zd" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/machinery/oven/range, +/turf/open/floor/iron/dark, +/area/centcom/tdome/observation) "Ze" = ( /obj/effect/turf_decal/tile/red, /turf/open/floor/iron, @@ -37631,7 +37917,7 @@ Lt aa aa Lt -Ci +Vh LI CH CH @@ -49390,9 +49676,9 @@ aa aa aa aa -Ie -tW -Ux +On +bS +JX On yO To @@ -49647,9 +49933,9 @@ aa aa aa aa -Nk -kh -tW +On +QL +JX On On Oc @@ -50160,10 +50446,10 @@ aa aa aa iX -OM +SZ mG nl -pd +zT On Rn EJ @@ -50417,10 +50703,10 @@ iX iX iN iF -Pg +eG mH nm -TO +yN On Ui JC @@ -51172,20 +51458,20 @@ aa aa aa aa -aa +Ib iF iQ -oJ -oJ -oJ -oJ -oJ -oJ -oJ -oJ -oJ -oJ -oJ +KJ +Iu +Iu +Iu +Iu +Iu +Iu +Iu +Iu +Iu +Tu ln iN zn @@ -51229,11 +51515,11 @@ oi QC aM BW -Rx -NH -Tp -OO -VT +Wi +Zd +Do +lH +og BY QC bR @@ -51429,20 +51715,20 @@ aa aa aa aa -aa +Ib iG iR -oJ -Qx +mB iO -oJ iO oJ iO oJ iO -uG oJ +iO +iO +hq lo lJ hz @@ -51491,7 +51777,7 @@ bi eI bi eI -hv +Ug QC bR KL @@ -51686,23 +51972,23 @@ aa aa aa aa -aa +Ib iG iR -oJ -Qx +mB jp -oJ jp oJ jp oJ jp -uG oJ +jp +jp +hq lo iF -XA +rj mJ lq XK @@ -51748,7 +52034,7 @@ Wf bi eI bi -cY +zv QC EI CW @@ -51943,20 +52229,20 @@ aa aa aa aa -aa +Ib iF iR -oJ -Qx +mB jp -oJ jp oJ jp oJ jp -uG oJ +jp +jp +hq EK iF iF @@ -52002,9 +52288,9 @@ Zj bi eI zw -Id -Bs -di +xA +dm +Ja QC QC xv @@ -52200,20 +52486,20 @@ aa aa aa aa -aa +Ib iG iR -oJ -Qx +mB jp -oJ jp oJ jp oJ jp -uG oJ +jp +jp +hq lp iF mi @@ -52457,20 +52743,20 @@ aa aa aa aa -aa +Ib iG iR -oJ -oJ -oJ -oJ -oJ -oJ -oJ -oJ -oJ -oJ -oJ +dc +wn +wn +wn +wn +wn +wn +wn +wn +wn +Os lo lK iR @@ -52714,20 +53000,20 @@ aa aa aa aa -aa +Ib iF iS iZ -iZ -jq +FM +IW ju eq vY jN -jQ +mv jN -iZ -iZ +FM +FM lq iF mj @@ -59169,15 +59455,15 @@ qz cg sN bL -uA -JU -xr -wK -Rf -wK -xr -JU -uA +fs +KP +YD +Gw +hs +Gw +YD +KP +Dn bL AV cg @@ -59198,7 +59484,7 @@ NO Uw NO ly -cX +tx Yn OZ HE @@ -59425,17 +59711,17 @@ qz qy cg sO -tT -us -us -us -us -us -us -us -us -us -At +sl +gQ +mr +mr +mr +mr +mr +mr +mr +Re +GU AW cg qz @@ -59455,7 +59741,7 @@ NO NO NO ly -TT +Gc Yn Yn Yn @@ -59681,19 +59967,19 @@ Hv qA qy fm -sP -tT -us -ve -vW -us -us -us -us -us -us -At -AX +gM +zN +mr +Lh +mr +mr +mr +mr +mr +mr +mr +YS +eC fm Cd cg @@ -59939,17 +60225,17 @@ qy qz cg fE -tT -us -vf -vX -vW -us -us -us -us -us -At +zN +mr +ab +Dr +mr +xq +mr +mr +mr +mr +YS aP cg qy @@ -60196,17 +60482,17 @@ qy qz cg sQ -tT -us -vf -Vd -vX -vW -us -us -us -us -At +zN +mr +ab +tY +Dr +mr +mr +mr +mr +mr +YS AY cg fm @@ -60453,17 +60739,17 @@ cg fm cg sQ -tT -us -ve -vZ -vZ -PG -vZ -vZ -yB -us -At +zN +mr +Lh +jS +jS +jS +jS +jS +Ce +mr +YS AY cg pg @@ -60710,17 +60996,17 @@ qB qW rT sO -tT -us -vg -Vd -Vd -Vd -xY -wa -zl -us -At +zN +mr +Zc +CB +tY +tY +fJ +fJ +QQ +mr +YS AW BN Cf @@ -60967,17 +61253,17 @@ qC qX rU sO -tT -us -lZ -vg -Vd -Vd -Vd -yB -lZ -us -At +zN +mr +Dg +mr +CB +Pa +Dr +mr +Dg +mr +YS DU BO Cg @@ -61224,17 +61510,17 @@ qD qY rV sO -tT -us -ve -vZ -wL -Vd -Vd -Vd -yB -us -At +zN +mr +Lh +jS +jS +tY +tY +Dr +Ce +mr +YS AW BP Cf @@ -61481,17 +61767,17 @@ cg fm cg sQ -tT -us -vg -wa -wa -dh -wa -wa -zl -us -At +zN +mr +Zc +fJ +fJ +fJ +fJ +fJ +QQ +mr +YS AY cg VY @@ -61738,17 +62024,17 @@ qz qy cg sR -tT -us -us -us -us -xt -xZ -Vd -zm -us -At +zN +mr +mr +mr +mr +mr +CB +tY +La +mr +YS AZ cg fm @@ -61995,23 +62281,23 @@ qy qz cg fE -tT -us -us -us -us -us -xt -xZ -zm -us -At +zN +mr +mr +mr +mr +mr +mr +CB +La +mr +YS aP cg qz cg -Nh -Ro +qN +JK Yn Se MP @@ -62251,23 +62537,23 @@ Hv qA qy fm -sS -tT -us -us -us -us -rq -us -xt -zl -us -At +VE +zN +mr +mr +mr +mr +Dg +mr +mr +QQ +mr +YS Bb fm Cd cg -MI +CC NO Yn Se @@ -62509,17 +62795,17 @@ qz qy cg sO -tT -us -us -us -us -us -us -us -us -us -At +Wu +zP +mr +mr +mr +mr +mr +mr +mr +bu +rC AW cg qy @@ -62767,21 +63053,21 @@ qy cg sT tU -tU -tU -tU -tU -tU -tU -tU -tU -tU +FP +bv +bv +bv +bv +bv +bv +bv +HQ tU Bc cg qz cg -sa +ft NO Yn Se @@ -63038,7 +63324,7 @@ tV cg cg cg -Tj +uS Su Yn Vk diff --git a/_maps/map_files/generic/CentCom_skyrat_z2.dmm b/_maps/map_files/generic/CentCom_skyrat_z2.dmm index d187e5f5dac48f..ebe14eb4f51ef5 100644 --- a/_maps/map_files/generic/CentCom_skyrat_z2.dmm +++ b/_maps/map_files/generic/CentCom_skyrat_z2.dmm @@ -2283,6 +2283,7 @@ "aDY" = ( /obj/machinery/processor, /obj/machinery/light/directional/west, +/obj/structure/table, /turf/open/indestructible/hoteltile{ icon_state = "cafeteria" }, diff --git a/_maps/map_files/tramstation/maintenance_modules/barcargoupper_1.dmm b/_maps/map_files/tramstation/maintenance_modules/barcargoupper_1.dmm index a34ab0e6fcf368..eab9280b8fa793 100644 --- a/_maps/map_files/tramstation/maintenance_modules/barcargoupper_1.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/barcargoupper_1.dmm @@ -1845,10 +1845,10 @@ gb gb gb gb -gb -gb -gb -gb +eJ +eJ +eJ +eJ eJ eJ eJ @@ -1882,10 +1882,10 @@ gb gb gb gb -gb -gb -gb -gb +eJ +eJ +eJ +eJ eJ eJ eJ @@ -1918,7 +1918,7 @@ eJ gb gb gb -eJ +gb eJ eJ eJ diff --git a/_maps/map_files/tramstation/maintenance_modules/barcargoupper_2.dmm b/_maps/map_files/tramstation/maintenance_modules/barcargoupper_2.dmm index f20109536f86da..0901318e301430 100644 --- a/_maps/map_files/tramstation/maintenance_modules/barcargoupper_2.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/barcargoupper_2.dmm @@ -2000,10 +2000,10 @@ se se se se -se -se -se -se +dx +dx +dx +dx dx dx dx @@ -2037,10 +2037,10 @@ se se se se -se -se -se -se +dx +dx +dx +dx dx dx dx @@ -2073,7 +2073,7 @@ dx se se se -dx +se dx dx dx diff --git a/_maps/map_files/tramstation/maintenance_modules/barcargoupper_3.dmm b/_maps/map_files/tramstation/maintenance_modules/barcargoupper_3.dmm index 63b18a69e75280..775e31e6b9d8a4 100644 --- a/_maps/map_files/tramstation/maintenance_modules/barcargoupper_3.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/barcargoupper_3.dmm @@ -1918,10 +1918,10 @@ cK cK cK cK -cK -cK -cK -cK +Hu +Hu +Hu +Hu Hu Hu Hu @@ -1955,10 +1955,10 @@ cK cK cK cK -cK -cK -cK -cK +Hu +Hu +Hu +Hu Hu Hu Hu @@ -1991,7 +1991,7 @@ Hu cK cK cK -Hu +cK Hu Hu Hu diff --git a/_maps/map_files/tramstation/maintenance_modules/barcargoupper_cave_1.dmm b/_maps/map_files/tramstation/maintenance_modules/barcargoupper_cave_1.dmm index 202e850684a518..ae78ae6731f9bb 100644 --- a/_maps/map_files/tramstation/maintenance_modules/barcargoupper_cave_1.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/barcargoupper_cave_1.dmm @@ -1079,10 +1079,10 @@ V V V V -V -V -V -V +l +l +l +l l l l @@ -1105,10 +1105,10 @@ V V V V -V -V -V -V +l +l +l +l l l l diff --git a/_maps/map_files/tramstation/maintenance_modules/barcargoupper_cave_2.dmm b/_maps/map_files/tramstation/maintenance_modules/barcargoupper_cave_2.dmm index 939d8bb0aafc2a..0e8deac0a590aa 100644 --- a/_maps/map_files/tramstation/maintenance_modules/barcargoupper_cave_2.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/barcargoupper_cave_2.dmm @@ -1013,10 +1013,10 @@ V V l V -V -V -V -V +b +b +b +b b b b @@ -1039,10 +1039,10 @@ V V V V -V -V -V -V +b +b +b +b b b b diff --git a/_maps/map_files/tramstation/maintenance_modules/barcargoupper_cave_3.dmm b/_maps/map_files/tramstation/maintenance_modules/barcargoupper_cave_3.dmm index 5831bc047d394a..fb637e9194fb2f 100644 --- a/_maps/map_files/tramstation/maintenance_modules/barcargoupper_cave_3.dmm +++ b/_maps/map_files/tramstation/maintenance_modules/barcargoupper_cave_3.dmm @@ -113,10 +113,6 @@ /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating, /area/station/maintenance/department/cargo) -"y" = ( -/obj/item/gps/mining, -/turf/open/misc/asteroid, -/area/station/asteroid) "z" = ( /obj/item/storage/bag/ore{ pixel_x = 6; @@ -129,6 +125,10 @@ /obj/item/assembly/signaler, /turf/open/misc/asteroid, /area/station/asteroid) +"C" = ( +/obj/item/gps/mining, +/turf/open/misc/asteroid/dug, +/area/station/asteroid) "D" = ( /obj/item/relic, /turf/open/misc/asteroid/dug, @@ -1048,7 +1048,7 @@ b i i I -I +C Y i Y @@ -1100,10 +1100,10 @@ B I I P -y -i -i -i +Q +Q +Q +Q Q Q Q @@ -1126,10 +1126,10 @@ Y Y I Y -i -i -i -i +Q +Q +Q +Q Q Q Q diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index ac5d9ba0e1d888..9bfe7ed759e295 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -451,6 +451,17 @@ "abM" = ( /turf/open/misc/asteroid, /area/station/asteroid) +"abN" = ( +/obj/machinery/firealarm/directional/south, +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/stripes, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "abO" = ( /obj/structure/disposalpipe/segment, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -2797,17 +2808,6 @@ }, /turf/open/floor/iron/dark, /area/station/commons/fitness/recreation/entertainment) -"amw" = ( -/obj/effect/turf_decal/trimline/yellow/filled/line{ - dir = 8 - }, -/obj/machinery/firealarm/directional/west, -/obj/structure/table/glass, -/obj/structure/disposalpipe/segment{ - dir = 6 - }, -/turf/open/floor/iron, -/area/station/engineering/break_room) "amA" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 9 @@ -3848,6 +3848,16 @@ /obj/effect/turf_decal/trimline/neutral/warning, /turf/open/floor/iron/dark, /area/station/medical/morgue) +"axF" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/effect/landmark/start/bitrunner, +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "axG" = ( /obj/effect/turf_decal/bot, /obj/effect/spawner/random/structure/crate_empty, @@ -6194,13 +6204,6 @@ }, /turf/open/floor/iron, /area/station/maintenance/tram/mid) -"aVM" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/brown/filled/line, -/turf/open/floor/iron, -/area/station/cargo/storage) "aVT" = ( /obj/effect/turf_decal/stripes/line, /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ @@ -6238,24 +6241,6 @@ /obj/machinery/suit_storage_unit/industrial/loader, /turf/open/floor/iron, /area/station/cargo/warehouse) -"aWQ" = ( -/obj/effect/turf_decal/trimline/brown/filled/corner{ - dir = 8 - }, -/obj/effect/turf_decal/trimline/brown/filled/corner{ - dir = 1 - }, -/obj/effect/turf_decal/siding/thinplating{ - dir = 1 - }, -/obj/effect/turf_decal/loading_area{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/corner{ - dir = 4 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "aWY" = ( /obj/structure/stairs/west, /turf/open/floor/iron/stairs/right{ @@ -6362,11 +6347,6 @@ }, /turf/open/floor/iron, /area/station/cargo/storage) -"aZT" = ( -/obj/effect/landmark/event_spawn, -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/storage) "aZX" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 1 @@ -8573,14 +8553,6 @@ /obj/structure/lattice/catwalk, /turf/open/floor/plating/airless, /area/station/solars/port) -"bRU" = ( -/obj/machinery/smartfridge/chemistry/preloaded, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "pharmacy_shutters_2"; - name = "Pharmacy Shutters" - }, -/turf/open/floor/iron/white, -/area/station/medical/pharmacy) "bSd" = ( /obj/effect/turf_decal/siding/wood, /turf/open/floor/wood/large, @@ -9523,6 +9495,18 @@ /obj/effect/turf_decal/tile/brown/fourcorners, /turf/open/floor/iron, /area/station/cargo/sorting) +"cfC" = ( +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/stripes, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 4 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "cga" = ( /obj/effect/turf_decal/trimline/neutral/filled/corner{ dir = 8 @@ -10102,6 +10086,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/cafeteria, /area/station/command/heads_quarters/rd) +"csn" = ( +/obj/machinery/elevator_control_panel{ + layer = 3.1; + linked_elevator_id = "tram_xeno_lift"; + pixel_y = 2; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/turf/closed/wall, +/area/station/science/xenobiology) "csA" = ( /turf/closed/wall, /area/station/solars/starboard/fore) @@ -10724,6 +10717,12 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/atmos) +"cEy" = ( +/obj/machinery/cryo_cell{ + dir = 4 + }, +/turf/open/floor/iron/dark, +/area/station/medical/treatment_center) "cEA" = ( /obj/effect/turf_decal/trimline/purple/filled/line, /obj/machinery/firealarm/directional/south, @@ -13462,12 +13461,6 @@ /obj/machinery/light/directional/south, /turf/open/floor/iron, /area/station/security/prison) -"dCY" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "dDi" = ( /obj/effect/turf_decal/trimline/yellow/filled/corner{ dir = 4 @@ -14005,23 +13998,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/hallway/secondary/entry) -"dMQ" = ( -/obj/effect/turf_decal/siding/thinplating{ - dir = 4 - }, -/obj/effect/turf_decal/trimline/dark_red/warning{ - dir = 4 - }, -/obj/structure/railing{ - dir = 4 - }, -/obj/structure/industrial_lift/public, -/obj/machinery/elevator_control_panel/directional/east{ - linked_elevator_id = "tram_lower_center_lift"; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/turf/open/floor/plating/elevatorshaft, -/area/station/maintenance/tram/mid) "dNa" = ( /obj/machinery/bookbinder, /obj/machinery/newscaster/directional/north, @@ -14690,14 +14666,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/showroomfloor, /area/station/security/lockers) -"dYi" = ( -/obj/machinery/smartfridge/chemistry/preloaded, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "pharmacy_shutters_2"; - name = "Pharmacy Shutters" - }, -/turf/open/floor/plating, -/area/station/medical/pharmacy) "dYm" = ( /obj/machinery/atmospherics/components/binary/pump{ name = "Port Mix to East Ports" @@ -15162,7 +15130,7 @@ /area/station/service/library/lounge) "ejJ" = ( /obj/structure/rack, -/obj/item/gun/energy/laser/practice{ +/obj/item/gun/energy/laser/carbine/practice{ pixel_x = 2; pixel_y = 5 }, @@ -15476,14 +15444,6 @@ }, /turf/open/floor/iron/grimy, /area/station/service/chapel/office) -"epQ" = ( -/obj/machinery/computer/atmos_control/oxygen_tank{ - atmos_chambers = list("o2ordance"="Oxygen Supply") - }, -/obj/effect/turf_decal/stripes/line, -/obj/machinery/airalarm/directional/north, -/turf/open/floor/iron/dark, -/area/station/science/ordnance/storage) "eqi" = ( /obj/effect/landmark/navigate_destination/tcomms, /turf/open/floor/iron, @@ -15593,6 +15553,11 @@ /mob/living/simple_animal/bot/cleanbot, /turf/open/floor/iron/dark, /area/station/ai_monitored/turret_protected/aisat_interior) +"esr" = ( +/obj/machinery/netpod, +/obj/item/radio/intercom/directional/north, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "esA" = ( /obj/machinery/iv_drip, /obj/effect/turf_decal/trimline/blue/filled/line{ @@ -15709,6 +15674,9 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/wood, /area/station/service/theater) +"euR" = ( +/turf/closed/wall, +/area/station/bitrunning/den) "euS" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -16325,6 +16293,15 @@ /obj/effect/turf_decal/stripes/line, /turf/open/floor/iron/white, /area/station/science/xenobiology) +"eGU" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=1"; + location = "QM #4" + }, +/obj/effect/turf_decal/tile/brown/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "eHj" = ( /obj/machinery/vending/tool, /obj/machinery/airalarm/directional/east, @@ -17641,15 +17618,6 @@ /obj/effect/spawner/structure/window, /turf/open/floor/plating, /area/station/science/lower) -"fiy" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=1"; - location = "QM #5" - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/storage) "fiP" = ( /obj/structure/table, /obj/item/storage/toolbox/electrical{ @@ -18026,6 +17994,21 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/science/ordnance) +"foU" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron, +/area/station/cargo/storage) +"foV" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=1"; + location = "QM #5" + }, +/obj/effect/turf_decal/tile/brown/fourcorners, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "foY" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -18348,9 +18331,7 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 }, -/mob/living/simple_animal/hostile/retaliate/goat{ - name = "Pete" - }, +/mob/living/basic/goat/pete, /turf/open/floor/iron/kitchen_coldroom, /area/station/service/kitchen/coldroom) "fvn" = ( @@ -18662,6 +18643,15 @@ /obj/machinery/light/warm/directional/west, /turf/open/floor/iron, /area/station/cargo/miningdock/cafeteria) +"fDd" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "fDg" = ( /obj/structure/table, /obj/item/clothing/gloves/boxing, @@ -19295,6 +19285,19 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron/freezer, /area/station/commons/toilet) +"fNG" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=2"; + location = "QM #1" + }, +/obj/effect/turf_decal/tile/brown/fourcorners, +/mob/living/simple_animal/bot/mulebot{ + home_destination = "QM #1"; + suffix = "#1" + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "fNR" = ( /obj/structure/closet/lasertag/blue, /obj/effect/landmark/start/hangover/closet, @@ -19695,6 +19698,14 @@ }, /turf/open/floor/iron/dark, /area/station/security/processing) +"fWK" = ( +/obj/machinery/computer/atmos_control/oxygen_tank{ + atmos_chambers = list("o2ordance"="Oxygen Supply") + }, +/obj/effect/turf_decal/stripes/line, +/obj/machinery/airalarm/directional/north, +/turf/open/floor/iron/dark, +/area/station/science/ordnance/storage) "fWM" = ( /obj/effect/turf_decal/trimline/red/filled/line, /obj/item/kirbyplants/random, @@ -20253,6 +20264,20 @@ }, /turf/open/floor/iron, /area/station/hallway/primary/tram/right) +"giW" = ( +/obj/effect/turf_decal/trimline/dark_red/warning{ + dir = 9 + }, +/obj/structure/industrial_lift/public, +/obj/structure/railing{ + dir = 9 + }, +/obj/machinery/elevator_control_panel/directional/west{ + linked_elevator_id = "tram_sci_lift"; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/turf/open/floor/plating/elevatorshaft, +/area/station/science/lower) "giZ" = ( /obj/structure/bed, /obj/effect/spawner/random/contraband/prison, @@ -20878,19 +20903,6 @@ /obj/effect/turf_decal/trimline/red/filled/corner, /turf/open/floor/iron, /area/station/security/courtroom) -"gtA" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=2"; - location = "QM #1" - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/mob/living/simple_animal/bot/mulebot{ - home_destination = "QM #1"; - suffix = "#1" - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "gtH" = ( /obj/structure/table/glass, /obj/effect/turf_decal/trimline/red/filled/line{ @@ -21974,15 +21986,6 @@ /obj/item/papercutter, /turf/open/floor/plating, /area/station/security/warden) -"gNM" = ( -/obj/machinery/elevator_control_panel{ - layer = 3.1; - linked_elevator_id = "tram_xeno_lift"; - pixel_y = 2; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/turf/closed/wall/r_wall, -/area/station/science/xenobiology) "gNN" = ( /obj/machinery/vending/wardrobe/coroner_wardrobe, /obj/structure/window/reinforced/spawner/directional/west, @@ -22364,6 +22367,13 @@ }, /turf/open/floor/iron/dark, /area/station/medical/break_room) +"gUL" = ( +/obj/effect/landmark/event_spawn, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "gUO" = ( /obj/effect/turf_decal/trimline/neutral/filled/line, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -22610,6 +22620,15 @@ }, /turf/open/floor/iron, /area/station/command/teleporter) +"haq" = ( +/obj/effect/turf_decal/stripes/corner{ + dir = 1 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "hay" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -23948,6 +23967,12 @@ }, /turf/open/floor/iron/white, /area/station/science/xenobiology) +"hDU" = ( +/obj/effect/turf_decal/siding/thinplating/corner{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "hDZ" = ( /obj/effect/turf_decal/sand/plating, /obj/effect/turf_decal/box, @@ -24720,13 +24745,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron, /area/station/hallway/secondary/exit) -"hSy" = ( -/obj/effect/turf_decal/siding/thinplating/corner{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/cargo/storage) "hSH" = ( /obj/structure/chair{ dir = 1 @@ -24739,6 +24757,19 @@ /obj/machinery/telecomms/server/presets/command, /turf/open/floor/iron/dark/telecomms, /area/station/tcommsat/server) +"hSM" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=1"; + location = "QM #6" + }, +/obj/effect/turf_decal/tile/brown/fourcorners, +/mob/living/simple_animal/bot/mulebot{ + home_destination = "QM #6"; + suffix = "#6" + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "hTa" = ( /obj/effect/turf_decal/trimline/neutral/filled/line, /turf/open/floor/iron, @@ -25097,20 +25128,6 @@ }, /turf/open/floor/iron, /area/station/tcommsat/computer) -"hZM" = ( -/obj/effect/turf_decal/trimline/dark_red/warning{ - dir = 9 - }, -/obj/structure/industrial_lift/public, -/obj/structure/railing{ - dir = 9 - }, -/obj/machinery/elevator_control_panel/directional/west{ - linked_elevator_id = "tram_sci_lift"; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/turf/open/floor/plating/elevatorshaft, -/area/station/science/lower) "hZP" = ( /obj/structure/railing/corner{ dir = 8 @@ -26330,7 +26347,6 @@ /obj/effect/turf_decal/trimline/red/filled/line{ dir = 8 }, -/obj/effect/landmark/generic_maintenance_landmark, /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/security/evidence) @@ -26761,6 +26777,15 @@ /obj/effect/landmark/start/hangover, /turf/open/floor/iron, /area/station/commons/fitness/recreation) +"iHQ" = ( +/obj/machinery/smartfridge/chemistry/preloaded, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "pharmacy_shutters_2"; + name = "Pharmacy Shutters" + }, +/obj/machinery/door/firedoor, +/turf/open/floor/iron/white, +/area/station/medical/pharmacy) "iHT" = ( /obj/effect/turf_decal/trimline/neutral/filled/corner, /obj/structure/disposalpipe/segment, @@ -28116,16 +28141,6 @@ /obj/structure/cable, /turf/closed/wall/r_wall, /area/station/ai_monitored/turret_protected/aisat/hallway) -"jfE" = ( -/obj/effect/turf_decal/trimline/dark_red/warning, -/obj/structure/industrial_lift/public, -/obj/machinery/elevator_control_panel/directional/south{ - linked_elevator_id = "tram_dorm_lift"; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/obj/structure/railing, -/turf/open/floor/plating/elevatorshaft, -/area/station/maintenance/tram/left) "jfH" = ( /obj/effect/turf_decal/trimline/red/filled/corner{ dir = 1 @@ -28622,6 +28637,14 @@ }, /turf/open/floor/iron, /area/station/security/checkpoint/supply) +"jnL" = ( +/obj/structure/railing{ + layer = 3.1; + dir = 4 + }, +/obj/machinery/netpod, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "jnR" = ( /obj/structure/bed{ dir = 8 @@ -28836,20 +28859,6 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/hallway/secondary/exit/departure_lounge) -"jrl" = ( -/obj/effect/turf_decal/caution/stand_clear/red{ - dir = 1 - }, -/obj/structure/industrial_lift/public, -/obj/structure/railing{ - dir = 8 - }, -/obj/machinery/elevator_control_panel/directional/west{ - linked_elevator_id = "tram_perma_lift"; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/turf/open/floor/plating/elevatorshaft, -/area/station/security/execution/transfer) "jrI" = ( /obj/structure/disposalpipe/trunk/multiz{ dir = 4 @@ -29125,6 +29134,27 @@ /obj/machinery/light/directional/north, /turf/open/floor/iron/showroomfloor, /area/station/security/lockers) +"jwP" = ( +/obj/effect/landmark/lift_id{ + specific_lift_id = "tram_cargo_lift" + }, +/obj/structure/railing{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/dark_red/warning{ + dir = 8 + }, +/obj/structure/industrial_lift/public, +/obj/machinery/elevator_control_panel/directional/west{ + linked_elevator_id = "tram_cargo_lift"; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck"); + req_access = list("mining") + }, +/obj/effect/abstract/elevator_music_zone{ + linked_elevator_id = "tram_cargo_lift" + }, +/turf/open/floor/plating/elevatorshaft, +/area/station/cargo/miningdock) "jwT" = ( /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -30365,6 +30395,14 @@ }, /turf/open/floor/iron, /area/station/construction/mining/aux_base) +"jTQ" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "jUa" = ( /obj/effect/turf_decal/trimline/purple/filled/corner{ dir = 4 @@ -32125,6 +32163,19 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/iron/grimy, /area/station/security/detectives_office) +"kyw" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=2"; + location = "QM #3" + }, +/obj/effect/turf_decal/tile/brown/fourcorners, +/mob/living/simple_animal/bot/mulebot{ + home_destination = "QM #3"; + suffix = "#3" + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "kyF" = ( /obj/structure/table, /obj/item/storage/backpack/duffelbag/sec{ @@ -32919,11 +32970,6 @@ /obj/machinery/light/small/dim/directional/north, /turf/open/floor/catwalk_floor, /area/station/hallway/primary/tram/center) -"kMw" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/generic_maintenance_landmark, -/turf/open/floor/iron, -/area/station/maintenance/disposal/incinerator) "kMD" = ( /obj/machinery/duct, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -33530,6 +33576,7 @@ dir = 1 }, /obj/machinery/light/cold/directional/north, +/obj/item/storage/box/bandages, /turf/open/floor/iron/white, /area/station/security/medical) "kVV" = ( @@ -34960,6 +35007,20 @@ /obj/effect/turf_decal/tile/red/fourcorners, /turf/open/floor/iron/dark, /area/station/security/office) +"lvz" = ( +/obj/effect/turf_decal/caution/stand_clear/red{ + dir = 1 + }, +/obj/structure/industrial_lift/public, +/obj/structure/railing{ + dir = 8 + }, +/obj/machinery/elevator_control_panel/directional/west{ + linked_elevator_id = "tram_perma_lift"; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/turf/open/floor/plating/elevatorshaft, +/area/station/security/execution/transfer) "lvH" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 1 @@ -36305,6 +36366,27 @@ }, /turf/open/floor/iron, /area/station/security/prison/safe) +"lTM" = ( +/obj/effect/turf_decal/trimline/brown/filled/corner{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/filled/corner{ + dir = 1 + }, +/obj/effect/turf_decal/siding/thinplating{ + dir = 1 + }, +/obj/effect/turf_decal/loading_area{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/turf/open/floor/iron, +/area/station/cargo/storage) "lTP" = ( /obj/structure/stairs/south, /turf/open/floor/iron/stairs/medium{ @@ -37427,6 +37509,15 @@ /obj/machinery/meter, /turf/open/floor/engine, /area/station/engineering/supermatter/room) +"mmX" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/trimline/neutral/filled/line{ + dir = 1 + }, +/obj/structure/table, +/obj/machinery/light/dim/directional/north, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "mng" = ( /obj/structure/window/reinforced/plasma/spawner/directional/west, /obj/machinery/atmospherics/pipe/smart/manifold4w/general/visible, @@ -37623,6 +37714,27 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/white, /area/station/medical/storage) +"mrg" = ( +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/stripes, +/obj/structure/table/reinforced, +/obj/item/reagent_containers/cup/glass/mug/coco{ + pixel_x = -7; + pixel_y = 7 + }, +/obj/item/reagent_containers/cup/glass/mug/coco{ + pixel_x = -6; + pixel_y = -1 + }, +/obj/item/folder/yellow{ + pixel_x = 5; + pixel_y = 3 + }, +/obj/item/pen{ + pixel_x = 6 + }, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "mrr" = ( /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/trimline/neutral/filled/line, @@ -38704,10 +38816,6 @@ /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating, /area/station/maintenance/central/greater) -"mNo" = ( -/obj/effect/landmark/generic_maintenance_landmark, -/turf/open/floor/iron/dark, -/area/station/engineering/supermatter/room) "mNp" = ( /obj/structure/chair/sofa/middle{ dir = 8 @@ -38993,6 +39101,20 @@ /obj/item/storage/secure/safe/directional/north, /turf/open/floor/carpet, /area/station/command/heads_quarters/hop) +"mUc" = ( +/obj/structure/railing{ + dir = 1 + }, +/obj/machinery/elevator_control_panel/directional/north{ + linked_elevator_id = "tram_upper_center_lift"; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/obj/effect/turf_decal/trimline/dark_red/warning{ + dir = 1 + }, +/obj/structure/industrial_lift/public, +/turf/open/floor/plating/elevatorshaft, +/area/station/maintenance/tram/mid) "mUd" = ( /obj/machinery/atmospherics/components/unary/vent_pump/high_volume/siphon/monitored/air_output{ dir = 1 @@ -39564,6 +39686,16 @@ }, /turf/open/floor/iron, /area/station/maintenance/tram/right) +"nfZ" = ( +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/stripes, +/obj/effect/turf_decal/siding/thinplating_new/dark/corner{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "ngg" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden, /obj/effect/spawner/structure/window/reinforced, @@ -40524,6 +40656,10 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /turf/open/floor/catwalk_floor, /area/station/maintenance/tram/left) +"nvF" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/station/bitrunning/den) "nvH" = ( /obj/effect/turf_decal/trimline/neutral/filled/corner{ dir = 4 @@ -40620,27 +40756,6 @@ }, /turf/open/openspace, /area/station/hallway/primary/tram/center) -"nxj" = ( -/obj/effect/landmark/lift_id{ - specific_lift_id = "tram_cargo_lift" - }, -/obj/structure/railing{ - dir = 8 - }, -/obj/effect/turf_decal/trimline/dark_red/warning{ - dir = 8 - }, -/obj/structure/industrial_lift/public, -/obj/machinery/elevator_control_panel/directional/west{ - linked_elevator_id = "tram_cargo_lift"; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck"); - req_access = list("mining") - }, -/obj/effect/abstract/elevator_music_zone{ - linked_elevator_id = "tram_cargo_lift" - }, -/turf/open/floor/plating/elevatorshaft, -/area/station/cargo/miningdock) "nxq" = ( /obj/structure/table/wood, /obj/structure/cable, @@ -41231,20 +41346,6 @@ /obj/structure/chair, /turf/open/floor/iron, /area/station/security/checkpoint/supply) -"nJb" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/machinery/elevator_control_panel/directional/north{ - linked_elevator_id = "tram_upper_center_lift"; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/obj/effect/turf_decal/trimline/dark_red/warning{ - dir = 1 - }, -/obj/structure/industrial_lift/public, -/turf/open/floor/plating/elevatorshaft, -/area/station/maintenance/tram/mid) "nJd" = ( /obj/effect/turf_decal/trimline/red/filled/line{ dir = 5 @@ -41897,6 +41998,12 @@ /obj/effect/turf_decal/trimline/purple/filled/line, /turf/open/floor/iron/white, /area/station/science/lobby) +"nUF" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/directional/north, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "nUM" = ( /obj/effect/turf_decal/siding/wood{ dir = 1 @@ -42047,6 +42154,12 @@ /obj/effect/landmark/event_spawn, /turf/open/floor/iron/dark, /area/station/medical/morgue) +"nXk" = ( +/obj/effect/turf_decal/siding/thinplating{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "nXn" = ( /obj/structure/cable, /obj/structure/disposalpipe/segment{ @@ -42188,6 +42301,21 @@ }, /turf/open/floor/iron, /area/station/cargo/miningdock) +"nZy" = ( +/obj/effect/turf_decal/trimline/yellow/filled/line{ + dir = 8 + }, +/obj/machinery/firealarm/directional/west, +/obj/structure/table/glass, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/item/storage/box/donkpockets/donkpocketberry{ + pixel_y = 10; + pixel_x = -6 + }, +/turf/open/floor/iron, +/area/station/engineering/break_room) "nZL" = ( /obj/effect/turf_decal/siding/thinplating/dark{ dir = 1 @@ -42959,6 +43087,13 @@ }, /turf/open/floor/engine, /area/station/engineering/supermatter) +"ooe" = ( +/obj/machinery/computer/quantum_console{ + dir = 1 + }, +/obj/machinery/light/directional/south, +/turf/open/floor/iron/dark/smooth_corner, +/area/station/bitrunning/den) "oog" = ( /obj/machinery/disposal/bin, /obj/effect/turf_decal/trimline/yellow/filled/line{ @@ -43293,7 +43428,6 @@ "ovK" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/light/small/directional/south{ dir = 1 }, @@ -43485,7 +43619,6 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/effect/landmark/generic_maintenance_landmark, /turf/open/floor/iron, /area/station/cargo/miningdock) "ozM" = ( @@ -43516,6 +43649,19 @@ /obj/effect/turf_decal/sand/plating, /turf/open/floor/catwalk_floor, /area/station/solars/starboard/fore) +"oAi" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/machinery/door/airlock/mining/glass{ + name = "MULE Storage" + }, +/obj/effect/mapping_helpers/airlock/access/all/supply/general, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "oAn" = ( /obj/machinery/airlock_sensor/incinerator_ordmix{ pixel_x = 23; @@ -43900,6 +44046,15 @@ /obj/structure/grille, /turf/open/space/openspace, /area/space/nearstation) +"oKn" = ( +/obj/machinery/elevator_control_panel{ + layer = 3.1; + linked_elevator_id = "tram_xeno_lift"; + pixel_y = 2; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/turf/closed/wall/r_wall, +/area/station/science/xenobiology) "oKZ" = ( /obj/effect/turf_decal/stripes/line{ dir = 4 @@ -44050,6 +44205,15 @@ }, /turf/open/space/openspace, /area/station/solars/port) +"oOP" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "oOT" = ( /obj/structure/table/wood, /obj/item/food/grown/poppy{ @@ -44722,6 +44886,13 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/security/courtroom) +"pcI" = ( +/obj/machinery/quantum_server, +/obj/effect/turf_decal/bot/left, +/turf/open/floor/iron/dark/smooth_corner{ + dir = 4 + }, +/area/station/bitrunning/den) "pcO" = ( /obj/effect/turf_decal/bot_white, /obj/effect/turf_decal/tile/neutral/fourcorners, @@ -45187,6 +45358,16 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/hallway/primary/tram/left) +"plq" = ( +/obj/machinery/smartfridge/chemistry/preloaded, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "pharmacy_shutters_2"; + name = "Pharmacy Shutters"; + dir = 4 + }, +/obj/machinery/door/firedoor, +/turf/open/floor/plating, +/area/station/medical/pharmacy) "plr" = ( /obj/machinery/door/airlock{ id_tag = "miningdorm3"; @@ -45211,6 +45392,15 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/plating, /area/station/commons/vacant_room) +"plH" = ( +/obj/effect/decal/cleanable/oil/streak, +/obj/structure/sign/poster/random/directional/north, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/obj/machinery/byteforge, +/obj/effect/turf_decal/box, +/turf/open/floor/iron/dark/smooth_large, +/area/station/bitrunning/den) "plQ" = ( /obj/effect/turf_decal/trimline/red/filled/corner, /obj/structure/disposalpipe/segment{ @@ -45307,6 +45497,24 @@ /obj/machinery/light/warm/directional/east, /turf/open/floor/iron, /area/station/engineering/break_room) +"pmZ" = ( +/obj/structure/table/reinforced, +/obj/structure/desk_bell{ + pixel_x = -7 + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "pharmacy_shutters_2"; + name = "Pharmacy Shutters"; + dir = 4 + }, +/obj/machinery/door/firedoor, +/obj/machinery/door/window/left/directional/south{ + dir = 4; + name = "Chemistry Desk"; + req_access = list("pharmacy") + }, +/turf/open/floor/iron/white, +/area/station/medical/pharmacy) "pne" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/structure/disposalpipe/segment{ @@ -45763,6 +45971,16 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/security/courtroom/holding) +"puo" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/machinery/light/small/directional/north, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "pur" = ( /obj/effect/turf_decal/trimline/white/line{ dir = 9 @@ -46126,19 +46344,6 @@ /obj/effect/turf_decal/tile/bar/opposingcorners, /turf/open/floor/iron, /area/station/cargo/miningdock/cafeteria) -"pzi" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=1"; - location = "QM #6" - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/mob/living/simple_animal/bot/mulebot{ - home_destination = "QM #6"; - suffix = "#6" - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "pzv" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -47051,6 +47256,13 @@ /obj/structure/railing, /turf/open/floor/plating/elevatorshaft, /area/station/maintenance/tram/left) +"pOL" = ( +/obj/effect/turf_decal/trimline/neutral/filled/line{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "pOQ" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 4 @@ -47788,14 +48000,6 @@ /obj/structure/cable, /turf/open/floor/iron/dark, /area/station/commons/fitness/recreation/entertainment) -"qey" = ( -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/brown/filled/line, -/obj/machinery/light/small/directional/west, -/turf/open/floor/iron, -/area/station/cargo/storage) "qez" = ( /obj/machinery/computer/slot_machine{ pixel_y = 2 @@ -48614,6 +48818,17 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/freezer, /area/station/commons/toilet) +"qul" = ( +/obj/effect/turf_decal/trimline/yellow/filled/line{ + dir = 9 + }, +/obj/machinery/power/apc/auto_name/directional/north, +/obj/structure/table/glass, +/obj/machinery/microwave/engineering/cell_included, +/obj/structure/cable, +/obj/machinery/light/warm/directional/west, +/turf/open/floor/iron, +/area/station/engineering/break_room) "qup" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -49706,15 +49921,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/commons/dorms) -"qPL" = ( -/obj/machinery/elevator_control_panel{ - layer = 3.1; - linked_elevator_id = "tram_xeno_lift"; - pixel_y = 2; - preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") - }, -/turf/closed/wall, -/area/station/science/xenobiology) "qPV" = ( /obj/machinery/power/apc/auto_name/directional/south, /obj/structure/cable, @@ -51356,23 +51562,6 @@ /obj/structure/disposalpipe/segment, /turf/open/floor/iron, /area/station/cargo/office) -"rqE" = ( -/obj/structure/table/reinforced, -/obj/structure/desk_bell{ - pixel_x = -7 - }, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "pharmacy_shutters_2"; - name = "Pharmacy Shutters" - }, -/obj/machinery/door/firedoor, -/obj/machinery/door/window/left/directional/south{ - dir = 8; - name = "Chemistry Desk"; - req_access = list("pharmacy") - }, -/turf/open/floor/iron/white, -/area/station/medical/pharmacy) "rqG" = ( /obj/machinery/crossing_signal/northwest{ inbound = 1; @@ -51381,10 +51570,6 @@ /obj/effect/turf_decal/stripes/white/line, /turf/open/floor/iron, /area/station/hallway/primary/tram/center) -"rqH" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4, -/turf/open/floor/iron, -/area/station/cargo/storage) "rre" = ( /obj/effect/turf_decal/trimline/neutral/filled/line, /obj/effect/landmark/start/hangover, @@ -51607,6 +51792,18 @@ /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating/airless, /area/station/asteroid) +"rwo" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/machinery/computer/order_console/bitrunning{ + dir = 4 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "rws" = ( /obj/structure/table/glass, /obj/item/storage/box/monkeycubes{ @@ -51996,6 +52193,19 @@ /obj/machinery/airalarm/directional/west, /turf/open/floor/iron/dark, /area/station/engineering/supermatter/room) +"rEX" = ( +/obj/effect/turf_decal/delivery, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=2"; + location = "QM #2" + }, +/obj/effect/turf_decal/tile/brown/fourcorners, +/mob/living/simple_animal/bot/mulebot{ + home_destination = "QM #2"; + suffix = "#2" + }, +/turf/open/floor/iron, +/area/station/cargo/warehouse) "rFW" = ( /obj/effect/turf_decal/delivery/white, /obj/structure/holosign/barrier/atmos/tram, @@ -53183,10 +53393,6 @@ }, /turf/open/floor/plating, /area/station/maintenance/tram/left) -"scF" = ( -/obj/effect/landmark/generic_maintenance_landmark, -/turf/open/floor/carpet, -/area/station/cargo/miningdock) "scO" = ( /obj/effect/turf_decal/trimline/purple/filled/corner{ dir = 1 @@ -53380,7 +53586,7 @@ /turf/open/floor/iron/white, /area/station/science/lower) "sha" = ( -/mob/living/simple_animal/sloth/paperwork, +/mob/living/basic/sloth/paperwork, /turf/open/floor/glass, /area/station/cargo/storage) "shw" = ( @@ -55421,17 +55627,6 @@ }, /turf/open/floor/plating, /area/station/cargo/warehouse) -"sRW" = ( -/obj/effect/turf_decal/trimline/yellow/filled/line{ - dir = 9 - }, -/obj/machinery/power/apc/auto_name/directional/north, -/obj/structure/table/glass, -/obj/machinery/microwave, -/obj/structure/cable, -/obj/machinery/light/warm/directional/west, -/turf/open/floor/iron, -/area/station/engineering/break_room) "sRZ" = ( /obj/effect/turf_decal/trimline/purple/filled/line, /obj/structure/chair{ @@ -57006,6 +57201,12 @@ /obj/structure/cable, /turf/open/floor/iron/freezer, /area/station/security/prison/shower) +"tte" = ( +/obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ + dir = 8 + }, +/turf/open/floor/iron, +/area/station/cargo/storage) "tth" = ( /obj/effect/landmark/event_spawn, /obj/structure/cable, @@ -57230,13 +57431,17 @@ /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 10 }, +/obj/machinery/power/apc/auto_name/directional/west, +/obj/structure/cable, +/obj/item/storage/box/bandages{ + pixel_y = 6; + pixel_x = -6 + }, /obj/item/storage/box/bodybags{ pixel_x = 3; pixel_y = 2 }, /obj/item/reagent_containers/syringe, -/obj/machinery/power/apc/auto_name/directional/west, -/obj/structure/cable, /turf/open/floor/iron/white, /area/station/medical/medbay/lobby) "txh" = ( @@ -58098,19 +58303,6 @@ /obj/effect/landmark/start/chemist, /turf/open/floor/iron/white, /area/station/medical/chemistry) -"tMq" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=2"; - location = "QM #3" - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/mob/living/simple_animal/bot/mulebot{ - home_destination = "QM #3"; - suffix = "#3" - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "tMw" = ( /obj/effect/turf_decal/trimline/purple/filled/corner{ dir = 1 @@ -59051,6 +59243,15 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron/dark, /area/station/security/interrogation) +"udE" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "pharmacy_shutters_2"; + name = "Pharmacy Shutters"; + dir = 4 + }, +/turf/open/floor/plating, +/area/station/medical/pharmacy) "udO" = ( /obj/structure/chair/stool/bar/directional/south, /obj/effect/turf_decal/trimline/red/filled/line{ @@ -59752,15 +59953,6 @@ /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron, /area/station/maintenance/tram/mid) -"uoG" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=1"; - location = "QM #4" - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/turf/open/floor/iron, -/area/station/cargo/storage) "uoJ" = ( /obj/structure/closet/secure_closet/security/science, /obj/item/clothing/mask/whistle, @@ -60074,6 +60266,23 @@ /obj/effect/spawner/random/maintenance/five, /turf/open/floor/iron, /area/station/cargo/warehouse) +"uud" = ( +/obj/effect/turf_decal/siding/thinplating{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/dark_red/warning{ + dir = 4 + }, +/obj/structure/railing{ + dir = 4 + }, +/obj/structure/industrial_lift/public, +/obj/machinery/elevator_control_panel/directional/east{ + linked_elevator_id = "tram_lower_center_lift"; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/turf/open/floor/plating/elevatorshaft, +/area/station/maintenance/tram/mid) "uue" = ( /obj/machinery/power/turbine/turbine_outlet{ dir = 4 @@ -60140,12 +60349,6 @@ /obj/effect/turf_decal/tile/neutral/fourcorners, /turf/open/floor/iron/dark, /area/station/commons/fitness) -"uvt" = ( -/obj/machinery/cryo_cell{ - dir = 4 - }, -/turf/open/floor/iron/dark, -/area/station/medical/treatment_center) "uvu" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 8 @@ -60720,20 +60923,6 @@ }, /turf/open/floor/noslip/tram_plate, /area/station/hallway/primary/tram/right) -"uEr" = ( -/obj/effect/turf_decal/trimline/neutral/filled/line, -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/generic_maintenance_landmark, -/obj/effect/turf_decal/siding/thinplating{ - dir = 1 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/trimline/white/warning{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/maintenance/tram/left) "uEw" = ( /obj/machinery/button/door/directional/east{ id = "miningdorm3"; @@ -61603,6 +61792,16 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/security/checkpoint/arrivals) +"uSl" = ( +/obj/effect/turf_decal/trimline/dark_red/warning, +/obj/structure/industrial_lift/public, +/obj/machinery/elevator_control_panel/directional/south{ + linked_elevator_id = "tram_dorm_lift"; + preset_destination_names = list("2"="Lower Deck","3"="Upper Deck") + }, +/obj/structure/railing, +/turf/open/floor/plating/elevatorshaft, +/area/station/maintenance/tram/left) "uSL" = ( /obj/effect/turf_decal/delivery/white, /obj/structure/fluff/tram_rail/floor, @@ -64051,15 +64250,6 @@ /obj/structure/cable, /turf/open/floor/iron/white, /area/station/science/ordnance) -"vJS" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 - }, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 8 - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "vKd" = ( /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, @@ -64257,17 +64447,6 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /turf/open/floor/iron, /area/station/security/checkpoint/supply) -"vNx" = ( -/obj/machinery/door/airlock/mining/glass{ - name = "MULE Storage" - }, -/obj/effect/turf_decal/trimline/brown/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/trimline/brown/filled/line, -/obj/effect/mapping_helpers/airlock/access/all/supply/general, -/turf/open/floor/iron, -/area/station/cargo/storage) "vNB" = ( /obj/effect/turf_decal/box, /obj/effect/turf_decal/trimline/yellow/filled/line{ @@ -64348,16 +64527,6 @@ }, /turf/open/openspace, /area/station/hallway/primary/tram/right) -"vPo" = ( -/obj/structure/table/reinforced, -/obj/machinery/microwave{ - pixel_y = 6 - }, -/obj/effect/turf_decal/tile/neutral/opposingcorners{ - dir = 1 - }, -/turf/open/floor/iron/dark, -/area/station/medical/break_room) "vPw" = ( /obj/effect/decal/cleanable/cobweb, /obj/effect/turf_decal/trimline/yellow/filled/corner{ @@ -64483,18 +64652,6 @@ dir = 1 }, /area/station/commons/fitness) -"vSc" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/landmark/generic_maintenance_landmark, -/obj/effect/turf_decal/trimline/neutral/filled/line{ - dir = 1 - }, -/obj/effect/turf_decal/siding/thinplating, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, -/obj/effect/turf_decal/trimline/white/warning, -/turf/open/floor/iron, -/area/station/maintenance/tram/right) "vSI" = ( /turf/open/openspace, /area/station/cargo/storage) @@ -64865,7 +65022,6 @@ /turf/open/floor/iron, /area/station/engineering/atmos) "vZc" = ( -/obj/effect/landmark/generic_maintenance_landmark, /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 }, @@ -65049,15 +65205,6 @@ /obj/machinery/door/firedoor, /turf/open/floor/iron, /area/station/hallway/secondary/service) -"wcZ" = ( -/obj/effect/turf_decal/trimline/neutral/filled/line{ - dir = 1 - }, -/obj/effect/decal/cleanable/dirt, -/obj/structure/table, -/obj/machinery/light/dim/directional/north, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "wda" = ( /obj/effect/turf_decal/trimline/yellow/filled/line{ dir = 8 @@ -65089,6 +65236,16 @@ /obj/structure/sign/calendar/directional/east, /turf/open/floor/iron/cafeteria, /area/station/science/breakroom) +"wdw" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/effect/decal/cleanable/generic, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "wdC" = ( /obj/effect/turf_decal/sand/plating, /turf/open/floor/plating, @@ -65595,10 +65752,6 @@ }, /turf/open/floor/iron/dark, /area/station/service/chapel/monastery) -"wod" = ( -/obj/structure/cable, -/turf/open/floor/iron, -/area/station/cargo/storage) "wop" = ( /obj/structure/industrial_lift/public, /obj/effect/turf_decal/caution/stand_clear/red, @@ -67030,6 +67183,14 @@ "wQm" = ( /turf/open/floor/iron, /area/station/engineering/atmos) +"wQq" = ( +/obj/structure/table/reinforced, +/obj/machinery/microwave/engineering/cell_included, +/obj/effect/turf_decal/tile/neutral/opposingcorners{ + dir = 1 + }, +/turf/open/floor/iron/dark, +/area/station/medical/break_room) "wQr" = ( /obj/effect/turf_decal/weather/snow, /obj/machinery/vending/wardrobe/chef_wardrobe, @@ -67138,19 +67299,6 @@ /obj/structure/sink/directional/south, /turf/open/floor/iron/white, /area/station/medical/virology) -"wTp" = ( -/obj/effect/turf_decal/delivery, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=2"; - location = "QM #2" - }, -/obj/effect/turf_decal/tile/brown/fourcorners, -/mob/living/simple_animal/bot/mulebot{ - home_destination = "QM #2"; - suffix = "#2" - }, -/turf/open/floor/iron, -/area/station/cargo/storage) "wTy" = ( /obj/machinery/button/crematorium{ id = "crematoriumChapel"; @@ -67185,6 +67333,11 @@ /obj/structure/cable, /turf/open/floor/iron, /area/station/engineering/atmos/pumproom) +"wUA" = ( +/obj/machinery/netpod, +/obj/machinery/airalarm/directional/north, +/turf/open/floor/catwalk_floor/iron_dark, +/area/station/bitrunning/den) "wUL" = ( /obj/machinery/status_display/evac/directional/north, /obj/machinery/fax{ @@ -67757,13 +67910,6 @@ /obj/item/papercutter, /turf/open/floor/iron, /area/station/command/bridge) -"xhg" = ( -/obj/effect/decal/cleanable/dirt, -/obj/effect/turf_decal/trimline/neutral/filled/line{ - dir = 1 - }, -/turf/open/floor/iron, -/area/station/cargo/warehouse) "xhk" = ( /obj/effect/turf_decal/trimline/neutral/filled/line{ dir = 4 @@ -68407,13 +68553,6 @@ }, /turf/open/floor/iron, /area/station/security/brig) -"xup" = ( -/obj/effect/turf_decal/siding/thinplating{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, -/turf/open/floor/iron, -/area/station/cargo/storage) "xuq" = ( /obj/effect/turf_decal/trimline/blue/filled/line{ dir = 4 @@ -68874,6 +69013,20 @@ "xDQ" = ( /turf/closed/wall, /area/station/security/processing) +"xDW" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, +/obj/machinery/door/airlock/mining/glass{ + name = "Bitrunning Den" + }, +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den, +/turf/open/floor/iron, +/area/station/bitrunning/den) "xDY" = ( /obj/structure/railing{ dir = 8 @@ -69428,6 +69581,17 @@ }, /turf/open/floor/iron, /area/station/security/checkpoint/supply) +"xPI" = ( +/obj/effect/turf_decal/trimline/brown/line, +/obj/effect/turf_decal/stripes, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/structure/extinguisher_cabinet/directional/west, +/obj/effect/decal/cleanable/oil/streak, +/obj/effect/landmark/start/bitrunner, +/turf/open/floor/iron/dark/textured_large, +/area/station/bitrunning/den) "xPN" = ( /obj/structure/closet/lasertag/blue, /obj/effect/turf_decal/tile/blue/full, @@ -80838,7 +81002,7 @@ aac aac aac aac -aac +aaR aac aac vXM @@ -81095,7 +81259,7 @@ aac aac aac aac -aaR +aac aac aac vXM @@ -86188,7 +86352,7 @@ jWs lDo ucA wox -jrl +lvz gTv jWs aaa @@ -90333,7 +90497,7 @@ qQq hvm qQq qQq -uEr +lyV ncF elr elr @@ -92395,7 +92559,7 @@ ncF ncF dFS tuU -jfE +uSl elr elr elr @@ -99830,7 +99994,7 @@ uTz hJM nAa ekB -nJb +mUc jSV uuD qjU @@ -99893,7 +100057,7 @@ sZA daJ gqp gqp -mNo +gqp gqp qHs aaa @@ -101912,8 +102076,8 @@ akI cJM ulV bbj -sRW -amw +qul +nZy ryJ gzZ cFP @@ -104474,7 +104638,7 @@ qjU aaa qjU fok -dMQ +uud sNq ceb pcx @@ -109905,7 +110069,7 @@ hkW rCd fFa gqV -kMw +gqV tTK xWj cdN @@ -113438,7 +113602,7 @@ aaa aaa uGW jdU -nxj +jwP rff uGW aaa @@ -113736,7 +113900,7 @@ abM abM abM iix -hZM +giW boW iix abM @@ -114470,7 +114634,7 @@ kDi cJX uGW kot -scF +sOS iRL abM arE @@ -114999,7 +115163,7 @@ abM abM aaa mbJ -vSc +wip hFC hFC dBM @@ -116330,7 +116494,7 @@ hDT keT iEF fof -qPL +csn sXX akC hFP @@ -120937,7 +121101,7 @@ kkK jXE lwF dfz -epQ +fWK qCP urA ygC @@ -165132,7 +165296,7 @@ dVj wrT xqO suG -bRU +iHQ ryy aKM jaQ @@ -166153,9 +166317,9 @@ cYi uQT sBr jyH -dYi -rqE -bqg +plq +pmZ +udE jyH jyH jyH @@ -167456,9 +167620,9 @@ pIk oIU aMG xdx -uvt +cEy uVW -uvt +cEy jtr dSZ aOO @@ -170036,7 +170200,7 @@ gVO vXT cyL nen -vPo +wQq adM oGJ qaO @@ -178711,10 +178875,10 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa +euR +euR +euR +euR cTU cTU cTU @@ -178968,10 +179132,10 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa +euR +wUA +xPI +ooe cTU vSI vSI @@ -179224,11 +179388,11 @@ aac aaa aaa aaa -cTU -cTU -cTU -cTU -cTU +aaa +euR +esr +cfC +pcI cTU vSI vSI @@ -179481,10 +179645,10 @@ aaa aaa aaa aaa -cTU -tMq -qey -pzi +euR +euR +jnL +abN cTU cTU ohS @@ -179738,10 +179902,10 @@ aac aaa aaa aaa -cTU -wTp -aVM -fiy +euR +plH +wdw +nfZ cTU exr pZA @@ -179995,10 +180159,10 @@ aac aac aaa aaa -cTU -gtA -aVM -uoG +euR +nUF +jTQ +mrg cTU lan pZA @@ -180252,10 +180416,10 @@ aac aaa aaa cTU -cTU -ohS -vNx -ohS +euR +nvF +xDW +nvF cTU nnb pZA @@ -180511,10 +180675,10 @@ aaa cTU blx tAJ -aWQ -dCY -dCY -vJS +lTM +axF +fDd +rwo dij uax uax @@ -180768,13 +180932,13 @@ aaa akr tjS hFV -gDr -uax -uax -uax -uax -aZT -wod +haq +dzw +dzw +dzw +dzw +gUL +foU dzw msn qza @@ -181029,9 +181193,9 @@ uax uax uax uax -rqH -xup -hSy +tte +nXk +hDU dzw sxR skb @@ -181612,7 +181776,7 @@ eJQ bNx aSt aSt -gNM +oKn aaa aaa aaa @@ -183335,12 +183499,12 @@ aac aac aac aac -cTU -cTU -cTU -cTU udQ -xhg +udQ +udQ +udQ +udQ +mmX pxD ayd ayt @@ -183592,10 +183756,10 @@ aac aac aac aac -aac -aac -aaa -aaa +udQ +hSM +foV +eGU udQ fBJ pxD @@ -183849,12 +184013,12 @@ aac aac aac aac -aac -aaa -aaa -aaa udQ -wcZ +puo +oOP +oOP +oAi +pOL kXr aye rgg @@ -184106,10 +184270,10 @@ aac aac aac aac -aaa -aaa -aaa -aaa +udQ +rEX +kyw +fNG udQ kSa cDP @@ -184363,10 +184527,10 @@ aac aac aac aac -aac -aaa -aaa -aaa +udQ +udQ +udQ +udQ udQ aWL tft diff --git a/_maps/safehouses/README.md b/_maps/safehouses/README.md new file mode 100644 index 00000000000000..8027ea38e2110d --- /dev/null +++ b/_maps/safehouses/README.md @@ -0,0 +1,17 @@ +# Safe House + +## Creating a new safe house + +1. Create a new map inside the `_maps\safe_houses` folder using the TGM format. +2. Create a new dm file inside `modules\bitrunning\virtual_domain\safe_houses` folder.. +4. Place exit and goal landmarks (obj/effect/landmark/bitrunning/..). Generally, 3 exits and 2 goals are ok. +5. Ideally, leave 3 spaces for gear. This has usually been xy [1x1] [1x2] [1x3] + +## Notes + +- Safe houses are intended to be 7x6 in size. You're not technically limited to this, but consider maps other maps might be using this size if you want it to be modular. +- Consider that avatars are not invincible and still require air. If you're making a safe house, it should start with an area that accommodates for this. +- For compatibility, your safe house should have a route open from the top center xy [3x0] of the map. +- If you want a custom safehouse for a custom map with no modularity, no problem. Make whatever sizes you want, just ensure there are exit and goal effects placed. +- Some maps can alter what is spawned into the safehouse by placing objects in the safehouse area. I'm using the left corner, starting from the top, for things like space gear. + diff --git a/_maps/safehouses/TEMPLATES/TEMPLATE.dmm b/_maps/safehouses/TEMPLATES/TEMPLATE.dmm new file mode 100644 index 00000000000000..c8e5059f0d0135 --- /dev/null +++ b/_maps/safehouses/TEMPLATES/TEMPLATE.dmm @@ -0,0 +1,82 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"c" = ( +/obj/effect/mapping_helpers/airlock/access/all, +/obj/machinery/door/airlock/external/glass, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"p" = ( +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"v" = ( +/obj/effect/bitrunning/exit_spawn, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"N" = ( +/obj/effect/bitrunning/goal_turf, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"R" = ( +/turf/closed/wall, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +R +R +a +a +R +R +"} +(2,1,1) = {" +a +p +p +p +p +R +"} +(3,1,1) = {" +R +p +p +p +v +a +"} +(4,1,1) = {" +c +p +p +p +v +R +"} +(5,1,1) = {" +R +p +p +p +v +a +"} +(6,1,1) = {" +a +p +N +N +p +R +"} +(7,1,1) = {" +R +R +a +a +R +R +"} diff --git a/_maps/safehouses/den.dmm b/_maps/safehouses/den.dmm new file mode 100644 index 00000000000000..235d786d6e9dab --- /dev/null +++ b/_maps/safehouses/den.dmm @@ -0,0 +1,224 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/structure/chair/office{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/small/directional/south, +/turf/open/floor/pod, +/area/virtual_domain/safehouse) +"c" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/small/directional/east, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"e" = ( +/obj/structure/table/reinforced/plastitaniumglass, +/obj/effect/spawner/random/food_or_drink/snack{ + pixel_x = 4; + pixel_y = 2 + }, +/turf/open/floor/pod/dark, +/area/virtual_domain/safehouse) +"i" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 1; + id = "safehouseshutter" + }, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"l" = ( +/obj/structure/railing/corner/end{ + dir = 4 + }, +/turf/open/floor/pod/dark, +/area/virtual_domain/safehouse) +"p" = ( +/turf/open/floor/pod, +/area/virtual_domain/safehouse) +"r" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 9 + }, +/turf/open/floor/pod/dark, +/area/virtual_domain/safehouse) +"u" = ( +/obj/structure/railing, +/obj/effect/turf_decal/siding/dark, +/obj/structure/sign/poster/contraband/hacking_guide/directional/east, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"z" = ( +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 4 + }, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/pod/light, +/area/virtual_domain/safehouse) +"C" = ( +/turf/closed/wall, +/area/virtual_domain/safehouse) +"D" = ( +/obj/effect/decal/cleanable/generic, +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 1 + }, +/turf/open/floor/pod, +/area/virtual_domain/safehouse) +"E" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 8 + }, +/obj/effect/decal/cleanable/generic, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/pod/light, +/area/virtual_domain/safehouse) +"G" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 4; + id = "safehouseshutter" + }, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"I" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 5 + }, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/pod/light, +/area/virtual_domain/safehouse) +"J" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + dir = 8; + id = "safehouseshutter" + }, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"K" = ( +/obj/effect/spawner/random/vending/colavend, +/obj/machinery/light/small/directional/south, +/turf/open/floor/pod, +/area/virtual_domain/safehouse) +"M" = ( +/turf/open/floor/pod/dark, +/area/virtual_domain/safehouse) +"O" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 8 + }, +/turf/open/floor/pod/dark, +/area/virtual_domain/safehouse) +"R" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 4 + }, +/turf/open/floor/pod/dark, +/area/virtual_domain/safehouse) +"U" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/sign/departments/cargo/directional/west, +/obj/machinery/light/small/directional/west, +/turf/open/floor/pod, +/area/virtual_domain/safehouse) +"W" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "safehouseshutter" + }, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"X" = ( +/obj/machinery/door/airlock/grunge, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"Y" = ( +/obj/structure/table/reinforced/plastitaniumglass, +/obj/machinery/button/door{ + pixel_x = 4; + pixel_y = 4; + id = "safehouseshutter" + }, +/obj/effect/spawner/random/food_or_drink/refreshing_beverage{ + pixel_y = 6; + pixel_x = -10 + }, +/turf/open/floor/pod/dark, +/area/virtual_domain/safehouse) +"Z" = ( +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 4 + }, +/turf/open/floor/pod/dark, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +C +C +C +G +G +C +"} +(2,1,1) = {" +W +U +p +M +K +C +"} +(3,1,1) = {" +C +r +O +O +E +i +"} +(4,1,1) = {" +X +D +Z +R +z +i +"} +(5,1,1) = {" +C +M +l +e +I +i +"} +(6,1,1) = {" +W +c +u +Y +a +C +"} +(7,1,1) = {" +C +C +C +J +J +C +"} diff --git a/_maps/safehouses/dig.dmm b/_maps/safehouses/dig.dmm new file mode 100644 index 00000000000000..7fbbd3e5549338 --- /dev/null +++ b/_maps/safehouses/dig.dmm @@ -0,0 +1,165 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/effect/turf_decal/sand/plating, +/obj/effect/turf_decal/siding/yellow/corner, +/obj/effect/turf_decal/sand/plating, +/obj/item/flashlight/glowstick{ + on = 1 + }, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"c" = ( +/obj/effect/turf_decal/siding/yellow/corner{ + dir = 8 + }, +/turf/open/misc/asteroid, +/area/virtual_domain/safehouse) +"h" = ( +/obj/effect/turf_decal/loading_area, +/obj/effect/turf_decal/box/corners{ + dir = 8 + }, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"i" = ( +/obj/effect/turf_decal/siding/yellow{ + dir = 8 + }, +/obj/effect/decal/remains/xeno/larva, +/turf/open/misc/asteroid, +/area/virtual_domain/safehouse) +"l" = ( +/obj/structure/table, +/obj/item/coin/gold{ + pixel_x = -6; + pixel_y = 2 + }, +/obj/item/flashlight/lantern{ + pixel_y = 8; + pixel_x = 4; + on = 1 + }, +/turf/open/misc/asteroid, +/area/virtual_domain/safehouse) +"o" = ( +/obj/effect/turf_decal/siding/yellow{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/misc/asteroid, +/area/virtual_domain/safehouse) +"u" = ( +/obj/effect/turf_decal/siding/yellow{ + dir = 8 + }, +/obj/effect/turf_decal/siding/yellow, +/obj/effect/decal/cleanable/oil/streak, +/turf/open/misc/asteroid, +/area/virtual_domain/safehouse) +"x" = ( +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"A" = ( +/turf/closed/wall/rock, +/area/virtual_domain/safehouse) +"B" = ( +/turf/open/misc/asteroid, +/area/virtual_domain/safehouse) +"H" = ( +/turf/closed/mineral/asteroid, +/area/virtual_domain/safehouse) +"I" = ( +/obj/machinery/door/airlock/maintenance/glass, +/obj/structure/fans/tiny, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"M" = ( +/obj/effect/turf_decal/siding/yellow, +/obj/effect/decal/remains/xeno, +/turf/open/misc/asteroid, +/area/virtual_domain/safehouse) +"N" = ( +/obj/effect/turf_decal/sand/plating, +/obj/effect/turf_decal/sand/plating, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"S" = ( +/obj/structure/railing{ + dir = 4 + }, +/obj/effect/turf_decal/loading_area, +/obj/effect/turf_decal/box/corners, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"T" = ( +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/misc/asteroid, +/area/virtual_domain/safehouse) +"U" = ( +/obj/effect/turf_decal/siding/yellow{ + dir = 8 + }, +/turf/open/misc/asteroid, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +H +H +A +A +H +H +"} +(2,1,1) = {" +A +N +x +a +H +A +"} +(3,1,1) = {" +A +i +U +u +h +A +"} +(4,1,1) = {" +I +B +B +M +S +A +"} +(5,1,1) = {" +A +l +B +c +o +H +"} +(6,1,1) = {" +A +A +T +T +T +A +"} +(7,1,1) = {" +H +A +H +H +A +A +"} diff --git a/_maps/safehouses/ice.dmm b/_maps/safehouses/ice.dmm new file mode 100644 index 00000000000000..a8293f9502aa77 --- /dev/null +++ b/_maps/safehouses/ice.dmm @@ -0,0 +1,254 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/effect/spawner/structure/window/ice, +/turf/open/floor/plating/snowed, +/area/virtual_domain/safehouse) +"c" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 6 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/small/directional/east, +/obj/structure/chair/wood{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"f" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating/snowed, +/area/virtual_domain/safehouse) +"g" = ( +/obj/effect/spawner/structure/window/ice, +/obj/structure/barricade/wooden/crude/snow, +/turf/open/floor/plating/snowed, +/area/virtual_domain/safehouse) +"i" = ( +/turf/closed/wall/ice, +/area/virtual_domain/safehouse) +"m" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/turf_decal/trimline/dark_blue/line{ + dir = 1 + }, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/pod, +/area/virtual_domain/safehouse) +"n" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/rack, +/obj/item/grown/log, +/obj/item/grown/log, +/obj/item/grown/log, +/obj/item/hatchet/wooden, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"o" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"p" = ( +/obj/structure/railing, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"u" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"v" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/turf_decal/trimline/dark_blue/line{ + dir = 5 + }, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/pod, +/area/virtual_domain/safehouse) +"x" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/vending/coffee, +/turf/open/floor/plating/snowed, +/area/virtual_domain/safehouse) +"z" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/generic, +/turf/open/floor/plating/snowed, +/area/virtual_domain/safehouse) +"A" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/railing/corner/end{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating/snowed, +/area/virtual_domain/safehouse) +"B" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating/snowed, +/area/virtual_domain/safehouse) +"C" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 1 + }, +/obj/structure/table/wood, +/obj/item/reagent_containers/cup/glass/coffee{ + pixel_x = 7; + pixel_y = 13 + }, +/obj/item/reagent_containers/cup/glass/coffee/no_lid{ + pixel_x = -4; + pixel_y = 14 + }, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"D" = ( +/obj/effect/turf_decal/weather/snow/corner, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/generic, +/obj/effect/turf_decal/trimline/dark_blue/line{ + dir = 9 + }, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/pod, +/area/virtual_domain/safehouse) +"I" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"L" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/small/directional/west, +/obj/machinery/smartfridge/drying_rack, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"O" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/door/airlock/freezer, +/obj/structure/fans/tiny, +/turf/open/floor/plating/snowed, +/area/virtual_domain/safehouse) +"S" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 5 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/table/wood, +/obj/item/trash/chips{ + pixel_x = 8; + pixel_y = 15 + }, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"W" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/closet/crate/internals, +/obj/item/tank/internals/oxygen, +/obj/item/tank/internals/oxygen, +/obj/item/tank/internals/oxygen, +/obj/item/clothing/mask/breath, +/obj/item/clothing/mask/breath, +/obj/item/clothing/mask/breath, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/obj/item/clothing/suit/hooded/wintercoat, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"Z" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +i +i +g +a +i +i +"} +(2,1,1) = {" +i +L +n +W +Z +i +"} +(3,1,1) = {" +a +x +u +I +D +i +"} +(4,1,1) = {" +O +z +B +I +m +i +"} +(5,1,1) = {" +a +f +A +C +v +i +"} +(6,1,1) = {" +i +o +p +S +c +i +"} +(7,1,1) = {" +i +i +g +g +i +i +"} diff --git a/_maps/safehouses/lavaland_boss.dmm b/_maps/safehouses/lavaland_boss.dmm new file mode 100644 index 00000000000000..7482846e61f7a2 --- /dev/null +++ b/_maps/safehouses/lavaland_boss.dmm @@ -0,0 +1,243 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 1 + }, +/area/virtual_domain/safehouse) +"f" = ( +/turf/closed/wall, +/area/virtual_domain/safehouse) +"p" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 5 + }, +/obj/structure/tank_dispenser/oxygen, +/turf/open/floor/iron/dark, +/area/virtual_domain/safehouse) +"v" = ( +/obj/structure/table, +/obj/item/borg/upgrade/modkit/damage{ + pixel_x = 8; + pixel_y = 8 + }, +/obj/item/borg/upgrade/modkit/damage{ + pixel_y = 4; + pixel_x = 8 + }, +/obj/item/borg/upgrade/modkit/damage{ + pixel_x = 8 + }, +/obj/item/borg/upgrade/modkit/range{ + pixel_y = 8 + }, +/obj/item/borg/upgrade/modkit/range{ + pixel_y = 4 + }, +/obj/item/borg/upgrade/modkit/range, +/obj/item/borg/upgrade/modkit/cooldown{ + pixel_x = -8; + pixel_y = 8 + }, +/obj/item/borg/upgrade/modkit/cooldown{ + pixel_x = -8; + pixel_y = 4 + }, +/obj/item/borg/upgrade/modkit/cooldown{ + pixel_x = -8 + }, +/obj/item/reagent_containers/hypospray/medipen/survival/luxury{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/item/reagent_containers/hypospray/medipen/survival/luxury{ + pixel_x = 6 + }, +/turf/open/floor/iron/dark/textured_large, +/area/virtual_domain/safehouse) +"w" = ( +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/obj/machinery/light/directional/east, +/obj/structure/railing, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"A" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/obj/structure/extinguisher_cabinet/directional/north, +/turf/open/floor/iron/dark/smooth_edge, +/area/virtual_domain/safehouse) +"B" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 10 + }, +/obj/structure/table, +/obj/item/flashlight/lantern{ + pixel_x = 8; + pixel_y = null + }, +/obj/item/flashlight/lantern{ + pixel_y = 4 + }, +/obj/item/flashlight/lantern{ + pixel_x = -8; + pixel_y = 8 + }, +/obj/item/clothing/glasses/meson/night, +/obj/item/clothing/glasses/meson/night, +/obj/item/clothing/glasses/meson/night, +/turf/open/floor/iron/dark, +/area/virtual_domain/safehouse) +"C" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 4 + }, +/obj/structure/closet, +/obj/item/gun/ballistic/rocketlauncher/unrestricted, +/obj/item/ammo_casing/rocket, +/obj/item/ammo_casing/rocket, +/obj/item/ammo_casing/rocket, +/obj/item/energy_katana, +/obj/item/ammo_box/magazine/m7mm, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 8 + }, +/area/virtual_domain/safehouse) +"H" = ( +/obj/machinery/door/airlock/external/glass{ + name = "Mining External Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all, +/obj/structure/fans/tiny, +/turf/open/floor/iron/dark/textured_large, +/area/virtual_domain/safehouse) +"K" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/turf/open/floor/iron/dark/smooth_edge, +/area/virtual_domain/safehouse) +"O" = ( +/obj/item/gun/energy/recharge/kinetic_accelerator{ + pixel_x = -6; + pixel_y = 6 + }, +/obj/item/gun/energy/recharge/kinetic_accelerator{ + pixel_x = -1; + pixel_y = 1 + }, +/obj/item/gun/energy/recharge/kinetic_accelerator{ + pixel_x = 4; + pixel_y = -4 + }, +/obj/structure/closet, +/obj/item/kinetic_crusher, +/obj/item/kinetic_crusher, +/turf/open/floor/iron/dark/textured_large, +/area/virtual_domain/safehouse) +"P" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"S" = ( +/turf/open/floor/iron/dark/textured_large, +/area/virtual_domain/safehouse) +"T" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 6 + }, +/obj/structure/sign/departments/cargo/directional/south, +/obj/structure/closet, +/obj/item/gun/ballistic/automatic/l6_saw/unrestricted, +/obj/item/ammo_box/magazine/sniper_rounds, +/obj/item/gun/ballistic/rifle/sniper_rifle, +/turf/open/floor/iron/dark, +/area/virtual_domain/safehouse) +"X" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/machinery/suit_storage_unit/mining, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 4 + }, +/area/virtual_domain/safehouse) +"Y" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/machinery/suit_storage_unit/mining, +/obj/machinery/light/directional/west, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 4 + }, +/area/virtual_domain/safehouse) +"Z" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 9 + }, +/obj/machinery/suit_storage_unit/mining, +/turf/open/floor/iron/dark, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +f +f +f +P +P +f +"} +(2,1,1) = {" +P +Z +Y +X +B +f +"} +(3,1,1) = {" +f +A +S +S +a +P +"} +(4,1,1) = {" +H +K +O +v +a +P +"} +(5,1,1) = {" +f +A +S +S +a +P +"} +(6,1,1) = {" +P +p +w +C +T +f +"} +(7,1,1) = {" +f +f +f +P +P +f +"} diff --git a/_maps/safehouses/mine.dmm b/_maps/safehouses/mine.dmm new file mode 100644 index 00000000000000..551e2ca0c001a6 --- /dev/null +++ b/_maps/safehouses/mine.dmm @@ -0,0 +1,164 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/effect/turf_decal/trimline/brown/filled/line, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 1 + }, +/area/virtual_domain/safehouse) +"f" = ( +/turf/closed/wall, +/area/virtual_domain/safehouse) +"p" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 5 + }, +/obj/structure/tank_dispenser/oxygen, +/turf/open/floor/iron/dark, +/area/virtual_domain/safehouse) +"w" = ( +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/obj/machinery/light/directional/east, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"B" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 10 + }, +/obj/structure/table, +/obj/item/flashlight/lantern{ + pixel_x = 8; + pixel_y = null + }, +/obj/item/flashlight/lantern{ + pixel_y = 4 + }, +/obj/item/flashlight/lantern{ + pixel_x = -8; + pixel_y = 8 + }, +/turf/open/floor/iron/dark, +/area/virtual_domain/safehouse) +"C" = ( +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/obj/structure/railing, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"H" = ( +/obj/machinery/door/airlock/external/glass{ + name = "Mining External Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all, +/obj/structure/fans/tiny, +/turf/open/floor/iron/dark/textured_large, +/area/virtual_domain/safehouse) +"K" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 1 + }, +/turf/open/floor/iron/dark/smooth_edge, +/area/virtual_domain/safehouse) +"P" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"S" = ( +/turf/open/floor/iron/dark/textured_large, +/area/virtual_domain/safehouse) +"T" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 6 + }, +/obj/item/kirbyplants/random, +/obj/structure/sign/departments/cargo/directional/south, +/turf/open/floor/iron/dark, +/area/virtual_domain/safehouse) +"X" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/machinery/suit_storage_unit/mining, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 4 + }, +/area/virtual_domain/safehouse) +"Y" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 8 + }, +/obj/machinery/suit_storage_unit/mining, +/obj/machinery/light/directional/west, +/turf/open/floor/iron/dark/smooth_edge{ + dir = 4 + }, +/area/virtual_domain/safehouse) +"Z" = ( +/obj/effect/turf_decal/trimline/brown/filled/line{ + dir = 9 + }, +/obj/machinery/suit_storage_unit/mining, +/turf/open/floor/iron/dark, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +f +f +f +P +P +f +"} +(2,1,1) = {" +P +Z +Y +X +B +f +"} +(3,1,1) = {" +f +K +S +S +a +P +"} +(4,1,1) = {" +H +K +S +S +a +P +"} +(5,1,1) = {" +f +K +S +S +a +P +"} +(6,1,1) = {" +P +p +w +C +T +f +"} +(7,1,1) = {" +f +f +f +P +P +f +"} diff --git a/_maps/safehouses/shuttle.dmm b/_maps/safehouses/shuttle.dmm new file mode 100644 index 00000000000000..92228c95bd3c4f --- /dev/null +++ b/_maps/safehouses/shuttle.dmm @@ -0,0 +1,228 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/closed/wall/mineral/titanium, +/area/virtual_domain/safehouse) +"e" = ( +/obj/effect/spawner/structure/window/reinforced/shuttle, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"f" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"g" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/obj/effect/turf_decal/loading_area, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"i" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"k" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/structure/table/reinforced, +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/toolbox/emergency, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"l" = ( +/obj/machinery/light/small/directional/south, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/obj/effect/turf_decal/loading_area, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"q" = ( +/obj/effect/turf_decal/stripes/end, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"r" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"t" = ( +/obj/machinery/power/shuttle_engine/propulsion/burst{ + dir = 8 + }, +/obj/structure/window/reinforced/spawner/directional/east, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plating/airless, +/area/virtual_domain/safehouse) +"u" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/stripes/line, +/obj/effect/decal/cleanable/blood/old, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"x" = ( +/obj/effect/turf_decal/tile/neutral/half/contrasted, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/light/small/directional/north, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"y" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/door/airlock/shuttle/glass, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/sand/volcanic, +/obj/structure/fans/tiny, +/turf/open/floor/iron/white, +/area/virtual_domain/safehouse) +"A" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/computer{ + dir = 8; + name = "shuttle console"; + icon_screen = "shuttle" + }, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"E" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/effect/decal/cleanable/generic, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"G" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/light/small/directional/south, +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"H" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"I" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/structure/table/reinforced, +/obj/item/tank/internals/emergency_oxygen{ + pixel_x = 3 + }, +/obj/item/clothing/mask/gas, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"L" = ( +/obj/effect/turf_decal/stripes/end{ + dir = 1 + }, +/obj/effect/turf_decal/sand/volcanic, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"M" = ( +/obj/effect/turf_decal/tile/neutral/half/contrasted, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/light/small/directional/north, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"T" = ( +/obj/effect/turf_decal/tile/neutral/half/contrasted{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"X" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/chair/comfy/shuttle{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +a +t +e +e +t +a +"} +(2,1,1) = {" +e +L +i +q +l +a +"} +(3,1,1) = {" +a +x +r +u +g +e +"} +(4,1,1) = {" +y +f +r +H +E +a +"} +(5,1,1) = {" +a +M +X +H +T +e +"} +(6,1,1) = {" +e +k +A +I +G +a +"} +(7,1,1) = {" +a +a +e +e +a +a +"} diff --git a/_maps/safehouses/shuttle_space.dmm b/_maps/safehouses/shuttle_space.dmm new file mode 100644 index 00000000000000..a5afaa475c654a --- /dev/null +++ b/_maps/safehouses/shuttle_space.dmm @@ -0,0 +1,231 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/effect/spawner/structure/window/reinforced/shuttle, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"b" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"c" = ( +/obj/effect/turf_decal/tile/neutral/half/contrasted, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/light/small/directional/north, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"i" = ( +/turf/closed/wall/mineral/titanium/overspace, +/area/virtual_domain/safehouse) +"l" = ( +/obj/effect/turf_decal/tile/neutral/half/contrasted{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"n" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/obj/machinery/computer{ + dir = 8; + name = "shuttle console"; + icon_screen = "shuttle" + }, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"o" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"q" = ( +/obj/effect/turf_decal/tile/neutral, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/structure/table/reinforced, +/obj/effect/decal/cleanable/dirt, +/obj/item/storage/toolbox/emergency, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"r" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/obj/effect/turf_decal/loading_area, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"z" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"A" = ( +/obj/effect/turf_decal/stripes/end{ + dir = 1 + }, +/obj/effect/turf_decal/sand/volcanic, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"B" = ( +/obj/effect/turf_decal/tile/neutral{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/machinery/light/small/directional/south, +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"D" = ( +/obj/machinery/light/small/directional/south, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/obj/effect/turf_decal/loading_area, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"E" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/door/airlock/shuttle/glass, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/sand/volcanic, +/obj/structure/fans/tiny, +/turf/open/floor/iron/white, +/area/virtual_domain/safehouse) +"G" = ( +/turf/closed/wall/mineral/titanium, +/area/virtual_domain/safehouse) +"H" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"I" = ( +/obj/effect/turf_decal/tile/neutral/half/contrasted, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/light/small/directional/north, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"L" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/obj/structure/table/reinforced, +/obj/item/tank/internals/emergency_oxygen{ + pixel_x = 3 + }, +/obj/item/clothing/mask/gas, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"N" = ( +/obj/machinery/power/shuttle_engine/propulsion/burst{ + dir = 8 + }, +/obj/structure/window/reinforced/spawner/directional/east, +/obj/effect/turf_decal/stripes/line{ + dir = 8 + }, +/turf/open/floor/plating/airless, +/area/virtual_domain/safehouse) +"O" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/structure/chair/comfy/shuttle{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"U" = ( +/obj/effect/turf_decal/tile/neutral/fourcorners, +/obj/effect/turf_decal/stripes/line, +/obj/effect/decal/cleanable/blood/old, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"W" = ( +/obj/effect/turf_decal/stripes/end, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) +"Y" = ( +/obj/effect/turf_decal/stripes/line{ + dir = 10 + }, +/obj/effect/decal/cleanable/generic, +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/iron, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +i +N +a +a +N +i +"} +(2,1,1) = {" +a +A +o +W +D +G +"} +(3,1,1) = {" +G +I +H +U +r +a +"} +(4,1,1) = {" +E +z +H +b +Y +G +"} +(5,1,1) = {" +G +c +O +b +l +a +"} +(6,1,1) = {" +a +q +n +L +B +G +"} +(7,1,1) = {" +i +G +a +a +G +i +"} diff --git a/_maps/safehouses/test_only_safehouse.dmm b/_maps/safehouses/test_only_safehouse.dmm new file mode 100644 index 00000000000000..c23f8c4a22b49e --- /dev/null +++ b/_maps/safehouses/test_only_safehouse.dmm @@ -0,0 +1,29 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/obj/effect/landmark/bitrunning/cache_goal_turf, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"d" = ( +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"u" = ( +/turf/open/floor/plating, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +u +d +"} +(2,1,1) = {" +u +d +"} +(3,1,1) = {" +u +d +"} +(4,1,1) = {" +u +a +"} diff --git a/_maps/safehouses/wood.dmm b/_maps/safehouses/wood.dmm new file mode 100644 index 00000000000000..0bb6b273fceaee --- /dev/null +++ b/_maps/safehouses/wood.dmm @@ -0,0 +1,120 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/open/indestructible/hotelwood, +/area/virtual_domain/safehouse) +"i" = ( +/obj/effect/spawner/structure/window, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"o" = ( +/turf/open/floor/carpet/green, +/area/virtual_domain/safehouse) +"p" = ( +/obj/item/kirbyplants/random/fullysynthetic, +/turf/open/indestructible/hotelwood, +/area/virtual_domain/safehouse) +"s" = ( +/obj/machinery/light/small/directional/east, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"v" = ( +/obj/machinery/light/small/directional/east, +/obj/structure/table/wood, +/obj/item/newspaper, +/turf/open/indestructible/hotelwood, +/area/virtual_domain/safehouse) +"x" = ( +/obj/structure/railing/corner/end{ + dir = 4 + }, +/turf/open/floor/carpet/green, +/area/virtual_domain/safehouse) +"z" = ( +/obj/structure/sign/poster/random/directional/east, +/turf/open/indestructible/hotelwood, +/area/virtual_domain/safehouse) +"G" = ( +/turf/closed/wall/mineral/wood, +/area/virtual_domain/safehouse) +"J" = ( +/obj/structure/railing, +/obj/effect/landmark/bitrunning/cache_goal_turf, +/obj/effect/turf_decal/loading_area{ + dir = 4 + }, +/turf/open/floor/bitrunning_transport, +/area/virtual_domain/safehouse) +"T" = ( +/obj/effect/landmark/bitrunning/hololadder_spawn, +/turf/open/indestructible/hotelwood, +/area/virtual_domain/safehouse) +"X" = ( +/obj/machinery/door/airlock/wood/glass, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/virtual_domain/safehouse) +"Z" = ( +/obj/machinery/light/small/directional/west, +/turf/open/indestructible/hotelwood, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +G +G +i +G +G +G +"} +(2,1,1) = {" +i +Z +a +a +Z +i +"} +(3,1,1) = {" +G +p +o +o +T +G +"} +(4,1,1) = {" +X +a +o +o +T +G +"} +(5,1,1) = {" +G +a +x +o +T +G +"} +(6,1,1) = {" +i +s +J +z +v +i +"} +(7,1,1) = {" +G +G +i +G +G +G +"} diff --git a/_maps/shuttles/emergency_rollerdome.dmm b/_maps/shuttles/emergency_rollerdome.dmm index f6cec0091aa95d..39aee0644e7f10 100644 --- a/_maps/shuttles/emergency_rollerdome.dmm +++ b/_maps/shuttles/emergency_rollerdome.dmm @@ -1,51 +1,61 @@ //MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE "cc" = ( -/obj/structure/railing{ - dir = 1 - }, -/obj/effect/turf_decal/siding/wood{ - dir = 1 - }, -/turf/open/floor/wood, +/obj/structure/railing, +/turf/open/floor/light/colour_cycle/dancefloor_a, /area/shuttle/escape) "ce" = ( -/obj/effect/turf_decal/siding/wood{ - dir = 1 +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/eighties, +/area/shuttle/escape) +"cs" = ( +/obj/structure/railing/corner{ + dir = 4 }, -/turf/open/floor/wood, +/turf/open/floor/light/colour_cycle/dancefloor_b, /area/shuttle/escape) "cP" = ( /obj/effect/spawner/random/entertainment/arcade, /turf/open/floor/eighties, /area/shuttle/escape) "dJ" = ( -/obj/effect/turf_decal/siding/wood, -/turf/open/floor/wood, +/obj/structure/railing/corner/end/flip, +/obj/structure/railing/corner/end{ + dir = 1 + }, +/turf/open/floor/light/colour_cycle/dancefloor_b, /area/shuttle/escape) "eR" = ( -/obj/structure/table, -/obj/item/reagent_containers/cup/glass/shaker, -/obj/item/storage/box/drinkingglasses, -/turf/open/floor/wood, +/obj/item/kirbyplants/potty{ + name = "Cake plant" + }, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "fX" = ( -/obj/structure/table, -/obj/machinery/chem_dispenser/drinks/beer{ - dir = 1 - }, -/turf/open/floor/wood, +/obj/structure/chair/stool/bar/directional/east, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "hD" = ( /obj/machinery/door/airlock/gold/glass, /obj/effect/mapping_helpers/airlock/access/all/command/general, -/turf/open/floor/wood, +/turf/open/floor/eighties, /area/shuttle/escape) "hF" = ( /turf/closed/wall/mineral/plastitanium/nodiagonal, /area/shuttle/escape) +"hM" = ( +/obj/machinery/jukebox/disco/indestructible, +/turf/open/floor/light/colour_cycle/dancefloor_a, +/area/shuttle/escape) +"hZ" = ( +/obj/structure/table, +/obj/machinery/chem_dispenser/drinks/beer{ + dir = 8 + }, +/turf/open/floor/wood/parquet, +/area/shuttle/escape) "im" = ( -/obj/machinery/computer/emergency_shuttle, -/turf/open/floor/wood, +/obj/structure/chair/comfy/lime, +/turf/open/floor/eighties, /area/shuttle/escape) "jD" = ( /obj/structure/rack, @@ -70,195 +80,270 @@ /obj/machinery/vending/games, /turf/open/floor/eighties, /area/shuttle/escape) +"mP" = ( +/obj/effect/turf_decal/siding/wood/corner, +/turf/open/floor/eighties, +/area/shuttle/escape) "ns" = ( -/obj/structure/table/wood/shuttle_bar, -/obj/effect/fun_balloon/sentience/emergency_shuttle{ - group_name = "snack bar drone at Uncle Pete's Rollerdome" - }, -/turf/open/floor/wood, +/obj/structure/etherealball, +/turf/open/floor/light/colour_cycle/dancefloor_b, /area/shuttle/escape) "nw" = ( -/obj/structure/table, -/obj/machinery/chem_dispenser/drinks{ - dir = 1 - }, -/turf/open/floor/wood, +/obj/effect/spawner/random/vending/snackvend, +/turf/open/floor/eighties, /area/shuttle/escape) "nN" = ( -/obj/structure/railing{ - dir = 5 +/obj/structure/railing/corner/end{ + dir = 4 }, -/obj/effect/turf_decal/siding/wood{ - dir = 5 +/obj/structure/railing/corner/end{ + dir = 8 }, -/turf/open/floor/wood, +/turf/open/floor/light/colour_cycle/dancefloor_b, /area/shuttle/escape) "nT" = ( /obj/machinery/computer/atmos_alert{ dir = 4 }, -/turf/open/floor/wood, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "od" = ( /obj/machinery/power/shuttle_engine/propulsion, /turf/open/floor/plating/airless, /area/shuttle/escape) "pa" = ( -/obj/structure/table/reinforced, -/turf/open/floor/wood, +/obj/structure/railing{ + dir = 5 + }, +/turf/open/floor/light/colour_cycle/dancefloor_b, /area/shuttle/escape) "pj" = ( /turf/template_noop, /area/template_noop) "pI" = ( /obj/machinery/light/directional/west, -/turf/open/floor/wood, +/turf/open/floor/eighties, /area/shuttle/escape) "qU" = ( /obj/machinery/light/directional/east, -/turf/open/floor/wood, +/obj/structure/table, +/obj/machinery/chem_dispenser/drinks{ + dir = 8 + }, +/turf/open/floor/wood/parquet, +/area/shuttle/escape) +"rX" = ( +/obj/effect/spawner/random/entertainment/arcade, +/obj/machinery/light/directional/north, +/turf/open/floor/eighties, /area/shuttle/escape) "ss" = ( /obj/docking_port/mobile/emergency{ name = "Uncle Pete's Rollerdome" }, -/obj/machinery/door/airlock/gold/glass, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/machinery/door/airlock/grunge, +/turf/open/floor/eighties, /area/shuttle/escape) "tG" = ( /turf/closed/wall/mineral/plastitanium, /area/shuttle/escape) "uN" = ( -/obj/structure/table/wood/shuttle_bar, -/obj/item/storage/bag/tray, -/turf/open/floor/wood, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "vq" = ( -/obj/structure/railing{ - dir = 9 - }, -/obj/effect/turf_decal/siding/wood{ - dir = 9 +/obj/machinery/computer/emergency_shuttle{ + dir = 4 }, -/turf/open/floor/wood, +/turf/open/floor/eighties, /area/shuttle/escape) "wf" = ( /obj/effect/spawner/structure/window/reinforced/plasma/plastitanium, /turf/open/floor/plating/elevatorshaft, /area/shuttle/escape) "wn" = ( -/obj/structure/chair/comfy/brown{ - dir = 1 +/obj/structure/table/wood, +/obj/item/clothing/head/soft/green{ + flipped = 1; + pixel_x = 7; + pixel_y = 6 }, -/turf/open/floor/wood, +/obj/item/clothing/glasses/sunglasses, +/obj/item/clothing/suit/costume/hawaiian, +/turf/open/floor/eighties, /area/shuttle/escape) "xK" = ( /obj/structure/chair/comfy/brown{ dir = 4 }, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/floor/wood/parquet, +/area/shuttle/escape) +"ys" = ( +/obj/structure/railing/corner/end/flip{ + dir = 4 + }, +/obj/structure/railing/corner/end/flip{ + dir = 8 + }, +/turf/open/floor/light/colour_cycle/dancefloor_b, /area/shuttle/escape) "ze" = ( -/obj/structure/railing, -/obj/effect/turf_decal/siding/wood, -/turf/open/floor/wood, +/obj/structure/railing/corner, +/turf/open/floor/light/colour_cycle/dancefloor_a, /area/shuttle/escape) "zs" = ( -/obj/effect/turf_decal/siding/wood{ +/obj/structure/railing{ dir = 4 }, -/turf/open/floor/wood, +/turf/open/floor/light/colour_cycle/dancefloor_a, /area/shuttle/escape) "zt" = ( /obj/structure/table/wood, -/obj/item/storage/fancy/cigarettes/cigars/havana, +/obj/item/storage/fancy/cigarettes/cigars/havana{ + pixel_y = 11 + }, /obj/item/lighter{ - pixel_x = -4; - pixel_y = 6 + pixel_x = 6; + pixel_y = -2 }, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "zx" = ( /obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/wood, +/turf/open/floor/plating, /area/shuttle/escape) "zZ" = ( -/obj/effect/turf_decal/siding/wood{ +/obj/structure/railing{ dir = 8 }, -/turf/open/floor/wood, +/turf/open/floor/light/colour_cycle/dancefloor_a, +/area/shuttle/escape) +"Au" = ( +/obj/structure/table/reinforced, +/obj/item/storage/box/drinkingglasses{ + pixel_y = 13 + }, +/obj/item/storage/box/drinkingglasses{ + pixel_y = 5; + pixel_x = 7 + }, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "AT" = ( /obj/structure/etherealball, -/turf/open/floor/light, +/turf/open/floor/light/colour_cycle/dancefloor_a, /area/shuttle/escape) "Cg" = ( /turf/open/floor/eighties, /area/shuttle/escape) +"Cx" = ( +/obj/machinery/vending/boozeomat, +/turf/open/floor/wood/parquet, +/area/shuttle/escape) "Dh" = ( -/obj/effect/spawner/random/vending/snackvend, -/turf/open/floor/wood, +/obj/item/reagent_containers/cup/glass/shaker{ + pixel_y = 14; + pixel_x = 11 + }, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "DR" = ( /obj/structure/railing{ dir = 6 }, -/obj/effect/turf_decal/siding/wood{ - dir = 6 - }, -/turf/open/floor/wood, +/turf/open/floor/light/colour_cycle/dancefloor_b, /area/shuttle/escape) "Hi" = ( /obj/structure/table/wood, -/obj/item/flashlight/lamp/green, -/turf/open/floor/wood, +/obj/item/flashlight/lamp/green{ + pixel_y = 14; + pixel_x = -3 + }, +/obj/item/reagent_containers/cup/glass/bottle/whiskey{ + pixel_y = 10; + pixel_x = 8 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "HA" = ( -/obj/effect/spawner/random/vending/colavend, -/turf/open/floor/wood, +/obj/structure/table, +/obj/item/pizzabox/meat{ + pixel_y = 11 + }, +/obj/item/pizzabox/meat{ + pixel_y = 17 + }, +/turf/open/floor/wood/parquet, +/area/shuttle/escape) +"HB" = ( +/obj/structure/railing/corner{ + dir = 8 + }, +/turf/open/floor/light/colour_cycle/dancefloor_a, /area/shuttle/escape) "HS" = ( -/turf/open/floor/light, +/turf/open/floor/light/colour_cycle/dancefloor_a, /area/shuttle/escape) "Jq" = ( /obj/machinery/computer/security{ dir = 8 }, -/turf/open/floor/wood, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "JR" = ( -/obj/machinery/vending/boozeomat, -/turf/open/floor/wood, +/obj/structure/table/reinforced, +/obj/item/storage/bag/tray{ + pixel_y = 5 + }, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "Ky" = ( -/turf/open/floor/wood, +/obj/structure/table/reinforced, +/obj/item/pizzabox/mushroom{ + pixel_y = 11; + pixel_x = -7 + }, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "KJ" = ( /obj/machinery/power/shuttle_engine/heater, /obj/structure/window/reinforced/spawner/directional/north, /turf/open/floor/plating/airless, /area/shuttle/escape) +"Ms" = ( +/obj/structure/railing/corner{ + dir = 1 + }, +/turf/open/floor/light/colour_cycle/dancefloor_a, +/area/shuttle/escape) "Ow" = ( -/obj/structure/table, -/obj/item/storage/box/drinkingglasses, -/turf/open/floor/wood, +/obj/structure/railing{ + dir = 1 + }, +/turf/open/floor/light/colour_cycle/dancefloor_a, /area/shuttle/escape) "Ox" = ( -/obj/structure/table/wood/shuttle_bar, -/obj/item/pizzabox/meat, -/obj/item/pizzabox/meat, -/obj/item/pizzabox/meat, -/obj/item/pizzabox/mushroom, -/obj/item/pizzabox/margherita, -/obj/item/pizzabox/pineapple, -/obj/item/pizzabox/vegetable, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/eighties, /area/shuttle/escape) "OG" = ( /obj/machinery/computer/communications{ dir = 8 }, -/turf/open/floor/wood, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "ON" = ( /obj/machinery/vending/donksofttoyvendor, @@ -268,66 +353,88 @@ /obj/machinery/computer/crew{ dir = 4 }, -/turf/open/floor/wood, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "Qv" = ( -/mob/living/simple_animal/drone/snowflake/bardrone, -/turf/open/floor/wood, +/obj/structure/table/reinforced, +/obj/item/pizzabox/meat{ + pixel_y = -1 + }, +/obj/item/pizzabox/pineapple{ + pixel_y = 7; + pixel_x = 6 + }, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "QO" = ( -/obj/machinery/door/airlock/gold/glass, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/machinery/door/airlock/grunge, /turf/open/floor/wood, /area/shuttle/escape) "Ry" = ( -/obj/effect/turf_decal/siding/wood, -/obj/structure/railing, -/turf/open/floor/wood, +/obj/structure/railing{ + dir = 9 + }, +/turf/open/floor/light/colour_cycle/dancefloor_b, /area/shuttle/escape) "RN" = ( -/obj/machinery/jukebox/disco/indestructible, -/turf/open/floor/light, +/turf/open/floor/light/colour_cycle/dancefloor_b, +/area/shuttle/escape) +"SR" = ( +/obj/structure/table/reinforced, +/obj/effect/fun_balloon/sentience/emergency_shuttle{ + group_name = "snack bar drone at Uncle Pete's Rollerdome" + }, +/obj/item/food/cake/birthday{ + pixel_y = 7 + }, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "TU" = ( /obj/structure/railing{ dir = 10 }, -/obj/effect/turf_decal/siding/wood{ - dir = 10 - }, -/turf/open/floor/wood, +/turf/open/floor/light/colour_cycle/dancefloor_b, /area/shuttle/escape) "We" = ( /obj/structure/chair/comfy/brown{ dir = 8 }, -/turf/open/floor/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/wood/parquet, /area/shuttle/escape) "Wg" = ( -/obj/structure/table/wood/shuttle_bar, -/obj/item/storage/bag/tray, -/obj/item/food/cake/birthday, -/obj/item/knife/kitchen, -/turf/open/floor/wood, +/obj/effect/spawner/random/vending/colavend, +/obj/effect/turf_decal/siding/wood{ + dir = 4 + }, +/turf/open/floor/eighties, /area/shuttle/escape) "Yr" = ( -/obj/structure/table/wood/poker, -/obj/item/storage/box/drinkingglasses, -/obj/item/reagent_containers/cup/glass/bottle/whiskey, /obj/machinery/light/directional/south, -/turf/open/floor/wood, +/turf/open/floor/eighties, /area/shuttle/escape) -"Zo" = ( -/obj/structure/table/wood/shuttle_bar, -/turf/open/floor/wood, +"Zf" = ( +/mob/living/simple_animal/drone/snowflake/bardrone, +/turf/open/floor/wood/parquet, /area/shuttle/escape) -"ZN" = ( +"Zo" = ( /obj/effect/turf_decal/siding/wood{ - dir = 1 + dir = 6 }, -/obj/structure/railing{ +/obj/effect/turf_decal/siding/wood/corner, +/turf/open/floor/eighties, +/area/shuttle/escape) +"ZN" = ( +/obj/structure/railing/corner/end/flip{ dir = 1 }, -/turf/open/floor/wood, +/obj/structure/railing/corner/end, +/turf/open/floor/light/colour_cycle/dancefloor_b, /area/shuttle/escape) (1,1,1) = {" @@ -361,6 +468,7 @@ tG tG hF AT +mP Cg Cg Cg @@ -370,11 +478,10 @@ Cg Cg Cg Cg -AT -ce -Ky +ns +Cg pI -Ky +nw tG tG "} @@ -386,17 +493,17 @@ Qf zx ln Cg -vq -zZ -zZ -zZ +Cg +Cg +Ry zZ +ZN zZ TU Cg Cg -ce -uN +Cg +mP Ox Wg KJ @@ -410,42 +517,42 @@ We zx cP Cg -cc -pa -Ky -Ky -Ky -pa -ze Cg +Ry +Ms +RN +HS +RN +HB +TU Cg -ce +mP Zo -Ky +uN eR KJ od "} (5,1,1) = {" wf -wn -Ky -Ky +vq +Cg +Cg zx cP Cg -ZN -pa -HS +Cg +Ow +RN HS +RN HS -pa -Ry +RN +cc jD -Cg ce uN -Ky +fX fX KJ od @@ -453,22 +560,22 @@ od (6,1,1) = {" wf im -Ky +Cg Yr zx -cP +rX Cg -ce -pa +Cg +nN HS RN +hM +RN HS -pa -dJ -Cg +ys Cg ce -ns +fX Qv JR KJ @@ -477,24 +584,24 @@ od (7,1,1) = {" wf wn -Ky -Ky +Cg +Cg hD Cg Cg -ZN -pa -HS +Cg +Ow +RN HS +RN HS -pa -Ry +RN +cc jD -Cg ce -Zo +JR Ky -nw +uN KJ od "} @@ -506,19 +613,19 @@ xK zx ON Cg -cc -pa -Ky -Ky -Ky +Cg pa +cs +RN +HS +RN ze -Cg +DR Cg ce +SR +Zf uN -Ky -Ow KJ od "} @@ -530,17 +637,17 @@ OG zx ln Cg -nN -zs -zs -zs +Cg +Cg +pa zs +dJ zs DR Cg Cg ce -Zo +Au Dh HA KJ @@ -552,7 +659,8 @@ tG tG tG hF -AT +ns +Cg Cg Cg Cg @@ -563,10 +671,9 @@ Cg Cg Cg AT -ce -Ky +Cx qU -Ky +hZ tG tG "} diff --git a/_maps/shuttles/pirate_geode.dmm b/_maps/shuttles/pirate_geode.dmm index d2e8f034f48399..693b7c8635ff76 100644 --- a/_maps/shuttles/pirate_geode.dmm +++ b/_maps/shuttles/pirate_geode.dmm @@ -127,21 +127,19 @@ }, /turf/open/floor/plating, /area/shuttle/pirate) +"iG" = ( +/obj/effect/spawner/structure/window/hollow/survival_pod, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "geodebridge"; + dir = 4 + }, +/turf/open/misc/dirt/station, +/area/shuttle/pirate) "jh" = ( /turf/open/floor/catwalk_floor, /area/shuttle/pirate) -"jt" = ( -/obj/machinery/power/terminal{ - dir = 8 - }, -/turf/closed/mineral/random/jungle{ - baseturfs = /turf/open/misc/dirt - }, -/area/shuttle/pirate) "jx" = ( -/turf/closed/mineral/random/jungle{ - baseturfs = /turf/open/misc/dirt - }, +/turf/closed/mineral/random/jungle/space_safe, /area/shuttle/pirate) "jD" = ( /obj/effect/turf_decal/lunar_sand/plating, @@ -465,7 +463,6 @@ /turf/open/floor/plating, /area/shuttle/pirate) "xg" = ( -/obj/structure/grille, /obj/effect/spawner/structure/window/hollow/survival_pod, /obj/structure/barricade/wooden/crude, /turf/open/misc/dirt/station, @@ -515,11 +512,6 @@ /obj/structure/reagent_dispensers/watertank, /turf/open/misc/dirt/station, /area/shuttle/pirate) -"At" = ( -/turf/closed/mineral/random/jungle{ - baseturfs = null - }, -/area/shuttle/pirate) "AT" = ( /obj/effect/turf_decal/lunar_sand/plating, /obj/docking_port/mobile/pirate{ @@ -864,14 +856,6 @@ }, /turf/open/misc/dirt/station, /area/shuttle/pirate) -"Qg" = ( -/obj/structure/grille, -/obj/effect/spawner/structure/window/hollow/survival_pod, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "geodebridge" - }, -/turf/open/misc/dirt/station, -/area/shuttle/pirate) "Qo" = ( /turf/open/floor/iron/stairs{ dir = 1 @@ -948,7 +932,6 @@ /obj/effect/turf_decal/lunar_sand/plating, /obj/structure/barricade/wooden/crude, /obj/effect/spawner/structure/window/hollow/survival_pod, -/obj/structure/grille, /turf/open/floor/plating, /area/shuttle/pirate) "Un" = ( @@ -963,7 +946,6 @@ /turf/closed/wall/mineral/plastitanium/nodiagonal, /area/shuttle/pirate) "UM" = ( -/obj/structure/grille, /obj/effect/spawner/structure/window/hollow/survival_pod, /turf/open/misc/dirt/station, /area/shuttle/pirate) @@ -1050,11 +1032,11 @@ mv Od Pq Pq -At +jx Pq Pq Pq -At +jx Pq Pq Od @@ -1066,8 +1048,8 @@ lt (3,1,1) = {" lt lt -At -At +jx +jx Od Uf Uf @@ -1079,8 +1061,8 @@ Od Uf Uf Od -At -At +jx +jx lt lt "} @@ -1212,7 +1194,7 @@ jx "} (10,1,1) = {" lt -jt +jx Od DT ZF @@ -1407,9 +1389,9 @@ jx jx Od Od -Qg -Qg -Qg +iG +iG +iG Od Od Od diff --git a/_maps/shuttles/skyrat/pirate_nri_raider.dmm b/_maps/shuttles/skyrat/pirate_nri_raider.dmm index 3008861bb1df18..36fc58bbf66fa1 100644 --- a/_maps/shuttles/skyrat/pirate_nri_raider.dmm +++ b/_maps/shuttles/skyrat/pirate_nri_raider.dmm @@ -17,9 +17,9 @@ /obj/item/storage/box/zipties{ pixel_x = 2 }, -/obj/item/gun/energy/e_gun/advtaser/assault_ops, -/obj/item/gun/energy/e_gun/advtaser/assault_ops, -/obj/item/gun/energy/e_gun/advtaser/assault_ops, +/obj/item/gun/energy/e_gun/advtaser, +/obj/item/gun/energy/e_gun/advtaser, +/obj/item/gun/energy/e_gun/advtaser, /obj/item/melee/baton, /obj/item/melee/baton, /obj/item/melee/baton, @@ -473,7 +473,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, -/obj/item/gun/ballistic/shotgun/m23, +/obj/item/gun/ballistic/shotgun/riot, /obj/item/gun/ballistic/automatic/nri_smg, /turf/open/floor/pod, /area/shuttle/pirate/nri) diff --git a/_maps/shuttles/skyrat/prison_transport.dmm b/_maps/shuttles/skyrat/prison_transport.dmm index 08318a8535d241..71d66097094ad8 100644 --- a/_maps/shuttles/skyrat/prison_transport.dmm +++ b/_maps/shuttles/skyrat/prison_transport.dmm @@ -18,10 +18,10 @@ /area/shuttle/prison_transport) "aI" = ( /obj/machinery/light/cold/no_nightlight/directional/north, -/obj/item/gun/ballistic/automatic/cfa_wildcat/no_mag, -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/rubber, -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/rubber, -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/rubber, +/obj/item/gun/ballistic/automatic/sol_smg/no_mag, +/obj/item/ammo_box/magazine/c35sol_pistol/stendo, +/obj/item/ammo_box/magazine/c35sol_pistol/stendo, +/obj/item/ammo_box/magazine/c35sol_pistol/stendo, /obj/structure/rack/shelf, /obj/effect/turf_decal/tile/dark_blue/fourcorners, /turf/open/floor/iron/dark, diff --git a/_maps/shuttles/skyrat/slaver_syndie.dmm b/_maps/shuttles/skyrat/slaver_syndie.dmm index 6cd82b4a88c4df..8347cf4016a26b 100644 --- a/_maps/shuttles/skyrat/slaver_syndie.dmm +++ b/_maps/shuttles/skyrat/slaver_syndie.dmm @@ -259,8 +259,8 @@ /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer2{ dir = 4 }, -/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/hp, -/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/incendiary, +/obj/item/ammo_box/magazine/c585trappiste_pistol, +/obj/item/ammo_box/magazine/c585trappiste_pistol, /obj/item/mod/control/pre_equipped/responsory, /obj/machinery/light/directional/west, /obj/structure/closet/secure_closet{ @@ -539,15 +539,15 @@ /area/shuttle/syndicate/slaver) "Aq" = ( /obj/effect/turf_decal/bot, -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/rubber, -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/rubber, -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/ap, -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/ap, -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/incendiary, -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat, +/obj/item/ammo_box/magazine/c35sol_pistol/stendo, +/obj/item/ammo_box/magazine/c35sol_pistol/stendo, +/obj/item/ammo_box/magazine/c35sol_pistol/stendo, +/obj/item/ammo_box/magazine/c35sol_pistol/stendo, +/obj/item/ammo_box/magazine/c35sol_pistol/stendo, +/obj/item/ammo_box/magazine/c35sol_pistol/stendo, /obj/item/storage/box, /obj/item/storage/box/handcuffs, -/obj/item/gun/ballistic/automatic/cfa_wildcat/no_mag, +/obj/item/gun/ballistic/automatic/sol_smg/no_mag, /obj/structure/closet/secure_closet{ icon_state = "hos"; name = "Crew Locker"; @@ -960,7 +960,6 @@ /obj/effect/turf_decal/bot, /obj/item/storage/box, /obj/item/storage/box/handcuffs, -/obj/item/gun/energy/e_gun/cfa_phalanx, /obj/structure/extinguisher_cabinet/directional/east, /obj/structure/closet/secure_closet{ icon_state = "hos"; diff --git a/_maps/skyrat/automapper/automapper_config.toml b/_maps/skyrat/automapper/automapper_config.toml index 6c45d2a3955a96..e051f32c4e56aa 100644 --- a/_maps/skyrat/automapper/automapper_config.toml +++ b/_maps/skyrat/automapper/automapper_config.toml @@ -362,6 +362,14 @@ required_map = "north_star.dmm" coordinates = [171, 129, 1] trait_name = "Station" +# Lavaland NE Ashwalker Nest +[templates.lavaland_ashwalker_nenest] +map_files = ["lavaland_ashwalker_nenest.dmm"] +directory = "_maps/skyrat/automapper/templates/mining/" +required_map = "Lavaland.dmm" +coordinates = [223, 224, 1] +trait_name = "Mining" + # Tannhauser Gate Overrides go below this line # ICEBOX MAP EDITS diff --git a/_maps/skyrat/automapper/templates/birdshot/birdshot_armory.dmm b/_maps/skyrat/automapper/templates/birdshot/birdshot_armory.dmm index ace5f4b93f2616..eef058070d4848 100644 --- a/_maps/skyrat/automapper/templates/birdshot/birdshot_armory.dmm +++ b/_maps/skyrat/automapper/templates/birdshot/birdshot_armory.dmm @@ -29,8 +29,8 @@ dir = 1 }, /obj/structure/rack/gunrack, -/obj/effect/spawner/armory_spawn/cmg, /obj/effect/decal/cleanable/dirt, +/obj/effect/spawner/armory_spawn/smg, /turf/open/floor/iron/dark/small, /area/station/ai_monitored/security/armory) "A" = ( @@ -80,11 +80,7 @@ /turf/open/floor/iron/dark/small, /area/station/ai_monitored/security/armory) "Q" = ( -/obj/structure/closet/ammunitionlocker/useful, -/obj/item/storage/box/lethalshot, -/obj/item/storage/box/lethalshot, -/obj/item/storage/box/lethalshot, -/obj/item/storage/box/lethalshot, +/obj/structure/closet/secure_closet/armory_kiboko, /turf/open/floor/iron/dark/small, /area/station/ai_monitored/security/armory) "R" = ( diff --git a/_maps/skyrat/automapper/templates/deltastation/deltastation_armory.dmm b/_maps/skyrat/automapper/templates/deltastation/deltastation_armory.dmm index 2f343683e77854..e8b78a69a9d503 100644 --- a/_maps/skyrat/automapper/templates/deltastation/deltastation_armory.dmm +++ b/_maps/skyrat/automapper/templates/deltastation/deltastation_armory.dmm @@ -58,7 +58,7 @@ pixel_x = 3 }, /obj/structure/rack/gunrack, -/obj/effect/spawner/armory_spawn/cmg, +/obj/effect/spawner/armory_spawn/smg, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "M" = ( @@ -108,7 +108,7 @@ pixel_x = 3 }, /obj/structure/window/reinforced/spawner/directional/north, -/obj/structure/closet/secure_closet/smartgun, +/obj/structure/closet/secure_closet/armory_kiboko, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "Y" = ( diff --git a/_maps/skyrat/automapper/templates/icebox/icebox_armory_middle.dmm b/_maps/skyrat/automapper/templates/icebox/icebox_armory_middle.dmm index 8d2359555ce217..d6797c049eeb90 100644 --- a/_maps/skyrat/automapper/templates/icebox/icebox_armory_middle.dmm +++ b/_maps/skyrat/automapper/templates/icebox/icebox_armory_middle.dmm @@ -16,8 +16,8 @@ "e" = ( /obj/machinery/light/directional/north, /obj/structure/rack/gunrack, -/obj/effect/spawner/armory_spawn/cmg, /obj/effect/turf_decal/tile/red/half, +/obj/effect/spawner/armory_spawn/smg, /turf/open/floor/iron/dark/textured, /area/station/ai_monitored/security/armory) "g" = ( @@ -80,7 +80,7 @@ c_tag = "Armory - Internal - Lower" }, /obj/effect/turf_decal/tile/red/half, -/obj/structure/closet/secure_closet/smartgun, +/obj/structure/closet/secure_closet/armory_kiboko, /turf/open/floor/iron/dark/textured, /area/station/ai_monitored/security/armory) "M" = ( diff --git a/_maps/skyrat/automapper/templates/kilostation/kilostation_armory.dmm b/_maps/skyrat/automapper/templates/kilostation/kilostation_armory.dmm index 32394a0dd4e4d9..229c3d31bd05dc 100644 --- a/_maps/skyrat/automapper/templates/kilostation/kilostation_armory.dmm +++ b/_maps/skyrat/automapper/templates/kilostation/kilostation_armory.dmm @@ -11,11 +11,7 @@ /obj/structure/window/reinforced/spawner/directional/south, /obj/structure/window/reinforced/spawner/directional/east, /obj/effect/decal/cleanable/dirt, -/obj/structure/closet/ammunitionlocker/useful, -/obj/item/storage/box/lethalshot, -/obj/item/storage/box/lethalshot, -/obj/item/storage/box/lethalshot, -/obj/item/storage/box/lethalshot, +/obj/structure/closet/secure_closet/armory_kiboko, /turf/open/floor/iron/showroomfloor, /area/station/ai_monitored/security/armory) "q" = ( @@ -74,7 +70,7 @@ /obj/structure/window/reinforced/spawner/directional/north, /obj/structure/window/reinforced/spawner/directional/east, /obj/structure/rack/gunrack, -/obj/effect/spawner/armory_spawn/cmg, +/obj/effect/spawner/armory_spawn/smg, /turf/open/floor/iron/showroomfloor, /area/station/ai_monitored/security/armory) "G" = ( diff --git a/_maps/skyrat/automapper/templates/metastation/metastation_armory.dmm b/_maps/skyrat/automapper/templates/metastation/metastation_armory.dmm index d123d8de9bce72..19dacb89944bce 100644 --- a/_maps/skyrat/automapper/templates/metastation/metastation_armory.dmm +++ b/_maps/skyrat/automapper/templates/metastation/metastation_armory.dmm @@ -23,8 +23,8 @@ /area/station/ai_monitored/security/armory) "g" = ( /obj/effect/turf_decal/bot_blue, -/obj/structure/closet/secure_closet/smartgun, /obj/machinery/firealarm/directional/east, +/obj/structure/closet/secure_closet/armory_kiboko, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "h" = ( @@ -128,7 +128,7 @@ "C" = ( /obj/effect/turf_decal/delivery/red, /obj/structure/rack/gunrack, -/obj/effect/spawner/armory_spawn/cmg, +/obj/effect/spawner/armory_spawn/smg, /turf/open/floor/iron/smooth, /area/station/ai_monitored/security/armory) "D" = ( diff --git a/_maps/skyrat/automapper/templates/mining/lavaland_ashwalker_nenest.dmm b/_maps/skyrat/automapper/templates/mining/lavaland_ashwalker_nenest.dmm new file mode 100644 index 00000000000000..1d969c81586ad2 --- /dev/null +++ b/_maps/skyrat/automapper/templates/mining/lavaland_ashwalker_nenest.dmm @@ -0,0 +1,2487 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aD" = ( +/obj/structure/closet/crate/wooden, +/obj/item/screwdriver/ashwalker, +/obj/item/crowbar/ashwalker, +/obj/item/wrench/ashwalker, +/obj/item/wirecutters/ashwalker, +/obj/item/hatchet/wooden, +/obj/item/weldingtool/mini, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"aN" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"bj" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"ct" = ( +/obj/structure/flora/ash/cacti, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"cD" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"cP" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/chair/stool/bamboo{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"cW" = ( +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/center/cracked, +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"dc" = ( +/obj/structure/stone_tile/block, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"dg" = ( +/obj/structure/stone_tile/surrounding, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"dk" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"dl" = ( +/obj/structure/closet/crate/wooden, +/obj/item/storage/bag/ore, +/obj/item/storage/bag/ore{ + pixel_y = 3 + }, +/obj/item/pickaxe, +/obj/item/pickaxe{ + pixel_y = 3 + }, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"dE" = ( +/obj/structure/stone_tile/surrounding/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"dN" = ( +/obj/structure/stone_tile/surrounding_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"em" = ( +/obj/structure/table/wood, +/obj/item/flashlight/flare/candle/infinite{ + pixel_x = 11; + pixel_y = 12 + }, +/obj/item/reagent_containers/cup/glass/bottle/hooch{ + pixel_x = -2; + pixel_y = 11 + }, +/obj/item/food/rootroll{ + pixel_x = -3; + pixel_y = -1 + }, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"es" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/stone_tile/surrounding/cracked{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"eR" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/item/flashlight/flare/candle/infinite, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"fd" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/reagent_containers/cup/glass/bottle/small{ + pixel_x = -5; + pixel_y = 12 + }, +/obj/item/reagent_containers/cup/glass/bottle/small{ + pixel_x = 5; + pixel_y = 12 + }, +/obj/item/reagent_containers/cup/beaker/large/ceramic{ + pixel_x = 7; + pixel_y = -5 + }, +/obj/item/reagent_containers/cup/beaker/large/blowing_glass{ + pixel_y = -5; + pixel_x = -3 + }, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"fl" = ( +/obj/structure/stone_tile/surrounding, +/obj/structure/stone_tile/center, +/obj/item/knife/hunting, +/obj/structure/table/bronze, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"fA" = ( +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 5 + }, +/obj/structure/stone_tile/surrounding/cracked{ + dir = 1 + }, +/obj/structure/stone_tile/center/burnt, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"fP" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/stone_tile/surrounding_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"gn" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/screwdriver/ashwalker, +/obj/item/crowbar/ashwalker, +/obj/item/wrench/ashwalker, +/obj/item/wirecutters/ashwalker, +/obj/item/hatchet/wooden, +/obj/item/weldingtool/mini, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"gu" = ( +/obj/structure/stone_tile/surrounding_tile/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"gB" = ( +/obj/structure/stone_tile/slab, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/machinery/primitive_stove, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"hv" = ( +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"hP" = ( +/obj/structure/closet/crate/wooden, +/obj/item/seeds/bamboo, +/obj/item/seeds/bamboo, +/obj/item/seeds/sugarcane, +/obj/item/seeds/sugarcane, +/obj/item/seeds/tower, +/obj/item/seeds/tower, +/obj/item/seeds/tower, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"hZ" = ( +/obj/structure/stone_tile/block/burnt{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"iz" = ( +/obj/structure/stone_tile/block, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"iP" = ( +/obj/structure/chair/stool/bamboo{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"iW" = ( +/obj/structure/flora/ash/seraka, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"jh" = ( +/obj/structure/bonfire/dense, +/obj/item/stack/rods{ + amount = 5 + }, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"jk" = ( +/obj/structure/flora/ash/seraka, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"jx" = ( +/obj/structure/closet/crate/wooden, +/obj/item/seeds/potato, +/obj/item/seeds/potato, +/obj/item/seeds/potato/sweet, +/obj/item/seeds/plump, +/obj/item/seeds/plump, +/obj/item/seeds/wheat, +/obj/item/seeds/wheat, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"jy" = ( +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/flora/ash/cacti, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"ko" = ( +/obj/structure/stone_tile/block/cracked, +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/statue/bone/rib{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"kw" = ( +/obj/structure/stone_tile/block/burnt{ + dir = 4 + }, +/obj/structure/stone_tile/burnt{ + dir = 8 + }, +/obj/structure/stone_tile/burnt{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"kH" = ( +/obj/structure/reagent_anvil, +/obj/item/forging/hammer/primitive, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"kP" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/forging/billow/primitive, +/obj/item/stack/sheet/mineral/coal/ten, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"lf" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/closet/crate/wooden, +/obj/item/stack/sheet/iron/twenty, +/obj/item/stack/sheet/leather{ + amount = 35 + }, +/obj/item/stack/sheet/cloth/ten, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"lk" = ( +/obj/structure/stone_tile/slab/burnt, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"ln" = ( +/obj/item/shovel, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"lS" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"mn" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/center, +/obj/structure/stone_tile/surrounding_tile, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"mp" = ( +/obj/structure/closet/crate/miningcar, +/obj/item/stack/sheet/mineral/coal/ten, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"mq" = ( +/obj/structure/stone_tile/slab, +/obj/effect/decal/cleanable/blood, +/obj/structure/headpike/bone, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"mr" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/cup/glass/bottle/moonshine{ + pixel_x = -5; + pixel_y = 7 + }, +/obj/item/flashlight/flare/candle/infinite{ + pixel_x = 5; + pixel_y = -2 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"nu" = ( +/obj/item/cultivator/rake, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"nv" = ( +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) +"ny" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile/cracked, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"nA" = ( +/obj/machinery/vending/ashclothingvendor, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"nJ" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/stone_tile/block/burnt, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"oH" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/forging/billow/primitive, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"pt" = ( +/obj/structure/flora/ash/leaf_shroom, +/obj/structure/stone_tile/surrounding_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"pE" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/cup/beaker/large/ceramic{ + pixel_x = 9; + pixel_y = 11 + }, +/obj/item/reagent_containers/cup/beaker/large/blowing_glass{ + pixel_x = -4; + pixel_y = 6 + }, +/obj/item/reagent_containers/cup/beaker/large/blowing_glass, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"pI" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 1 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"qb" = ( +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"qv" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"qD" = ( +/obj/structure/chair/stool/bamboo{ + dir = 8 + }, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"ru" = ( +/obj/structure/necropolis_gate, +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"rU" = ( +/obj/structure/bonfire/dense, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"sp" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/bedsheet/black{ + pixel_x = 5 + }, +/obj/item/bedsheet/black{ + pixel_x = 5; + pixel_y = 4 + }, +/obj/item/bedsheet/black{ + pixel_x = 5; + pixel_y = 8 + }, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"sD" = ( +/obj/structure/reagent_water_basin, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"sN" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/stack/sheet/iron/twenty, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"tp" = ( +/obj/structure/bed/maint, +/obj/structure/curtain/bounty, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"tu" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"un" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/structure/stone_tile/slab, +/obj/item/reagent_containers/cup/bowl/mushroom_bowl{ + pixel_y = 7; + pixel_x = -5 + }, +/obj/item/reagent_containers/cup/bowl/mushroom_bowl{ + pixel_y = 7; + pixel_x = 7 + }, +/obj/item/reagent_containers/cup/bowl/mushroom_bowl{ + pixel_y = 11; + pixel_x = 1 + }, +/obj/item/smelling_salts{ + pixel_y = -9; + pixel_x = -5 + }, +/obj/item/smelling_salts{ + pixel_y = -9; + pixel_x = 6 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"uz" = ( +/obj/structure/flora/ash/stem_shroom, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"uE" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"uN" = ( +/obj/structure/stone_tile/block, +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"uY" = ( +/obj/structure/table/wood, +/obj/structure/stone_tile/slab, +/obj/structure/chem_separator, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"vg" = ( +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"vh" = ( +/obj/structure/stone_tile/block/burnt{ + dir = 1 + }, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/burnt, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"vH" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"vS" = ( +/obj/structure/geyser, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"wi" = ( +/obj/structure/stone_tile/block/burnt{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"wn" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile/cracked, +/obj/item/flashlight/flare/candle/infinite, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"ws" = ( +/obj/structure/stone_tile/surrounding_tile, +/obj/item/flashlight/flare/candle/infinite, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"wu" = ( +/obj/structure/stone_tile/block/burnt, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"wF" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/flora/ash/stem_shroom, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"wM" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"wO" = ( +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/center, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"wZ" = ( +/obj/structure/necropolis_gate, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"xl" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/reagent_containers/cup/bowl/mushroom_bowl{ + pixel_y = -3 + }, +/obj/item/reagent_containers/cup/bowl/mushroom_bowl, +/obj/item/reagent_containers/cup/bowl/mushroom_bowl{ + pixel_y = 3 + }, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"xo" = ( +/mob/living/simple_animal/hostile/asteroid/gutlunch/grublunch, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"xY" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"ym" = ( +/obj/structure/stone_tile/surrounding/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/center/burnt, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"yw" = ( +/obj/structure/lavaland/ash_walker, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"yy" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/syringe/crude{ + pixel_x = 4; + pixel_y = 19 + }, +/obj/item/reagent_containers/syringe/crude{ + pixel_x = 2; + pixel_y = 15 + }, +/obj/structure/stone_tile/slab, +/obj/item/paper_bin/bundlenatural, +/obj/item/pen/charcoal, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"yO" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/gun/ballistic/bow/longbow, +/obj/structure/stone_tile/slab, +/obj/item/storage/bag/quiver, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"za" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"zt" = ( +/obj/structure/stone_tile/slab, +/obj/machinery/oven/stone, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"zE" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/fermenting_barrel, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"zU" = ( +/obj/structure/stone_tile/surrounding_tile/cracked, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/center, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"zV" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/knife/combat/bone{ + pixel_y = -4 + }, +/obj/item/knife/combat/bone{ + pixel_y = 2 + }, +/obj/item/knife/combat/bone{ + pixel_y = 8 + }, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"zX" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/stone_tile/burnt, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"zY" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"Ac" = ( +/obj/structure/table/wood, +/obj/structure/large_mortar, +/obj/item/pestle, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"AW" = ( +/obj/machinery/iv_drip, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Br" = ( +/obj/structure/millstone, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"BG" = ( +/obj/structure/stone_tile/surrounding/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Cb" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Cs" = ( +/obj/structure/closet/crate/wooden, +/obj/item/seeds/chanter, +/obj/item/seeds/chanter, +/obj/item/seeds/coffee, +/obj/item/seeds/herbs, +/obj/item/seeds/herbs, +/obj/item/seeds/kronkus, +/obj/item/seeds/tea, +/obj/item/seeds/tea, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Cv" = ( +/obj/structure/closet/crate/wooden, +/obj/item/seeds/cotton, +/obj/item/seeds/cotton, +/obj/item/seeds/cotton, +/obj/item/seeds/korta_nut, +/obj/item/seeds/korta_nut, +/obj/item/seeds/korta_nut, +/obj/item/seeds/korta_nut/sweet, +/obj/item/seeds/korta_nut/sweet, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Db" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"DL" = ( +/obj/structure/necropolis_gate, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"DN" = ( +/turf/closed/wall/mineral/wood/nonmetal, +/area/ruin/unpowered/ash_walkers) +"DW" = ( +/obj/structure/flora/ash/leaf_shroom, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Ea" = ( +/obj/structure/stone_tile/surrounding/cracked{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Eh" = ( +/turf/closed/indestructible/riveted/boss, +/area/lavaland/surface/outdoors) +"Ez" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"EP" = ( +/obj/structure/curtain/bounty, +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"EV" = ( +/obj/structure/stone_tile/block/cracked, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"FD" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Gi" = ( +/obj/structure/reagent_forge, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Go" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/flora/ash/cacti, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"GG" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"GH" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"GS" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/mob/living/simple_animal/hostile/asteroid/gutlunch/guthen, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Hf" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Hz" = ( +/obj/structure/fermenting_barrel, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Id" = ( +/obj/structure/stone_tile/slab/cracked, +/obj/item/flashlight/flare/candle/infinite, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"Ih" = ( +/obj/structure/stone_tile/slab/cracked, +/obj/structure/headpike/bone, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Im" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/surrounding_tile, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"IF" = ( +/obj/structure/stone_tile/slab/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"IM" = ( +/obj/structure/flora/ash/cap_shroom, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Jx" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/reagent_containers/cup/bottle/nutrient/rh{ + pixel_x = -6; + pixel_y = 6 + }, +/obj/item/reagent_containers/cup/bottle/nutrient/l4z{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/item/reagent_containers/cup/bottle/nutrient/ez{ + pixel_y = 4 + }, +/obj/item/reagent_containers/cup/bottle/nutrient/rh{ + pixel_x = -6; + pixel_y = 2 + }, +/obj/item/reagent_containers/cup/bottle/nutrient/l4z{ + pixel_x = 6; + pixel_y = 2 + }, +/obj/item/reagent_containers/cup/bottle/nutrient/ez, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Jy" = ( +/obj/structure/stone_tile/slab, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors) +"JC" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"JY" = ( +/obj/structure/flora/ash/tall_shroom, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Ks" = ( +/obj/structure/chair/stool/bamboo{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"KJ" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile/block/burnt{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"KO" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/mob/living/basic/chicken{ + name = "\improper gunther"; + desc = "An odd looking gutlunch, this one seems to have feathers and lay eggs, not like you'd complain about that."; + unsuitable_atmos_damage = 0 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"LE" = ( +/obj/structure/stone_tile/block/burnt{ + dir = 8 + }, +/obj/structure/stone_tile/burnt{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile/cracked, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"LR" = ( +/obj/structure/stone_tile/block/burnt{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"LV" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 4 + }, +/obj/item/flashlight/flare/candle/infinite, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"Mc" = ( +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"NB" = ( +/obj/structure/stone_tile/surrounding/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"NI" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"NM" = ( +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"OX" = ( +/obj/structure/stone_tile/block/cracked, +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/statue/bone/rib, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Px" = ( +/obj/structure/closet/crate/wooden, +/obj/item/reagent_containers/blood/lizard{ + pixel_x = -2; + pixel_y = -2 + }, +/obj/item/reagent_containers/blood/lizard{ + pixel_x = 5; + pixel_y = -2 + }, +/obj/item/stack/sheet/cloth/ten, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Py" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/cup/primitive_centrifuge{ + pixel_x = -14; + pixel_y = -1 + }, +/obj/item/reagent_containers/cup/mortar{ + pixel_y = 12; + pixel_x = -10 + }, +/obj/item/reagent_containers/cup/glass/bottle/small{ + pixel_x = 7; + pixel_y = 12 + }, +/obj/item/reagent_containers/cup/glass/bottle/small{ + pixel_x = 3; + pixel_y = 5 + }, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Qt" = ( +/obj/structure/bed/maint, +/obj/structure/curtain/bounty, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Qu" = ( +/obj/structure/chair/stool/bamboo, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"QI" = ( +/obj/item/flashlight/flare/torch{ + on = 1 + }, +/turf/closed/indestructible/riveted/boss, +/area/ruin/unpowered/ash_walkers) +"QU" = ( +/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Re" = ( +/obj/structure/stone_tile/block/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"RV" = ( +/obj/machinery/smartfridge/drying_rack, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Sf" = ( +/obj/structure/stone_tile/block, +/obj/structure/stone_tile{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Sn" = ( +/obj/structure/stone_tile/slab, +/obj/structure/closet/crate/wooden, +/obj/item/seeds/ambrosia, +/obj/item/seeds/ambrosia, +/obj/item/seeds/aloe, +/obj/item/seeds/aloe, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Su" = ( +/turf/closed/indestructible/riveted/boss/see_through, +/area/ruin/unpowered/ash_walkers) +"SP" = ( +/obj/structure/stone_tile/surrounding_tile/cracked, +/obj/structure/stone_tile/center, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/stone_tile/surrounding_tile/cracked, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"SS" = ( +/obj/structure/table/wood, +/obj/item/cutting_board, +/obj/item/knife/hunting, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Tn" = ( +/obj/structure/reagent_crafting_bench, +/obj/item/forging/tongs/primitive, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"TD" = ( +/obj/effect/ash_rune, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"TH" = ( +/obj/structure/closet/crate/wooden, +/obj/item/hemostat/ashwalker, +/obj/item/retractor/ashwalker{ + pixel_y = -9 + }, +/obj/item/scalpel/ashwalker{ + pixel_y = -4 + }, +/obj/item/surgicaldrill/ashwalker, +/obj/item/circular_saw/ashwalker, +/obj/item/cautery/ashwalker, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"TJ" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/stone_tile/center, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"UD" = ( +/obj/structure/table/wood, +/obj/item/food/rootdough{ + pixel_x = 3; + pixel_y = 2 + }, +/obj/item/food/rootdough{ + pixel_x = -3 + }, +/obj/item/kitchen/rollingpin, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"UJ" = ( +/obj/structure/stone_tile/block/burnt{ + dir = 8 + }, +/obj/structure/stone_tile/block/burnt{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"UN" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/reagent_containers/cup/glass/bottle/lizardwine, +/obj/item/reagent_containers/cup/glass/trophy/bronze_cup{ + pixel_x = -7 + }, +/obj/item/reagent_containers/cup/glass/bottle{ + pixel_x = 6; + pixel_y = -2 + }, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"UO" = ( +/obj/structure/barricade/wooden, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"VA" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"VM" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Wh" = ( +/obj/structure/flora/ash/seraka, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Wl" = ( +/obj/structure/chair/stool/bamboo{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Wn" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/claymore/bone, +/obj/item/claymore/bone{ + pixel_y = 6 + }, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Wp" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/table/wood, +/obj/item/plate/oven_tray/material/fake_tin, +/obj/item/reagent_containers/cup/soup_pot/material/fake_brass{ + pixel_y = 6; + pixel_x = -3 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Wv" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"WD" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/stone_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"WN" = ( +/obj/structure/stone_tile/surrounding/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Xq" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/secateurs, +/obj/item/hatchet/wooden, +/obj/item/hatchet/wooden{ + pixel_y = 6 + }, +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"XH" = ( +/obj/structure/rack/shelf{ + icon = 'modular_skyrat/modules/mapping/icons/unique/furniture.dmi'; + icon_state = "empty_shelf_1" + }, +/obj/item/spear/bonespear, +/obj/item/spear/bonespear{ + pixel_y = 5 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"XI" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile, +/turf/open/lava/smooth/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"XJ" = ( +/obj/structure/water_source/puddle, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"XP" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/ruin/unpowered/ash_walkers) +"Yn" = ( +/obj/structure/stone_tile/surrounding/cracked{ + dir = 1 + }, +/obj/structure/stone_tile/center, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Yo" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Yx" = ( +/turf/closed/indestructible/riveted/boss, +/area/ruin/unpowered/ash_walkers) +"YM" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Zk" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/closet/xenoarch/ashwalker_version, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"Zu" = ( +/obj/item/flashlight/flare/candle/infinite, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"ZG" = ( +/obj/structure/curtain/bounty, +/obj/structure/stone_tile/block{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) +"ZI" = ( +/obj/structure/closet/crate/wooden, +/obj/item/seeds/tobacco, +/obj/item/seeds/tobacco, +/obj/item/seeds/cannabis, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/unpowered/ash_walkers) + +(1,1,1) = {" +Eh +Eh +Eh +Eh +Eh +Eh +Eh +Eh +wM +wM +wM +wM +wM +wM +wM +wM +wM +nv +nv +nv +nv +nv +nv +nv +nv +wM +wM +wM +"} +(2,1,1) = {" +Eh +Eh +Eh +Eh +Eh +DN +DN +QI +DN +DN +wM +wM +wM +wM +wM +wM +wM +nv +nv +nv +nv +nv +nv +nv +nv +wM +wM +wM +"} +(3,1,1) = {" +Eh +Eh +Eh +DN +QI +DN +tp +dl +tp +DN +DN +wM +wM +wM +wM +wM +wM +nv +nv +nv +nv +nv +nv +nv +nv +wM +wM +wM +"} +(4,1,1) = {" +Eh +Eh +DN +DN +tp +yO +Cb +dN +Yo +Wn +DN +UO +UO +UO +wM +wM +wM +DN +DN +DN +QI +DN +nv +nv +nv +nv +wM +wM +"} +(5,1,1) = {" +Eh +Eh +DN +zV +dN +lS +Wv +qD +GH +Qt +QI +tu +tu +UO +UO +DN +QI +DN +RV +Hz +Hz +DN +DN +nv +nv +nv +wM +wM +"} +(6,1,1) = {" +Eh +Eh +QI +es +dE +vH +dN +tu +Yo +uN +fP +tu +tu +tu +DN +DN +zt +kP +Yn +wi +Ea +Ac +DN +nv +nv +nv +wM +wM +"} +(7,1,1) = {" +Eh +Eh +DN +tp +WN +vg +Qu +rU +tu +vg +IF +vg +GH +jk +DN +jh +vg +vg +wu +tu +lS +UD +DN +nv +nv +nv +wM +wM +"} +(8,1,1) = {" +Eh +Eh +DN +DN +dE +WD +YM +Wl +lS +Sf +qb +tu +vg +lS +QI +za +cP +za +dN +QU +SS +pE +DN +nv +nv +nv +wM +wM +"} +(9,1,1) = {" +Eh +Eh +Eh +DN +nA +XH +aN +vg +Hf +dN +Yx +tu +vg +vg +IF +Qu +mr +gB +Wp +YM +Yo +QI +Yx +nv +nv +nv +wM +wM +"} +(10,1,1) = {" +Eh +Eh +Eh +DN +DN +QI +zE +za +VM +QI +Yx +tu +IF +Ez +vg +dE +Wl +Ez +dg +dc +iP +LR +DN +nv +nv +nv +nv +wM +"} +(11,1,1) = {" +Eh +Eh +Eh +Eh +Yx +UO +lf +DW +xo +gn +dN +IM +ym +Yo +QI +xl +KO +Yo +GS +dN +em +Ks +DN +nv +nv +nv +nv +wM +"} +(12,1,1) = {" +Eh +Eh +Eh +Eh +Yx +UO +UO +aD +tu +iW +YM +tu +lk +tu +DN +DN +fd +UN +hZ +VA +VA +NB +DN +nv +nv +nv +nv +wM +"} +(13,1,1) = {" +Eh +Eh +Eh +Eh +Eh +Yx +UO +Zk +IM +Yx +dN +tu +vg +tu +tu +DN +DN +QI +lk +IF +vg +DN +DN +nv +nv +nv +nv +wM +"} +(14,1,1) = {" +Eh +Eh +Eh +Yx +Yx +Yx +Yx +Yx +VA +YM +tu +IM +aN +vg +GH +tu +tu +Yo +za +za +uE +QI +nv +nv +nv +nv +nv +wM +"} +(15,1,1) = {" +Eh +Yx +Yx +QI +KJ +qv +LE +QI +Yx +mq +tu +tu +tu +tu +IF +vS +tu +IM +tu +tu +Yx +Yx +nv +nv +nv +nv +nv +wM +"} +(16,1,1) = {" +Yx +QI +nJ +fA +ny +wn +pI +TJ +Yx +QI +hv +tu +Go +Wv +vg +GH +YM +tu +JY +QI +Yx +nv +nv +nv +nv +nv +nv +wM +"} +(17,1,1) = {" +Yx +ko +zX +eR +SP +FD +cW +NM +XI +Su +IF +hv +vH +ws +tu +Yo +uN +tu +lS +vg +Yx +Jy +Jy +Jy +Jy +Jy +Eh +wM +"} +(18,1,1) = {" +Yx +fl +XP +XP +EV +yw +NI +Id +GG +ru +Ez +IF +vg +tu +TD +Zu +vg +vg +vg +vg +wZ +Jy +Jy +Jy +Jy +Jy +DL +wM +"} +(19,1,1) = {" +Yx +OX +nJ +eR +zU +dk +wO +Im +JC +Su +IF +gu +WD +YM +Zu +lS +Sf +tu +Mc +vg +Yx +Jy +Jy +Jy +Jy +Jy +Eh +wM +"} +(20,1,1) = {" +Yx +QI +vh +bj +zY +LV +zY +mn +Yx +QI +dN +tu +Yo +aN +vg +Hf +jy +tu +tu +QI +Yx +nv +nv +nv +nv +nv +nv +wM +"} +(21,1,1) = {" +Eh +Yx +Yx +QI +UJ +KJ +kw +QI +Yx +Ih +tu +wF +hZ +VA +vg +VA +cD +YM +tu +tu +Yx +Yx +nv +nv +nv +nv +nv +wM +"} +(22,1,1) = {" +Eh +Eh +Eh +Yx +Yx +Yx +Yx +Yx +za +dN +vS +Ez +Yx +Yx +IF +za +QI +Yx +YM +IM +tu +QI +nv +nv +nv +nv +wM +wM +"} +(23,1,1) = {" +Eh +Eh +Eh +Eh +Eh +Eh +UO +IM +tu +tu +tu +Db +QI +oH +lS +YM +Ea +vg +dc +XJ +tu +DN +DN +nv +nv +nv +wM +wM +"} +(24,1,1) = {" +Eh +Eh +Eh +Eh +Eh +Eh +UO +tu +tu +tu +IM +Ez +sN +BG +Yo +dN +lS +vg +Re +tu +tu +Cv +DN +nv +nv +nv +wM +wM +"} +(25,1,1) = {" +Eh +Eh +Eh +Eh +Eh +DN +QI +EP +EP +QI +tu +LR +iz +YM +tu +tu +Tn +Yx +dN +ct +ln +tu +DN +nv +nv +nv +wM +wM +"} +(26,1,1) = {" +Eh +Eh +Eh +Yx +DN +DN +Hz +tu +tu +ZG +tu +Ez +Yx +Gi +YM +NB +kH +QI +jx +tu +ct +tu +DN +nv +nv +nv +wM +wM +"} +(27,1,1) = {" +Eh +Eh +DN +DN +tp +TH +xY +VA +YM +ZG +tu +Yo +Yx +QI +mp +sD +Yx +Yx +Wh +tu +ct +nu +QI +nv +nv +nv +wM +wM +"} +(28,1,1) = {" +Eh +Eh +QI +sp +BG +tu +Ez +dg +dc +QI +Yx +tu +tu +Yx +Yx +QI +Yx +Br +dc +ZI +tu +tu +DN +nv +nv +nv +wM +wM +"} +(29,1,1) = {" +Eh +Eh +DN +dc +tu +tu +Yo +za +dN +Ac +DN +tu +tu +uz +tu +tu +hP +za +pt +jk +tu +DN +DN +nv +nv +nv +wM +wM +"} +(30,1,1) = {" +Eh +Eh +DN +tp +AW +dE +NB +uY +yy +Py +DN +jk +tu +tu +ln +IM +ct +tu +tu +jk +Cs +DN +wM +nv +nv +nv +wM +wM +"} +(31,1,1) = {" +Eh +Eh +DN +DN +DN +Px +un +DN +QI +DN +DN +QI +tu +lS +hZ +VA +VA +YM +ln +tu +DN +DN +wM +nv +nv +nv +wM +wM +"} +(32,1,1) = {" +Eh +Eh +Eh +Eh +DN +QI +DN +DN +Eh +Eh +Eh +Yx +DN +DN +Sn +Jx +Xq +DN +DN +QI +DN +wM +wM +nv +nv +nv +wM +wM +"} +(33,1,1) = {" +Eh +Eh +Eh +Eh +Eh +Eh +Eh +Eh +Eh +Eh +Eh +Eh +Yx +DN +DN +QI +DN +DN +wM +wM +wM +wM +nv +nv +nv +nv +wM +wM +"} diff --git a/_maps/skyrat/automapper/templates/northstar/northstar_armory.dmm b/_maps/skyrat/automapper/templates/northstar/northstar_armory.dmm index f45792c6c38434..3c8ea12baedaad 100644 --- a/_maps/skyrat/automapper/templates/northstar/northstar_armory.dmm +++ b/_maps/skyrat/automapper/templates/northstar/northstar_armory.dmm @@ -4,8 +4,8 @@ /area/template_noop) "y" = ( /obj/structure/rack/gunrack, -/obj/effect/spawner/armory_spawn/cmg, /obj/structure/window/reinforced/spawner/directional/west, +/obj/effect/spawner/armory_spawn/smg, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "F" = ( @@ -15,7 +15,7 @@ /area/station/ai_monitored/security/armory) "I" = ( /obj/effect/turf_decal/tile/red/fourcorners, -/obj/structure/closet/secure_closet/smartgun, +/obj/structure/closet/secure_closet/armory_kiboko, /turf/open/floor/iron/dark, /area/station/ai_monitored/security/armory) "O" = ( diff --git a/_maps/skyrat/automapper/templates/tramstation/tramstation_armory.dmm b/_maps/skyrat/automapper/templates/tramstation/tramstation_armory.dmm index 80ba797d1483a7..6b9b4479c1da0d 100644 --- a/_maps/skyrat/automapper/templates/tramstation/tramstation_armory.dmm +++ b/_maps/skyrat/automapper/templates/tramstation/tramstation_armory.dmm @@ -3,7 +3,7 @@ /obj/structure/window/reinforced/spawner/directional/south, /obj/structure/window/reinforced/spawner/directional/north, /obj/structure/rack/gunrack, -/obj/effect/spawner/armory_spawn/cmg, +/obj/effect/spawner/armory_spawn/smg, /turf/open/floor/iron, /area/station/ai_monitored/security/armory) "fc" = ( @@ -61,7 +61,7 @@ layer = 2.9 }, /obj/structure/window/reinforced/spawner/directional/south, -/obj/structure/closet/secure_closet/smartgun, +/obj/structure/closet/secure_closet/armory_kiboko, /turf/open/floor/iron, /area/station/ai_monitored/security/armory) "SD" = ( diff --git a/_maps/templates/holodeck_firingrange.dmm b/_maps/templates/holodeck_firingrange.dmm index 67b6cd5e0d38c1..cb727801a052dd 100644 --- a/_maps/templates/holodeck_firingrange.dmm +++ b/_maps/templates/holodeck_firingrange.dmm @@ -122,6 +122,7 @@ "N" = ( /obj/structure/rack, /obj/item/gun/energy/laser/practice, +/obj/item/gun/energy/laser/carbine/practice, /obj/item/clothing/ears/earmuffs, /obj/effect/turf_decal/tile/green/half/contrasted, /turf/open/floor/holofloor, diff --git a/_maps/templates/lazy_templates/nukie_base.dmm b/_maps/templates/lazy_templates/nukie_base.dmm index 68913efe70dbf3..d6e8dcfc6078c2 100644 --- a/_maps/templates/lazy_templates/nukie_base.dmm +++ b/_maps/templates/lazy_templates/nukie_base.dmm @@ -210,6 +210,9 @@ /obj/effect/turf_decal/siding/thinplating_new/dark{ dir = 4 }, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 8 + }, /turf/open/floor/mineral/plastitanium, /area/centcom/syndicate_mothership/control) "cT" = ( @@ -696,6 +699,16 @@ }, /turf/open/floor/plating/snowed/icemoon, /area/centcom/syndicate_mothership/control) +"hX" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/effect/turf_decal/siding/thinplating_new/dark/corner{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/centcom/syndicate_mothership/control) "ia" = ( /obj/structure/rack, /obj/effect/turf_decal/siding/thinplating_new/dark{ @@ -937,6 +950,7 @@ dir = 9 }, /obj/structure/sign/poster/contraband/gorlex_recruitment/directional/north, +/obj/effect/turf_decal/siding/thinplating_new/dark/corner, /turf/open/floor/mineral/plastitanium, /area/centcom/syndicate_mothership/control) "kU" = ( @@ -1155,6 +1169,10 @@ /obj/effect/turf_decal/stripes/full, /turf/open/floor/mineral/titanium/yellow, /area/centcom/syndicate_mothership/control) +"nF" = ( +/obj/effect/turf_decal/syndicateemblem/top/middle, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) "nH" = ( /obj/effect/turf_decal/siding/thinplating_new/dark, /obj/structure/closet/syndicate/personal, @@ -1740,6 +1758,9 @@ }, /obj/structure/extinguisher_cabinet/directional/east, /obj/structure/sign/poster/contraband/gorlex_recruitment/directional/south, +/obj/effect/turf_decal/siding/thinplating_new/dark/corner{ + dir = 1 + }, /turf/open/floor/mineral/plastitanium, /area/centcom/syndicate_mothership/control) "um" = ( @@ -1778,6 +1799,12 @@ /obj/effect/turf_decal/tile/bar/opposingcorners, /turf/open/floor/iron, /area/centcom/syndicate_mothership/control) +"ve" = ( +/obj/effect/turf_decal/syndicateemblem/top/middle{ + dir = 1 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) "vv" = ( /obj/structure/table/reinforced, /obj/item/paper/fluff/stations/centcom/disk_memo{ @@ -2042,6 +2069,9 @@ /obj/machinery/camera/autoname/directional/south{ network = list("nukie") }, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, /turf/open/floor/mineral/plastitanium, /area/centcom/syndicate_mothership/control) "zi" = ( @@ -2134,6 +2164,13 @@ }, /turf/open/misc/ice/icemoon, /area/centcom/syndicate_mothership/control) +"zZ" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/turf/open/floor/mineral/plastitanium, +/area/centcom/syndicate_mothership/control) "Ab" = ( /obj/effect/turf_decal/siding/thinplating_new/light{ dir = 8 @@ -2382,6 +2419,9 @@ dir = 10 }, /obj/structure/sign/poster/contraband/energy_swords/directional/west, +/obj/effect/turf_decal/siding/thinplating_new/dark/corner{ + dir = 4 + }, /turf/open/floor/mineral/plastitanium, /area/centcom/syndicate_mothership/control) "CX" = ( @@ -2425,6 +2465,16 @@ /obj/structure/railing, /turf/open/floor/plating/snowed/icemoon, /area/centcom/syndicate_mothership/control) +"DM" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/effect/turf_decal/siding/thinplating_new/dark/corner{ + dir = 1 + }, +/turf/open/floor/mineral/plastitanium, +/area/centcom/syndicate_mothership/control) "DY" = ( /obj/structure/table/wood/poker, /obj/machinery/light/warm/directional/north, @@ -2734,9 +2784,28 @@ }, /turf/open/floor/mineral/titanium/tiled/blue, /area/centcom/syndicate_mothership/control) +"GU" = ( +/obj/effect/turf_decal/syndicateemblem/top/right{ + dir = 1 + }, +/obj/effect/turf_decal/syndicateemblem/top/left{ + dir = 1 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) "Hc" = ( /turf/open/floor/plating/icemoon, /area/centcom/syndicate_mothership/control) +"Hm" = ( +/obj/effect/turf_decal/syndicateemblem/bottom/middle{ + dir = 8 + }, +/obj/effect/turf_decal/syndicateemblem/top/left, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 8 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) "Ho" = ( /obj/effect/light_emitter{ set_cap = 1; @@ -2972,6 +3041,9 @@ "JL" = ( /obj/machinery/light/cold/directional/south, /obj/effect/turf_decal/siding/thinplating_new/dark, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, /turf/open/floor/mineral/plastitanium, /area/centcom/syndicate_mothership/control) "JR" = ( @@ -2996,6 +3068,11 @@ /obj/effect/turf_decal/siding/purple, /turf/open/floor/mineral/plastitanium, /area/centcom/syndicate_mothership/expansion_chemicalwarfare) +"JX" = ( +/obj/effect/turf_decal/syndicateemblem/top/right, +/obj/effect/turf_decal/syndicateemblem/top/left, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) "Ka" = ( /obj/structure/chair/sofa/bench/right{ dir = 4 @@ -3408,6 +3485,9 @@ /obj/effect/turf_decal/siding/thinplating_new/dark{ dir = 8 }, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, /turf/open/floor/mineral/plastitanium, /area/centcom/syndicate_mothership/control) "Ox" = ( @@ -3438,6 +3518,16 @@ }, /turf/open/misc/asteroid/snow/icemoon, /area/centcom/syndicate_mothership/control) +"OM" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/effect/turf_decal/siding/thinplating_new/dark, +/obj/effect/turf_decal/siding/thinplating_new/dark/corner{ + dir = 8 + }, +/turf/open/floor/mineral/plastitanium, +/area/centcom/syndicate_mothership/control) "OO" = ( /obj/item/gun/energy/ionrifle, /obj/structure/rack, @@ -3833,6 +3923,14 @@ "To" = ( /turf/open/misc/asteroid/snow/icemoon, /area/centcom/syndicate_mothership/control) +"Ts" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/effect/turf_decal/siding/thinplating_new/dark, +/obj/effect/turf_decal/siding/thinplating_new/dark/corner, +/turf/open/floor/mineral/plastitanium, +/area/centcom/syndicate_mothership/control) "Tw" = ( /obj/machinery/door/airlock/hatch{ name = "Gangway" @@ -3912,6 +4010,15 @@ /turf/open/misc/asteroid/snow/airless, /area/centcom/syndicate_mothership) "TY" = ( +/obj/effect/turf_decal/syndicateemblem/bottom/middle{ + dir = 4 + }, +/obj/effect/turf_decal/syndicateemblem/top/left{ + dir = 1 + }, +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 4 + }, /turf/open/floor/mineral/plastitanium/red, /area/centcom/syndicate_mothership/control) "Un" = ( @@ -3944,6 +4051,16 @@ /obj/machinery/light/cold/directional/east, /turf/open/floor/plating, /area/centcom/syndicate_mothership/control) +"Va" = ( +/obj/effect/turf_decal/syndicateemblem/middle/left{ + dir = 8 + }, +/obj/effect/turf_decal/syndicateemblem/middle/left{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/dark, +/turf/open/floor/mineral/plastitanium/red, +/area/centcom/syndicate_mothership/control) "Vm" = ( /obj/structure/flora/rock/pile/style_random, /turf/open/misc/asteroid/snow/icemoon, @@ -3952,6 +4069,9 @@ /obj/effect/turf_decal/siding/thinplating_new/dark{ dir = 5 }, +/obj/effect/turf_decal/siding/thinplating_new/dark/corner{ + dir = 8 + }, /turf/open/floor/mineral/plastitanium, /area/centcom/syndicate_mothership/control) "VC" = ( @@ -4340,6 +4460,13 @@ /obj/effect/turf_decal/tile/bar/opposingcorners, /turf/open/floor/iron, /area/centcom/syndicate_mothership/control) +"ZI" = ( +/obj/effect/turf_decal/siding/thinplating_new/dark{ + dir = 1 + }, +/obj/effect/turf_decal/siding/thinplating_new/dark, +/turf/open/floor/mineral/plastitanium, +/area/centcom/syndicate_mothership/control) "ZL" = ( /obj/structure/flora/grass/both/style_random, /obj/structure/flora/rock/icy/style_random, @@ -5252,9 +5379,9 @@ yf yf na PD -zE -TY -lt +OM +Hm +DM ws Wz KL @@ -5354,9 +5481,9 @@ Ge Ge Ge xf -zE -TY -lt +ZI +nF +zZ ZO JJ mb @@ -5456,8 +5583,8 @@ Jf eu hN PD -zE -TY +ZI +JX yP RD RD @@ -5558,8 +5685,8 @@ nQ nQ nQ nQ -zE -TY +ZI +Va JL RD SD @@ -5660,9 +5787,9 @@ yK Ht In VK -zE -TY -lt +ZI +GU +zZ FM wM ee @@ -5762,9 +5889,9 @@ Zg pU lt XQ -zE -TY -lt +ZI +ve +zZ Lu ae ae @@ -5864,9 +5991,9 @@ rS iH Bn VK -zE +Ts TY -lt +hX FM iL mB diff --git a/_maps/virtual_domains/README.md b/_maps/virtual_domains/README.md new file mode 100644 index 00000000000000..a02d43e1575eeb --- /dev/null +++ b/_maps/virtual_domains/README.md @@ -0,0 +1,32 @@ +# Making new virtual domains + +## From scratch + +1. Create a new map using TGM format. It can be any size, but please, consider limiting to 75x75 max. +2. Ensure that the map has ONE tile marked with the safehouse bottom left landmark. If you're using modular safehouses, it will need to be a 7x6 area. +4. Provide a way for players to enter your new map via the north door, which is 4th tile over. +5. Enclose your area with a single wall binary closed wall. + +## From an existing map + +1. Create a new map using the existing map's size - give yourself enough room to enclose it with a binary wall. There's no need for any space outside of it, so ensure that it fits and is enclosed, nothing outside of this. +2. Copy and paste the existing map into it. +3. Find an accessible area for a safehouse, 7x6 - or with a custom, just ensure the necessary landmarks are placed. +4. Place a bottom left safehouse landmark somewhere on the map to load the safehouse. + +## BOTH. +1. You need to have one (1) way that the encrypted cache can spawn. This can be from a mob drop, a landmark (place a few, it'll pick one), or a signable landmark if you have a points system. +2. Make note of the size of the map. Make sure this is in the dm file. +3. Create the dm file that defines the map qualities. Examples are in the bitrunning file. + +### Notes + +You shouldn't need to fully enclose your map in 15 tiles of binary filler. Using one solid wall should do the trick. + +Adding some open tile padding around the safehouse is a good touch. About 7 tiles West/East for the visual effect of a larger map. + +If you want to add prep gear, you can do so within the safehouse's area as long you don't overlap with goal turfs or exit spawners. The top left corner is a good spot for this, with respect for the walls, therefore [1, 1], [1, 2], [1, 3] + +You can also create safehouses if you find yourself needing the same gear over and over again. There is a readme for that as well. + +Boss zones should give players pretty ample space, I've been using a 23x23 minimum area. diff --git a/_maps/virtual_domains/ash_drake.dmm b/_maps/virtual_domains/ash_drake.dmm new file mode 100644 index 00000000000000..50fbac8696ab39 --- /dev/null +++ b/_maps/virtual_domains/ash_drake.dmm @@ -0,0 +1,1750 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"c" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"e" = ( +/obj/structure/marker_beacon/cerulean, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"f" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"g" = ( +/obj/structure/marker_beacon/lime, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"h" = ( +/obj/machinery/light/small/blacklight/directional/south, +/obj/effect/baseturf_helper/virtual_domain, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/virtual_domain/powered) +"i" = ( +/obj/structure/marker_beacon/jade, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"j" = ( +/obj/structure/marker_beacon/teal, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"l" = ( +/obj/structure/marker_beacon/bronze, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"q" = ( +/mob/living/simple_animal/hostile/megafauna/dragon/virtual_domain, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"s" = ( +/turf/closed/mineral/volcanic/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"u" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"v" = ( +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"G" = ( +/obj/structure/marker_beacon/purple, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"J" = ( +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"L" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"P" = ( +/obj/structure/marker_beacon/fuchsia, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Z" = ( +/obj/effect/mob_spawn/corpse/human/miner, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) + +(1,1,1) = {" +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +u +"} +(2,1,1) = {" +v +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +v +"} +(3,1,1) = {" +v +s +s +s +s +J +J +s +s +J +J +s +s +J +J +J +J +s +s +s +J +J +J +s +s +s +s +s +s +s +s +s +s +J +J +s +s +s +J +J +s +s +J +J +s +v +"} +(4,1,1) = {" +v +s +s +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +a +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +s +v +"} +(5,1,1) = {" +v +s +s +J +a +J +J +J +J +a +J +J +J +J +a +a +J +J +J +J +J +a +a +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +s +s +v +"} +(6,1,1) = {" +v +s +s +J +a +J +J +a +a +a +a +a +a +a +a +a +a +a +a +J +a +a +a +a +a +J +J +J +a +a +J +J +J +a +a +J +a +J +a +a +J +J +J +s +s +v +"} +(7,1,1) = {" +v +s +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +J +s +v +"} +(8,1,1) = {" +v +s +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +s +v +"} +(9,1,1) = {" +v +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +i +a +a +a +a +a +Z +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(10,1,1) = {" +v +s +J +J +J +a +a +a +a +a +a +G +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(11,1,1) = {" +v +s +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(12,1,1) = {" +v +s +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +J +s +v +"} +(13,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +a +a +g +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(14,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(15,1,1) = {" +v +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +h +c +c +c +c +c +L +a +a +J +J +s +v +"} +(16,1,1) = {" +v +s +J +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +c +c +c +c +c +c +a +a +J +J +s +v +"} +(17,1,1) = {" +v +s +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +l +a +a +c +c +c +c +c +c +a +a +J +J +s +v +"} +(18,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +q +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +c +c +c +c +c +c +a +J +J +s +s +v +"} +(19,1,1) = {" +v +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +c +c +c +c +c +c +a +a +J +J +s +v +"} +(20,1,1) = {" +v +s +J +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +c +c +c +c +c +c +a +a +J +J +s +v +"} +(21,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +e +a +a +a +a +a +a +a +a +a +a +a +a +h +c +c +c +c +c +f +a +a +J +s +s +v +"} +(22,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +s +s +v +"} +(23,1,1) = {" +v +s +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +s +s +v +"} +(24,1,1) = {" +v +s +J +J +a +a +a +a +j +a +a +a +a +a +P +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(25,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +J +s +v +"} +(26,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(27,1,1) = {" +v +s +s +J +J +J +a +a +a +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +j +a +a +a +a +a +a +a +J +J +s +v +"} +(28,1,1) = {" +v +s +J +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +J +s +v +"} +(29,1,1) = {" +v +s +J +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +s +v +"} +(30,1,1) = {" +v +s +s +J +J +J +J +a +a +J +J +J +a +a +a +a +J +J +J +a +a +a +J +J +J +a +a +a +J +J +a +a +a +a +a +a +J +J +a +a +a +J +J +s +s +v +"} +(31,1,1) = {" +v +s +s +a +J +J +J +J +J +J +J +J +J +a +a +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +a +a +a +J +J +J +J +J +J +J +J +J +s +v +"} +(32,1,1) = {" +v +s +s +a +J +J +J +J +J +J +J +J +J +J +J +J +J +a +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +s +v +"} +(33,1,1) = {" +v +s +s +s +s +s +J +J +s +s +s +s +J +J +s +s +s +s +s +s +J +J +s +s +s +s +J +J +s +s +s +s +J +J +J +s +s +s +s +s +s +J +J +J +s +v +"} +(34,1,1) = {" +v +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +v +"} +(35,1,1) = {" +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +"} diff --git a/_maps/virtual_domains/beach_bar.dmm b/_maps/virtual_domains/beach_bar.dmm new file mode 100644 index 00000000000000..29fe04d82837f3 --- /dev/null +++ b/_maps/virtual_domains/beach_bar.dmm @@ -0,0 +1,2932 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"ab" = ( +/obj/machinery/vending/cigarette/beach, +/obj/effect/turf_decal/sand, +/obj/structure/sign/poster/contraband/have_a_puff/directional/west, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"ag" = ( +/turf/open/floor/carpet/red, +/area/virtual_domain/powered) +"as" = ( +/obj/structure/closet/crate/bin, +/obj/item/tank/internals/emergency_oxygen, +/obj/item/trash/candy, +/obj/item/toy/talking/owl, +/obj/effect/turf_decal/sand, +/obj/machinery/light/directional/west, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"aw" = ( +/obj/machinery/grill, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"aE" = ( +/turf/open/floor/pod/light, +/area/virtual_domain/powered) +"aZ" = ( +/obj/machinery/light/small/directional/east, +/obj/structure/closet/crate{ + name = "fuel crate" + }, +/obj/item/stack/sheet/mineral/coal/ten, +/obj/item/stack/sheet/mineral/coal/ten, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"bf" = ( +/mob/living/basic/crab{ + name = "Jonny" + }, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"bC" = ( +/obj/effect/turf_decal/sand, +/mob/living/basic/crab{ + name = "James" + }, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"bM" = ( +/mob/living/basic/crab{ + name = "Jon" + }, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"bQ" = ( +/obj/structure/fluff/beach_umbrella/cap, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"bS" = ( +/obj/machinery/chem_master/condimaster{ + name = "CondiMaster Neo"; + pixel_x = -4 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"cb" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/pill/lsd, +/obj/item/reagent_containers/pill/lsd, +/obj/item/reagent_containers/pill/lsd, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"cv" = ( +/turf/open/floor/carpet/royalblue, +/area/virtual_domain/powered) +"cz" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/jukebox, +/obj/item/coin/gold, +/turf/open/floor/sepia, +/area/virtual_domain/powered) +"cG" = ( +/obj/structure/flora/bush/sparsegrass/style_random, +/turf/open/water/beach, +/area/virtual_domain/powered) +"db" = ( +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/vending_refill/cigarette, +/obj/item/vending_refill/boozeomat, +/obj/structure/closet/secure_closet{ + icon_state = "cabinet"; + name = "booze storage"; + req_access = list("bar") + }, +/obj/item/storage/backpack/duffelbag, +/obj/item/etherealballdeployer, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/colocup, +/obj/item/reagent_containers/cup/glass/colocup, +/obj/item/reagent_containers/cup/glass/colocup, +/obj/item/reagent_containers/cup/glass/colocup, +/obj/item/reagent_containers/cup/glass/colocup, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"di" = ( +/obj/machinery/vending/boozeomat, +/obj/effect/mapping_helpers/atom_injector/obj_flag{ + inject_flags = 1; + target_type = /obj/machinery/vending/boozeomat + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"dj" = ( +/turf/open/misc/beach/coast{ + dir = 1 + }, +/area/virtual_domain/powered) +"dx" = ( +/obj/effect/turf_decal/sand, +/obj/effect/turf_decal/stripes/asteroid/line{ + dir = 8 + }, +/turf/open/floor/sepia, +/area/virtual_domain/powered) +"dI" = ( +/obj/machinery/light/directional/south, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"dZ" = ( +/obj/structure/bookcase/random/reference, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"ed" = ( +/obj/machinery/atmospherics/components/tank/air{ + dir = 1 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"er" = ( +/obj/structure/noticeboard/staff, +/turf/closed/wall/mineral/wood/nonmetal, +/area/virtual_domain/powered) +"fc" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/pill/happy, +/obj/item/toy/figure/bartender{ + pixel_x = -8; + pixel_y = -1 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass/filled/virtual_domain{ + pixel_y = 8; + pixel_x = 5 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"fr" = ( +/obj/item/melee/skateboard/hoverboard, +/obj/machinery/light/directional/west, +/turf/open/floor/pod/light, +/area/virtual_domain/powered) +"gh" = ( +/obj/structure/flora/bush/stalky/style_random, +/obj/structure/flora/bush/sparsegrass/style_random, +/turf/open/water/beach, +/area/virtual_domain/powered) +"gl" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"gJ" = ( +/obj/structure/railing{ + dir = 8 + }, +/turf/open/misc/beach/coast{ + dir = 4 + }, +/area/virtual_domain/powered) +"hk" = ( +/obj/structure/reagent_dispensers/watertank, +/turf/open/floor/pod/light, +/area/virtual_domain/powered) +"hE" = ( +/obj/structure/sign/departments/restroom/directional/east, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"hG" = ( +/obj/machinery/door/airlock/sandstone{ + name = "Surfer Shack 1" + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"iz" = ( +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"iR" = ( +/obj/structure/table, +/obj/item/book/manual/wiki/barman_recipes, +/obj/item/reagent_containers/cup/glass/shaker, +/obj/item/reagent_containers/cup/rag, +/obj/machinery/light/small/directional/west, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"jc" = ( +/turf/open/floor/iron/stairs/right, +/area/virtual_domain/powered) +"jg" = ( +/obj/machinery/vending/hydronutrients, +/turf/open/floor/iron/grimy, +/area/virtual_domain/powered) +"jl" = ( +/obj/structure/flora/rock/pile/jungle/style_random, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"jy" = ( +/obj/effect/turf_decal/sand{ + density = 1 + }, +/obj/effect/decal/fakelattice, +/turf/open/floor/pod/light{ + density = 1 + }, +/area/virtual_domain/powered) +"ke" = ( +/obj/structure/marker_beacon/bronze, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"kn" = ( +/obj/effect/turf_decal/sand, +/obj/effect/turf_decal/stripes/asteroid/line{ + dir = 8 + }, +/obj/structure/chair/stool/bar/directional/west, +/turf/open/floor/sepia, +/area/virtual_domain/powered) +"kv" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"kG" = ( +/obj/structure/table, +/obj/machinery/reagentgrinder, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"kK" = ( +/obj/structure/mirror/directional/west, +/obj/structure/sink/kitchen/directional/south, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"kT" = ( +/obj/structure/chair/stool/bar/directional/south, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"lq" = ( +/obj/item/melee/skateboard/hoverboard, +/turf/open/floor/pod/light, +/area/virtual_domain/powered) +"lB" = ( +/obj/item/toy/seashell, +/obj/effect/turf_decal/sand, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"lS" = ( +/turf/open/floor/light/colour_cycle/dancefloor_a, +/area/virtual_domain/powered) +"ml" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"mq" = ( +/obj/structure/closet/secure_closet/freezer/kitchen/all_access, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"mG" = ( +/obj/structure/easel, +/obj/item/canvas/twentythree_twentythree, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"mP" = ( +/turf/open/misc/beach/coast/corner{ + dir = 1 + }, +/area/virtual_domain/powered) +"mX" = ( +/obj/structure/closet/secure_closet/freezer/meat/all_access, +/obj/item/food/meat/rawbacon, +/obj/item/food/meat/rawbacon, +/obj/item/food/meat/rawcutlet, +/obj/item/food/meat/rawcutlet, +/obj/item/food/meat/slab/rawcrab, +/obj/item/food/meat/slab/rawcrab, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"nP" = ( +/obj/item/stack/sheet/iron/fifty, +/obj/effect/mapping_helpers/burnt_floor, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"oE" = ( +/obj/structure/railing/corner{ + dir = 1 + }, +/obj/machinery/light/directional/south, +/turf/open/misc/beach/coast/corner{ + dir = 8 + }, +/area/virtual_domain/powered) +"oP" = ( +/obj/structure/table/wood, +/obj/machinery/reagentgrinder, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"pr" = ( +/turf/template_noop, +/area/template_noop) +"pC" = ( +/obj/machinery/computer/arcade/battle, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"pT" = ( +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"pZ" = ( +/obj/machinery/light/directional/south, +/turf/open/misc/beach/coast{ + dir = 1 + }, +/area/virtual_domain/powered) +"qc" = ( +/obj/structure/extinguisher_cabinet/directional/south, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"qg" = ( +/obj/structure/sign/poster/contraband/space_up/directional/west, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"qR" = ( +/obj/effect/spawner/structure/window, +/obj/structure/curtain, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"qW" = ( +/obj/item/melee/skateboard/hoverboard, +/mob/living/basic/chicken{ + name = "Chicken Joe" + }, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"rc" = ( +/obj/machinery/light/directional/east, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"ri" = ( +/obj/structure/sign/poster/official/fruit_bowl, +/turf/closed/wall/mineral/wood/nonmetal, +/area/virtual_domain/powered) +"rm" = ( +/obj/item/storage/crayons, +/obj/structure/closet/crate/wooden, +/obj/item/canvas/twentythree_twentythree, +/obj/item/canvas/twentythree_twentythree, +/obj/item/canvas/twentythree_twentythree, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"rT" = ( +/obj/item/toy/seashell, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"sT" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"tE" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Resort Casino" + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"tF" = ( +/obj/structure/extinguisher_cabinet/directional/east, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"tZ" = ( +/obj/structure/toilet, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"uc" = ( +/obj/machinery/light/small/directional/east, +/obj/machinery/light/small/directional/east, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/virtual_domain/powered) +"ug" = ( +/obj/structure/closet/secure_closet{ + icon_state = "cabinet"; + name = "bartender's closet"; + req_access = list("bar") + }, +/obj/item/clothing/shoes/sandal{ + desc = "A very fashionable pair of flip-flops."; + name = "flip-flops" + }, +/obj/item/clothing/neck/beads, +/obj/item/clothing/glasses/sunglasses/reagent, +/obj/item/clothing/suit/costume/hawaiian, +/obj/machinery/light/small/directional/east, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"uk" = ( +/obj/structure/closet/crate/hydroponics, +/obj/item/shovel/spade, +/obj/item/reagent_containers/cup/bucket, +/obj/item/cultivator, +/turf/open/floor/iron/grimy, +/area/virtual_domain/powered) +"uq" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/cup/glass/drinkingglass/filled/virtual_domain, +/obj/item/reagent_containers/cup/glass/drinkingglass/filled/virtual_domain{ + pixel_x = -4; + pixel_y = 8 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"uU" = ( +/obj/effect/turf_decal/sand, +/turf/open/floor/sepia, +/area/virtual_domain/powered) +"uV" = ( +/obj/structure/flora/coconuts, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"ve" = ( +/obj/item/toy/dodgeball, +/obj/item/toy/dodgeball, +/obj/item/toy/dodgeball, +/obj/item/toy/dodgeball, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"vp" = ( +/obj/machinery/light/directional/east, +/obj/structure/chair/stool/bar/directional/south, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"vq" = ( +/obj/machinery/oven/range, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"vv" = ( +/obj/structure/chair/stool/directional/south, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"vN" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/pill/morphine, +/obj/item/reagent_containers/pill/morphine, +/obj/item/reagent_containers/pill/morphine, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"vT" = ( +/obj/structure/railing{ + dir = 8 + }, +/turf/open/misc/beach/coast/corner, +/area/virtual_domain/powered) +"wb" = ( +/obj/structure/closet/crate/freezer{ + name = "Cooler" + }, +/obj/item/reagent_containers/cup/glass/ice, +/obj/item/reagent_containers/cup/glass/colocup, +/obj/item/reagent_containers/cup/glass/colocup, +/obj/item/reagent_containers/cup/glass/bottle/beer{ + desc = "Beer advertised to be the best in space."; + name = "Masterbrand Beer" + }, +/obj/item/reagent_containers/cup/glass/bottle/beer{ + desc = "Beer advertised to be the best in space."; + name = "Masterbrand Beer" + }, +/obj/item/reagent_containers/cup/glass/bottle/beer{ + desc = "Beer advertised to be the best in space."; + name = "Masterbrand Beer" + }, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/obj/item/reagent_containers/cup/glass/bottle/beer/light, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"wD" = ( +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"xb" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"xk" = ( +/obj/structure/table/wood/poker, +/obj/item/storage/dice, +/obj/item/stack/spacecash/c1000, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"xq" = ( +/obj/structure/window/reinforced/spawner/directional/west, +/obj/structure/window/reinforced/spawner/directional/south, +/obj/item/megaphone, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"xw" = ( +/turf/open/floor/pod/dark, +/area/virtual_domain/powered) +"xJ" = ( +/obj/structure/closet/cabinet, +/obj/item/storage/backpack/duffelbag, +/obj/item/clothing/under/shorts/blue, +/obj/item/clothing/shoes/sandal{ + desc = "A very fashionable pair of flip-flops."; + name = "flip-flops" + }, +/obj/item/clothing/glasses/sunglasses, +/obj/item/clothing/neck/beads, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"xR" = ( +/obj/structure/window/reinforced/spawner/directional/east, +/obj/structure/window/reinforced/spawner/directional/north{ + layer = 2.9 + }, +/obj/structure/chair/stool/directional/south, +/obj/item/storage/backpack/duffelbag, +/obj/item/clothing/under/shorts/red, +/obj/item/clothing/glasses/sunglasses, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"xW" = ( +/turf/open/space/basic, +/area/space) +"ya" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/pill/zoom, +/obj/item/reagent_containers/pill/zoom, +/obj/item/reagent_containers/pill/zoom, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"yi" = ( +/obj/structure/sink/kitchen/directional/west{ + desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; + name = "old sink" + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"yl" = ( +/obj/item/reagent_containers/cup/glass/colocup{ + pixel_x = -7; + pixel_y = -2 + }, +/obj/item/reagent_containers/cup/glass/colocup{ + pixel_x = 5; + pixel_y = 6 + }, +/obj/item/reagent_containers/cup/glass/bottle/rum{ + pixel_x = 4; + pixel_y = -3 + }, +/turf/open/floor/carpet/red, +/area/virtual_domain/powered) +"ys" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/light/directional/east, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"yv" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/food_cart, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"yB" = ( +/obj/item/instrument/guitar, +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"yU" = ( +/obj/structure/sign/warning/gas_mask/directional/north, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"yX" = ( +/obj/structure/chair/stool/bar/directional/south, +/turf/open/floor/carpet/red, +/area/virtual_domain/powered) +"zn" = ( +/obj/machinery/light/directional/east, +/turf/open/misc/beach/coast{ + dir = 8 + }, +/area/virtual_domain/powered) +"zw" = ( +/obj/structure/punching_bag, +/turf/open/floor/pod/dark, +/area/virtual_domain/powered) +"zI" = ( +/obj/structure/marker_beacon/indigo, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"zU" = ( +/obj/structure/flora/rock/pile/style_random, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Aa" = ( +/obj/effect/turf_decal/sand, +/obj/effect/turf_decal/stripes/asteroid/line{ + dir = 8 + }, +/obj/machinery/light/directional/west, +/turf/open/floor/sepia, +/area/virtual_domain/powered) +"Ae" = ( +/obj/structure/chair, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Al" = ( +/turf/closed/mineral/random/volcanic, +/area/lavaland/surface/outdoors/virtual_domain) +"An" = ( +/obj/structure/marker_beacon/yellow, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Au" = ( +/obj/structure/fluff/beach_umbrella/science, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"AI" = ( +/obj/structure/table/reinforced, +/obj/machinery/reagentgrinder, +/turf/open/floor/pod/light, +/area/virtual_domain/powered) +"AP" = ( +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade{ + dir = 1 + }, +/obj/structure/table/wood, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Br" = ( +/obj/structure/table/wood/poker, +/obj/item/toy/cards/deck/cas{ + pixel_x = -6 + }, +/obj/item/toy/cards/deck/cas/black{ + pixel_x = -6; + pixel_y = 2 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Bu" = ( +/turf/open/misc/beach/coast{ + dir = 8 + }, +/area/virtual_domain/powered) +"Bw" = ( +/obj/structure/flora/bush/sparsegrass/style_random, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"BD" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/condiment/saltshaker, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"BJ" = ( +/obj/structure/table/wood/poker, +/obj/item/toy/cards/deck, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"BM" = ( +/turf/closed/wall/mineral/wood/nonmetal, +/area/virtual_domain/powered) +"BQ" = ( +/obj/machinery/seed_extractor, +/turf/open/floor/pod/light, +/area/virtual_domain/powered) +"Cb" = ( +/obj/machinery/light/directional/north, +/mob/living/basic/crab{ + name = "Eddie" + }, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Cv" = ( +/obj/machinery/hydroponics/constructable, +/turf/open/floor/iron/grimy, +/area/virtual_domain/powered) +"CA" = ( +/obj/structure/window/reinforced/spawner/directional/east, +/obj/effect/mob_spawn/ghost_role/human/beach/lifeguard, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"CO" = ( +/obj/machinery/vending/dinnerware, +/obj/machinery/light/directional/east, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Db" = ( +/obj/machinery/barsign/all_access, +/turf/closed/wall/mineral/wood/nonmetal, +/area/virtual_domain/powered) +"Ds" = ( +/obj/machinery/door/airlock/public/glass{ + name = "Resort Lobby" + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Dt" = ( +/obj/machinery/light/directional/east, +/obj/effect/turf_decal/sand, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"DL" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/wall/mineral/sandstone, +/area/virtual_domain/powered) +"Em" = ( +/obj/item/reagent_containers/condiment/enzyme{ + layer = 5 + }, +/obj/item/reagent_containers/cup/beaker{ + pixel_x = 5 + }, +/obj/structure/table, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Et" = ( +/obj/machinery/light/small/directional/east, +/obj/effect/mapping_helpers/burnt_floor, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Ev" = ( +/obj/structure/reagent_dispensers/beerkeg, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"EC" = ( +/obj/structure/sign/warning/gas_mask/directional/west, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"EP" = ( +/obj/machinery/light/directional/north, +/obj/machinery/washing_machine, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Fn" = ( +/turf/closed/wall/mineral/sandstone, +/area/virtual_domain/powered) +"FM" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"FQ" = ( +/obj/structure/table/reinforced, +/obj/item/secateurs, +/obj/item/reagent_containers/cup/bottle/nutrient/ez, +/turf/open/floor/pod/light, +/area/virtual_domain/powered) +"FS" = ( +/obj/effect/turf_decal/sand, +/obj/structure/sign/warning/no_smoking/circle/directional/east, +/obj/machinery/light/directional/east, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"FY" = ( +/obj/structure/mineral_door/wood, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Gh" = ( +/obj/effect/turf_decal/sand, +/obj/structure/sign/poster/contraband/starkist/directional/north, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Gz" = ( +/obj/structure/flora/tree/palm, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"GA" = ( +/obj/structure/window/reinforced/spawner/directional/north, +/obj/structure/window/reinforced/spawner/directional/west, +/obj/item/bikehorn/airhorn, +/obj/structure/table/wood, +/obj/item/storage/medkit/regular, +/obj/item/storage/medkit/brute, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Hs" = ( +/obj/machinery/shower/directional/west, +/turf/open/floor/iron/white, +/area/virtual_domain/powered) +"HF" = ( +/obj/machinery/deepfryer, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Ia" = ( +/obj/structure/urinal/directional/north, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Ii" = ( +/obj/machinery/light/directional/west, +/turf/open/floor/iron/stairs/left, +/area/virtual_domain/powered) +"Ir" = ( +/obj/machinery/vending/cola, +/obj/effect/turf_decal/sand, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Iv" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/condiment/peppermill, +/obj/item/reagent_containers/condiment/soysauce, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"IH" = ( +/obj/item/toy/beach_ball, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"IM" = ( +/obj/machinery/hydroponics/constructable, +/obj/machinery/light/directional/east, +/turf/open/floor/iron/grimy, +/area/virtual_domain/powered) +"IP" = ( +/obj/machinery/vending/snack, +/obj/effect/turf_decal/sand, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Jt" = ( +/obj/item/reagent_containers/cup/glass/bottle/beer, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"JC" = ( +/obj/structure/fluff/beach_umbrella/engine, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"JE" = ( +/obj/structure/closet/secure_closet/freezer/kitchen/all_access, +/obj/item/reagent_containers/condiment/milk, +/obj/item/reagent_containers/condiment/mayonnaise, +/obj/item/reagent_containers/condiment/flour, +/obj/item/reagent_containers/condiment/flour, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"JY" = ( +/obj/structure/flora/rock/style_random, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Kd" = ( +/obj/structure/sign/warning/secure_area, +/turf/closed/wall/mineral/sandstone, +/area/virtual_domain/powered) +"KH" = ( +/obj/structure/mineral_door/wood{ + name = "Croupier's Booth" + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"KZ" = ( +/obj/structure/flora/bush/stalky/style_random, +/turf/open/water/beach, +/area/virtual_domain/powered) +"LD" = ( +/turf/open/floor/plating, +/area/virtual_domain/powered) +"LW" = ( +/obj/item/storage/cans/sixbeer, +/turf/open/floor/carpet/orange, +/area/virtual_domain/powered) +"Mp" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/cup/glass/drinkingglass/filled/virtual_domain{ + pixel_y = 7; + pixel_x = 4 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass/filled/virtual_domain, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Mw" = ( +/obj/structure/chair/sofa/right/brown, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Mz" = ( +/obj/structure/chair/sofa/left/brown, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Nr" = ( +/obj/machinery/light/directional/north, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Nw" = ( +/obj/item/bedsheet/dorms{ + dir = 4 + }, +/obj/structure/bed{ + dir = 4 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"NM" = ( +/obj/structure/closet/crate/hydroponics, +/obj/item/food/grown/ambrosia/vulgaris, +/obj/item/food/grown/ambrosia/vulgaris, +/obj/item/food/grown/ambrosia/vulgaris, +/obj/item/food/grown/ambrosia/vulgaris, +/obj/item/food/grown/ambrosia/vulgaris, +/obj/item/food/grown/ambrosia/vulgaris, +/obj/item/food/grown/ambrosia/vulgaris, +/obj/item/food/grown/ambrosia/vulgaris, +/obj/item/food/grown/ambrosia/vulgaris, +/obj/item/food/grown/ambrosia/vulgaris, +/turf/open/floor/iron/grimy, +/area/virtual_domain/powered) +"NX" = ( +/obj/effect/landmark/bitrunning/loot_signal, +/turf/open/floor/light/colour_cycle/dancefloor_a, +/area/virtual_domain/powered) +"OE" = ( +/obj/effect/mob_spawn/ghost_role/human/beach{ + dir = 4 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"OK" = ( +/obj/structure/sign/warning/gas_mask/directional/north, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"OR" = ( +/obj/machinery/light/directional/south, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"OW" = ( +/obj/structure/sink/kitchen/directional/east{ + desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; + name = "old sink" + }, +/turf/open/floor/pod/light, +/area/virtual_domain/powered) +"OZ" = ( +/obj/structure/marker_beacon/teal, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Pc" = ( +/obj/structure/chair/wood, +/obj/machinery/light/directional/west, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Pg" = ( +/obj/structure/sign/poster/official/high_class_martini/directional/west, +/obj/effect/mob_spawn/ghost_role/human/bartender{ + dir = 4 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"PM" = ( +/obj/machinery/door/airlock/external/ruin, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Qb" = ( +/obj/machinery/griddle, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Qu" = ( +/obj/structure/curtain, +/turf/open/floor/iron/white, +/area/virtual_domain/powered) +"QP" = ( +/obj/structure/extinguisher_cabinet/directional/north, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"QX" = ( +/obj/machinery/chem_dispenser/drinks/fullupgrade{ + dir = 1 + }, +/obj/structure/table/wood, +/obj/machinery/light/small/directional/east, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Rx" = ( +/turf/open/floor/iron/stairs/medium, +/area/virtual_domain/powered) +"RL" = ( +/obj/structure/closet/cabinet, +/obj/item/storage/backpack/duffelbag, +/obj/item/clothing/under/shorts/purple, +/obj/item/clothing/shoes/cookflops{ + desc = "A very fashionable pair of flip flops."; + name = "flip-flops" + }, +/obj/item/clothing/glasses/sunglasses/big, +/obj/item/clothing/neck/beads, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Sg" = ( +/obj/structure/flora/coconuts, +/obj/machinery/light/directional/north, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"SB" = ( +/obj/machinery/door/airlock/sandstone{ + name = "Resort Bathroom" + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"SD" = ( +/obj/machinery/door/airlock/sandstone{ + name = "Bar Access" + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"SY" = ( +/obj/machinery/door/airlock/sandstone{ + name = "Surfer Shack 2" + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"TG" = ( +/turf/open/floor/wood, +/area/virtual_domain/powered) +"TJ" = ( +/obj/structure/fluff/beach_umbrella/security, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"TX" = ( +/obj/structure/sign/poster/contraband/ambrosia_vulgaris/directional/north, +/turf/open/floor/iron/grimy, +/area/virtual_domain/powered) +"Ud" = ( +/obj/effect/turf_decal/sand, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Uh" = ( +/turf/open/floor/iron/stairs/old, +/area/virtual_domain/powered) +"Uq" = ( +/obj/structure/weightmachine/weightlifter, +/turf/open/floor/pod/dark, +/area/virtual_domain/powered) +"UU" = ( +/obj/structure/flora/bush/large/style_random, +/obj/structure/flora/bush/jungle/a/style_random, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Ve" = ( +/obj/machinery/processor, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"VA" = ( +/obj/machinery/computer/slot_machine, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"VH" = ( +/obj/machinery/light/directional/west, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"VX" = ( +/obj/structure/flora/bush/large/style_random, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"We" = ( +/obj/structure/table/wood, +/obj/item/book/manual/wiki/cooking_to_serve_man, +/obj/item/clothing/suit/apron/chef, +/obj/item/clothing/head/utility/chefhat, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Wg" = ( +/obj/structure/dresser, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Ww" = ( +/turf/open/water/beach, +/area/virtual_domain/powered) +"WL" = ( +/obj/machinery/light/directional/north, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"WO" = ( +/obj/structure/flora/bush/jungle/a/style_random, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"WW" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/icecream_vat, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"WX" = ( +/obj/item/toy/plush/lizard_plushie/green{ + name = "Soaks-The-Rays" + }, +/turf/open/floor/carpet/orange, +/area/virtual_domain/powered) +"Xt" = ( +/turf/open/misc/beach/coast/corner{ + dir = 4 + }, +/area/virtual_domain/powered) +"Xv" = ( +/obj/structure/table/wood, +/obj/structure/bedsheetbin, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"XL" = ( +/obj/machinery/light/directional/east, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"XM" = ( +/turf/open/misc/beach/coast, +/area/virtual_domain/powered) +"XP" = ( +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"XT" = ( +/obj/effect/turf_decal/sand, +/obj/structure/sign/departments/botany/directional/south, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Yi" = ( +/obj/structure/flora/bush/sparsegrass/style_random, +/obj/item/toy/seashell, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Yq" = ( +/obj/machinery/portable_atmospherics/canister/air, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"YI" = ( +/obj/machinery/door/airlock/maintenance{ + name = "Supply Room" + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"YJ" = ( +/turf/open/floor/carpet/purple, +/area/virtual_domain/powered) +"YN" = ( +/obj/effect/turf_decal/sand, +/obj/machinery/light/directional/west, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Zb" = ( +/obj/structure/sign/poster/official/cohiba_robusto_ad/directional/west, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Zd" = ( +/obj/structure/sign/poster/contraband/space_cola/directional/north, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Zg" = ( +/obj/structure/table, +/obj/machinery/microwave, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Zt" = ( +/obj/structure/table/wood, +/obj/item/reagent_containers/pill/morphine, +/obj/item/storage/fancy/donut_box, +/turf/open/floor/wood, +/area/virtual_domain/powered) + +(1,1,1) = {" +pr +pr +pr +pr +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +kv +"} +(2,1,1) = {" +pr +pr +pr +pr +iz +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +iz +"} +(3,1,1) = {" +pr +pr +pr +pr +iz +Al +gl +gl +gl +gl +gl +Al +Al +gl +gl +gl +gl +gl +Al +Al +gl +gl +gl +Al +gl +gl +gl +gl +Al +Al +gl +gl +gl +Al +Al +gl +gl +gl +gl +Al +iz +"} +(4,1,1) = {" +pr +pr +pr +pr +iz +Al +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +Al +iz +"} +(5,1,1) = {" +pr +pr +pr +pr +iz +Al +gl +gl +gl +gl +gl +gl +gl +gl +gl +zI +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +Al +iz +"} +(6,1,1) = {" +pr +pr +pr +pr +iz +Al +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +OZ +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +Al +iz +"} +(7,1,1) = {" +pr +pr +pr +pr +iz +Al +gl +gl +gl +An +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +ke +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +ml +ml +ml +ml +ml +FM +gl +Al +iz +"} +(8,1,1) = {" +pr +pr +pr +pr +iz +Al +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +ml +ml +ml +ml +ml +ml +gl +Al +iz +"} +(9,1,1) = {" +pr +pr +pr +pr +iz +Al +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +gl +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +gl +gl +ml +ml +ml +ml +ml +ml +gl +Al +iz +"} +(10,1,1) = {" +pr +pr +pr +pr +iz +Al +Al +Al +Al +xb +xb +uc +Al +Al +gl +gl +gl +Al +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Al +gl +gl +ml +ml +ml +ml +ml +ml +gl +Al +iz +"} +(11,1,1) = {" +iz +iz +iz +iz +iz +Al +Al +Al +Fn +PM +PM +Fn +Fn +Al +Al +Al +Fn +Fn +Fn +Pc +bf +Bw +Fn +Ev +Pg +iR +kG +di +Fn +DL +Al +gl +ml +ml +ml +ml +ml +ml +gl +Al +iz +"} +(12,1,1) = {" +iz +Al +Al +Al +Al +Al +Al +Al +Fn +pT +LD +LD +Fn +Fn +Kd +Fn +Fn +bQ +cv +wD +Bw +JY +Fn +db +TG +TG +TG +TG +AP +Fn +Al +gl +ml +ml +ml +ml +ml +ml +gl +Al +iz +"} +(13,1,1) = {" +iz +Al +Fn +Fn +Fn +Fn +Fn +Fn +Fn +LD +pT +LD +EC +LD +pT +PM +wD +wD +cv +wD +wD +OR +Fn +ug +TG +TG +TG +TG +QX +Fn +Al +gl +ml +ml +ml +ml +ml +sT +gl +Al +iz +"} +(14,1,1) = {" +iz +Al +Fn +VA +kT +Zb +TG +Fn +Fn +Fn +yU +LD +Et +LD +LD +PM +wD +wD +wD +wD +wD +qc +Fn +Fn +SD +Mp +uq +fc +Fn +Fn +Al +gl +gl +gl +gl +gl +gl +gl +gl +Al +iz +"} +(15,1,1) = {" +iz +Al +Fn +VA +yX +ag +kT +Br +TG +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Gz +wD +Bw +rm +wD +wD +wD +Ii +dx +kn +kn +kn +Aa +Fn +Al +gl +gl +gl +gl +gl +gl +gl +gl +Al +iz +"} +(16,1,1) = {" +iz +Al +Fn +pC +yX +ag +kT +BJ +kT +Fn +as +ab +Ir +IP +YN +uV +wD +wD +wD +mG +vv +Bw +wD +Rx +uU +lS +lS +lS +uU +Fn +Al +gl +gl +gl +gl +gl +gl +gl +gl +Al +iz +"} +(17,1,1) = {" +iz +Al +Fn +Mw +ag +ag +vp +xk +TG +Fn +Ud +Ud +bC +Ud +Ud +wD +IH +wD +wD +Bw +wD +wD +wD +Rx +uU +lS +NX +lS +cz +Fn +Al +gl +gl +gl +gl +gl +gl +gl +gl +Al +iz +"} +(18,1,1) = {" +iz +Al +Fn +Mz +TG +TG +Fn +Fn +KH +Fn +Zd +wD +wD +Bw +wD +VX +wD +UU +wD +wD +wD +wD +wD +Rx +uU +lS +lS +lS +uU +Fn +Al +gl +gl +gl +gl +gl +gl +gl +gl +Al +iz +"} +(19,1,1) = {" +iz +Al +Fn +Fn +tE +tE +Fn +uV +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +jc +uU +uU +uU +uU +uU +Fn +Fn +gl +gl +gl +gl +gl +gl +gl +gl +Al +iz +"} +(20,1,1) = {" +iz +Al +Fn +zU +wD +wD +wD +wD +Dt +Ud +Ud +Ud +Ud +Ud +Ud +Ud +ys +wD +wD +TJ +wb +wD +wD +vT +gJ +gJ +gJ +gJ +gJ +oE +Fn +gl +gl +Al +Al +gl +gl +Al +gl +Al +iz +"} +(21,1,1) = {" +iz +Al +Fn +wD +wD +Bw +wD +wD +BM +BM +BM +We +Zt +BD +Iv +BM +Db +Nr +wD +yl +ag +wD +wD +XM +KZ +Ww +Ww +Ww +cG +dj +Fn +Al +Al +Al +Al +Al +Al +Al +Al +Al +iz +"} +(22,1,1) = {" +iz +Al +Fn +Fn +wD +wD +wD +wD +BM +Zg +VH +TG +TG +TG +TG +mX +BM +wD +wD +Au +wD +rT +wD +XM +Ww +Ww +Ww +Ww +Ww +dj +Fn +Al +iz +iz +iz +iz +iz +iz +iz +iz +iz +"} +(23,1,1) = {" +iz +Al +xb +Fn +Cb +wD +JC +wD +BM +HF +TG +JE +BM +aw +TG +TG +ya +wD +wD +YJ +YJ +wD +wD +XM +Ww +Ww +Ww +Ww +Ww +dj +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(24,1,1) = {" +iz +Al +xb +Fn +wD +Gz +WX +wD +BM +Em +TG +mq +ri +Qb +TG +TG +cb +wD +wD +bQ +wD +wD +wD +XM +Ww +Ww +KZ +KZ +Ww +pZ +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(25,1,1) = {" +iz +Al +xb +Fn +OK +Gz +LW +wD +BM +bS +TG +oP +BM +vq +TG +TG +vN +wD +wD +XP +yB +wD +wD +XM +KZ +Ww +KZ +gh +Ww +dj +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(26,1,1) = {" +iz +Al +xb +Fn +Sg +wD +wD +wD +BM +Ve +rc +yi +TG +TG +TG +CO +BM +wD +Yi +XL +wD +wD +wD +XM +Ww +Ww +Ww +Ww +Ww +dj +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(27,1,1) = {" +iz +Al +Fn +Fn +Bw +wD +wD +wD +BM +BM +BM +BM +FY +BM +BM +BM +er +wD +GA +xq +jy +wD +wD +XM +Ww +cG +Ww +Ww +KZ +dj +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(28,1,1) = {" +iz +Al +Fn +Nr +wD +wD +Bw +wD +YN +Ud +WW +yv +Ud +Ud +Ud +Ud +YN +wD +xR +CA +Uh +wD +qW +XM +Ww +Ww +Ww +Ww +Ww +pZ +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(29,1,1) = {" +iz +Al +Fn +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +wD +Jt +wD +mP +zn +Bu +Bu +Bu +Bu +Xt +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(30,1,1) = {" +iz +Al +Fn +Ds +Ds +Fn +VX +wD +wD +wD +wD +wD +XL +wD +wD +wD +wD +wD +wD +wD +wD +XT +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(31,1,1) = {" +iz +Al +Fn +TG +TG +Fn +Fn +jl +Fn +Fn +qR +Fn +Fn +WO +wD +Bw +wD +wD +wD +wD +bM +Ud +aE +aE +aE +lq +fr +hk +Fn +Al +Al +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(32,1,1) = {" +iz +Al +Fn +TG +TG +TG +Fn +Fn +Fn +dZ +OE +Nw +Fn +Fn +qR +Fn +Fn +wD +wD +wD +Ae +Ud +zw +xw +Uq +aE +aE +aE +Fn +Fn +Al +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(33,1,1) = {" +iz +Al +Fn +EP +TG +TG +TG +TG +hG +TG +TG +TG +Fn +dZ +OE +Nw +Fn +Gz +uV +wD +wD +Ud +xw +xw +xw +aE +aE +aE +OW +Fn +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(34,1,1) = {" +iz +Al +Fn +Xv +TG +hE +TG +TG +Fn +Wg +rc +xJ +Fn +TG +TG +dI +Fn +wD +wD +Bw +wD +lB +zw +xw +Uq +aE +FQ +aE +aE +jg +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(35,1,1) = {" +iz +Al +Fn +Fn +SB +Fn +WL +TG +Fn +Fn +Fn +Fn +Fn +Wg +TG +RL +Fn +Gh +Ud +Ud +Ud +FS +aE +aE +aE +aE +AI +BQ +aE +NM +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(36,1,1) = {" +iz +Al +Fn +kK +TG +Fn +TG +TG +TG +TG +qg +TG +Fn +Fn +SY +Fn +Fn +Ds +Ds +Fn +YI +Fn +Fn +Fn +TX +aE +aE +aE +aE +uk +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(37,1,1) = {" +iz +Al +Fn +Ia +dI +Fn +Fn +Fn +QP +TG +TG +TG +TG +TG +TG +TG +TG +TG +TG +Fn +ve +nP +ed +Fn +Cv +Cv +IM +Cv +Cv +Fn +Fn +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(38,1,1) = {" +iz +Al +Fn +tZ +TG +Qu +Hs +Fn +Fn +Fn +TG +rc +TG +TG +TG +tF +rc +TG +TG +Fn +Yq +aZ +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Al +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(39,1,1) = {" +iz +Al +Fn +Fn +Fn +Fn +Fn +Fn +Al +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Fn +Al +Al +Al +Al +Al +Al +Al +Al +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(40,1,1) = {" +iz +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +Al +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} +(41,1,1) = {" +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +iz +pr +pr +pr +pr +pr +pr +pr +xW +"} diff --git a/_maps/virtual_domains/blood_drunk_miner.dmm b/_maps/virtual_domains/blood_drunk_miner.dmm new file mode 100644 index 00000000000000..c3369a1c822de7 --- /dev/null +++ b/_maps/virtual_domains/blood_drunk_miner.dmm @@ -0,0 +1,1887 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"b" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"c" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"d" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"f" = ( +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile/block/cracked, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"h" = ( +/obj/machinery/light/small/blacklight/directional/south, +/obj/effect/baseturf_helper/virtual_domain, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/virtual_domain/powered) +"i" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"j" = ( +/obj/structure/marker_beacon/jade, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"k" = ( +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"l" = ( +/obj/structure/stone_tile/block, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"m" = ( +/obj/structure/marker_beacon/olive, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"n" = ( +/obj/structure/marker_beacon/cerulean, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"o" = ( +/obj/structure/marker_beacon/yellow, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"q" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"r" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"s" = ( +/turf/closed/mineral/volcanic/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"t" = ( +/obj/structure/marker_beacon/indigo, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"u" = ( +/obj/structure/stone_tile/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"v" = ( +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"w" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"x" = ( +/obj/structure/stone_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"y" = ( +/obj/structure/marker_beacon/violet, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"z" = ( +/obj/structure/stone_tile/block, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"A" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"C" = ( +/obj/effect/mob_spawn/corpse/human/miner, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"G" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"H" = ( +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"I" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"J" = ( +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"K" = ( +/obj/structure/marker_beacon/teal, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"L" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"O" = ( +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/block{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"P" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"S" = ( +/obj/structure/stone_tile/surrounding/cracked{ + dir = 6 + }, +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/virtual_domain, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"T" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"W" = ( +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"X" = ( +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Y" = ( +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Z" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) + +(1,1,1) = {" +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +d +"} +(2,1,1) = {" +v +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +v +"} +(3,1,1) = {" +v +s +s +s +s +J +J +s +s +J +J +s +s +J +J +J +J +s +s +s +J +J +J +s +s +s +s +s +s +s +s +s +s +J +J +s +s +s +J +J +s +s +J +J +s +v +"} +(4,1,1) = {" +v +s +s +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +a +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +s +v +"} +(5,1,1) = {" +v +s +s +J +a +J +J +J +J +a +J +J +J +J +a +a +J +J +J +J +J +a +a +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +s +s +v +"} +(6,1,1) = {" +v +s +s +J +a +J +J +a +a +a +a +a +a +a +a +a +a +a +a +J +a +a +a +a +a +J +J +J +a +a +J +J +J +a +a +J +a +J +a +a +J +J +J +s +s +v +"} +(7,1,1) = {" +v +s +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +J +s +v +"} +(8,1,1) = {" +v +s +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +s +v +"} +(9,1,1) = {" +v +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +j +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(10,1,1) = {" +v +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +t +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(11,1,1) = {" +v +s +s +J +J +J +a +a +a +y +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(12,1,1) = {" +v +s +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +C +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +J +s +v +"} +(13,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(14,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +T +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(15,1,1) = {" +v +s +J +J +J +a +a +a +a +a +a +a +a +a +a +X +z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +h +c +c +c +c +c +L +a +a +J +J +s +v +"} +(16,1,1) = {" +v +s +J +J +J +J +a +a +a +a +a +a +a +T +W +a +r +a +i +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +c +c +c +c +c +c +a +a +J +J +s +v +"} +(17,1,1) = {" +v +s +s +J +J +J +a +a +a +a +a +a +a +a +I +b +k +l +x +a +T +k +a +a +a +m +a +a +a +a +a +o +a +a +c +c +c +c +c +c +a +a +J +J +s +v +"} +(18,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +a +P +S +A +O +u +r +k +a +a +a +a +a +a +a +a +a +a +a +c +c +c +c +c +c +a +J +J +s +s +v +"} +(19,1,1) = {" +v +s +J +J +J +a +a +a +a +a +a +a +a +k +G +H +x +f +k +a +Y +T +u +a +a +a +a +a +a +a +a +a +a +a +c +c +c +c +c +c +a +a +J +J +s +v +"} +(20,1,1) = {" +v +s +J +J +J +J +a +a +a +a +a +a +a +Y +x +a +Z +a +z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +c +c +c +c +c +c +a +a +J +J +s +v +"} +(21,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +a +z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +h +c +c +c +c +c +q +a +a +J +s +s +v +"} +(22,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +w +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +s +s +v +"} +(23,1,1) = {" +v +s +J +J +a +a +a +a +a +a +n +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +s +s +v +"} +(24,1,1) = {" +v +s +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +C +a +a +a +a +a +J +J +s +v +"} +(25,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +J +s +v +"} +(26,1,1) = {" +v +s +s +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +K +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(27,1,1) = {" +v +s +s +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +j +a +a +a +a +a +a +a +a +a +J +J +s +v +"} +(28,1,1) = {" +v +s +J +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +J +s +v +"} +(29,1,1) = {" +v +s +J +J +J +J +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +J +J +s +s +v +"} +(30,1,1) = {" +v +s +s +J +J +J +J +a +a +J +J +J +a +a +a +a +J +J +J +a +a +a +J +J +J +a +a +a +J +J +a +a +a +a +a +a +J +J +a +a +a +J +J +s +s +v +"} +(31,1,1) = {" +v +s +s +a +J +J +J +J +J +J +J +J +J +a +a +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +a +a +a +J +J +J +J +J +J +J +J +J +s +v +"} +(32,1,1) = {" +v +s +s +a +J +J +J +J +J +J +J +J +J +J +J +J +J +a +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +J +s +v +"} +(33,1,1) = {" +v +s +s +s +s +s +J +J +s +s +s +s +J +J +s +s +s +s +s +s +J +J +s +s +s +s +J +J +s +s +s +s +J +J +J +s +s +s +s +s +s +J +J +J +s +v +"} +(34,1,1) = {" +v +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +s +v +"} +(35,1,1) = {" +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +"} diff --git a/_maps/virtual_domains/bubblegum.dmm b/_maps/virtual_domains/bubblegum.dmm new file mode 100644 index 00000000000000..3381b1735398b6 --- /dev/null +++ b/_maps/virtual_domains/bubblegum.dmm @@ -0,0 +1,2250 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"c" = ( +/obj/effect/mob_spawn/corpse/human/miner, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"d" = ( +/obj/structure/marker_beacon/jade, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"f" = ( +/obj/structure/marker_beacon/burgundy, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"g" = ( +/obj/structure/marker_beacon/teal, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"p" = ( +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"r" = ( +/obj/structure/marker_beacon/fuchsia, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"w" = ( +/obj/machinery/light/small/blacklight/directional/south, +/obj/effect/baseturf_helper/virtual_domain, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/virtual_domain/powered) +"x" = ( +/obj/structure/marker_beacon/olive, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"z" = ( +/obj/structure/marker_beacon/purple, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"A" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"C" = ( +/mob/living/simple_animal/hostile/megafauna/bubblegum/virtual_domain, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"F" = ( +/turf/open/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"G" = ( +/obj/structure/marker_beacon/violet, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"I" = ( +/obj/structure/marker_beacon/bronze, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"M" = ( +/obj/structure/marker_beacon/indigo, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"R" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/open/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"S" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"T" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"W" = ( +/obj/structure/marker_beacon/cerulean, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"X" = ( +/obj/structure/marker_beacon/lime, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Y" = ( +/obj/structure/marker_beacon/yellow, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Z" = ( +/turf/closed/mineral/volcanic/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) + +(1,1,1) = {" +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +R +"} +(2,1,1) = {" +F +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +F +"} +(3,1,1) = {" +F +Z +a +a +Z +Z +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +Z +Z +a +a +a +a +a +a +a +a +Z +Z +a +a +a +a +a +a +Z +Z +Z +F +"} +(4,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(5,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +p +Z +F +"} +(6,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +G +a +a +a +a +a +a +a +a +a +a +a +a +p +p +Z +F +"} +(7,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +x +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +a +a +a +a +p +Z +F +"} +(8,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +Z +a +a +a +Z +Z +F +"} +(9,1,1) = {" +F +Z +a +a +a +a +a +a +p +p +p +p +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +Z +F +"} +(10,1,1) = {" +F +Z +Z +a +a +a +a +a +Z +Z +Z +p +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +Z +F +"} +(11,1,1) = {" +F +Z +Z +a +a +a +a +a +Z +Z +Z +p +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +Z +a +a +a +a +a +a +a +a +p +p +a +a +a +a +a +Z +F +"} +(12,1,1) = {" +F +Z +Z +a +a +a +a +a +p +Z +p +p +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +Z +a +a +a +a +a +a +a +p +a +a +a +a +a +Z +F +"} +(13,1,1) = {" +F +Z +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +Z +Z +a +a +a +a +a +M +a +a +a +a +a +a +a +Z +F +"} +(14,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +Z +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(15,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +c +a +a +a +a +a +a +Z +F +"} +(16,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +I +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(17,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +W +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(18,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(19,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(20,1,1) = {" +F +Z +a +a +a +a +a +z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(21,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +w +S +S +S +S +S +T +a +Z +F +"} +(22,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +S +S +S +S +S +S +a +Z +F +"} +(23,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +C +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +S +S +S +S +S +S +a +Z +F +"} +(24,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +X +a +a +S +S +S +S +S +S +a +Z +F +"} +(25,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +S +S +S +S +S +S +a +Z +F +"} +(26,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +S +S +S +S +S +S +a +Z +F +"} +(27,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +w +S +S +S +S +S +A +a +Z +F +"} +(28,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +f +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(29,1,1) = {" +F +Z +a +a +a +a +a +a +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +r +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(30,1,1) = {" +F +Z +a +a +a +a +a +a +Z +Z +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(31,1,1) = {" +F +Z +a +a +a +a +a +a +Z +Z +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(32,1,1) = {" +F +Z +a +a +a +a +a +a +a +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(33,1,1) = {" +F +Z +a +a +a +a +a +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +d +a +a +a +a +a +a +a +Z +F +"} +(34,1,1) = {" +F +Z +Z +a +a +a +a +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(35,1,1) = {" +F +Z +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +X +a +a +a +a +a +a +a +a +Z +Z +Z +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(36,1,1) = {" +F +Z +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +Z +Z +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(37,1,1) = {" +F +Z +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +Z +F +"} +(38,1,1) = {" +F +Z +a +a +a +p +p +a +a +a +a +a +g +a +a +a +a +Z +a +a +a +a +a +a +p +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +Z +F +"} +(39,1,1) = {" +F +Z +a +a +a +p +p +a +a +a +a +a +a +a +a +a +Z +Z +Z +a +a +a +a +a +p +p +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(40,1,1) = {" +F +Z +a +c +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(41,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Y +a +a +a +a +a +a +a +Z +F +"} +(42,1,1) = {" +F +Z +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +Z +F +"} +(43,1,1) = {" +F +Z +a +Z +Z +Z +Z +a +a +a +a +a +Z +Z +Z +Z +a +a +a +Z +Z +Z +Z +Z +a +a +a +a +a +a +Z +Z +Z +Z +a +a +a +a +a +a +Z +Z +a +a +Z +F +"} +(44,1,1) = {" +F +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +Z +F +"} +(45,1,1) = {" +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +F +"} diff --git a/_maps/virtual_domains/clown_planet.dmm b/_maps/virtual_domains/clown_planet.dmm new file mode 100644 index 00000000000000..01d7b88a5efb5f --- /dev/null +++ b/_maps/virtual_domains/clown_planet.dmm @@ -0,0 +1,2323 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"ai" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/small/directional/west, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"aI" = ( +/obj/item/bikehorn/airhorn, +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"aM" = ( +/obj/item/bikehorn, +/turf/open/indestructible/honk, +/area/virtual_domain/powered) +"aP" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/effect/decal/cleanable/food/pie_smudge, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"ba" = ( +/obj/structure/mecha_wreckage/honker, +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"bi" = ( +/obj/item/bikehorn, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"bp" = ( +/turf/open/indestructible/light, +/area/virtual_domain/powered) +"bq" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"by" = ( +/turf/closed/wall/r_wall, +/area/lavaland/surface/outdoors/virtual_domain) +"bQ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/turf_decal/tile/red/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"bR" = ( +/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/hope, +/obj/effect/decal/cleanable/blood/old, +/obj/effect/mapping_helpers/no_lava, +/turf/open/floor/noslip, +/area/virtual_domain/powered) +"bU" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"cw" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"cM" = ( +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/structure/disposaloutlet{ + dir = 1 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"cW" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"ed" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/machinery/light/small/directional/west, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"eE" = ( +/obj/structure/window/reinforced/spawner/directional/south, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"fh" = ( +/obj/effect/mob_spawn/corpse/human/damaged, +/obj/effect/decal/cleanable/blood/old, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"gr" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"gy" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/baseturf_helper/virtual_domain, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"gH" = ( +/obj/item/bikehorn, +/obj/effect/decal/cleanable/dirt, +/turf/open/indestructible/honk, +/area/virtual_domain/powered) +"gK" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"hK" = ( +/obj/item/clothing/head/cone, +/obj/effect/mapping_helpers/no_lava, +/turf/open/floor/noslip, +/area/virtual_domain/powered) +"hY" = ( +/turf/template_noop, +/area/template_noop) +"ij" = ( +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/machinery/disposal/delivery_chute{ + dir = 4 + }, +/turf/open/floor/noslip, +/area/virtual_domain/powered) +"ik" = ( +/turf/open/lava/smooth, +/area/virtual_domain/powered) +"iR" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"ki" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"kn" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"lj" = ( +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/machinery/disposal/delivery_chute{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"lm" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/machinery/light/small/directional/east, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"lr" = ( +/obj/item/bikehorn, +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"lx" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"ly" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"lP" = ( +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"mD" = ( +/turf/open/floor/plating, +/area/virtual_domain/powered) +"mE" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"mF" = ( +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"nE" = ( +/obj/effect/mapping_helpers/no_lava, +/turf/closed/wall/r_wall, +/area/virtual_domain/powered) +"oA" = ( +/obj/effect/turf_decal/tile/red/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"oI" = ( +/obj/structure/table/glass, +/obj/item/grown/bananapeel/bluespace, +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"pl" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"ps" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/effect/turf_decal/tile/red/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"qM" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/machinery/light/small/directional/north, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"rg" = ( +/obj/item/coin/bananium, +/obj/item/coin/bananium, +/obj/item/coin/bananium, +/obj/item/coin/bananium, +/obj/machinery/light/small/directional/west, +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"rh" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"rr" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"rH" = ( +/obj/structure/disposalpipe/junction/yjunction{ + dir = 1; + invisibility = 101 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"rT" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"sq" = ( +/obj/machinery/light/directional/north, +/obj/effect/turf_decal/tile/red/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"sT" = ( +/obj/structure/disposalpipe/sorting/mail/flip{ + dir = 1 + }, +/obj/effect/mapping_helpers/mail_sorting/supply/qm_office, +/turf/closed/wall/r_wall, +/area/virtual_domain/powered) +"tq" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"tt" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/open/indestructible/light, +/area/virtual_domain/powered) +"tv" = ( +/obj/effect/mob_spawn/corpse/human/damaged, +/obj/effect/decal/cleanable/blood/old, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"tF" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"tI" = ( +/obj/item/coin/bananium, +/obj/item/coin/bananium, +/obj/item/coin/bananium, +/obj/item/coin/bananium, +/obj/machinery/light/small/directional/east, +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"uX" = ( +/obj/effect/mapping_helpers/no_lava, +/mob/living/basic/clown, +/turf/open/floor/noslip, +/area/virtual_domain/powered) +"uY" = ( +/turf/closed/mineral/bananium, +/area/virtual_domain/powered) +"uZ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/structure/table, +/obj/item/paper/crumpled/bloody/ruins/lavaland/clown_planet/escape, +/obj/item/pen/fourcolor, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"wz" = ( +/obj/machinery/light/small/directional/south, +/obj/effect/mapping_helpers/no_lava, +/mob/living/basic/clown, +/turf/open/floor/noslip, +/area/virtual_domain/powered) +"xt" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"yd" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"yz" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/closed/wall/r_wall, +/area/virtual_domain/powered) +"yS" = ( +/obj/structure/marker_beacon/yellow, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"yZ" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"zm" = ( +/obj/effect/decal/cleanable/cobweb, +/obj/effect/turf_decal/tile/red/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"zA" = ( +/obj/structure/statue/bananium/clown, +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"zF" = ( +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/structure/disposaloutlet{ + dir = 8 + }, +/turf/open/floor/noslip, +/area/virtual_domain/powered) +"Aa" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/effect/turf_decal/tile/red/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"Bi" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/decal/cleanable/cobweb, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"Cp" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/machinery/light/small/directional/west, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"Cs" = ( +/obj/item/bikehorn, +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"Dh" = ( +/turf/closed/wall/r_wall, +/area/virtual_domain/powered) +"Do" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"DL" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/item/bikehorn, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"Ex" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"FI" = ( +/obj/item/reagent_containers/cup/glass/trophy/gold_cup, +/obj/structure/table/glass, +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"Gg" = ( +/obj/structure/table/glass, +/obj/item/gun/magic/staff/honk, +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"Hq" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Hr" = ( +/obj/structure/table/glass, +/obj/item/clothing/shoes/clown_shoes/banana_shoes, +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"HQ" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/machinery/light/small/directional/east, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"Ie" = ( +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"Iz" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"IN" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/closed/wall/r_wall, +/area/virtual_domain/powered) +"IY" = ( +/turf/open/indestructible/honk, +/area/virtual_domain/powered) +"Jv" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/indestructible/honk, +/area/virtual_domain/powered) +"JB" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/machinery/light/small/directional/north, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"Ka" = ( +/obj/effect/decal/cleanable/food/pie_smudge, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"Kh" = ( +/obj/effect/mob_spawn/corpse/human/damaged, +/obj/effect/decal/cleanable/blood/old, +/turf/open/indestructible/honk, +/area/virtual_domain/powered) +"KG" = ( +/obj/item/pickaxe, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"KI" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/closed/wall/r_wall, +/area/lavaland/surface/outdoors/virtual_domain) +"Lv" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/machinery/light/small/directional/east, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"Nv" = ( +/obj/effect/decal/cleanable/cobweb, +/turf/open/indestructible/honk, +/area/virtual_domain/powered) +"NB" = ( +/obj/machinery/disposal/delivery_chute, +/obj/structure/disposalpipe/trunk{ + dir = 1 + }, +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"NL" = ( +/obj/machinery/disposal/delivery_chute{ + desc = "The following is engraved upon the chute: A FATE WORSE THAN DEATH LIES WITHIN"; + dir = 1; + name = "THE TRIAL OF HONKITUDE" + }, +/obj/structure/disposalpipe/trunk, +/obj/effect/mapping_helpers/no_lava, +/turf/open/floor/noslip, +/area/virtual_domain/powered) +"NW" = ( +/obj/structure/table/glass, +/obj/item/reagent_containers/spray/waterflower/superlube, +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"Ok" = ( +/obj/item/bikehorn, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"Ov" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"PJ" = ( +/obj/structure/disposalpipe/trunk, +/obj/structure/disposaloutlet{ + dir = 1 + }, +/obj/effect/mapping_helpers/no_lava, +/turf/open/floor/noslip, +/area/virtual_domain/powered) +"PM" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"PQ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/item/pickaxe, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"QP" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"QX" = ( +/obj/structure/closet/crate/secure/bitrunning/encrypted, +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"Rh" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"Rx" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/structure/table, +/obj/item/flashlight/lamp/bananalamp, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"RU" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"Sg" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/decal/cleanable/food/pie_smudge, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"Sm" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/closed/wall/r_wall, +/area/virtual_domain/powered) +"Tm" = ( +/obj/effect/decal/cleanable/food/pie_smudge, +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"Tx" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"TH" = ( +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, +/obj/structure/disposaloutlet{ + dir = 8 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"TK" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/turf/closed/wall/r_wall, +/area/virtual_domain/powered) +"Ug" = ( +/obj/machinery/light/small/directional/north, +/turf/open/floor/carpet, +/area/virtual_domain/powered) +"UL" = ( +/obj/effect/decal/cleanable/oil, +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"UN" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"UQ" = ( +/obj/structure/disposalpipe/segment{ + invisibility = 101 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"UY" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"Vv" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/closed/wall/r_wall, +/area/virtual_domain/powered) +"Vx" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"VI" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"VQ" = ( +/turf/open/floor/noslip, +/area/virtual_domain/powered) +"Ww" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/tile/yellow/fourcorners, +/turf/open/indestructible/permalube, +/area/virtual_domain/powered) +"WB" = ( +/obj/machinery/disposal/delivery_chute{ + dir = 1 + }, +/obj/structure/disposalpipe/trunk, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"WT" = ( +/obj/machinery/door/airlock/bananium, +/turf/open/indestructible/honk, +/area/virtual_domain/powered) +"WX" = ( +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"Xp" = ( +/obj/machinery/light/directional/south, +/turf/open/indestructible/honk, +/area/virtual_domain/powered) +"XB" = ( +/obj/machinery/light/directional/north, +/turf/open/indestructible/honk, +/area/virtual_domain/powered) +"Yb" = ( +/obj/effect/decal/cleanable/cobweb/cobweb2, +/turf/open/indestructible/honk, +/area/virtual_domain/powered) +"YP" = ( +/obj/structure/disposalpipe/segment{ + dir = 4; + invisibility = 101 + }, +/turf/open/indestructible/white, +/area/virtual_domain/powered) +"ZR" = ( +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/structure/disposaloutlet{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) + +(1,1,1) = {" +Ie +Ie +rT +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +rr +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(2,1,1) = {" +Ie +Ie +Vx +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(3,1,1) = {" +Ie +Ie +Vx +Ie +Ie +Ie +Ie +Ie +Dh +Dh +Dh +Dh +Dh +Dh +Dh +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Dh +Dh +Dh +Dh +Dh +Ie +Ie +Ie +Ie +Ie +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(4,1,1) = {" +Ie +Ie +Vx +Ie +Ie +Ie +Dh +Dh +Dh +ik +ik +ik +ik +ik +Dh +Dh +Ie +Ie +Ie +Ie +Ie +Dh +Dh +ik +ik +ik +Dh +Dh +Dh +Ie +Ie +Ie +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(5,1,1) = {" +Ie +Ie +Vx +Ie +Ie +Dh +Dh +ik +ik +ik +Hq +Sm +Hq +Sm +ik +Dh +Dh +Ie +Ie +Ie +Dh +Dh +ik +ik +tq +mD +ik +ik +Dh +Dh +Ie +Ie +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(6,1,1) = {" +Ie +Ie +Vx +Ie +Dh +Dh +ik +ik +IN +Tx +bU +ai +yZ +aP +Sm +ik +Dh +Dh +Dh +Dh +Dh +Nv +IY +tq +ik +ik +ik +ik +ik +Dh +Dh +Ie +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(7,1,1) = {" +Ie +Ie +Vx +Ie +Dh +ik +ik +Dh +Bi +cw +UQ +lr +UQ +UY +Vv +ik +Dh +IY +Jv +IY +Dh +IY +Jv +Kh +IY +tq +ik +tq +ik +ik +Dh +Ie +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(8,1,1) = {" +Ie +Ie +Vx +Dh +Dh +ik +IN +Tm +lx +Ww +cw +UQ +Sm +Vv +Vv +Dh +zm +oA +IY +Jv +Jv +IY +Jv +IY +IY +IY +Dh +ik +mD +ik +Dh +Dh +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(9,1,1) = {" +Ie +Ie +Vx +Dh +ik +ik +UN +UQ +UY +Ww +Vv +TH +Vv +YP +Cp +uY +Dh +sq +oA +IY +Dh +Dh +Jv +Dh +IY +IY +IY +tq +ik +ik +ik +Dh +Ie +Vx +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +tF +"} +(10,1,1) = {" +Ie +Ie +Vx +Dh +ik +IN +UQ +UQ +yZ +Do +Do +Vv +YP +YP +YP +KG +uY +Dh +Dh +oA +IY +IY +Jv +IY +IY +gH +Jv +Xp +Dh +ik +ik +Dh +by +KI +by +by +by +by +by +by +by +by +by +Ie +"} +(11,1,1) = {" +Ie +Ie +Vx +Dh +ik +yz +fh +UQ +UY +Vv +Ww +Vv +YP +YP +tt +bp +WX +oA +oA +oA +IY +Dh +IY +IY +Jv +Jv +IY +IY +ik +tq +ik +Dh +by +iR +PM +PM +PM +PM +PM +PM +PM +PM +by +Ie +"} +(12,1,1) = {" +Ie +Ie +Vx +Dh +ik +Hq +TK +qM +yZ +Ww +Ww +Vv +YP +PQ +tt +bp +uY +Dh +oA +oA +IY +IY +Dh +IY +IY +IY +IY +Jv +ik +tq +ik +ik +by +iR +yS +PM +PM +PM +PM +PM +yS +PM +by +Ie +"} +(13,1,1) = {" +Ie +Ie +Vx +Dh +ik +UN +UQ +UQ +DL +Ww +yz +lx +Vv +YP +Lv +WX +Dh +Dh +oA +IY +IY +Dh +Dh +IY +IY +Dh +IY +Jv +ik +mD +tq +ik +by +iR +PM +PM +PM +PM +PM +PM +PM +PM +by +Ie +"} +(14,1,1) = {" +Ie +Dh +Vv +nE +nE +mD +cw +UQ +lx +Ex +Tm +UQ +lx +Vv +Vv +ps +TK +Sm +Dh +Dh +Dh +zA +rg +Dh +XB +IY +Jv +gH +IY +ik +tq +ik +by +iR +PM +QP +QP +QP +QP +QP +xt +PM +by +Ie +"} +(15,1,1) = {" +Ie +Dh +ij +hK +nE +Dh +yz +UQ +UQ +UQ +UQ +bi +UQ +yZ +Do +Iz +kn +Ww +Dh +Dh +FI +mF +mF +mF +Dh +IY +Jv +Jv +IY +ik +tq +ik +by +ZR +PM +QP +QP +QP +QP +QP +QP +PM +by +Ie +"} +(16,1,1) = {" +Ie +Dh +VQ +uX +NL +TK +Tx +UQ +TK +UQ +cW +TK +Tm +UQ +yZ +pl +Do +Ex +UY +Dh +Ug +oI +NW +mF +Dh +Dh +Jv +IY +IY +ik +tq +ik +by +PM +PM +QP +QP +QP +QP +QP +QP +PM +by +Ie +"} +(17,1,1) = {" +Ie +Dh +VQ +bR +wz +Dh +Hq +UQ +Sm +cw +UY +cw +UQ +UQ +Tx +gy +Ex +UY +Iz +TK +NB +mF +aI +mF +WT +IY +Jv +IY +Dh +ik +tq +ik +by +PM +PM +QP +QP +QP +QP +QP +QP +PM +by +Ie +"} +(18,1,1) = {" +Ie +Dh +VQ +uX +PJ +TK +sT +kn +Do +Do +Vv +Do +Ov +UQ +UY +Ok +mE +rH +pl +Dh +mF +Hr +Gg +mF +Dh +IY +IY +IY +IY +ik +tq +ik +by +PM +PM +QP +QP +QP +QP +QP +QP +PM +by +Ie +"} +(19,1,1) = {" +Ie +Dh +zF +uX +nE +Dh +Dh +Ww +Ww +Ww +Do +Do +Do +lP +Ex +UY +Ka +Vv +tv +Dh +FI +mF +mF +QX +Dh +IY +IY +IY +IY +ik +tq +ik +by +lj +PM +QP +QP +QP +QP +QP +QP +PM +by +Ie +"} +(20,1,1) = {" +Ie +Dh +Vv +nE +nE +ik +Dh +Ww +Ww +Cs +Do +Do +Vv +Dh +Dh +bQ +Dh +ba +Dh +IY +Dh +zA +tI +Dh +XB +IY +Jv +Jv +IY +ik +tq +ik +by +iR +PM +QP +QP +QP +QP +QP +gr +PM +by +Ie +"} +(21,1,1) = {" +Ie +Ie +Vx +Dh +ik +Dh +Dh +Do +Do +Do +Ww +Do +Vv +rh +ed +gK +Dh +UL +Sm +IY +IY +Dh +Dh +Kh +IY +IY +Jv +IY +ik +tq +mD +ik +by +iR +PM +PM +PM +PM +PM +PM +PM +PM +by +Ie +"} +(22,1,1) = {" +Ie +Ie +Vx +Dh +ik +Dh +Dh +JB +Sg +Vv +Ww +Vv +uZ +YP +bp +bp +uY +Dh +bQ +oA +IY +IY +Dh +IY +Jv +IY +IY +IY +ik +tq +ik +ik +by +iR +PM +PM +yS +PM +PM +PM +PM +PM +by +Ie +"} +(23,1,1) = {" +Ie +Ie +Vx +Dh +ik +cM +eE +lx +Vv +ki +Ww +Vv +Rx +YP +bp +bp +WB +TK +Aa +Dh +IY +IY +Jv +Jv +Jv +IY +aM +Xp +Dh +tq +ik +Dh +by +iR +PM +PM +PM +PM +PM +PM +PM +PM +by +Ie +"} +(24,1,1) = {" +Ie +Ie +Vx +Dh +ik +Dh +Dh +lP +Do +Do +Cs +bQ +YP +bq +Rh +WX +uY +Dh +oA +oA +IY +IY +Jv +Jv +IY +IY +Dh +Dh +ik +mD +ik +Dh +by +KI +by +by +by +by +by +by +by +by +by +Ie +"} +(25,1,1) = {" +Ie +Ie +Vx +Dh +ik +Dh +Dh +pl +Do +Vv +Do +Vv +Vv +rh +lm +uY +Dh +sq +oA +IY +IY +IY +IY +IY +Dh +IY +IY +ik +mD +ik +ik +Dh +Ie +Vx +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +"} +(26,1,1) = {" +Ie +Ie +Vx +Dh +ik +ik +Dh +yd +Do +Do +Do +Ex +lx +Vv +Dh +Dh +oA +oA +IY +IY +IY +Jv +aM +IY +IY +IY +Dh +ik +tq +ik +Dh +Dh +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(27,1,1) = {" +Ie +Ie +Vx +Dh +Dh +ik +Dh +Dh +Ex +lx +HQ +UQ +UQ +bU +Dh +ik +Dh +Yb +IY +IY +Dh +IY +IY +Dh +IY +IY +ik +mD +ik +ik +Dh +Ie +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(28,1,1) = {" +Ie +Ie +Vx +Ie +Dh +Dh +ik +ik +Dh +mD +Dh +Ka +lP +mD +Dh +ik +Dh +Dh +Dh +Dh +Dh +IY +IY +IY +ik +ik +ik +ik +ik +Dh +Dh +Ie +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(29,1,1) = {" +Ie +Ie +Vx +Ie +Ie +Dh +Dh +ik +ik +ik +tq +tq +tq +Dh +ik +Dh +Dh +Ie +Ie +Ie +Dh +Dh +ik +ik +mD +tq +ik +ik +Dh +Dh +Ie +Ie +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(30,1,1) = {" +Ie +Ie +Vx +Ie +Ie +Ie +Dh +Dh +Dh +ik +ik +ik +ik +ik +Dh +Dh +Ie +Ie +Ie +Ie +Ie +Dh +Dh +ik +ik +ik +Dh +Dh +Dh +Ie +Ie +Ie +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(31,1,1) = {" +Ie +Ie +Vx +Ie +Ie +Ie +Ie +Ie +Dh +Dh +Dh +Dh +Dh +Dh +Dh +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Dh +Dh +Dh +Dh +Dh +Ie +Ie +Ie +Ie +Ie +Ie +Vx +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(32,1,1) = {" +Ie +Ie +VI +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +RU +ly +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} +(33,1,1) = {" +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +Ie +hY +hY +hY +hY +hY +hY +hY +hY +hY +hY +"} diff --git a/_maps/virtual_domains/colossus.dmm b/_maps/virtual_domains/colossus.dmm new file mode 100644 index 00000000000000..a9c3c6e6d79e72 --- /dev/null +++ b/_maps/virtual_domains/colossus.dmm @@ -0,0 +1,2250 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"c" = ( +/obj/structure/marker_beacon/olive, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"e" = ( +/obj/structure/marker_beacon/bronze, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"j" = ( +/obj/structure/marker_beacon/cerulean, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"k" = ( +/turf/closed/mineral/volcanic/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"l" = ( +/obj/structure/marker_beacon/lime, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"m" = ( +/obj/structure/marker_beacon/violet, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"o" = ( +/obj/effect/mob_spawn/corpse/human/miner, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"p" = ( +/mob/living/simple_animal/hostile/megafauna/colossus/virtual_domain, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"q" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/open/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"r" = ( +/obj/machinery/light/small/blacklight/directional/south, +/obj/effect/baseturf_helper/virtual_domain, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/virtual_domain/powered) +"s" = ( +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"u" = ( +/obj/structure/marker_beacon/indigo, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"v" = ( +/turf/open/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"x" = ( +/obj/structure/marker_beacon/purple, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"z" = ( +/obj/structure/marker_beacon/jade, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"B" = ( +/obj/structure/marker_beacon/teal, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"D" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"L" = ( +/obj/structure/marker_beacon/yellow, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"N" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"T" = ( +/obj/structure/marker_beacon/burgundy, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"U" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"W" = ( +/obj/structure/marker_beacon/fuchsia, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) + +(1,1,1) = {" +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +q +"} +(2,1,1) = {" +v +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +v +"} +(3,1,1) = {" +v +k +a +a +k +k +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +k +k +a +a +a +a +a +a +a +a +k +k +a +a +a +a +a +a +k +k +k +v +"} +(4,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(5,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +s +k +v +"} +(6,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +m +a +a +a +a +a +a +a +a +a +a +a +a +s +s +k +v +"} +(7,1,1) = {" +v +k +a +a +a +a +o +a +a +a +a +a +a +a +a +a +c +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +a +a +a +a +s +k +v +"} +(8,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +k +a +a +a +k +k +v +"} +(9,1,1) = {" +v +k +a +a +a +a +a +a +s +s +s +s +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +k +v +"} +(10,1,1) = {" +v +k +k +a +a +a +a +a +k +k +k +s +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +k +v +"} +(11,1,1) = {" +v +k +k +a +a +a +a +a +k +k +k +s +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +k +a +a +a +a +a +a +a +a +s +s +a +a +a +a +a +k +v +"} +(12,1,1) = {" +v +k +k +a +a +a +a +a +s +k +s +s +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +k +a +a +a +a +a +a +a +s +a +a +a +a +a +k +v +"} +(13,1,1) = {" +v +k +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +k +k +a +a +a +a +a +u +a +a +a +a +a +a +a +k +v +"} +(14,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +k +k +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(15,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(16,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +e +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(17,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +j +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(18,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(19,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(20,1,1) = {" +v +k +a +a +a +a +a +x +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(21,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +r +U +U +U +U +U +N +a +k +v +"} +(22,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +U +U +U +U +U +U +a +k +v +"} +(23,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +p +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +U +U +U +U +U +U +a +k +v +"} +(24,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +l +a +a +U +U +U +U +U +U +a +k +v +"} +(25,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +U +U +U +U +U +U +a +k +v +"} +(26,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +U +U +U +U +U +U +a +k +v +"} +(27,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +o +a +r +U +U +U +U +U +D +a +k +v +"} +(28,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +T +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(29,1,1) = {" +v +k +a +a +a +a +a +a +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +W +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(30,1,1) = {" +v +k +a +a +a +a +a +a +k +k +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(31,1,1) = {" +v +k +a +a +a +a +a +a +k +k +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(32,1,1) = {" +v +k +a +a +a +a +a +a +a +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(33,1,1) = {" +v +k +a +a +a +a +a +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +z +a +a +a +a +a +a +a +k +v +"} +(34,1,1) = {" +v +k +k +a +a +a +a +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(35,1,1) = {" +v +k +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +l +a +a +a +a +a +a +a +a +k +k +k +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(36,1,1) = {" +v +k +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +k +k +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(37,1,1) = {" +v +k +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +k +v +"} +(38,1,1) = {" +v +k +a +a +a +s +s +a +a +a +a +a +B +a +a +a +a +k +a +a +a +a +a +a +s +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +k +v +"} +(39,1,1) = {" +v +k +a +a +a +s +s +a +a +a +a +a +a +a +a +a +k +k +k +a +a +a +a +a +s +s +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(40,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(41,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +L +a +a +a +a +a +a +a +k +v +"} +(42,1,1) = {" +v +k +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +k +v +"} +(43,1,1) = {" +v +k +a +k +k +k +k +a +a +a +a +a +k +k +k +k +a +a +a +k +k +k +k +k +a +a +a +a +a +a +k +k +k +k +a +a +a +a +a +a +k +k +a +a +k +v +"} +(44,1,1) = {" +v +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +k +v +"} +(45,1,1) = {" +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +v +"} diff --git a/_maps/virtual_domains/gondola_asteroid.dmm b/_maps/virtual_domains/gondola_asteroid.dmm new file mode 100644 index 00000000000000..d6377a4a4c10af --- /dev/null +++ b/_maps/virtual_domains/gondola_asteroid.dmm @@ -0,0 +1,1784 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/closed/indestructible/binary, +/area/ruin/space/has_grav/powered/virtual_domain) +"c" = ( +/turf/open/space/basic, +/area/space) +"e" = ( +/turf/open/misc/asteroid/airless, +/area/ruin/space/has_grav/powered/virtual_domain) +"g" = ( +/obj/structure/marker_beacon{ + light_color = "#FFE8AA"; + light_range = 20 + }, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"h" = ( +/turf/closed/mineral/random, +/area/ruin/space/has_grav/powered/virtual_domain) +"m" = ( +/obj/structure/closet/crate/secure/bitrunning/encrypted/gondola, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"n" = ( +/obj/structure/flora/bush/fullgrass/style_random, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"o" = ( +/turf/template_noop, +/area/template_noop) +"q" = ( +/obj/structure/flora/tree/palm, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"r" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"s" = ( +/obj/structure/flora/bush/sparsegrass/style_random, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"t" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"w" = ( +/obj/structure/water_source/puddle, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"y" = ( +/obj/structure/flora/bush/stalky/style_random, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"z" = ( +/mob/living/simple_animal/pet/gondola/virtual_domain, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"A" = ( +/obj/structure/chair/wood{ + dir = 8 + }, +/turf/template_noop, +/area/virtual_domain/safehouse) +"C" = ( +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"D" = ( +/obj/structure/flora/bush/flowers_br/style_random, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"F" = ( +/obj/structure/flora/bush/grassy/style_random, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"I" = ( +/obj/structure/flora/bush/reed/style_random, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"J" = ( +/obj/structure/flora/bush/flowers_yw/style_random, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"K" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/binary, +/area/ruin/space/has_grav/powered/virtual_domain) +"M" = ( +/obj/structure/table/wood, +/obj/item/storage/bag/tray, +/obj/item/kitchen/fork, +/obj/item/knife/kitchen, +/turf/template_noop, +/area/virtual_domain/safehouse) +"N" = ( +/obj/structure/flora/bush/large/style_random, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"O" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"Q" = ( +/obj/structure/flora/bush/lavendergrass/style_random, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"T" = ( +/obj/structure/flora/bush/sunny/style_random, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"V" = ( +/obj/structure/flora/coconuts, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) +"W" = ( +/obj/structure/flora/bush/ferny/style_random, +/turf/open/floor/grass, +/area/ruin/space/has_grav/powered/virtual_domain) + +(1,1,1) = {" +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +a +a +a +a +a +a +a +a +o +o +o +o +o +o +o +o +o +o +"} +(2,1,1) = {" +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +a +a +a +h +h +h +h +h +h +a +a +o +o +o +o +o +o +o +o +o +"} +(3,1,1) = {" +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +a +a +a +a +a +h +h +h +h +h +h +h +h +h +a +a +K +o +o +o +o +o +o +o +"} +(4,1,1) = {" +o +o +o +o +o +o +o +o +o +o +o +o +o +o +a +a +a +a +a +a +a +h +h +h +h +h +h +h +h +h +h +h +h +h +e +a +o +o +o +o +o +o +o +"} +(5,1,1) = {" +o +o +o +o +o +o +o +o +o +o +o +o +o +a +a +h +h +h +h +h +h +h +h +h +h +h +h +h +h +C +h +h +h +h +h +a +o +o +o +o +o +o +o +"} +(6,1,1) = {" +o +o +o +o +o +o +o +o +a +a +a +a +a +a +h +h +h +h +h +h +h +h +h +h +h +C +C +C +C +C +C +C +h +h +h +a +o +o +o +o +o +o +o +"} +(7,1,1) = {" +o +o +o +o +o +o +o +a +a +h +h +h +h +h +h +h +h +h +h +h +h +h +h +C +C +C +C +J +C +C +C +z +C +h +h +a +o +o +o +o +o +o +o +"} +(8,1,1) = {" +o +o +o +o +o +a +a +a +h +h +h +h +h +h +h +h +h +h +h +h +h +C +C +C +C +Q +C +q +C +h +h +h +h +h +e +a +a +a +a +a +a +a +a +"} +(9,1,1) = {" +o +o +o +o +a +a +h +h +h +h +h +h +h +h +h +h +C +h +C +C +C +C +C +C +C +C +V +C +C +C +C +h +h +h +e +c +c +c +c +c +c +c +a +"} +(10,1,1) = {" +o +o +a +a +a +h +h +h +h +h +h +h +h +C +q +C +C +W +C +C +V +C +C +q +C +C +C +C +F +C +C +h +h +h +e +c +c +c +c +c +c +c +a +"} +(11,1,1) = {" +o +a +a +h +h +h +h +h +h +h +h +h +h +h +h +C +C +C +C +C +N +C +C +C +C +C +C +s +C +C +C +h +h +h +e +c +c +c +c +c +c +c +a +"} +(12,1,1) = {" +o +a +h +h +h +h +h +h +h +h +h +h +h +h +C +s +I +J +C +C +g +C +C +V +C +z +C +y +C +g +C +h +h +h +e +c +c +c +c +c +c +c +a +"} +(13,1,1) = {" +a +a +h +h +h +h +h +h +h +h +h +h +C +C +C +C +Q +Q +C +z +C +C +C +C +C +C +C +s +Q +C +C +h +h +h +e +c +c +c +c +c +c +c +a +"} +(14,1,1) = {" +a +h +h +h +h +h +h +h +h +h +h +h +C +C +w +C +s +C +W +C +C +C +C +C +C +N +C +C +C +C +h +h +h +h +e +c +c +c +c +c +c +c +a +"} +(15,1,1) = {" +a +h +h +h +h +h +h +h +h +h +h +z +C +C +C +C +y +C +C +C +F +s +C +C +C +C +C +w +C +h +h +h +h +h +e +c +c +c +c +c +c +c +a +"} +(16,1,1) = {" +a +h +h +h +h +h +h +h +h +h +h +h +h +h +h +C +C +C +C +C +s +Q +C +C +C +C +C +C +C +C +h +h +h +h +e +c +c +c +c +c +c +c +a +"} +(17,1,1) = {" +a +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +C +C +C +Q +D +C +C +C +C +q +C +C +C +C +h +h +h +h +t +t +t +t +t +O +c +a +"} +(18,1,1) = {" +a +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +C +n +I +C +C +C +C +C +C +C +C +C +C +C +h +h +h +t +t +M +M +t +t +c +a +"} +(19,1,1) = {" +a +h +h +h +h +h +h +h +h +h +C +n +C +h +h +h +h +h +C +C +C +C +C +C +s +T +C +C +C +s +C +C +h +C +C +t +t +A +A +t +t +c +a +"} +(20,1,1) = {" +a +h +h +h +h +h +h +h +h +C +C +C +C +C +C +h +h +h +C +C +q +V +C +C +C +J +C +C +C +C +C +C +C +C +C +t +t +t +t +t +t +c +a +"} +(21,1,1) = {" +a +e +h +h +h +h +h +h +h +z +C +C +g +C +C +C +C +C +C +C +C +C +C +C +C +C +C +C +C +C +C +C +C +C +C +t +t +t +t +t +t +c +a +"} +(22,1,1) = {" +a +e +e +h +h +h +h +h +h +C +C +C +q +C +s +s +C +C +W +C +m +C +C +C +g +C +z +C +C +C +C +C +h +h +h +t +t +t +t +t +t +c +a +"} +(23,1,1) = {" +a +e +e +h +h +h +h +h +h +C +C +C +C +C +C +y +C +C +C +C +C +C +C +C +C +C +C +C +C +q +C +C +h +h +h +t +t +t +t +t +r +c +a +"} +(24,1,1) = {" +a +e +e +h +h +h +h +h +h +C +C +V +C +C +C +C +C +C +C +w +C +z +N +C +C +C +N +C +C +C +C +C +h +h +h +c +c +c +c +c +c +c +a +"} +(25,1,1) = {" +a +a +e +e +h +h +h +h +n +C +C +C +C +C +z +C +C +C +C +C +C +C +C +C +F +C +C +C +C +C +C +C +h +h +h +c +c +c +c +c +c +c +a +"} +(26,1,1) = {" +o +a +e +e +h +h +h +C +C +C +C +C +C +C +C +C +s +y +C +C +C +C +C +C +I +F +C +C +C +C +C +h +h +h +c +c +c +c +c +c +c +c +a +"} +(27,1,1) = {" +o +a +e +e +h +h +h +C +C +C +w +C +C +C +C +F +D +s +C +J +C +C +C +C +C +C +q +C +C +V +C +h +h +h +c +c +c +c +c +c +c +c +a +"} +(28,1,1) = {" +o +a +e +e +h +h +h +h +C +C +C +C +C +C +C +C +C +C +C +g +F +s +C +C +C +C +C +C +C +C +h +h +h +c +c +c +c +c +c +c +c +c +a +"} +(29,1,1) = {" +o +a +a +e +e +h +h +h +C +C +C +C +C +n +C +C +C +C +C +C +s +y +D +C +C +C +C +w +C +h +h +h +h +c +c +c +c +c +c +c +c +c +a +"} +(30,1,1) = {" +o +o +a +e +e +h +h +C +C +C +n +C +C +C +C +C +C +C +C +C +C +C +C +C +C +s +C +C +C +h +h +h +e +e +c +c +c +c +c +c +c +c +a +"} +(31,1,1) = {" +o +o +a +e +h +h +C +g +J +C +s +C +C +C +h +C +C +C +C +C +V +C +C +C +C +C +C +C +h +h +h +e +e +e +c +c +c +c +c +c +c +c +a +"} +(32,1,1) = {" +o +o +a +h +h +h +h +C +C +C +C +C +C +h +h +h +C +C +C +q +C +C +C +C +C +C +h +h +h +h +e +e +e +h +h +a +a +a +a +a +a +a +a +"} +(33,1,1) = {" +o +o +a +h +h +h +C +C +C +C +C +C +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +e +e +h +h +h +a +o +o +o +o +o +o +o +"} +(34,1,1) = {" +o +o +a +h +h +C +C +C +C +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +h +a +a +h +h +h +a +a +o +o +o +o +o +o +o +"} +(35,1,1) = {" +o +o +a +h +h +h +h +h +h +h +h +h +h +h +e +e +e +e +e +h +h +h +h +h +a +a +a +a +a +a +a +h +h +h +a +a +o +o +o +o +o +o +o +"} +(36,1,1) = {" +o +o +a +a +h +h +h +h +h +h +h +h +h +a +a +a +a +a +a +a +a +a +a +a +a +o +o +o +o +o +a +a +a +a +a +o +o +o +o +o +o +o +o +"} +(37,1,1) = {" +o +o +o +a +a +a +a +a +a +a +a +a +a +a +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +o +"} diff --git a/_maps/virtual_domains/hierophant.dmm b/_maps/virtual_domains/hierophant.dmm new file mode 100644 index 00000000000000..02b11ad4e1ef43 --- /dev/null +++ b/_maps/virtual_domains/hierophant.dmm @@ -0,0 +1,1066 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/open/indestructible/hierophant, +/area/lavaland/surface/outdoors/virtual_domain) +"c" = ( +/obj/effect/light_emitter{ + set_cap = 3; + set_luminosity = 5 + }, +/turf/open/indestructible/hierophant/two, +/area/lavaland/surface/outdoors/virtual_domain) +"h" = ( +/obj/effect/light_emitter{ + set_cap = 3; + set_luminosity = 5 + }, +/turf/open/indestructible/hierophant, +/area/lavaland/surface/outdoors/virtual_domain) +"n" = ( +/obj/structure/marker_beacon/indigo, +/turf/open/indestructible/hierophant, +/area/lavaland/surface/outdoors/virtual_domain) +"o" = ( +/turf/template_noop, +/area/template_noop) +"r" = ( +/turf/closed/indestructible/riveted/hierophant, +/area/lavaland/surface/outdoors/virtual_domain) +"u" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"w" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"y" = ( +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"E" = ( +/mob/living/simple_animal/hostile/megafauna/hierophant/virtual_domain, +/turf/open/indestructible/hierophant/two, +/area/lavaland/surface/outdoors/virtual_domain) +"H" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"K" = ( +/turf/open/indestructible/hierophant/two, +/area/lavaland/surface/outdoors/virtual_domain) +"N" = ( +/obj/machinery/light/small/blacklight/directional/south, +/obj/effect/baseturf_helper/virtual_domain, +/turf/open/indestructible/hierophant, +/area/virtual_domain/powered) +"S" = ( +/obj/effect/mob_spawn/corpse/human/miner, +/turf/open/indestructible/hierophant, +/area/lavaland/surface/outdoors/virtual_domain) +"W" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"Y" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) + +(1,1,1) = {" +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +o +o +y +y +y +y +y +y +y +y +y +y +W +"} +(2,1,1) = {" +y +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +y +o +o +y +Y +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(3,1,1) = {" +y +r +a +a +a +a +a +a +a +a +a +a +h +a +a +a +a +a +a +a +a +a +a +r +y +o +o +y +Y +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(4,1,1) = {" +y +r +a +a +a +h +h +a +a +a +r +a +a +a +r +a +a +a +h +h +a +a +a +r +y +y +y +y +Y +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(5,1,1) = {" +y +r +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +r +r +y +y +Y +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(6,1,1) = {" +y +r +a +h +a +r +r +a +h +n +a +a +h +a +a +a +h +a +r +r +a +h +a +a +a +a +r +y +Y +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(7,1,1) = {" +y +r +a +h +a +r +r +a +h +a +a +a +h +a +a +a +h +a +r +r +a +h +a +a +a +a +a +r +Y +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(8,1,1) = {" +y +r +a +a +a +a +a +K +K +K +K +K +K +K +K +K +K +K +a +a +a +n +a +a +r +a +a +a +r +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(9,1,1) = {" +y +r +a +a +a +h +h +K +K +K +r +K +K +K +r +K +K +K +h +h +a +a +a +r +y +r +S +a +a +r +Y +Y +Y +Y +Y +Y +Y +y +"} +(10,1,1) = {" +y +r +a +a +a +a +a +K +K +K +K +K +c +K +K +K +K +K +a +a +a +a +a +r +y +y +r +a +a +N +w +w +w +w +w +H +Y +y +"} +(11,1,1) = {" +y +r +a +r +a +a +a +K +r +K +K +K +K +K +K +K +r +K +a +a +a +r +a +r +y +y +y +r +a +a +w +w +w +w +w +w +Y +y +"} +(12,1,1) = {" +y +r +a +a +a +a +a +K +K +K +K +K +K +K +K +K +K +K +a +a +a +a +a +r +y +y +y +r +a +a +w +w +w +w +w +w +Y +y +"} +(13,1,1) = {" +y +r +h +a +a +h +h +K +K +c +K +K +E +K +K +c +K +K +h +h +a +a +h +r +y +y +y +r +a +a +w +w +w +w +w +w +Y +y +"} +(14,1,1) = {" +y +r +a +a +a +a +a +K +K +K +K +K +K +K +K +K +K +K +a +a +a +a +a +r +y +y +y +r +a +a +w +w +w +w +w +w +Y +y +"} +(15,1,1) = {" +y +r +a +r +a +a +a +K +r +K +K +K +K +K +K +K +r +K +a +a +a +r +a +r +y +y +y +r +a +a +w +w +w +w +w +w +Y +y +"} +(16,1,1) = {" +y +r +a +a +a +a +a +K +K +K +K +K +c +K +K +K +K +K +a +a +a +a +a +r +y +y +r +a +a +N +w +w +w +w +w +u +Y +y +"} +(17,1,1) = {" +y +r +a +a +a +h +h +K +K +K +r +K +K +K +r +K +K +K +h +h +a +a +a +r +y +r +a +a +a +r +Y +Y +Y +Y +Y +Y +Y +y +"} +(18,1,1) = {" +y +r +a +a +a +a +a +K +K +K +K +K +K +K +K +K +K +K +a +a +a +a +a +a +r +a +a +a +r +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(19,1,1) = {" +y +r +a +h +a +r +r +a +h +a +a +a +h +a +a +a +h +a +r +r +a +h +a +a +a +a +a +r +Y +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(20,1,1) = {" +y +r +a +h +a +r +r +S +h +a +a +a +h +a +n +a +h +a +r +r +a +h +a +a +a +a +r +y +Y +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(21,1,1) = {" +y +r +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +r +r +y +y +Y +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(22,1,1) = {" +y +r +a +a +a +h +h +a +a +a +r +a +a +a +r +a +a +a +h +h +a +a +a +r +y +y +y +y +Y +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(23,1,1) = {" +y +r +a +a +a +a +a +a +a +a +a +a +h +a +a +a +a +a +a +a +a +a +a +r +y +o +o +y +Y +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(24,1,1) = {" +y +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +r +y +o +o +y +Y +Y +Y +Y +Y +Y +Y +Y +Y +y +"} +(25,1,1) = {" +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +y +o +o +y +y +y +y +y +y +y +y +y +y +y +"} diff --git a/_maps/virtual_domains/legion.dmm b/_maps/virtual_domains/legion.dmm new file mode 100644 index 00000000000000..55843177ad0f19 --- /dev/null +++ b/_maps/virtual_domains/legion.dmm @@ -0,0 +1,6370 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"ah" = ( +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/obj/structure/stone_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"ak" = ( +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"aI" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"aR" = ( +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"bd" = ( +/obj/structure/stone_tile/block, +/obj/structure/stone_tile/block{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"be" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"bt" = ( +/obj/effect/decal/cleanable/blood, +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 1 + }, +/turf/open/floor/pod/dark, +/area/lavaland/surface/outdoors/virtual_domain) +"bu" = ( +/obj/structure/marker_beacon/bronze, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"ca" = ( +/obj/effect/mob_spawn/corpse/human/legioninfested, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"cf" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"cp" = ( +/turf/template_noop, +/area/template_noop) +"dm" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"dn" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/obj/effect/mob_spawn/corpse/human/legioninfested, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"dr" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/stone_tile/block/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"dx" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 8 + }, +/obj/effect/decal/cleanable/blood/drip, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"dL" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"dQ" = ( +/turf/closed/wall/mineral/titanium/survival/pod, +/area/lavaland/surface/outdoors/virtual_domain) +"et" = ( +/obj/structure/stone_tile/block/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"ew" = ( +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"eJ" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"fA" = ( +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"fG" = ( +/obj/structure/marker_beacon/violet, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"gh" = ( +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"gk" = ( +/obj/structure/necropolis_gate/locked, +/obj/structure/stone_tile/slab, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"gK" = ( +/obj/effect/decal/cleanable/blood/footprints, +/obj/effect/decal/cleanable/blood/drip, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"gQ" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/obj/structure/stone_tile, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"hc" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"hw" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"hx" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"hU" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"ib" = ( +/turf/closed/mineral/volcanic/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"ie" = ( +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"iP" = ( +/obj/structure/fluff/drake_statue/falling, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"iR" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"iV" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"jk" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"jt" = ( +/obj/structure/stone_tile/slab/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"jw" = ( +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"jN" = ( +/obj/machinery/sleeper/survival_pod, +/turf/open/floor/pod/dark, +/area/lavaland/surface/outdoors/virtual_domain) +"ka" = ( +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"kg" = ( +/turf/closed/indestructible/riveted/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"kT" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"kZ" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"ll" = ( +/obj/structure/stone_tile/cracked, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"lz" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"lC" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"lO" = ( +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"lT" = ( +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"mz" = ( +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"mG" = ( +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"nm" = ( +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"nu" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"nv" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"ny" = ( +/obj/structure/stone_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"nI" = ( +/obj/structure/stone_tile/block, +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"nO" = ( +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/center, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"ob" = ( +/obj/structure/necropolis_gate/legion_gate, +/obj/structure/necropolis_arch, +/obj/structure/stone_tile/slab, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"og" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"oo" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"ox" = ( +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"oS" = ( +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"pP" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"qo" = ( +/obj/structure/stone_tile/slab/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"qs" = ( +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"qW" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 1 + }, +/obj/machinery/door/airlock/survival_pod/glass, +/turf/open/floor/pod/dark, +/area/lavaland/surface/outdoors/virtual_domain) +"rt" = ( +/obj/effect/mob_spawn/corpse/human/miner, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"rU" = ( +/obj/structure/stone_tile/block{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"sd" = ( +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"sk" = ( +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"sz" = ( +/obj/structure/stone_tile/center, +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"sA" = ( +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"tk" = ( +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"tF" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"uK" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"vf" = ( +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"wq" = ( +/obj/structure/marker_beacon/teal, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"wy" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"xd" = ( +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"xm" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"xw" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"xD" = ( +/obj/structure/stone_tile/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"yu" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/obj/structure/stone_tile/block, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"yZ" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"zg" = ( +/obj/machinery/light/small/directional/south, +/obj/effect/baseturf_helper/virtual_domain, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/virtual_domain/powered) +"zo" = ( +/obj/effect/turf_decal/mining/survival, +/turf/closed/wall/mineral/titanium/survival/pod, +/area/lavaland/surface/outdoors/virtual_domain) +"zW" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/stone_tile/center/cracked, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Ah" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/binary, +/area/lavaland/surface/outdoors/virtual_domain) +"Aj" = ( +/obj/structure/marker_beacon/burgundy, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Ak" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/stone_tile/center/cracked, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"As" = ( +/obj/structure/marker_beacon/cerulean, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"AY" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Bo" = ( +/obj/structure/marker_beacon/indigo, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"BO" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"CX" = ( +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/blood/footprints{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Dm" = ( +/turf/closed/mineral/random/volcanic, +/area/lavaland/surface/outdoors/virtual_domain) +"DP" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 1 + }, +/obj/structure/stone_tile/center, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Ek" = ( +/obj/structure/stone_tile/block, +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Ep" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"Ez" = ( +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"EC" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Fg" = ( +/obj/structure/stone_tile/surrounding/cracked{ + dir = 6 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Fp" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"Fq" = ( +/obj/structure/marker_beacon/fuchsia, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"FV" = ( +/obj/structure/stone_tile/block, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Gj" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Gn" = ( +/turf/closed/indestructible/riveted/boss/see_through, +/area/lavaland/surface/outdoors/virtual_domain) +"Go" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 1 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"GH" = ( +/obj/structure/fans, +/turf/open/floor/pod/dark, +/area/lavaland/surface/outdoors/virtual_domain) +"GM" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Hi" = ( +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Hu" = ( +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"Hw" = ( +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/center/cracked, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"HK" = ( +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"HQ" = ( +/obj/structure/stone_tile/block/cracked, +/obj/structure/stone_tile/block{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"HZ" = ( +/obj/structure/stone_tile{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Ii" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Io" = ( +/obj/structure/marker_beacon/jade, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Ip" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"IB" = ( +/obj/structure/stone_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"IG" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"IL" = ( +/obj/structure/stone_tile/surrounding, +/obj/structure/stone_tile/center/cracked, +/mob/living/simple_animal/hostile/megafauna/legion/virtual_domain, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"IQ" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Jc" = ( +/obj/structure/stone_tile/slab, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Jp" = ( +/obj/structure/stone_tile/block/cracked, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Jt" = ( +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/obj/structure/stone_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Jw" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"JD" = ( +/obj/structure/fluff/drake_statue, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"KG" = ( +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Le" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Lx" = ( +/obj/effect/decal/cleanable/blood/footprints{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"LH" = ( +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Ml" = ( +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Mm" = ( +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/stone_tile/center/cracked, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Mo" = ( +/obj/structure/stone_tile/block/cracked, +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"MH" = ( +/obj/structure/stone_tile/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"MP" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"MW" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Nl" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/stone_tile/center, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"Ot" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/stone_tile/center, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Pv" = ( +/obj/effect/turf_decal/mining/survival{ + dir = 4 + }, +/turf/closed/wall/mineral/titanium/survival/pod, +/area/lavaland/surface/outdoors/virtual_domain) +"Px" = ( +/obj/structure/stone_tile{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"PO" = ( +/obj/structure/stone_tile/block{ + dir = 8 + }, +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"Qi" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/cracked, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Qx" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/marker_beacon/burgundy, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"QD" = ( +/obj/item/pickaxe, +/obj/effect/decal/cleanable/blood, +/turf/open/floor/pod/dark, +/area/lavaland/surface/outdoors/virtual_domain) +"RC" = ( +/obj/effect/turf_decal/mining/survival{ + dir = 1 + }, +/turf/closed/wall/mineral/titanium/survival/pod, +/area/lavaland/surface/outdoors/virtual_domain) +"RV" = ( +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"So" = ( +/obj/structure/stone_tile/cracked, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Sw" = ( +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"SI" = ( +/obj/effect/turf_decal/mining, +/turf/closed/wall/mineral/titanium/survival/pod, +/area/lavaland/surface/outdoors/virtual_domain) +"SJ" = ( +/obj/structure/stone_tile/slab/cracked, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"SX" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Ti" = ( +/turf/closed/mineral/random/high_chance/volcanic, +/area/lavaland/surface/outdoors/virtual_domain) +"Tm" = ( +/obj/structure/bed/pod, +/obj/item/bedsheet/black, +/obj/structure/tubes, +/obj/machinery/light/small/broken/directional/east, +/turf/open/floor/pod/dark, +/area/lavaland/surface/outdoors/virtual_domain) +"TC" = ( +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"TJ" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Ud" = ( +/obj/machinery/light/small/directional/north, +/obj/effect/baseturf_helper/virtual_domain, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/virtual_domain/powered) +"UD" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/stone_tile/center/cracked, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"UM" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Vc" = ( +/obj/structure/tubes, +/obj/item/crowbar, +/obj/effect/decal/cleanable/blood/drip, +/turf/open/floor/pod/dark, +/area/lavaland/surface/outdoors/virtual_domain) +"VI" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile, +/obj/structure/stone_tile/center, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"Wa" = ( +/obj/structure/stone_tile/surrounding_tile{ + dir = 4 + }, +/obj/structure/stone_tile/surrounding_tile/cracked{ + dir = 1 + }, +/obj/structure/stone_tile/surrounding_tile{ + dir = 8 + }, +/obj/structure/stone_tile/center/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Wm" = ( +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"WM" = ( +/obj/structure/stone_tile/block, +/obj/structure/stone_tile/cracked{ + dir = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"WR" = ( +/obj/structure/stone_tile/block, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"WS" = ( +/obj/item/gps/computer, +/obj/structure/tubes, +/turf/open/floor/pod/dark, +/area/lavaland/surface/outdoors/virtual_domain) +"Xb" = ( +/obj/structure/marker_beacon/yellow, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Xn" = ( +/obj/structure/stone_tile, +/obj/structure/stone_tile/cracked{ + dir = 8 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Xo" = ( +/obj/structure/stone_tile/block, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Xv" = ( +/obj/structure/stone_tile{ + dir = 1 + }, +/obj/structure/stone_tile/cracked, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"XO" = ( +/obj/effect/turf_decal/mining/survival{ + dir = 8 + }, +/turf/closed/wall/mineral/titanium/survival/pod, +/area/lavaland/surface/outdoors/virtual_domain) +"Yu" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"YN" = ( +/obj/structure/stone_tile/block/cracked, +/obj/structure/stone_tile/block/cracked{ + dir = 1 + }, +/turf/open/lava/smooth/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"YV" = ( +/obj/structure/stone_tile{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Zc" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 4 + }, +/obj/structure/stone_tile/block{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"Zh" = ( +/obj/structure/marker_beacon/purple, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/lavaland/surface/outdoors/virtual_domain) +"Zj" = ( +/obj/structure/stone_tile/block/cracked{ + dir = 8 + }, +/obj/structure/stone_tile/block{ + dir = 4 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"Zq" = ( +/obj/structure/stone_tile/block{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 4 + }, +/obj/structure/stone_tile{ + dir = 8 + }, +/turf/open/indestructible/boss, +/area/lavaland/surface/outdoors/virtual_domain) +"Zu" = ( +/obj/machinery/smartfridge/survival_pod{ + desc = "A heated storage unit. This one's seen better days."; + name = "dusty survival pod storage" + }, +/turf/open/floor/pod/dark, +/area/lavaland/surface/outdoors/virtual_domain) +"ZM" = ( +/obj/structure/stone_tile/cracked{ + dir = 4 + }, +/obj/structure/stone_tile, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors/virtual_domain) +"ZN" = ( +/obj/structure/table/survival_pod, +/obj/item/knife/combat/survival, +/turf/open/floor/pod/dark, +/area/lavaland/surface/outdoors/virtual_domain) + +(1,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +Ah +"} +(2,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ox +"} +(3,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +ib +nu +nu +ib +ib +ib +ib +nu +nu +nu +nu +nu +nu +nu +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ib +nu +nu +nu +nu +nu +nu +ib +ib +nu +nu +ib +ox +"} +(4,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(5,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(6,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +wq +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(7,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ox +"} +(8,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +ib +nu +nu +nu +nu +nu +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +rt +nu +nu +ib +ib +ox +"} +(9,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +ib +nu +nu +nu +nu +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ox +"} +(10,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ib +ib +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ox +"} +(11,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ib +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(12,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +fA +fA +fA +nu +nu +nu +nu +ib +ox +"} +(13,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +ib +nu +fG +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +fA +fA +fA +nu +nu +nu +nu +ib +ox +"} +(14,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +fA +fA +nu +nu +nu +nu +ib +ox +"} +(15,1,1) = {" +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(16,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +nu +nu +nu +nu +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(17,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +Ti +Ti +Ti +Ti +GM +nu +nu +nu +nu +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +Io +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +Xb +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(18,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +et +Ti +GM +GM +GM +nu +nu +nu +nu +GM +GM +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(19,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +GM +nu +nu +nu +nu +nu +nu +nu +nu +GM +GM +GM +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +wq +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(20,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +Ti +nu +nu +nu +nu +nu +nu +nu +nu +GM +GM +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(21,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +Ti +nu +nu +nu +nu +GM +Ti +GM +GM +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +Zh +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(22,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +FV +nu +nu +nu +nu +Ti +Dm +Dm +GM +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(23,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +Ti +GM +GM +GM +Ti +Ti +Dm +Dm +Ti +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(24,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +FV +Ml +Ti +Dm +Dm +Ti +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ox +"} +(25,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +GM +GM +Ti +Dm +Dm +IB +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +GM +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ox +"} +(26,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +GM +GM +GM +GM +GM +GM +fA +fA +fA +fA +RV +fA +fA +fA +fA +fA +fA +Xn +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +As +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ox +"} +(27,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +Ek +Le +be +be +kT +GM +GM +GM +GM +fA +fA +xm +fA +fA +fA +GM +ZM +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(28,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +dr +KG +mz +KG +KG +jt +GM +GM +GM +GM +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +HZ +nu +bu +nu +nu +nu +MH +nu +nu +lz +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +nu +nu +ib +ox +"} +(29,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +bd +mG +Hw +hU +Mm +lO +et +GM +tk +fA +fA +fA +fA +ak +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +YV +nu +nu +So +nu +nu +nu +nu +nu +nu +bu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +nu +nu +ib +ox +"} +(30,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +Ez +WR +JD +rU +KG +dm +GM +GM +fA +Hi +fA +fA +fA +ll +fA +fA +Wm +fA +fA +YV +qs +MH +nu +nu +nu +ny +ca +oS +nu +nu +Qx +nu +nu +hx +nu +nu +nu +nu +nu +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +nu +nu +ib +ox +"} +(31,1,1) = {" +ox +kg +kg +kg +Hu +Zq +wy +Zq +lT +kg +kg +Gn +Gn +KG +Ak +nv +Ot +mG +hw +kg +kg +Wm +fA +fA +fA +fA +fA +fA +fA +fA +fA +ak +nu +nu +qs +nu +nu +TC +nu +YV +nu +ny +nu +oS +nu +nu +nu +SX +nu +nu +nu +zg +BO +BO +BO +BO +BO +og +Ud +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +nu +nu +ib +ox +"} +(32,1,1) = {" +ox +kg +kg +Gn +VI +xw +gQ +ka +iR +kg +kg +Gn +Gn +sz +KG +KG +KG +KG +mz +kg +kZ +kZ +sd +kZ +lC +kZ +TJ +UM +kZ +IQ +UM +UM +AY +nu +nI +nu +nu +nu +nu +oS +nu +nu +nu +nu +nu +qs +nu +nu +nu +nu +nu +nu +BO +BO +BO +BO +BO +BO +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +nu +nu +ib +ox +"} +(33,1,1) = {" +ox +PO +PO +gk +PO +Zc +IL +Yu +SJ +Yu +Yu +Yu +ob +dL +uK +MP +uK +uK +dL +Jc +Mo +eJ +Mo +hc +yu +eJ +Fg +eJ +YN +tF +Mo +Zj +HQ +qo +Jp +nu +aR +nu +TC +nu +YV +nu +nu +oS +nu +nu +ny +Sw +nu +nu +nu +nu +BO +BO +BO +BO +BO +BO +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +Io +ib +ib +nu +nu +ib +ox +"} +(34,1,1) = {" +ox +kg +kg +Gn +Nl +gh +jw +lT +oo +kg +kg +Gn +Gn +Wa +KG +xd +Ez +mz +HK +kg +ie +Jw +Jw +jk +Jw +jk +dn +Jw +Jw +LH +Ii +Qi +aI +nu +Xo +nu +nu +YV +Sw +nu +nu +nu +sA +nu +Gj +nu +nu +HZ +nu +YV +nu +nu +BO +BO +BO +BO +BO +BO +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +nu +nu +ib +ox +"} +(35,1,1) = {" +ox +kg +kg +kg +Hu +Ep +iV +Go +Ip +kg +kg +Gn +Gn +lO +nO +hU +UD +KG +dm +kg +kg +ll +fA +fA +fA +ak +fA +fA +fA +fA +ll +fA +nu +nu +ny +nu +nu +Aj +HZ +nu +ew +nu +nu +bu +nu +nu +nu +nu +nu +Aj +nu +nu +BO +BO +BO +BO +BO +BO +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +nu +nu +ib +ox +"} +(36,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +KG +WR +iP +rU +Ez +cf +GM +GM +fA +fA +yZ +vf +ll +fA +fA +fA +ak +fA +fA +oS +ny +qs +YV +qs +nu +nu +nu +nu +nu +nu +Sw +nu +qs +oS +nu +nu +Sw +nu +nu +BO +BO +BO +BO +BO +BO +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +nu +nu +ib +ox +"} +(37,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +bd +xd +zW +nv +DP +KG +FV +GM +GM +fA +fA +fA +GM +Px +fA +IG +GM +Hi +fA +fA +nu +nu +nu +nu +TC +nu +ah +nu +nu +nm +nu +nu +nu +nu +nu +nu +sk +nu +nu +zg +BO +BO +BO +BO +BO +Fp +Ud +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +nu +nu +ib +ox +"} +(38,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +bd +KG +KG +KG +lO +Jc +GM +GM +GM +fA +fA +fA +fA +fA +fA +GM +Jt +fA +fA +fA +nu +TC +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(39,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +Ek +KG +lO +MW +pP +GM +GM +GM +GM +fA +fA +fA +fA +fA +fA +fA +xD +fA +fA +fA +oS +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(40,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +IB +nu +nu +nu +nu +GM +RV +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(41,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +GM +nu +nu +Sw +Xv +GM +fA +fA +fA +fA +fA +fA +fA +fA +fA +GM +GM +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(42,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +GM +nu +nu +nu +ny +GM +fA +fA +fA +fA +fA +fA +fA +fA +fA +EC +GM +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +Bo +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ox +"} +(43,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +WM +GM +Px +ny +nu +nu +nu +nu +nu +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ox +"} +(44,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +GM +GM +GM +nu +nu +nu +nu +nu +nu +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(45,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +GM +GM +GM +nu +nu +nu +nu +nu +nu +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(46,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +Ti +GM +GM +nu +nu +nu +nu +nu +nu +fA +fA +ak +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +wq +nu +nu +nu +nu +nu +nu +nu +nu +nu +fA +ib +ox +"} +(47,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +Ti +GM +nu +nu +nu +nu +nu +nu +fA +fA +fA +xD +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +fA +fA +ib +ox +"} +(48,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +Ti +GM +nu +nu +nu +nu +nu +nu +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +fA +fA +ib +ox +"} +(49,1,1) = {" +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +Ti +GM +nu +nu +nu +nu +nu +nu +fA +fA +fA +GM +fA +fA +fA +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +Fq +nu +ib +ib +ib +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +fA +ib +ox +"} +(50,1,1) = {" +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +kg +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +rt +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(51,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +dQ +dQ +XO +dQ +dQ +GM +nu +nu +nu +ib +ox +"} +(52,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +Fq +nu +nu +nu +nu +nu +nu +nu +nu +nu +dQ +GH +jN +ZN +zo +GM +nu +nu +nu +ib +ox +"} +(53,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +RC +Zu +QD +bt +qW +CX +nu +nu +nu +ib +ox +"} +(54,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +dQ +WS +Tm +Vc +SI +Lx +nu +nu +nu +ib +ox +"} +(55,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +dQ +dQ +Pv +dQ +dQ +Lx +nu +nu +nu +ib +ox +"} +(56,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +ib +nu +nu +nu +fA +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +GM +GM +GM +GM +dx +gK +nu +nu +nu +ib +ox +"} +(57,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +Io +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(58,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ox +"} +(59,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +fA +fA +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +ox +"} +(60,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +fA +fA +fA +fA +nu +nu +nu +nu +nu +nu +Xb +nu +nu +nu +ib +ox +"} +(61,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +nu +nu +ib +ox +"} +(62,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +nu +ib +ox +"} +(63,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +ib +nu +nu +nu +ib +ib +ib +nu +nu +nu +nu +nu +ib +ib +nu +nu +nu +nu +ib +ib +ib +nu +nu +nu +nu +nu +nu +nu +nu +ib +ib +nu +nu +nu +nu +ib +ib +ox +"} +(64,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ib +ox +"} +(65,1,1) = {" +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +cp +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +ox +"} diff --git a/_maps/virtual_domains/pipedream.dmm b/_maps/virtual_domains/pipedream.dmm new file mode 100644 index 00000000000000..44bd845477a188 --- /dev/null +++ b/_maps/virtual_domains/pipedream.dmm @@ -0,0 +1,3713 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"af" = ( +/obj/structure/chair/plastic{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"aw" = ( +/obj/structure/disposalpipe/sorting/mail/flip{ + dir = 1 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"ax" = ( +/obj/effect/turf_decal/tile/yellow/fourcorners, +/obj/structure/frame/computer{ + anchored = 1; + dir = 4 + }, +/obj/item/shard{ + icon_state = "medium" + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"aK" = ( +/turf/open/space/basic, +/area/space) +"aL" = ( +/obj/effect/turf_decal/tile/yellow/half/contrasted, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"bq" = ( +/obj/machinery/light/small/red/dim{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"bs" = ( +/turf/open/floor/carpet/orange, +/area/virtual_domain/powered) +"bw" = ( +/obj/structure/disposalpipe/broken{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/closet/crate/preopen, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"bx" = ( +/obj/structure/frame/computer, +/obj/item/shard, +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-12" + }, +/area/virtual_domain/powered) +"bA" = ( +/obj/structure/chair/plastic, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"bG" = ( +/obj/structure/lattice/catwalk{ + name = "industrial lift" + }, +/obj/structure/closet/crate/preopen, +/obj/structure/railing, +/turf/open/chasm, +/area/virtual_domain/powered) +"bS" = ( +/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ + dir = 1 + }, +/obj/structure/table/reinforced, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/item/folder/yellow, +/obj/item/folder/blue{ + pixel_x = 2; + pixel_y = -2 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"cw" = ( +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 9 + }, +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"cB" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 10 + }, +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"cF" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 9 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"dx" = ( +/obj/effect/turf_decal/trimline/yellow/line, +/obj/item/shard, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"dz" = ( +/obj/machinery/light/broken, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/trimline/yellow/corner, +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 8 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"dA" = ( +/obj/machinery/light/dim{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"dP" = ( +/obj/effect/turf_decal/tile/yellow/half/contrasted, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"eg" = ( +/turf/closed/wall, +/area/virtual_domain/powered) +"ei" = ( +/obj/machinery/conveyor/auto{ + dir = 6; + icon_state = "conveyor_map_inverted"; + inverted = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"ev" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"eJ" = ( +/obj/structure/disposalpipe/sorting{ + dir = 2 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"eN" = ( +/obj/effect/turf_decal/trimline/yellow/arrow_cw{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/broken{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"eY" = ( +/turf/closed/wall/r_wall, +/area/virtual_domain/powered) +"fe" = ( +/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ + dir = 8 + }, +/obj/structure/table/reinforced, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"fg" = ( +/turf/open/floor/iron/stairs/left{ + dir = 8 + }, +/area/virtual_domain/powered) +"fj" = ( +/obj/structure/closet/crate/preopen, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"fl" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"fw" = ( +/obj/structure/door_assembly/door_assembly_eng, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"fK" = ( +/obj/structure/chair/stool/bar/directional/west, +/turf/open/floor/iron/cafeteria, +/area/virtual_domain/powered) +"fR" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 5 + }, +/obj/structure/sign/poster/official/random/directional/west, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"fZ" = ( +/obj/effect/turf_decal/tile/yellow/fourcorners, +/obj/structure/chair/office{ + dir = 8 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"gc" = ( +/obj/structure/disposalpipe/broken, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"gj" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"gs" = ( +/obj/machinery/door/airlock/external/glass/ruin, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"gN" = ( +/obj/structure/disposalpipe/sorting{ + dir = 8 + }, +/turf/open/floor/catwalk_floor/iron, +/area/virtual_domain/powered) +"gV" = ( +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 8 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"hg" = ( +/obj/effect/turf_decal/caution{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"hi" = ( +/turf/open/floor/iron, +/area/virtual_domain/powered) +"hk" = ( +/obj/effect/turf_decal/tile/yellow/anticorner/contrasted, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/broken{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"ho" = ( +/obj/effect/turf_decal/siding/white{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"iw" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"iz" = ( +/obj/structure/broken_flooring/corner, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"iI" = ( +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/yellow/corner, +/obj/effect/decal/cleanable/blood/drip, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"jv" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 8 + }, +/obj/machinery/light/small/red/dim{ + dir = 8 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"jw" = ( +/obj/effect/turf_decal/delivery, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"jH" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/catwalk_floor/iron, +/area/virtual_domain/powered) +"jQ" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/light/small/red/dim{ + dir = 1 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"jS" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"jW" = ( +/obj/effect/decal/cleanable/generic, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"kh" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"ki" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/landmark/bitrunning/cache_spawn, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"kn" = ( +/obj/machinery/light/small/red/dim{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"kJ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/door/poddoor/shutters/indestructible{ + dir = 4; + id = "factorylockdown" + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"kU" = ( +/turf/open/floor/plating, +/area/virtual_domain/powered) +"lp" = ( +/obj/machinery/door/airlock/maintenance, +/obj/effect/mapping_helpers/airlock/locked, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"lt" = ( +/obj/structure/disposalpipe/sorting{ + dir = 8 + }, +/mob/living/basic/hivebot/range, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"lx" = ( +/obj/machinery/door/poddoor/shutters/indestructible{ + dir = 4; + id = "factorylockdown" + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"lB" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 5 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"lC" = ( +/obj/machinery/door/airlock/glass, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"lI" = ( +/obj/effect/mapping_helpers/burnt_floor, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"lN" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"lW" = ( +/obj/structure/disposalpipe/sorting{ + dir = 8 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"mh" = ( +/obj/structure/broken_flooring/pile{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"mu" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"mE" = ( +/obj/machinery/door/airlock/maintenance, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"mY" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 1 + }, +/obj/machinery/light/small/red/dim{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"nc" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/sign/poster/official/safety_internals/directional/south, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"nz" = ( +/obj/structure/broken_flooring/side/directional/north, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"nD" = ( +/obj/structure/disposalpipe/trunk/multiz, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"nL" = ( +/obj/effect/turf_decal/tile/dark/half, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"nS" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"op" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/dim{ + dir = 1 + }, +/obj/structure/sign/warning/doors/directional/north, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"oN" = ( +/obj/machinery/conveyor/auto, +/obj/structure/window/reinforced/spawner/directional/west, +/obj/structure/window/reinforced/spawner/directional/east, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"oX" = ( +/obj/structure/broken_flooring/corner/directional/north, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"pa" = ( +/obj/machinery/light/small/red/dim{ + dir = 1 + }, +/turf/open/floor/carpet/orange, +/area/virtual_domain/powered) +"pb" = ( +/obj/structure/broken_flooring/corner{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"pf" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/effect/mapping_helpers/damaged_window, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"pi" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"po" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/crate/maint, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"pv" = ( +/obj/structure/broken_flooring/side{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"pI" = ( +/obj/effect/turf_decal/tile/yellow/fourcorners, +/obj/machinery/light/small/red/dim{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"pJ" = ( +/obj/structure/broken_flooring/pile{ + dir = 1 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"qc" = ( +/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ + dir = 8 + }, +/obj/structure/table/reinforced, +/obj/effect/spawner/random/bureaucracy/briefcase, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"qk" = ( +/obj/structure/disposalpipe/segment{ + dir = 10 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"qK" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/sign/warning/secure_area/directional/north, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"qN" = ( +/obj/effect/turf_decal/siding/white{ + dir = 4 + }, +/obj/effect/mob_spawn/corpse/human/factory, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"qT" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light/small/red/dim{ + dir = 1 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"qV" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"qW" = ( +/obj/machinery/light/dim{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"rc" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/sign/poster/contraband/random/directional/north, +/obj/effect/landmark/bitrunning/cache_spawn, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"rz" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 1 + }, +/obj/machinery/light/small/red/dim, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"rG" = ( +/obj/machinery/light/dim, +/obj/effect/turf_decal/trimline/yellow/line, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"rJ" = ( +/obj/structure/railing, +/obj/effect/decal/cleanable/oil, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"rM" = ( +/obj/structure/disposalpipe/broken{ + dir = 1 + }, +/mob/living/basic/hivebot/strong, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"rO" = ( +/turf/closed/mineral, +/area/space) +"sn" = ( +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-38" + }, +/area/virtual_domain/powered) +"sB" = ( +/obj/machinery/light/broken{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/stripes{ + dir = 8 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"sW" = ( +/obj/effect/decal/cleanable/oil/streak, +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 4 + }, +/obj/effect/decal/cleanable/blood/drip, +/obj/effect/decal/cleanable/blood/drip, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"tl" = ( +/obj/machinery/door/poddoor/shutters/indestructible{ + id = "factorylockdown" + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"tr" = ( +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"tE" = ( +/obj/structure/disposalpipe/segment, +/mob/living/basic/hivebot/range, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"ud" = ( +/obj/effect/decal/cleanable/blood/drip, +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-110" + }, +/area/virtual_domain/powered) +"uk" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/effect/decal/cleanable/blood/splatter/over_window, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"um" = ( +/obj/machinery/light/dim{ + dir = 1 + }, +/turf/open/floor/iron/cafeteria, +/area/virtual_domain/powered) +"uv" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/structure/broken_flooring/pile{ + dir = 1 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"uz" = ( +/obj/effect/spawner/random/trash/mess, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"uC" = ( +/obj/structure/falsewall, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"uF" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"uP" = ( +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-55" + }, +/area/virtual_domain/powered) +"uU" = ( +/obj/structure/broken_flooring/side, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"vb" = ( +/obj/effect/turf_decal/trimline/yellow/line, +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 5 + }, +/obj/machinery/light/broken, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"ve" = ( +/obj/machinery/mass_driver/trash{ + dir = 1 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"vA" = ( +/obj/structure/closet/crate/maint, +/obj/effect/turf_decal/stripes{ + dir = 9 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"vL" = ( +/obj/effect/decal/cleanable/glass, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"vQ" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"vU" = ( +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"wg" = ( +/obj/machinery/light/small/red/dim{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/closet/crate/preopen, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"wh" = ( +/obj/structure/table/wood, +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-207" + }, +/area/virtual_domain/powered) +"wl" = ( +/obj/item/shard, +/turf/open/space/basic, +/area/space) +"wm" = ( +/obj/effect/turf_decal/tile/yellow/half/contrasted{ + dir = 1 + }, +/obj/structure/sign/clock/directional/north, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"wq" = ( +/obj/structure/table/wood, +/obj/machinery/button/door{ + name = "Cargo Bay Lockdown"; + id = "factorylockdown" + }, +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-63" + }, +/area/virtual_domain/powered) +"ws" = ( +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"ww" = ( +/obj/effect/turf_decal/stripes{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt, +/mob/living/basic/hivebot, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"wU" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"wW" = ( +/obj/effect/turf_decal/tile/yellow/fourcorners, +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"xa" = ( +/obj/machinery/door/poddoor/shutters/indestructible{ + dir = 8; + id = "factorylockdown" + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"xj" = ( +/obj/structure/railing/corner/end{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"xk" = ( +/obj/machinery/light/dim{ + dir = 4 + }, +/obj/effect/landmark/bitrunning/cache_spawn, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"xl" = ( +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"xA" = ( +/obj/effect/decal/cleanable/generic, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"xE" = ( +/obj/effect/turf_decal/trimline/yellow/line, +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 9 + }, +/obj/machinery/light/broken, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"xF" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/binary, +/area/virtual_domain/powered) +"xM" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/obj/structure/bed/dogbed{ + name = "cat bed" + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"xT" = ( +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"yB" = ( +/obj/machinery/door/airlock/maintenance, +/obj/effect/mapping_helpers/airlock/welded, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"yM" = ( +/turf/closed/indestructible/fakedoor{ + name = "Stairwell Access" + }, +/area/virtual_domain/powered) +"yQ" = ( +/turf/template_noop, +/area/template_noop) +"yX" = ( +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"zp" = ( +/obj/structure/chair/sofa/corp/right{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/obj/machinery/light/broken, +/turf/open/floor/carpet/orange, +/area/virtual_domain/powered) +"zB" = ( +/obj/structure/closet/crate/bin, +/obj/item/trash/tray, +/obj/effect/spawner/random/trash/garbage, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"zE" = ( +/obj/structure/disposalpipe/broken{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"zO" = ( +/obj/effect/turf_decal/siding/white{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/machinery/light/broken, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Av" = ( +/obj/item/stack/rods/two, +/turf/open/space/basic, +/area/space) +"Aw" = ( +/obj/structure/lattice/catwalk{ + name = "industrial lift" + }, +/mob/living/basic/hivebot/rapid, +/turf/open/chasm, +/area/virtual_domain/powered) +"AJ" = ( +/obj/effect/decal/cleanable/generic, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"AP" = ( +/obj/structure/railing, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"AU" = ( +/turf/open/misc/asteroid/airless, +/area/space) +"Bd" = ( +/obj/structure/closet/secure_closet/tac{ + req_access = null + }, +/obj/item/ammo_casing/shotgun/buckshot, +/obj/item/ammo_casing/shotgun/buckshot, +/obj/item/ammo_casing/shotgun/buckshot, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Bh" = ( +/obj/structure/broken_flooring/corner/directional/east, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Bx" = ( +/obj/structure/table/reinforced, +/obj/machinery/microwave{ + broken = 1; + desc = "No longer cooks and boils stuff." + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"BA" = ( +/obj/structure/broken_flooring/corner/directional/south, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"BI" = ( +/obj/machinery/door/airlock/command/glass{ + name = "Quartermaster's Office" + }, +/obj/effect/mapping_helpers/airlock/access/any/away/command, +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"BN" = ( +/obj/structure/flora/rock/pile/style_random, +/turf/open/misc/asteroid/airless, +/area/space) +"BW" = ( +/obj/effect/decal/cleanable/dirt, +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"BX" = ( +/obj/effect/decal/cleanable/robot_debris/old, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Ci" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 8 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Ct" = ( +/obj/machinery/conveyor/auto{ + dir = 6 + }, +/obj/machinery/light/broken{ + dir = 1 + }, +/obj/structure/sign/warning/vacuum/directional/north, +/obj/structure/window/reinforced/spawner/directional/east, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Cv" = ( +/obj/structure/chair/office{ + dir = 8 + }, +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-157" + }, +/area/virtual_domain/powered) +"CA" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/broken_flooring/side{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"CQ" = ( +/obj/effect/spawner/random/trash/botanical_waste, +/obj/item/trash/chips, +/obj/structure/closet/secure_closet/freezer/empty/open, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"CR" = ( +/obj/structure/flora/rock/pile/style_random, +/turf/open/misc/asteroid/airless, +/area/virtual_domain/powered) +"CX" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Dr" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/obj/machinery/light/dim{ + dir = 8 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"DA" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/catwalk_floor/iron, +/area/virtual_domain/powered) +"DE" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"DP" = ( +/obj/structure/table/reinforced, +/obj/effect/spawner/random/food_or_drink/snack, +/turf/open/floor/iron/cafeteria, +/area/virtual_domain/powered) +"Ex" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-137" + }, +/area/virtual_domain/powered) +"Ez" = ( +/obj/structure/flora/rock/style_random, +/turf/open/misc/asteroid/airless, +/area/space) +"EI" = ( +/obj/effect/turf_decal/stripes{ + dir = 8 + }, +/obj/effect/decal/cleanable/oil, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"EJ" = ( +/obj/machinery/recycler/deathtrap{ + dir = 8 + }, +/obj/machinery/conveyor/auto{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Fa" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/closet/crate/maint, +/obj/effect/turf_decal/delivery, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Ff" = ( +/obj/structure/disposalpipe/trunk/multiz{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Fo" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron/cafeteria, +/area/virtual_domain/powered) +"Fr" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/closet/crate/preopen, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Fw" = ( +/obj/structure/flora/bush/fullgrass/style_random, +/obj/structure/flora/rock/pile/style_random, +/obj/structure/flora/bush/flowers_yw/style_random, +/obj/structure/window/reinforced/spawner/directional/north, +/obj/structure/window/reinforced/spawner/directional/west, +/turf/open/floor/grass, +/area/virtual_domain/powered) +"FK" = ( +/obj/effect/mapping_helpers/burnt_floor, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"FO" = ( +/turf/open/misc/asteroid/airless, +/area/virtual_domain/powered) +"FP" = ( +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-110" + }, +/area/virtual_domain/powered) +"Gb" = ( +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Ge" = ( +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-21" + }, +/area/virtual_domain/powered) +"Gh" = ( +/obj/machinery/door/airlock/maintenance, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Gi" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 9 + }, +/obj/effect/turf_decal/trimline/yellow/corner, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Gs" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 1 + }, +/obj/machinery/light/broken{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Gy" = ( +/obj/machinery/conveyor/auto{ + dir = 9; + inverted = 1; + icon_state = "conveyor_map_inverted" + }, +/obj/effect/turf_decal/stripes/line, +/obj/structure/window/reinforced/spawner/directional/west, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"GI" = ( +/obj/effect/turf_decal/trimline/yellow/arrow_ccw, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"GV" = ( +/obj/machinery/light/small/red/dim{ + dir = 8 + }, +/obj/effect/turf_decal/stripes{ + dir = 9 + }, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Hn" = ( +/turf/open/floor/iron/cafeteria, +/area/virtual_domain/powered) +"HI" = ( +/obj/structure/broken_flooring/pile/directional/north, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Ib" = ( +/obj/structure/chair/sofa/corp/left{ + dir = 1 + }, +/turf/open/floor/carpet/orange, +/area/virtual_domain/powered) +"Ip" = ( +/obj/machinery/door/airlock/engineering/glass, +/obj/effect/mapping_helpers/airlock/access/any/away/supply, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Is" = ( +/obj/machinery/door/airlock/engineering/glass, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"IF" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"IK" = ( +/obj/effect/turf_decal/trimline/yellow/line, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"IZ" = ( +/obj/structure/lattice/catwalk{ + name = "industrial lift" + }, +/obj/structure/closet/crate, +/turf/open/chasm, +/area/virtual_domain/powered) +"Jl" = ( +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Jm" = ( +/obj/structure/broken_flooring/pile/directional/north, +/obj/machinery/light/dim, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Jn" = ( +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/railing/corner/end/flip{ + dir = 8 + }, +/obj/structure/sign/warning/doors/directional/east, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Jq" = ( +/obj/structure/broken_flooring/pile{ + dir = 1 + }, +/obj/structure/sign/poster/contraband/random/directional/west, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"JE" = ( +/obj/machinery/light/small/red/dim{ + dir = 1 + }, +/obj/structure/sign/warning/chem_diamond/directional/west, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"JR" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"JT" = ( +/obj/structure/lattice/catwalk{ + name = "industrial lift" + }, +/obj/effect/spawner/random/trash/grime, +/turf/open/chasm, +/area/virtual_domain/powered) +"Kb" = ( +/obj/effect/mob_spawn/corpse/human/factory/guard, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Kt" = ( +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"KO" = ( +/obj/structure/broken_flooring/side/directional/north, +/obj/machinery/light/small/red/dim, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"KX" = ( +/obj/structure/lattice/catwalk{ + name = "industrial lift" + }, +/turf/open/chasm, +/area/virtual_domain/powered) +"Ln" = ( +/obj/structure/disposalpipe/broken{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Lp" = ( +/obj/effect/turf_decal/trimline/yellow/line, +/obj/machinery/light/broken, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"LN" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 10 + }, +/obj/machinery/light/dim{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"LU" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 6 + }, +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Mc" = ( +/obj/effect/turf_decal/trimline/yellow/warning, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Mh" = ( +/obj/machinery/conveyor/auto{ + dir = 8 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Mi" = ( +/obj/effect/mob_spawn/corpse/human/factory, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Mj" = ( +/turf/closed/mineral, +/area/virtual_domain/powered) +"Mu" = ( +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Mx" = ( +/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ + dir = 1 + }, +/obj/structure/filingcabinet, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"My" = ( +/obj/machinery/conveyor/auto{ + dir = 1 + }, +/obj/machinery/light/small/red/dim{ + dir = 8 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"MI" = ( +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-74" + }, +/area/virtual_domain/powered) +"MN" = ( +/obj/effect/turf_decal/tile/dark, +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + dir = 5 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Nc" = ( +/obj/structure/chair/plastic{ + dir = 8 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Nu" = ( +/obj/effect/turf_decal/trimline/yellow/line, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"NW" = ( +/obj/effect/decal/cleanable/dirt, +/mob/living/basic/hivebot/strong, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Ok" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"On" = ( +/obj/structure/broken_flooring/side{ + dir = 4 + }, +/obj/machinery/light/broken{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"OJ" = ( +/obj/structure/disposalpipe/segment, +/obj/effect/turf_decal/stripes{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"OL" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"OQ" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/sign/poster/ripped/directional/west, +/turf/open/floor/carpet/orange, +/area/virtual_domain/powered) +"OR" = ( +/obj/machinery/light/broken, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Po" = ( +/obj/machinery/light/small/red/dim{ + dir = 4 + }, +/obj/structure/disposalpipe/segment, +/obj/structure/broken_flooring/corner, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Pr" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 5 + }, +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 8 + }, +/obj/structure/sign/poster/official/random/directional/east, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"PH" = ( +/obj/structure/railing/corner/end/flip{ + dir = 8 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Qd" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 8 + }, +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 6 + }, +/obj/machinery/light/dim{ + dir = 8 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Qh" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/light/broken{ + dir = 8 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Qj" = ( +/obj/machinery/light/dim{ + dir = 8 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Qo" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"Qr" = ( +/turf/closed/indestructible/fakedoor/maintenance{ + name = "maintenance access" + }, +/area/virtual_domain/powered) +"Qv" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 9 + }, +/obj/machinery/light/small/red/dim{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Qy" = ( +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/structure/disposaloutlet{ + dir = 1 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"QI" = ( +/obj/structure/sign/calendar/directional/north, +/obj/effect/spawner/random/trash/garbage, +/turf/open/floor/iron/cafeteria, +/area/virtual_domain/powered) +"QK" = ( +/obj/structure/table, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"QN" = ( +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"QP" = ( +/obj/structure/sign/poster/contraband/random/directional/east, +/obj/effect/decal/cleanable/blood/old, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"QW" = ( +/obj/machinery/conveyor/auto{ + dir = 5 + }, +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Ru" = ( +/obj/machinery/door/airlock/external/glass/ruin, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Ry" = ( +/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ + dir = 4 + }, +/obj/structure/disposalpipe/trunk{ + dir = 8 + }, +/obj/machinery/disposal/bin, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"RJ" = ( +/turf/closed/indestructible/binary, +/area/virtual_domain/powered) +"RK" = ( +/obj/effect/decal/cleanable/blood/drip, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"RZ" = ( +/obj/effect/turf_decal/tile/yellow/half/contrasted{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 6 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Sg" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Sl" = ( +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 4 + }, +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 8 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"SC" = ( +/mob/living/basic/hivebot/strong, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"SR" = ( +/obj/effect/turf_decal/trimline/yellow/line, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"SS" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/closed/mineral, +/area/virtual_domain/powered) +"SU" = ( +/obj/effect/spawner/structure/window, +/obj/item/stack/rods/two, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"SZ" = ( +/obj/structure/table/reinforced, +/obj/effect/spawner/random/food_or_drink/booze, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Te" = ( +/obj/effect/decal/cleanable/blood/tracks{ + dir = 5 + }, +/obj/effect/mob_spawn/corpse/human/factory/qm, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Tn" = ( +/obj/structure/broken_flooring/corner{ + dir = 4 + }, +/mob/living/basic/hivebot, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Tp" = ( +/obj/machinery/door/poddoor/shutters/indestructible{ + dir = 4; + id = "factorylockdown" + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Tt" = ( +/obj/machinery/conveyor/auto{ + dir = 9 + }, +/obj/effect/turf_decal/stripes/corner{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"TH" = ( +/obj/structure/broken_flooring/corner/directional/south, +/obj/item/ammo_casing/shotgun/buckshot/spent, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Ue" = ( +/obj/structure/table/reinforced, +/obj/machinery/light/small/red/dim{ + dir = 8 + }, +/obj/structure/sign/poster/official/cleanliness/directional/west, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Uw" = ( +/obj/machinery/light/dim{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"UO" = ( +/obj/structure/broken_flooring/side/directional/north, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"UV" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 6 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"UX" = ( +/obj/effect/turf_decal/trimline/yellow/line, +/obj/machinery/light/small/red/dim, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"UY" = ( +/obj/effect/decal/cleanable/blood/tracks{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Vb" = ( +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 4 + }, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light/broken, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Vg" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 1 + }, +/obj/structure/disposalpipe/segment{ + dir = 9 + }, +/obj/machinery/light/small/red/dim, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Vh" = ( +/obj/structure/table/reinforced, +/turf/open/floor/iron/cafeteria, +/area/virtual_domain/powered) +"Vy" = ( +/obj/structure/broken_flooring/singular{ + dir = 4 + }, +/obj/effect/mob_spawn/corpse/human/factory/guard, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"VA" = ( +/obj/machinery/light/small/red/dim{ + dir = 1 + }, +/obj/structure/table, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"VJ" = ( +/obj/structure/broken_flooring/corner{ + dir = 1 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"VL" = ( +/obj/structure/sign/warning/secure_area/directional/south, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"VO" = ( +/obj/machinery/light/broken{ + dir = 1 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Wd" = ( +/obj/structure/lattice/catwalk{ + name = "industrial lift" + }, +/obj/structure/railing, +/turf/open/chasm, +/area/virtual_domain/powered) +"Wp" = ( +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"WT" = ( +/obj/effect/turf_decal/stripes{ + dir = 8 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"WV" = ( +/obj/machinery/conveyor/auto{ + dir = 10; + inverted = 1; + icon_state = "conveyor_map_inverted" + }, +/obj/effect/turf_decal/stripes/line{ + dir = 6 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Xb" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/closed/wall, +/area/virtual_domain/powered) +"Xc" = ( +/obj/effect/turf_decal/trimline/yellow/line, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Xm" = ( +/obj/item/gun/ballistic/shotgun/lethal, +/obj/machinery/light/broken{ + dir = 1 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Xo" = ( +/obj/machinery/conveyor/auto{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Xw" = ( +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 1 + }, +/obj/effect/turf_decal/trimline/yellow/line{ + dir = 10 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"XL" = ( +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 5 + }, +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 4 + }, +/obj/structure/sign/warning/vacuum/external/directional/south, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"XN" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"XO" = ( +/obj/effect/turf_decal/delivery, +/obj/effect/decal/cleanable/dirt, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"XP" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/railing/corner/end{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"XQ" = ( +/obj/effect/turf_decal/tile/yellow/anticorner/contrasted{ + dir = 4 + }, +/obj/machinery/light/dim{ + dir = 4 + }, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"XR" = ( +/obj/effect/turf_decal/trimline/yellow/warning{ + dir = 1 + }, +/obj/structure/disposalpipe/segment, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Yc" = ( +/obj/item/gun/ballistic/revolver, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Yl" = ( +/obj/structure/broken_flooring/corner/directional/west, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Ym" = ( +/mob/living/simple_animal/pet/cat/space, +/obj/structure/bed/dogbed{ + name = "cat bed" + }, +/obj/item/toy/plush/moth{ + pixel_x = 3; + pixel_y = 4 + }, +/obj/machinery/light/small/dim/directional/south, +/obj/structure/sign/poster/official/moth_hardhat/directional/west, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Yt" = ( +/obj/effect/decal/cleanable/dirt, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Yz" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/door/poddoor/shutters/indestructible{ + id = "factorylockdown" + }, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"YF" = ( +/obj/machinery/light/small/red/dim, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"YL" = ( +/obj/effect/turf_decal/tile/yellow/anticorner/contrasted, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"YP" = ( +/obj/effect/turf_decal/trimline/yellow/corner{ + dir = 1 + }, +/obj/machinery/light/dim, +/turf/open/floor/iron, +/area/virtual_domain/powered) +"Zb" = ( +/obj/effect/decal/cleanable/oil, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"Zg" = ( +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-157" + }, +/area/virtual_domain/powered) +"Zy" = ( +/obj/structure/table, +/obj/item/flashlight/lantern, +/turf/open/floor/plating, +/area/virtual_domain/powered) +"ZI" = ( +/turf/open/floor/carpet/royalblue{ + icon_state = "carpet_royalblue-203" + }, +/area/virtual_domain/powered) +"ZP" = ( +/obj/structure/railing, +/turf/open/floor/iron/stairs/right{ + dir = 8 + }, +/area/virtual_domain/powered) + +(1,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +"} +(2,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +Mj +Mj +eg +eg +SS +eg +eg +eg +Xb +Mj +Mj +RJ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +"} +(3,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +Mj +Bx +SZ +Ue +CQ +zB +eg +OQ +bs +Ib +Mj +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +yQ +yQ +"} +(4,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +eg +ho +ho +qN +ho +zO +eg +pa +bs +zp +eY +RJ +RJ +Mj +RJ +RJ +rO +rO +RJ +RJ +xF +"} +(5,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +eg +eg +eg +eg +eg +eg +eg +RJ +eg +um +DP +Vh +Vh +Hn +tr +fg +ZP +Fw +eY +Mj +Mj +Mj +AU +AU +AU +rO +rO +rO +RJ +"} +(6,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +eg +vA +Dr +bw +Jq +gc +eg +RJ +eg +Hn +fK +fK +fK +Hn +lC +hi +FK +eY +eY +Mj +Ez +AU +aK +aK +AU +AU +BN +rO +RJ +"} +(7,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +eg +jQ +lt +kU +vU +lN +eg +RJ +eg +QI +Fo +Hn +Hn +Hn +tr +hi +Ln +eY +Mj +Mj +AU +AU +BN +aK +aK +aK +AU +rO +RJ +"} +(8,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +eg +uU +gj +kU +Tn +OR +eg +RJ +eg +eg +uk +pf +pf +eg +eg +qV +Vb +eY +aK +aK +aK +aK +aK +aK +aK +aK +aK +aK +RJ +"} +(9,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +eg +ki +gj +kU +kU +kU +eg +RJ +eg +kU +kU +nD +nS +kU +Qj +FK +nc +eY +aK +aK +aK +aK +aK +aK +AU +aK +aK +aK +RJ +"} +(10,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +RJ +RJ +RJ +RJ +RJ +eg +eg +kJ +lx +lx +lp +eg +RJ +eg +mu +AJ +mu +eJ +MN +BW +hi +Sg +eY +aK +aK +aK +aK +aK +aK +aK +aK +aK +aK +RJ +"} +(11,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +eg +eg +eg +Qr +eg +eg +JE +gj +pi +kU +VL +eg +eg +eg +VO +kU +Fr +jw +qk +XR +vQ +Vg +eY +aK +aK +aK +JR +JR +JR +JR +JR +Qo +aK +RJ +"} +(12,1,1) = {" +yQ +yQ +yQ +yQ +RJ +RJ +RJ +eg +eg +eg +eg +eg +eg +yM +eg +GV +WT +xj +qk +Qh +XP +lW +ww +EI +Kt +Qh +mu +Yz +xl +HI +kU +Bh +Kb +kU +hi +CX +eY +eY +aK +aK +JR +JR +JR +JR +JR +JR +aK +RJ +"} +(13,1,1) = {" +yQ +yQ +yQ +yQ +RJ +RJ +RJ +eg +VA +bA +eg +kU +sB +WT +mh +kU +pv +AP +IZ +KX +Wd +uv +DE +Mi +gj +xT +hi +tl +IF +kU +hi +Yc +kU +kU +vU +lB +XL +eg +tr +eY +JR +JR +JR +JR +JR +JR +aK +RJ +"} +(14,1,1) = {" +yQ +yQ +yQ +yQ +RJ +RJ +kU +kU +Zy +kU +Gh +Kt +mu +mu +mu +uF +xl +AP +KX +JT +bG +qk +DA +DA +zE +gc +mu +Yz +lW +pi +kU +kU +nL +BW +hi +hg +Wp +Ru +hi +gs +JR +JR +JR +JR +JR +JR +aK +RJ +"} +(15,1,1) = {" +yQ +RJ +RJ +RJ +RJ +RJ +RJ +kU +QP +kU +eg +qT +Gb +Uw +iz +jS +gj +rJ +KX +Aw +Wd +Ff +lN +XO +gj +DE +SC +tl +qk +mu +mu +xl +kU +oX +hi +cF +cw +eY +tr +eY +JR +JR +JR +JR +JR +JR +aK +RJ +"} +(16,1,1) = {" +yQ +RJ +Mj +Mj +Mj +Mj +RJ +eg +eg +eg +eg +Xb +yB +eg +eg +kU +qk +PH +dA +Po +Jn +aw +OJ +CA +QN +kU +Uw +tl +kU +Mc +kU +kh +fj +kU +FK +CX +eY +eY +aK +aK +JR +JR +JR +JR +JR +JR +aK +RJ +"} +(17,1,1) = {" +yQ +RJ +Mj +BN +AU +Mj +Mj +Mj +eg +QW +My +Qy +kU +po +eg +tr +Is +tr +eg +eg +eg +kU +pi +kU +lI +YF +eg +eg +op +kU +BA +iw +kU +kU +FK +rz +eY +aK +aK +aK +JR +JR +JR +JR +JR +ev +aK +RJ +"} +(18,1,1) = {" +yQ +RJ +aK +AU +AU +AU +aK +aK +eg +Ct +oN +Gy +jW +xT +eg +Tp +Tp +Tp +eg +Ym +eg +eg +xa +xa +xa +eg +eg +eg +kU +Zb +kU +Yt +kU +UO +hi +CX +eY +aK +aK +aK +aK +aK +aK +aK +aK +aK +aK +RJ +"} +(19,1,1) = {" +RJ +RJ +aK +aK +aK +aK +wl +aK +yX +ve +Tt +Xo +DE +oX +eg +Sl +gV +dz +eg +uC +eg +qK +mh +kU +kU +Qj +VJ +eg +kU +kU +kU +gj +kU +kU +hi +Ok +eY +aK +aK +aK +aK +aK +aK +aK +aK +aK +aK +RJ +"} +(20,1,1) = {" +RJ +aK +aK +aK +aK +aK +aK +aK +tr +uz +Mh +EJ +kU +kU +mE +Mu +Yl +pJ +eg +kn +pb +kU +kU +kU +Fa +kU +YF +eg +eg +pf +tr +XN +eg +eg +Ci +YP +eY +eY +aK +aK +aK +aK +aK +aK +aK +aK +aK +RJ +"} +(21,1,1) = {" +RJ +aK +aK +aK +aK +aK +Av +CR +tr +kU +ei +WV +pi +Jm +eg +eN +gN +GI +eg +rc +mu +rM +gc +vQ +tE +mu +mu +eg +Mx +qc +ax +bS +fe +pf +hi +hi +af +eY +aK +aK +aK +aK +aK +aK +aK +aK +aK +RJ +"} +(22,1,1) = {" +RJ +aK +aK +aK +aK +aK +aK +FO +eg +eg +wg +uU +lN +uz +eg +mY +jH +rG +eg +xT +Uw +kU +kU +On +pi +kU +Mj +eg +wm +xA +fZ +OL +aL +Ip +hi +lN +QK +eY +aK +aK +aK +aK +BN +aK +aK +aK +aK +RJ +"} +(23,1,1) = {" +RJ +aK +aK +aK +aK +aK +AU +FO +Mj +eg +eg +Mj +Mj +eY +eY +UO +jH +Nu +eg +eg +eg +eg +eg +Mj +Mj +Mj +Mj +eg +RZ +vQ +wW +wU +dP +tr +hi +hi +Nc +eY +aK +BN +AU +aK +aK +aK +aK +aK +aK +RJ +"} +(24,1,1) = {" +RJ +RJ +aK +aK +aK +AU +Ez +Mj +Mj +RJ +Mj +Mj +Vy +hi +eY +CX +jH +Nu +eg +Gi +Qd +jv +fR +cB +Mj +RJ +RJ +eg +Ry +hk +pI +XQ +YL +eg +bq +hi +Mj +eY +Mj +Mj +AU +AU +aK +aK +aK +aK +rO +RJ +"} +(25,1,1) = {" +yQ +RJ +aK +AU +BN +AU +Mj +Mj +RJ +RJ +eY +Xm +TH +fw +eY +qW +hi +dx +pf +UV +sn +uP +Ge +vb +eg +RJ +RJ +eg +Mj +Mj +eg +eg +eg +eg +eg +Mj +Mj +RJ +RJ +Mj +Mj +Mj +RJ +RJ +Mj +Mj +Mj +RJ +"} +(26,1,1) = {" +yQ +RJ +RJ +RJ +RJ +rO +Mj +RJ +RJ +RJ +eY +Bd +vL +hi +vU +sW +hi +SR +SU +CX +FP +wh +Zg +Nu +eg +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +RJ +"} +(27,1,1) = {" +yQ +yQ +yQ +yQ +RJ +RJ +RJ +RJ +yQ +RJ +eY +Jl +RK +BX +eY +CX +RK +iI +BI +ws +ud +bx +Cv +Nu +eg +RJ +RJ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +"} +(28,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +eY +NW +UY +KO +eY +fl +jH +Nu +uk +CX +FP +wq +Zg +Nu +eg +RJ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +"} +(29,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +eY +xk +Te +xT +eY +CX +jH +Nu +pf +Xw +MI +ZI +Ex +xE +eg +RJ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +"} +(30,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +eY +eY +eY +eY +eY +CX +jH +Xc +eg +Pr +LN +xM +Qv +LU +Mj +RJ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +"} +(31,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +RJ +RJ +RJ +RJ +eg +Gs +jH +UX +eg +eg +eg +eg +Mj +Mj +Mj +RJ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +"} +(32,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +eg +Ok +nz +IK +eg +RJ +RJ +RJ +RJ +RJ +RJ +RJ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +"} +(33,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +Mj +CX +hi +Nu +RJ +RJ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +"} +(34,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +Mj +CX +RJ +Lp +eg +RJ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +"} +(35,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +RJ +fl +RJ +RJ +RJ +RJ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +"} +(36,1,1) = {" +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +RJ +RJ +RJ +RJ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +yQ +"} diff --git a/_maps/virtual_domains/pirates.dmm b/_maps/virtual_domains/pirates.dmm new file mode 100644 index 00000000000000..9c970f78c371a0 --- /dev/null +++ b/_maps/virtual_domains/pirates.dmm @@ -0,0 +1,2601 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"ag" = ( +/obj/effect/mapping_helpers/burnt_floor, +/obj/effect/decal/cleanable/garbage, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"by" = ( +/obj/effect/turf_decal/weather/sand{ + dir = 5 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"bz" = ( +/obj/structure/flora/bush/grassy{ + pixel_y = 8 + }, +/obj/structure/flora/bush/lavendergrass{ + pixel_y = -10 + }, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"bP" = ( +/obj/structure/flora/bush/flowers_br/style_random, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"cl" = ( +/obj/structure/flora/rock/style_3, +/turf/open/water/beach, +/area/virtual_domain/powered) +"ct" = ( +/obj/structure/closet/cabinet, +/obj/item/clothing/head/costume/pirate/armored, +/obj/item/clothing/suit/costume/pirate/captain/armored, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/parquet, +/area/virtual_domain/powered) +"cx" = ( +/turf/closed/indestructible/binary, +/area/virtual_domain/powered) +"cJ" = ( +/obj/item/stack/cannonball/shellball{ + pixel_x = 13; + pixel_y = 11 + }, +/obj/item/stack/cannonball{ + pixel_x = 9; + pixel_y = 9 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"cQ" = ( +/obj/structure/flora/grass/jungle/b{ + pixel_x = -15; + pixel_y = 9 + }, +/obj/structure/flora/rock/pile/jungle/large/style_2{ + pixel_x = -3; + pixel_y = -1 + }, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"dp" = ( +/turf/closed/wall/mineral/wood/nonmetal, +/area/virtual_domain/powered) +"dA" = ( +/obj/structure/bonfire/prelit, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"dQ" = ( +/obj/structure/flora/rock/style_4, +/turf/open/water/beach, +/area/virtual_domain/powered) +"eb" = ( +/obj/structure/flora/bush/sparsegrass, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"eD" = ( +/obj/structure/flora/coconuts{ + pixel_x = 9; + pixel_y = -14 + }, +/obj/structure/flora/tree/palm/style_2, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"eQ" = ( +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"eW" = ( +/obj/effect/turf_decal/weather/sand{ + dir = 6 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"fx" = ( +/obj/structure/fluff/beach_umbrella{ + pixel_x = -7; + pixel_y = -10 + }, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"gk" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/landmark/bitrunning/cache_spawn, +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"gw" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"ht" = ( +/obj/structure/bookcase/random/fiction, +/turf/open/floor/wood/parquet, +/area/virtual_domain/powered) +"hH" = ( +/obj/item/clothing/suit/armor/militia{ + pixel_x = -5; + pixel_y = 12 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/item/clothing/suit/armor/militia{ + pixel_x = -5; + pixel_y = 6 + }, +/obj/item/clothing/suit/armor/militia{ + pixel_x = -5; + pixel_y = -3 + }, +/obj/item/clothing/head/costume/fancy{ + pixel_x = 6; + pixel_y = 12 + }, +/obj/item/clothing/head/costume/fancy{ + pixel_x = 6; + pixel_y = 6 + }, +/obj/item/clothing/head/hats/coordinator{ + pixel_x = 8; + pixel_y = -5 + }, +/obj/structure/closet/cabinet, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"hM" = ( +/obj/structure/closet/crate/goldcrate, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"hW" = ( +/obj/structure/chair/comfy/carp{ + dir = 1 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"iM" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/mob/living/simple_animal/hostile/pirate/ranged/space, +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"iO" = ( +/obj/effect/turf_decal/weather/sand{ + dir = 4 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"jl" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/table/wood, +/obj/item/flashlight/flare/torch{ + pixel_y = 10; + pixel_x = 7 + }, +/obj/item/reagent_containers/cup/bucket/wooden{ + pixel_y = -16; + pixel_x = 12 + }, +/obj/machinery/recharger{ + pixel_y = 6; + pixel_x = -5 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"jz" = ( +/obj/effect/mapping_helpers/burnt_floor, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"jB" = ( +/obj/effect/turf_decal/weather/sand{ + dir = 4 + }, +/obj/effect/decal/cleanable/cobweb/cobweb2, +/obj/machinery/jukebox, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"jC" = ( +/obj/structure/table/wood, +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/item/reagent_containers/cup/glass/bottle/rum{ + desc = "Rum with ghostly properties that can help the drinker enter the spirit realm. It has fermented under the sea of space for ages."; + name = "Ghost Pirate Rum"; + pixel_x = -4; + pixel_y = 12 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass{ + pixel_x = -7; + pixel_y = 5 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass/shotglass{ + pixel_x = 3; + pixel_y = 7 + }, +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"jQ" = ( +/obj/item/gun/energy/laser/hellgun{ + pixel_y = 10 + }, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"kg" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"kl" = ( +/obj/structure/cannon, +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/ash/large{ + pixel_y = -5; + pixel_x = 8 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"lC" = ( +/obj/item/stack/cannonball{ + pixel_x = 7; + pixel_y = 8 + }, +/obj/item/stack/cannonball{ + pixel_x = 11; + pixel_y = -4 + }, +/obj/effect/turf_decal/weather/sand{ + dir = 1 + }, +/obj/effect/decal/cleanable/oil/streak, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"me" = ( +/obj/effect/turf_decal/siding/wood, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"mw" = ( +/obj/structure/flora/grass/jungle/b/style_random{ + pixel_x = -13; + pixel_y = 18 + }, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"mP" = ( +/obj/structure/flora/bush/fullgrass, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"nz" = ( +/obj/effect/mob_spawn/corpse/human/pirate, +/turf/open/misc/beach/coast{ + dir = 8 + }, +/area/virtual_domain/powered) +"nQ" = ( +/obj/machinery/loot_locator, +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"nS" = ( +/obj/structure/flora/rock/pile/jungle/large, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"nX" = ( +/obj/effect/decal/cleanable/dirt/dust, +/mob/living/simple_animal/hostile/pirate/melee/space, +/turf/open/floor/wood/parquet, +/area/virtual_domain/powered) +"oo" = ( +/obj/machinery/smartfridge/drying_rack, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"oU" = ( +/turf/open/misc/beach/coast{ + dir = 10 + }, +/area/virtual_domain/powered) +"pq" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"px" = ( +/obj/structure/headpike/bone{ + pixel_y = 24 + }, +/turf/open/misc/beach/coast, +/area/virtual_domain/powered) +"pP" = ( +/turf/open/misc/beach/coast, +/area/virtual_domain/powered) +"pU" = ( +/obj/effect/mob_spawn/corpse/human/pirate, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"qj" = ( +/obj/structure/barricade/wooden, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"qm" = ( +/obj/effect/turf_decal/siding/wood, +/obj/item/melee/sabre{ + pixel_y = 12; + pixel_x = -10 + }, +/obj/item/gun/energy/laser/retro, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"qx" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/mapping_helpers/burnt_floor, +/obj/effect/decal/cleanable/dirt/dust, +/mob/living/simple_animal/hostile/pirate/ranged, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"qN" = ( +/obj/structure/flora/bush/sunny/style_3{ + pixel_y = 22 + }, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"qX" = ( +/obj/effect/turf_decal/weather/sand{ + dir = 9 + }, +/obj/structure/fermenting_barrel{ + pixel_x = 6; + pixel_y = 11 + }, +/obj/effect/mob_spawn/ghost_role/human/pirate/skeleton, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"sn" = ( +/obj/structure/table/wood, +/obj/item/book/manual/wiki/ordnance, +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"so" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"th" = ( +/obj/effect/turf_decal/weather/sand, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"tk" = ( +/obj/structure/flora/bush/flowers_pp, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"to" = ( +/mob/living/simple_animal/hostile/pirate/melee, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"ub" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"uw" = ( +/obj/structure/barricade/sandbags, +/obj/effect/turf_decal/weather/sand{ + dir = 4 + }, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"uM" = ( +/obj/structure/flora/bush/stalky{ + pixel_y = 13; + pixel_x = -8 + }, +/turf/open/water/beach, +/area/virtual_domain/powered) +"uT" = ( +/obj/structure/closet/crate/grave, +/obj/structure/flora/grass/jungle/b, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"wb" = ( +/obj/structure/flora/rock, +/turf/open/water/beach, +/area/virtual_domain/powered) +"we" = ( +/obj/effect/mine/explosive/light, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"xc" = ( +/turf/open/misc/beach/coast{ + dir = 4 + }, +/area/virtual_domain/powered) +"xg" = ( +/turf/template_noop, +/area/template_noop) +"xm" = ( +/obj/structure/barricade/wooden/crude, +/turf/closed/wall/mineral/wood/nonmetal, +/area/virtual_domain/powered) +"xB" = ( +/obj/structure/fermenting_barrel/gunpowder{ + pixel_x = -4; + pixel_y = 17 + }, +/obj/structure/fermenting_barrel/gunpowder{ + pixel_x = 4 + }, +/obj/item/stack/cannonball/four{ + pixel_x = -9; + pixel_y = -10 + }, +/obj/item/stack/cannonball{ + pixel_x = 3; + pixel_y = 8 + }, +/obj/item/reagent_containers/cup/bucket/wooden{ + pixel_y = -10 + }, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"xC" = ( +/obj/effect/turf_decal/weather/dirt{ + dir = 1 + }, +/obj/effect/turf_decal/weather/dirt, +/turf/open/water/beach, +/area/virtual_domain/powered) +"xI" = ( +/obj/structure/flora/rock/pile/style_2, +/turf/open/water/beach, +/area/virtual_domain/powered) +"yc" = ( +/obj/effect/turf_decal/weather/dirt, +/turf/open/water/beach, +/area/virtual_domain/powered) +"ye" = ( +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"yi" = ( +/mob/living/simple_animal/hostile/pirate/melee, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"yq" = ( +/obj/structure/barricade/sandbags, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"yw" = ( +/obj/effect/mapping_helpers/burnt_floor, +/mob/living/simple_animal/hostile/pirate/ranged, +/obj/structure/chair/wood, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"yA" = ( +/obj/item/bedsheet/rainbow/double, +/obj/structure/bed/double, +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"zf" = ( +/obj/structure/flora/bush/flowers_br/style_random, +/obj/structure/flora/bush/ferny, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"zg" = ( +/obj/structure/flora/rock/pile/style_3, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"zR" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"Ax" = ( +/obj/effect/turf_decal/weather/dirt, +/obj/effect/turf_decal/weather/dirt, +/turf/open/water/beach, +/area/virtual_domain/powered) +"AU" = ( +/obj/effect/turf_decal/weather/dirt{ + dir = 1 + }, +/turf/open/water/beach, +/area/virtual_domain/powered) +"BC" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"BO" = ( +/obj/structure/bookcase/random/adult, +/obj/effect/decal/cleanable/cobweb, +/turf/open/floor/wood/parquet, +/area/virtual_domain/powered) +"Cc" = ( +/obj/structure/flora/tree/palm, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Ct" = ( +/turf/open/misc/beach/coast/corner, +/area/virtual_domain/powered) +"Dm" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/table/wood, +/obj/item/flashlight/flare/torch{ + pixel_y = 10 + }, +/obj/item/flashlight/flare/torch{ + pixel_x = 8; + pixel_y = 6 + }, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"DJ" = ( +/obj/effect/mapping_helpers/burnt_floor, +/obj/structure/bed/maint{ + pixel_x = -10; + pixel_y = 9 + }, +/obj/effect/decal/cleanable/wrapping, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"DL" = ( +/obj/structure/flora/bush/sunny, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"ED" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/turf_decal/weather/sand{ + dir = 10 + }, +/obj/effect/turf_decal/weather/sand{ + dir = 9 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"EZ" = ( +/obj/effect/turf_decal/weather/sand{ + dir = 9 + }, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"FG" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/item/claymore/cutlass, +/obj/item/clothing/head/costume/pirate/bandana/armored{ + pixel_x = -9; + pixel_y = 7 + }, +/obj/structure/table/wood, +/obj/item/gun/energy/laser{ + pixel_y = -3 + }, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"FT" = ( +/turf/closed/mineral/random/jungle, +/area/virtual_domain/powered) +"GF" = ( +/obj/effect/turf_decal/weather/dirt, +/obj/structure/flora/rock/pile, +/turf/open/water/beach, +/area/virtual_domain/powered) +"GG" = ( +/obj/structure/barricade/sandbags, +/obj/effect/turf_decal/weather/sand{ + dir = 6 + }, +/obj/item/binoculars{ + pixel_x = -1; + pixel_y = 1 + }, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"Hp" = ( +/obj/effect/turf_decal/siding/wood, +/mob/living/simple_animal/hostile/pirate/ranged, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"HY" = ( +/turf/open/misc/beach/coast{ + dir = 6 + }, +/area/virtual_domain/powered) +"It" = ( +/obj/structure/flora/bush/sparsegrass, +/obj/structure/flora/bush/lavendergrass, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"Iz" = ( +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/bed/maint, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"IF" = ( +/obj/effect/turf_decal/weather/dirt{ + dir = 4 + }, +/turf/open/water/beach, +/area/virtual_domain/powered) +"IG" = ( +/obj/effect/mob_spawn/corpse/human/pirate, +/obj/effect/decal/cleanable/blood/gibs/old, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"IM" = ( +/obj/effect/turf_decal/weather/sand{ + dir = 10 + }, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"Jo" = ( +/obj/effect/landmark/bitrunning/cache_spawn, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"Jr" = ( +/obj/structure/headpike/bone, +/turf/open/misc/beach/coast, +/area/virtual_domain/powered) +"Jv" = ( +/obj/effect/turf_decal/siding/wood, +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"JT" = ( +/obj/effect/decal/cleanable/ants, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"Kb" = ( +/obj/structure/railing{ + color = "#4C3117"; + name = "wooden railing" + }, +/obj/effect/decal/cleanable/vomit/old, +/obj/effect/turf_decal/weather/sand{ + dir = 1 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Kl" = ( +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Kw" = ( +/obj/machinery/door/airlock/vault{ + color = "#825427"; + name = "Ye Olde Strong Door" + }, +/turf/open/floor/wood/parquet, +/area/virtual_domain/powered) +"KC" = ( +/obj/effect/turf_decal/weather/dirt{ + dir = 5 + }, +/turf/open/water/beach, +/area/virtual_domain/powered) +"KG" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/obj/structure/table/wood, +/obj/item/gun/energy/laser/musket{ + pixel_y = 7 + }, +/obj/item/gun/energy/laser/musket{ + pixel_y = 2 + }, +/obj/item/gun/energy/laser/musket{ + pixel_y = -3 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"KQ" = ( +/obj/structure/flora/rock/style_2, +/turf/open/water/beach, +/area/virtual_domain/powered) +"Ld" = ( +/obj/structure/flora/rock/pile, +/turf/open/water/beach, +/area/virtual_domain/powered) +"Ma" = ( +/obj/structure/flora/bush/sparsegrass/style_random, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"Mi" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/decal/cleanable/dirt/dust, +/obj/effect/decal/cleanable/oil, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"MW" = ( +/obj/effect/turf_decal/weather/sand{ + dir = 5 + }, +/obj/effect/decal/cleanable/glass, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Nh" = ( +/obj/structure/flora/rock/pile/jungle/style_3{ + pixel_x = -15; + pixel_y = -4 + }, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"Nk" = ( +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Nz" = ( +/obj/structure/flora/bush/jungle, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"NI" = ( +/obj/structure/railing{ + color = "#4C3117"; + name = "wooden railing" + }, +/obj/effect/turf_decal/weather/sand{ + dir = 9 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"ON" = ( +/obj/item/kirbyplants/organic/plant21{ + pixel_x = -8 + }, +/obj/structure/filingcabinet{ + pixel_x = 11 + }, +/turf/open/floor/wood/parquet, +/area/virtual_domain/powered) +"OP" = ( +/obj/structure/flora/bush/stalky, +/turf/open/misc/beach/coast, +/area/virtual_domain/powered) +"Pq" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/effect/mapping_helpers/burnt_floor, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/bed/maint{ + pixel_x = 2; + pixel_y = 13 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Pz" = ( +/obj/structure/table/wood, +/mob/living/simple_animal/parrot{ + name = "pepper" + }, +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"PQ" = ( +/obj/structure/flora/grass/jungle/b, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"Qb" = ( +/obj/structure/flora/rock{ + pixel_x = 7 + }, +/turf/open/water/beach, +/area/virtual_domain/powered) +"Rr" = ( +/obj/structure/bed/maint{ + pixel_x = -5; + pixel_y = 9 + }, +/obj/effect/turf_decal/weather/sand{ + dir = 6 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"RR" = ( +/obj/effect/mapping_helpers/broken_floor, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"Sm" = ( +/obj/structure/flora/tree/jungle, +/obj/structure/flora/bush/fullgrass/style_random, +/turf/open/misc/grass, +/area/virtual_domain/powered) +"St" = ( +/obj/structure/table/wood, +/obj/item/melee/energy/sword/pirate{ + pixel_y = 10 + }, +/obj/item/clothing/mask/cigarette/cigar{ + pixel_x = 4 + }, +/obj/item/lighter{ + pixel_x = 10; + pixel_y = -8 + }, +/obj/machinery/light/small/directional/north, +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"Tp" = ( +/turf/open/misc/beach/coast/corner{ + dir = 1 + }, +/area/virtual_domain/powered) +"Tt" = ( +/obj/structure/cannon{ + dir = 1 + }, +/obj/effect/turf_decal/siding/wood{ + dir = 1 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"TO" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 8 + }, +/obj/machinery/light/small/directional/south, +/obj/effect/landmark/bitrunning/cache_spawn, +/turf/open/floor/carpet/blue, +/area/virtual_domain/powered) +"TP" = ( +/obj/effect/turf_decal/weather/dirt{ + dir = 4 + }, +/turf/open/misc/beach/coast{ + dir = 6 + }, +/area/virtual_domain/powered) +"TQ" = ( +/obj/effect/mapping_helpers/broken_floor, +/obj/effect/decal/cleanable/dirt/dust, +/obj/structure/bed/maint{ + pixel_x = 2; + pixel_y = 1 + }, +/obj/effect/decal/cleanable/cobweb, +/obj/item/toy/plush/beeplushie, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Uy" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/binary, +/area/virtual_domain/powered) +"UE" = ( +/obj/structure/barricade/sandbags, +/obj/effect/turf_decal/weather/sand{ + dir = 10 + }, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"Vg" = ( +/obj/effect/mob_spawn/corpse/human/pirate/melee, +/turf/open/water/beach, +/area/virtual_domain/powered) +"Vk" = ( +/obj/structure/barricade/sandbags, +/obj/effect/turf_decal/weather/sand, +/turf/open/floor/wood{ + icon_state = "wood_large" + }, +/area/virtual_domain/powered) +"VC" = ( +/obj/effect/mob_spawn/corpse/human/damaged, +/turf/open/water/beach, +/area/virtual_domain/powered) +"VF" = ( +/turf/open/water/beach, +/area/virtual_domain/powered) +"VX" = ( +/obj/effect/mapping_helpers/burnt_floor, +/obj/structure/rack{ + icon = 'icons/obj/fluff/general.dmi'; + icon_state = "minibar"; + name = "skeletal minibar" + }, +/obj/item/storage/bag/money/dutchmen{ + pixel_y = 13 + }, +/turf/open/floor/wood/parquet, +/area/virtual_domain/powered) +"WM" = ( +/obj/structure/flora/rock/pile/jungle/style_2, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) +"WP" = ( +/turf/open/floor/wood/parquet, +/area/virtual_domain/powered) +"Xn" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"XG" = ( +/obj/structure/fermenting_barrel/gunpowder{ + pixel_x = -4; + pixel_y = 17 + }, +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Yj" = ( +/obj/effect/landmark/bitrunning/cache_spawn, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"Yk" = ( +/obj/effect/decal/cleanable/dirt/dust, +/turf/open/floor/wood/parquet, +/area/virtual_domain/powered) +"Yq" = ( +/obj/effect/turf_decal/siding/wood{ + dir = 10 + }, +/turf/open/floor/wood, +/area/virtual_domain/powered) +"Zk" = ( +/obj/structure/flora/coconuts{ + pixel_x = 12 + }, +/obj/structure/flora/tree/palm, +/turf/open/misc/beach/sand, +/area/virtual_domain/powered) +"ZZ" = ( +/obj/structure/flora/grass/jungle, +/turf/open/misc/dirt/jungle, +/area/virtual_domain/powered) + +(1,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +cx +cx +cx +cx +cx +cx +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(2,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +cx +FT +FT +FT +FT +FT +FT +cx +cx +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(3,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +cx +cx +FT +FT +FT +FT +FT +FT +FT +FT +FT +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(4,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +cx +FT +FT +FT +FT +FT +FT +FT +FT +FT +FT +FT +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(5,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +FT +FT +FT +FT +FT +FT +zf +eb +we +FT +FT +FT +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(6,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +cx +cx +cx +FT +FT +FT +Sm +Ma +bz +JT +Kl +Kl +Kl +FT +FT +cx +cx +cx +cx +cx +cx +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(7,1,1) = {" +xg +xg +xg +xg +xg +cx +cx +cx +cx +FT +FT +FT +FT +It +tk +DL +Kl +Kl +Kl +Cc +Kl +IG +FT +cx +cx +FT +FT +FT +FT +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(8,1,1) = {" +xg +xg +xg +xg +cx +cx +FT +FT +FT +FT +FT +Nz +bP +mP +to +Kl +Kl +we +Kl +Kl +Kl +Kl +we +cx +cx +FT +FT +FT +FT +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(9,1,1) = {" +xg +xg +xg +cx +cx +FT +dp +dp +dp +dp +xB +yq +yq +Kl +Kl +Ct +xc +xc +xc +xc +xc +xc +xc +HY +VF +VF +VF +VF +VF +cx +cx +cx +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(10,1,1) = {" +xg +xg +xg +cx +FT +dp +dp +Pq +qx +Mi +th +Kl +yq +Kl +IG +OP +uM +VF +VF +VF +VF +VF +VF +VF +VF +VC +VF +VF +VF +VF +VF +dp +cx +cx +cx +xg +xg +xg +xg +xg +xg +xg +"} +(11,1,1) = {" +xg +xg +cx +cx +FT +dp +TQ +Iz +DJ +ag +eW +Kl +Kl +ED +Kl +Jr +VF +VF +VF +VF +VF +VF +VF +VF +VF +KQ +VF +VF +VF +VF +VF +dp +KG +pq +cx +cx +cx +cx +cx +cx +cx +Uy +"} +(12,1,1) = {" +xg +xg +cx +FT +FT +dp +Yj +MW +iO +Rr +qj +Kl +NI +xm +Ct +HY +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +wb +dp +jl +pq +BC +ub +ub +ub +ub +ub +Xn +cx +"} +(13,1,1) = {" +cx +cx +cx +FT +FT +FT +qj +Kl +Kl +Kl +Kl +Kl +lC +kl +pP +VF +VF +VF +VF +VF +VF +Vg +VF +VF +VF +VF +VF +VF +VF +VF +cl +dp +hH +Nk +qm +ub +ub +ub +ub +ub +ub +cx +"} +(14,1,1) = {" +cx +dp +dp +dp +dp +dp +dp +oo +Kl +Kl +Kl +Kl +Kb +dp +px +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +dp +dp +Nk +Jv +ub +ub +ub +ub +ub +ub +cx +"} +(15,1,1) = {" +cx +dp +BO +ht +VX +ct +dp +yi +Kl +dA +Kl +Kl +by +Hp +pP +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +me +ub +ub +ub +ub +ub +ub +cx +"} +(16,1,1) = {" +cx +dp +ON +WP +nX +Yk +Kw +Kl +Kl +Kl +Kl +Kl +Kl +dp +px +VF +VF +VF +VF +Qb +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +ub +ub +ub +ub +ub +ub +cx +"} +(17,1,1) = {" +cx +dp +jC +iM +so +TO +dp +Kl +Kl +EZ +IM +Kl +Kl +Kl +pP +VF +VF +VF +VF +cl +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +ub +ub +ub +ub +ub +ub +cx +"} +(18,1,1) = {" +cx +dp +sn +hW +eQ +gk +dp +dp +qX +gw +jz +UE +Kl +Zk +pP +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +me +VF +ub +ub +ub +ub +ub +zR +cx +"} +(19,1,1) = {" +cx +dp +St +Pz +nQ +yA +dp +dp +Dm +jz +jz +Vk +Kl +Kl +pP +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +dp +BC +VF +VF +VF +VF +VF +VF +cx +cx +"} +(20,1,1) = {" +cx +dp +dp +dp +dp +dp +dp +xm +FG +RR +yw +Vk +Kl +Kl +pP +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +Tt +cJ +Yq +VF +VF +VF +VF +VF +cx +xg +"} +(21,1,1) = {" +cx +cx +cx +FT +FT +Kl +Kl +dp +dp +jB +uw +GG +Kl +Kl +pP +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +xI +dp +XG +BC +VF +VF +VF +VF +VF +cx +xg +"} +(22,1,1) = {" +xg +xg +cx +FT +FT +fx +Kl +Kl +dp +dp +Kl +Kl +Kl +Kl +pP +VF +VF +VF +VF +VF +VF +dQ +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +kg +pq +Ld +VF +VF +VF +VF +VF +cx +xg +"} +(23,1,1) = {" +xg +xg +cx +FT +FT +FT +Kl +Kl +Kl +Kl +Kl +Kl +Kl +Kl +Tp +oU +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +FT +FT +cx +xg +"} +(24,1,1) = {" +xg +xg +cx +FT +FT +FT +FT +dp +Kl +eD +Kl +Kl +Kl +Kl +Kl +Tp +nz +oU +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +FT +FT +cx +xg +"} +(25,1,1) = {" +xg +xg +cx +cx +FT +FT +FT +FT +Kl +Kl +Kl +Kl +Kl +Kl +yi +Kl +Kl +pP +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +FT +FT +FT +cx +xg +"} +(26,1,1) = {" +xg +xg +xg +cx +cx +cx +FT +FT +FT +FT +FT +FT +FT +FT +FT +FT +FT +TP +VF +FT +FT +cx +cx +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +cx +FT +FT +FT +FT +cx +xg +"} +(27,1,1) = {" +xg +xg +xg +xg +xg +cx +FT +FT +FT +FT +FT +FT +FT +FT +FT +FT +FT +PQ +AU +FT +FT +FT +cx +cx +VF +VF +VF +VF +VF +VF +VF +VF +VF +VF +cx +cx +FT +FT +FT +cx +cx +xg +"} +(28,1,1) = {" +xg +xg +xg +xg +xg +cx +cx +FT +FT +FT +FT +FT +FT +FT +FT +FT +FT +Nh +AU +FT +FT +FT +FT +cx +cx +cx +cx +VF +VF +VF +VF +VF +VF +cx +cx +cx +cx +cx +cx +cx +xg +xg +"} +(29,1,1) = {" +xg +xg +xg +xg +xg +xg +cx +cx +cx +cx +cx +cx +FT +FT +FT +FT +FT +ye +KC +VF +FT +FT +FT +FT +FT +FT +cx +cx +cx +cx +cx +cx +cx +cx +xg +xg +xg +xg +xg +xg +xg +xg +"} +(30,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +cx +FT +FT +FT +FT +FT +zg +ye +KC +IF +VF +FT +FT +FT +FT +FT +cx +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(31,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +cx +FT +FT +FT +FT +FT +ye +ye +pU +AU +VF +GF +WM +FT +FT +FT +cx +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(32,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +cx +FT +FT +FT +FT +FT +ye +nS +KC +VF +Ax +ye +hM +FT +FT +FT +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(33,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +cx +FT +FT +FT +FT +ZZ +ye +cQ +KC +yc +qN +ye +hM +FT +FT +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(34,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +cx +FT +FT +FT +FT +ye +ye +mw +xC +uT +jQ +Jo +FT +FT +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(35,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +cx +cx +FT +FT +FT +FT +FT +FT +FT +FT +FT +FT +FT +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(36,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +FT +FT +FT +FT +FT +FT +FT +FT +FT +FT +FT +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} +(37,1,1) = {" +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +cx +cx +cx +cx +cx +cx +cx +cx +cx +cx +cx +cx +cx +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +xg +"} diff --git a/_maps/virtual_domains/stairs_and_cliffs.dmm b/_maps/virtual_domains/stairs_and_cliffs.dmm new file mode 100644 index 00000000000000..82e15fcc09097a --- /dev/null +++ b/_maps/virtual_domains/stairs_and_cliffs.dmm @@ -0,0 +1,6056 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"be" = ( +/obj/structure/railing/corner{ + dir = 1 + }, +/turf/open/cliff/snowrock/virtual_domain, +/area/icemoon/underground/explored/virtual_domain) +"cu" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/railing, +/obj/structure/railing{ + dir = 1 + }, +/turf/open/floor/wood, +/area/icemoon/underground/explored/virtual_domain) +"cJ" = ( +/obj/structure/chair/sofa/bench, +/turf/open/floor/plating/snowed/smoothed, +/area/icemoon/underground/explored/virtual_domain) +"dR" = ( +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"en" = ( +/obj/item/clothing/under/color/grey, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"eB" = ( +/obj/structure/flora/rock/icy/style_random, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"gB" = ( +/obj/structure/railing/corner, +/turf/open/cliff/snowrock/virtual_domain, +/area/icemoon/underground/explored/virtual_domain) +"hc" = ( +/obj/structure/railing/corner/end{ + dir = 8 + }, +/obj/structure/railing/corner/end/flip{ + dir = 8 + }, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"hE" = ( +/turf/open/floor/wood, +/area/icemoon/underground/explored/virtual_domain) +"jK" = ( +/obj/structure/railing/corner{ + dir = 8 + }, +/turf/open/cliff/snowrock/virtual_domain, +/area/icemoon/underground/explored/virtual_domain) +"kc" = ( +/obj/effect/decal/cleanable/blood/old, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"km" = ( +/obj/effect/decal/cleanable/blood/old, +/obj/effect/decal/cleanable/ash/large, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"kK" = ( +/obj/structure/flora/tree/pine/style_random, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"mx" = ( +/obj/structure/railing, +/obj/structure/railing{ + dir = 1 + }, +/turf/open/floor/wood, +/area/icemoon/underground/explored/virtual_domain) +"nj" = ( +/obj/structure/chair/sofa/bench/left, +/turf/open/floor/plating/snowed/smoothed, +/area/icemoon/underground/explored/virtual_domain) +"no" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/railing, +/obj/structure/railing{ + dir = 1 + }, +/turf/open/floor/wood, +/area/icemoon/underground/explored/virtual_domain) +"pl" = ( +/obj/structure/bonfire/prelit, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"pL" = ( +/turf/open/lava/plasma/virtual_domain, +/area/icemoon/underground/explored/virtual_domain) +"qc" = ( +/turf/open/misc/ice, +/area/icemoon/underground/explored/virtual_domain) +"sa" = ( +/obj/structure/flora/grass/green/style_random, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"sw" = ( +/obj/structure/flora/rock/pile/icy/style_random, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"sM" = ( +/turf/open/cliff/snowrock/virtual_domain, +/area/icemoon/underground/explored/virtual_domain) +"uJ" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"vz" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"xB" = ( +/obj/structure/railing/corner{ + dir = 4 + }, +/turf/open/floor/wood, +/area/icemoon/underground/explored/virtual_domain) +"yo" = ( +/turf/open/floor/plating/snowed/smoothed, +/area/icemoon/underground/explored/virtual_domain) +"yJ" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/obj/structure/railing, +/obj/structure/railing/corner{ + dir = 1 + }, +/turf/open/floor/wood, +/area/icemoon/underground/explored/virtual_domain) +"yL" = ( +/obj/structure/chair/sofa/bench/right, +/turf/open/floor/plating/snowed/smoothed, +/area/icemoon/underground/explored/virtual_domain) +"zn" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 8 + }, +/turf/open/floor/wood, +/area/icemoon/underground/explored/virtual_domain) +"Am" = ( +/turf/closed/indestructible/binary, +/area/icemoon/underground/explored/virtual_domain) +"AI" = ( +/obj/structure/flora/grass/green/style_random, +/turf/open/floor/plating/snowed/smoothed, +/area/icemoon/underground/explored/virtual_domain) +"BV" = ( +/obj/effect/decal/remains/plasma, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"Dz" = ( +/obj/structure/railing/corner/end{ + dir = 4 + }, +/obj/structure/railing/corner/end/flip{ + dir = 4 + }, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"DB" = ( +/obj/structure/flora/rock/icy/style_random, +/obj/structure/flora/rock/pile/icy/style_random, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"DY" = ( +/obj/structure/flora/rock/icy/style_random, +/obj/structure/flora/grass/green/style_random, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"Eh" = ( +/obj/structure/railing/corner{ + dir = 4 + }, +/turf/open/cliff/snowrock/virtual_domain, +/area/icemoon/underground/explored/virtual_domain) +"Gn" = ( +/obj/structure/flora/rock/pile/icy/style_random, +/obj/effect/decal/cleanable/blood/old, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"GX" = ( +/obj/effect/decal/cleanable/ash/large, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"HU" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/turf/open/floor/wood, +/area/icemoon/underground/explored/virtual_domain) +"Kl" = ( +/obj/effect/decal/remains/plasma, +/obj/effect/decal/cleanable/ash/large, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"KA" = ( +/obj/structure/statue/snow/snowman{ + name = "Norm"; + desc = "Norm has seen many a man roll down these cliffs, some more stubborn than others. Its usually the stubborn ones who stop getting back up." + }, +/obj/item/pickaxe/mini, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"Lw" = ( +/obj/structure/flora/rock/pile/icy/style_random, +/obj/structure/flora/grass/green/style_random, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"MP" = ( +/obj/structure/railing/corner/end/flip{ + dir = 4 + }, +/obj/structure/railing/corner/end{ + dir = 4 + }, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"MT" = ( +/obj/structure/railing/corner{ + dir = 8 + }, +/turf/open/floor/wood, +/area/icemoon/underground/explored/virtual_domain) +"Nv" = ( +/turf/open/floor/iron/stairs, +/area/icemoon/underground/explored/virtual_domain) +"NM" = ( +/obj/structure/railing/corner/end/flip{ + dir = 8 + }, +/obj/structure/railing/corner/end{ + dir = 8 + }, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"Pl" = ( +/obj/effect/turf_decal/weather/snow/corner{ + dir = 4 + }, +/obj/structure/railing{ + dir = 1 + }, +/obj/structure/railing/corner, +/turf/open/floor/wood, +/area/icemoon/underground/explored/virtual_domain) +"Qv" = ( +/turf/closed/indestructible/rock/snow/ice, +/area/icemoon/underground/explored/virtual_domain) +"RD" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/binary, +/area/icemoon/underground/explored/virtual_domain) +"Tz" = ( +/obj/item/pickaxe/mini, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"Ug" = ( +/obj/structure/flora/rock/icy/style_random, +/obj/effect/decal/cleanable/blood/old, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"VW" = ( +/obj/structure/closet/crate/secure/bitrunning/encrypted, +/turf/open/floor/plating/snowed/smoothed, +/area/icemoon/underground/explored/virtual_domain) +"YR" = ( +/obj/structure/flora/tree/pine/style_random, +/obj/structure/flora/grass/green/style_random, +/turf/open/misc/asteroid/snow, +/area/icemoon/underground/explored/virtual_domain) +"YT" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +RD +"} +(2,1,1) = {" +Am +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(3,1,1) = {" +Am +Qv +Qv +Qv +Qv +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(4,1,1) = {" +Am +Qv +Qv +Qv +dR +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(5,1,1) = {" +Am +Qv +Qv +dR +dR +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(6,1,1) = {" +Am +Qv +Qv +kK +sw +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(7,1,1) = {" +Am +Qv +Qv +dR +dR +sa +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(8,1,1) = {" +Am +Qv +Qv +eB +sw +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +Qv +Qv +Qv +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(9,1,1) = {" +Am +Qv +Qv +dR +eB +dR +sw +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(10,1,1) = {" +Am +Qv +dR +sw +eB +eB +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(11,1,1) = {" +Am +Qv +dR +eB +sw +sa +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pl +dR +sw +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(12,1,1) = {" +Am +Qv +dR +dR +sw +sa +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sw +dR +Nv +Nv +Nv +sM +sM +Nv +Nv +Nv +Nv +Nv +Nv +sM +sM +sM +sM +Nv +Nv +Nv +Nv +dR +qc +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(13,1,1) = {" +Am +Qv +dR +sa +sw +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sw +dR +dR +sM +Nv +Nv +Nv +Nv +sM +sM +sM +sM +Nv +Nv +Nv +Nv +Nv +Nv +Nv +Nv +Nv +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(14,1,1) = {" +Am +Qv +dR +dR +dR +dR +kK +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sw +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sa +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(15,1,1) = {" +Am +Qv +sw +sa +dR +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(16,1,1) = {" +Am +Qv +dR +sa +sa +sa +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +pl +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +GX +pL +pL +pL +pL +Qv +Qv +Qv +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(17,1,1) = {" +Am +Qv +dR +sa +sa +dR +yo +Nv +Nv +Nv +Nv +sM +sM +Nv +Nv +Nv +dR +dR +sM +sM +sM +sM +sM +dR +qc +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +sw +dR +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +dR +dR +pL +pL +pL +Qv +Qv +Qv +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(18,1,1) = {" +Am +Qv +Qv +dR +dR +yo +yo +sM +sM +sM +Nv +Nv +Nv +Nv +sM +sM +sa +qc +sM +sM +sM +sM +sM +dR +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +pL +dR +sa +pL +pL +sM +sM +sM +sM +sM +sM +sw +dR +sM +sM +sM +sM +sM +sM +sM +sM +pL +dR +en +dR +dR +pL +pL +Qv +Qv +Qv +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(19,1,1) = {" +Am +Qv +Qv +kK +sa +yo +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sw +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sw +BV +pL +sM +sM +sM +sM +sM +sM +eB +dR +sM +sM +sM +sM +sM +sM +sM +sM +pL +GX +sw +dR +dR +pL +pL +pL +pL +Qv +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(20,1,1) = {" +Am +Qv +Qv +dR +dR +yo +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +qc +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +kK +GX +pL +pL +sM +sM +sM +sM +sM +sM +sM +dR +qc +dR +sM +sM +sM +sM +sM +sM +pL +dR +dR +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(21,1,1) = {" +Am +Qv +Qv +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +pL +pL +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +sM +dR +dR +dR +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(22,1,1) = {" +Am +Qv +Qv +dR +sa +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sw +dR +dR +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Am +"} +(23,1,1) = {" +Am +Qv +Qv +Qv +sa +qc +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +qc +sM +sM +sM +sM +sM +sM +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +qc +sM +sM +sM +sM +sM +sM +DB +kc +dR +dR +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Am +"} +(24,1,1) = {" +Am +Qv +Qv +sw +eB +qc +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +qc +sM +sM +sM +sM +sM +sM +qc +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sa +dR +sM +sM +sM +sM +sM +sM +Ug +eB +dR +dR +dR +pL +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Am +"} +(25,1,1) = {" +Am +Qv +Qv +dR +dR +sa +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +qc +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +dR +Nv +Nv +Nv +Nv +Nv +Nv +Nv +Nv +Nv +Nv +Nv +Nv +sM +Nv +Nv +dR +dR +sM +sM +sM +sM +sM +sM +Ug +sw +dR +dR +dR +dR +dR +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Am +"} +(26,1,1) = {" +Am +Qv +Qv +dR +yo +dR +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +qc +dR +sM +sM +sM +sM +sM +dR +Nv +Nv +Nv +Nv +Nv +sM +sM +sM +sM +Nv +Nv +Nv +Nv +Nv +Nv +qc +qc +sM +sM +sM +sM +sM +sM +Ug +sw +dR +dR +dR +sa +dR +dR +dR +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Am +"} +(27,1,1) = {" +Am +Qv +Qv +dR +yo +sa +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sa +dR +sM +sM +sM +sM +dR +sM +sM +sM +sM +eB +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +dR +dR +kK +dR +dR +dR +sw +dR +dR +pL +pL +pL +pL +pL +Qv +Qv +Qv +Am +"} +(28,1,1) = {" +Am +Qv +Qv +sa +yo +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sa +dR +sM +sM +sM +sM +dR +sM +sM +sM +sM +dR +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +kK +sa +dR +qc +qc +sa +sa +dR +kK +dR +pL +pL +pL +pL +pL +pL +Qv +Qv +Am +"} +(29,1,1) = {" +Am +Qv +Qv +sa +yo +yo +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +dR +sM +sM +sM +sM +MP +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +dR +qc +qc +qc +sa +sa +dR +dR +dR +pL +pL +pL +pL +pL +Qv +Qv +Qv +Am +"} +(30,1,1) = {" +Am +Qv +Qv +qc +dR +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +dR +sM +sM +sM +sM +no +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +yL +dR +dR +dR +kK +dR +dR +dR +dR +dR +dR +dR +dR +pL +pL +pL +Qv +Qv +Qv +Am +"} +(31,1,1) = {" +Am +Qv +pl +qc +dR +yo +sM +sM +sM +sM +sM +sM +sM +dR +dR +Nv +Nv +Nv +Nv +qc +sM +sM +sM +sM +dR +dR +sM +sM +sM +mx +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +cJ +yo +dR +dR +dR +dR +dR +kK +sa +sa +dR +dR +dR +dR +dR +dR +dR +dR +Qv +Am +"} +(32,1,1) = {" +Am +Qv +sM +sM +zn +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sw +dR +sM +sM +sM +cu +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +nj +yo +dR +kK +dR +dR +dR +kK +sa +sa +dR +dR +dR +dR +kK +dR +dR +Qv +Qv +Am +"} +(33,1,1) = {" +Am +Qv +sM +sM +hE +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +NM +sM +sM +sM +sM +sM +sM +sM +qc +dR +Nv +Nv +Nv +Nv +Nv +dR +dR +sw +sM +sM +sM +sM +sM +sM +sM +sM +yo +yo +dR +dR +sa +dR +sw +dR +dR +dR +dR +sa +sa +dR +dR +dR +dR +Qv +Qv +Am +"} +(34,1,1) = {" +Am +Qv +sM +sM +hE +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sa +dR +sM +sM +sM +sM +sM +sM +sM +sM +qc +sM +sM +sM +dR +qc +sM +sM +sM +sM +sM +sM +qc +yo +Nv +Nv +Nv +Nv +Nv +yo +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +yo +dR +dR +sa +dR +dR +dR +dR +kK +qc +dR +dR +dR +dR +dR +dR +dR +Qv +Am +"} +(35,1,1) = {" +Am +Qv +sM +sM +hE +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +qc +sM +sM +sM +qc +sa +sM +sM +sM +sM +sM +sM +qc +dR +sM +sM +sM +sM +sM +eB +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +dR +yo +yo +dR +dR +dR +qc +qc +qc +qc +qc +dR +YT +YT +YT +YT +YT +vz +Qv +Am +"} +(36,1,1) = {" +Am +Qv +dR +sM +HU +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +qc +sM +sM +sM +sM +sM +sM +sM +sM +dR +qc +sM +sM +sw +dR +sM +sM +sM +sM +sM +sM +qc +dR +sM +sM +sM +sM +sM +kK +dR +qc +sM +sM +sM +sM +sM +sM +sM +sM +pl +dR +yo +dR +dR +dR +dR +dR +qc +qc +qc +dR +YT +YT +YT +YT +YT +YT +Qv +Am +"} +(37,1,1) = {" +Am +Qv +Qv +dR +dR +dR +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +dR +dR +sM +sM +sM +sM +eB +dR +sa +sM +sM +sM +sM +sM +sM +sa +yo +dR +sM +sM +sM +sM +sM +sM +sM +yo +dR +yo +dR +dR +dR +dR +sw +qc +qc +dR +dR +YT +YT +YT +YT +YT +YT +Qv +Am +"} +(38,1,1) = {" +Am +Qv +Qv +dR +yo +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +qc +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +dR +dR +sM +sM +sM +sM +dR +dR +qc +sM +sM +sM +sM +sM +sM +sM +yo +AI +Nv +Nv +Nv +Nv +Nv +Nv +Nv +yo +yo +yo +yo +yo +yo +dR +dR +yo +dR +yo +yo +YT +YT +YT +YT +YT +YT +Qv +Am +"} +(39,1,1) = {" +Am +Qv +Qv +dR +dR +dR +kK +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +qc +sM +sM +sM +sM +sM +sM +sM +dR +qc +sM +sM +sM +pl +dR +dR +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +yo +AI +Nv +Nv +Nv +Nv +Nv +Nv +Nv +yo +yo +yo +yo +dR +yo +yo +yo +yo +yo +yo +yo +YT +YT +YT +YT +YT +YT +Qv +Am +"} +(40,1,1) = {" +Am +Qv +Qv +dR +yo +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +qc +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +dR +dR +Nv +Nv +Nv +dR +kK +sM +sM +sM +sM +sM +sM +sM +sM +sw +dR +Nv +Nv +Nv +Nv +Nv +Nv +Nv +yo +yo +dR +dR +dR +yo +dR +yo +yo +yo +dR +yo +YT +YT +YT +YT +YT +YT +Qv +Am +"} +(41,1,1) = {" +Am +Qv +dR +sa +yo +dR +sa +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +dR +qc +sM +sM +sM +qc +Tz +Nv +Nv +Nv +qc +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +dR +sw +dR +dR +dR +dR +dR +dR +dR +dR +YT +YT +YT +YT +YT +uJ +Qv +Am +"} +(42,1,1) = {" +Am +Qv +dR +AI +yo +yo +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pl +KA +dR +dR +dR +sa +sa +dR +qc +qc +qc +dR +dR +dR +dR +dR +dR +dR +Qv +Am +"} +(43,1,1) = {" +Am +Qv +yo +yo +VW +yo +yo +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sa +dR +dR +kK +sa +sa +dR +dR +qc +qc +qc +dR +sa +sa +dR +dR +dR +Qv +Am +"} +(44,1,1) = {" +Am +Qv +dR +yo +yo +yo +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +qc +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sa +dR +sa +dR +dR +dR +dR +kK +qc +qc +qc +dR +sa +sa +dR +dR +dR +Qv +Am +"} +(45,1,1) = {" +Am +Qv +dR +dR +yo +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +dR +dR +dR +dR +kK +dR +dR +dR +dR +Qv +dR +Qv +dR +kK +dR +Qv +Qv +Am +"} +(46,1,1) = {" +Am +Qv +Qv +sa +dR +dR +sa +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +qc +dR +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +kK +dR +dR +dR +dR +dR +dR +dR +dR +dR +dR +Qv +Qv +Qv +dR +dR +dR +Qv +Qv +Am +"} +(47,1,1) = {" +Am +Qv +Qv +dR +dR +YR +sa +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +dR +dR +qc +Nv +Nv +Nv +sM +sM +sM +sM +Nv +Nv +Nv +Nv +sM +sM +sM +Nv +Nv +Nv +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +dR +pL +dR +dR +dR +dR +dR +dR +Qv +Qv +Qv +Qv +Qv +dR +dR +dR +Qv +Qv +Am +"} +(48,1,1) = {" +Am +Qv +Qv +dR +kK +sa +YR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +dR +dR +dR +sw +sM +Nv +Nv +Nv +Nv +Nv +Nv +sM +sM +Nv +Nv +Nv +Nv +Nv +sM +Nv +Nv +Nv +qc +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +dR +dR +dR +dR +Qv +Qv +Qv +Qv +dR +sw +dR +dR +dR +Qv +Am +"} +(49,1,1) = {" +Am +Qv +Qv +dR +dR +YR +sa +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +qc +sM +sM +sM +sM +sM +eB +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +dR +dR +dR +dR +dR +pL +pL +Qv +Qv +Qv +Qv +dR +sw +dR +dR +Qv +Am +"} +(50,1,1) = {" +Am +Qv +Qv +sa +dR +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sa +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +pl +sM +sM +sM +sM +sM +sM +dR +pL +pL +dR +dR +sa +dR +pL +pL +pL +pL +Qv +Qv +Qv +sw +eB +dR +dR +Qv +Am +"} +(51,1,1) = {" +Am +Qv +Qv +Qv +dR +sa +kK +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sa +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sa +sM +sM +sM +sM +sM +sM +dR +pL +dR +dR +kK +dR +dR +pL +pL +pL +pL +Qv +Qv +Qv +Qv +dR +dR +sa +Qv +Am +"} +(52,1,1) = {" +Am +Qv +Qv +Qv +dR +sa +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +pL +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sa +sM +sM +sM +sM +sM +sM +dR +pL +dR +dR +dR +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +dR +dR +dR +Qv +Am +"} +(53,1,1) = {" +Am +Qv +Qv +Qv +dR +YR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sw +Dz +sM +sM +sM +sM +sM +pL +pL +pL +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +dR +dR +dR +sa +dR +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +dR +dR +Qv +Am +"} +(54,1,1) = {" +Am +Qv +Qv +Qv +dR +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +jK +yJ +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +sM +sM +GX +dR +dR +pL +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sa +dR +sw +sa +dR +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +dR +Qv +Qv +Am +"} +(55,1,1) = {" +Am +Qv +Qv +dR +dR +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +MT +be +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +pL +dR +kK +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +qc +sM +sM +sM +sM +sM +dR +sw +eB +dR +dR +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +dR +dR +dR +Qv +Am +"} +(56,1,1) = {" +Am +Qv +Qv +dR +eB +sw +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +gB +xB +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +qc +sM +sM +sM +sM +sM +km +sw +eB +eB +sw +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +dR +dR +dR +Qv +Am +"} +(57,1,1) = {" +Am +Qv +Qv +dR +Lw +sa +sa +kK +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +Pl +Eh +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +dR +sw +dR +sM +sM +sM +sM +sM +sM +sM +sM +sa +eB +sM +sM +sM +sM +sM +pL +dR +eB +eB +dR +dR +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +dR +dR +dR +Qv +Am +"} +(58,1,1) = {" +Am +Qv +Qv +dR +sa +sa +YR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +hc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +Gn +eB +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +dR +sw +sM +sM +sM +sM +sM +pL +GX +dR +pL +dR +dR +pL +pL +pL +pL +Qv +Qv +Qv +Qv +dR +sa +dR +dR +Qv +Am +"} +(59,1,1) = {" +Am +Qv +Qv +sa +YR +sa +sa +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +qc +sM +sM +sM +dR +sM +sM +Nv +Nv +Nv +dR +sM +sM +sM +sM +sM +kK +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +pL +dR +dR +pL +dR +pL +pL +pL +pL +pL +pL +Qv +Qv +dR +dR +dR +Qv +Qv +Qv +Am +"} +(60,1,1) = {" +Am +Qv +Qv +dR +dR +sw +kK +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +dR +dR +Nv +Nv +Nv +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +kK +dR +qc +sM +sM +sM +sM +sM +pL +GX +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +dR +dR +dR +Qv +Qv +Qv +Am +"} +(61,1,1) = {" +Am +Qv +dR +kK +sw +eB +eB +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +dR +sM +sM +sM +sM +sM +dR +sa +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +dR +dR +dR +Qv +Qv +Qv +Qv +Am +"} +(62,1,1) = {" +Am +Qv +dR +sa +DY +eB +eB +dR +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sa +dR +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sa +dR +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +dR +dR +Qv +Qv +Qv +Qv +Qv +Am +"} +(63,1,1) = {" +Am +Qv +dR +Lw +Lw +dR +sa +dR +sM +sM +sM +sM +sM +sM +sM +sM +eB +dR +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sa +dR +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +dR +Qv +Qv +dR +dR +dR +dR +Qv +Qv +Qv +Qv +Am +"} +(64,1,1) = {" +Am +Qv +dR +sa +sa +sw +kK +dR +sM +sM +sM +sM +sM +sM +sM +sM +sw +dR +sM +sM +sM +sM +sM +qc +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +eB +dR +dR +dR +sa +dR +sw +Qv +Qv +Qv +Qv +Qv +Am +"} +(65,1,1) = {" +Am +Qv +dR +dR +kK +dR +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +qc +sM +sM +sM +sM +qc +sM +sM +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +Nv +Nv +Nv +Nv +Nv +Nv +dR +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +sw +sa +sa +dR +sw +sw +eB +Qv +Qv +Qv +Qv +Qv +Am +"} +(66,1,1) = {" +Am +Qv +dR +kK +sa +sa +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +sa +dR +sM +sM +sM +sM +qc +sM +sM +sM +sM +sa +dR +sM +sM +sM +sM +sM +sw +dR +Nv +Nv +Nv +Nv +Nv +sM +sM +sM +Nv +Nv +dR +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +dR +sa +sa +dR +dR +dR +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(67,1,1) = {" +Am +Qv +dR +dR +YR +DY +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sa +dR +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +dR +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +sa +dR +dR +dR +Qv +Qv +Qv +Qv +Qv +Am +"} +(68,1,1) = {" +Am +Qv +dR +dR +Lw +sa +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +sM +sM +sM +dR +dR +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +sa +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +dR +dR +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(69,1,1) = {" +Am +Qv +Qv +dR +eB +sw +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +dR +Nv +Nv +Nv +dR +dR +sM +sM +sM +sM +sM +dR +sM +sM +sM +sM +sM +dR +qc +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(70,1,1) = {" +Am +Qv +Qv +Qv +dR +eB +sw +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +kK +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +Nv +dR +dR +dR +dR +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(71,1,1) = {" +Am +Qv +Qv +dR +sa +sa +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +dR +qc +dR +pl +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +Kl +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(72,1,1) = {" +Am +Qv +Qv +sa +sa +Lw +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(73,1,1) = {" +Am +Qv +Qv +Qv +dR +sw +dR +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +sM +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +pL +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(74,1,1) = {" +Am +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Qv +Am +"} +(75,1,1) = {" +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +Am +"} diff --git a/_maps/virtual_domains/syndicate_assault.dmm b/_maps/virtual_domains/syndicate_assault.dmm new file mode 100644 index 00000000000000..770f0967404c7f --- /dev/null +++ b/_maps/virtual_domains/syndicate_assault.dmm @@ -0,0 +1,4265 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aq" = ( +/obj/item/storage/backpack/duffelbag/syndie/surgery, +/obj/structure/table/reinforced, +/turf/open/floor/plastic, +/area/ruin/space/has_grav/powered/virtual_domain) +"aw" = ( +/obj/structure/table/reinforced, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"aN" = ( +/obj/structure/closet/crate/secure/gear{ + req_access = list("syndicate") + }, +/obj/item/stack/sheet/iron/fifty, +/obj/item/stack/sheet/iron/fifty, +/obj/item/stack/sheet/iron/fifty, +/obj/item/stack/sheet/plasteel/twenty, +/obj/item/stack/sheet/mineral/plastitanium{ + amount = 50 + }, +/obj/item/stack/sheet/glass/fifty, +/obj/item/stack/rods/fifty, +/turf/open/floor/pod/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"aO" = ( +/obj/machinery/recharge_station, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"aZ" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/mob/living/basic/syndicate/ranged/shotgun/space/stormtrooper, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"bh" = ( +/turf/open/floor/carpet/royalblack, +/area/ruin/space/has_grav/powered/virtual_domain) +"bo" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 1 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"bD" = ( +/obj/structure/table/reinforced, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"bG" = ( +/turf/open/floor/pod/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"cc" = ( +/obj/structure/closet/crate/secure/gear{ + req_access = list("syndicate") + }, +/obj/effect/spawner/random/clothing/costume, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"cj" = ( +/obj/structure/transit_tube/crossing, +/turf/closed/wall/r_wall/syndicate, +/area/ruin/space/has_grav/powered/virtual_domain) +"ct" = ( +/obj/structure/closet/syndicate{ + anchored = 1; + desc = "A basic closet for all your villainous needs."; + locked = 1; + name = "Closet"; + req_access = list("syndicate"); + secure = 1 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"cw" = ( +/obj/structure/closet/syndicate{ + anchored = 1; + desc = "A basic closet for all your villainous needs."; + locked = 1; + name = "Closet"; + req_access = list("syndicate"); + secure = 1 + }, +/obj/item/clothing/under/syndicate/combat, +/obj/item/clothing/gloves/combat, +/obj/item/clothing/shoes/combat, +/obj/item/clothing/mask/gas/syndicate, +/obj/item/clothing/under/syndicate/skirt, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"cy" = ( +/obj/machinery/door/airlock/grunge{ + name = "Syndicate Ship Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"cB" = ( +/obj/machinery/camera/xray{ + c_tag = "Medbay"; + dir = 6; + network = list("fsci"); + screen_loc = "" + }, +/turf/open/floor/plastic, +/area/ruin/space/has_grav/powered/virtual_domain) +"cR" = ( +/obj/machinery/light/small/directional/south, +/turf/open/floor/carpet/royalblack, +/area/ruin/space/has_grav/powered/virtual_domain) +"cZ" = ( +/obj/structure/table/reinforced, +/obj/item/gun/ballistic/automatic/l6_saw/unrestricted, +/obj/item/ammo_box/magazine/m7mm, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"da" = ( +/obj/machinery/stasis, +/turf/open/floor/plastic, +/area/ruin/space/has_grav/powered/virtual_domain) +"dd" = ( +/obj/structure/sign/warning/vacuum/external, +/turf/closed/wall/r_wall/syndicate, +/area/ruin/space/has_grav/powered/virtual_domain) +"di" = ( +/obj/machinery/power/terminal{ + dir = 1 + }, +/obj/structure/cable, +/obj/item/paper/fluff/ruins/forgottenship/powerissues, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"dw" = ( +/obj/machinery/light/small/directional/south, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"dz" = ( +/obj/effect/landmark/bitrunning/cache_spawn, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"dU" = ( +/obj/structure/cable, +/obj/structure/fans/tiny, +/obj/machinery/door/airlock/external/ruin{ + name = "Syndicate Ship Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"eB" = ( +/obj/machinery/camera/xray{ + c_tag = "Cargo pod"; + dir = 9; + network = list("fsci"); + screen_loc = "" + }, +/obj/structure/closet, +/obj/item/clothing/under/syndicate/tacticool, +/obj/item/clothing/under/syndicate/tacticool, +/obj/item/clothing/under/syndicate/tacticool, +/obj/item/card/id/advanced/black/syndicate_command/crew_id, +/obj/item/card/id/advanced/black/syndicate_command/crew_id, +/obj/item/card/id/advanced/black/syndicate_command/crew_id, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"fd" = ( +/obj/structure/transit_tube/crossing, +/turf/open/space/basic, +/area/space) +"fG" = ( +/obj/structure/toilet{ + dir = 1 + }, +/obj/machinery/light/directional/south, +/turf/open/floor/iron, +/area/ruin/space/has_grav/powered/virtual_domain) +"fJ" = ( +/obj/machinery/light/small/directional/north, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"fM" = ( +/obj/machinery/computer/crew/syndie{ + dir = 8 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"fV" = ( +/obj/machinery/atmospherics/components/unary/vent_pump, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"gD" = ( +/obj/effect/mob_spawn/ghost_role/human/syndicatespace, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"hg" = ( +/obj/structure/window/reinforced/plasma/plastitanium, +/obj/machinery/door/poddoor{ + id = "fslockdown"; + name = "Ship Blast Door"; + state_open = 1 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"hy" = ( +/obj/structure/table/reinforced, +/obj/item/paper/fluff/ruins/forgottenship/missionobj, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"hA" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/wall/r_wall/syndicate, +/area/ruin/space/has_grav/powered/virtual_domain) +"hD" = ( +/obj/structure/table/reinforced, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"ip" = ( +/mob/living/basic/syndicate/melee/sword/space/stormtrooper, +/turf/open/floor/plastic, +/area/ruin/space/has_grav/powered/virtual_domain) +"iB" = ( +/obj/machinery/light/directional/north, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"iL" = ( +/obj/structure/sign/departments/cargo, +/turf/closed/wall/r_wall/syndicate, +/area/ruin/space/has_grav/powered/virtual_domain) +"iU" = ( +/obj/structure/closet/crate/secure/gear{ + req_access = list("syndicate") + }, +/obj/item/melee/energy/sword/saber/red, +/obj/machinery/light/small/directional/north, +/turf/open/floor/pod/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"iW" = ( +/obj/structure/table/reinforced, +/obj/machinery/button/door{ + id = "fslockdown"; + name = "Window shutters"; + req_access = list("syndicate") + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"iX" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/mob/living/basic/syndicate/ranged/smg/space/stormtrooper, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"ja" = ( +/obj/machinery/door/window{ + dir = 1; + name = "Spare Equipment"; + req_access = list("syndicate") + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"jl" = ( +/obj/structure/bodycontainer/crematorium{ + id = "fscremate" + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"jA" = ( +/obj/structure/cable, +/mob/living/basic/syndicate/melee/space/stormtrooper, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"jJ" = ( +/obj/machinery/door/airlock/grunge{ + name = "Syndicate Ship Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/iron/dark/side{ + dir = 1 + }, +/area/ruin/space/has_grav/powered/virtual_domain) +"kh" = ( +/obj/machinery/door/airlock/grunge{ + name = "Syndicate Ship Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"ki" = ( +/obj/structure/table/reinforced, +/obj/machinery/computer/security/telescreen/interrogation{ + name = "Cameras monitor"; + network = list("fsci"); + req_access = list("syndicate"); + screen_loc = "" + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"kI" = ( +/obj/machinery/computer/atmos_alert{ + dir = 8 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"kJ" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"li" = ( +/obj/structure/transit_tube/station/dispenser/reverse{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"ln" = ( +/obj/machinery/turretid{ + control_area = "/area/ruin/space/has_grav/syndicate_forgotten_ship"; + enabled = 0; + icon_state = "control_kill"; + lethal = 1; + name = "Ship turret control panel"; + pixel_y = 32; + req_access = list("syndicate") + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"lo" = ( +/obj/structure/fans/tiny, +/obj/machinery/door/airlock/external/ruin{ + name = "Syndicate Ship Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"lN" = ( +/obj/machinery/light/small/directional/east, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"mo" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/layer2{ + dir = 8 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"mD" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 10 + }, +/obj/item/wrench, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"nk" = ( +/obj/machinery/power/apc/auto_name/directional/north, +/obj/effect/mapping_helpers/apc/syndicate_access, +/obj/structure/cable, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"nB" = ( +/turf/closed/mineral/random, +/area/space) +"nG" = ( +/obj/machinery/light/directional/south, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"nO" = ( +/obj/machinery/mineral/ore_redemption{ + name = "Syndicate ore redemption machine"; + ore_multiplier = 4; + req_access = list("syndicate") + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"nU" = ( +/obj/structure/sign/poster/contraband/syndicate_pistol, +/turf/closed/wall/r_wall/syndicate, +/area/ruin/space/has_grav/powered/virtual_domain) +"oM" = ( +/obj/structure/cable, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"oZ" = ( +/mob/living/basic/syndicate/melee/sword/space/stormtrooper, +/turf/open/floor/carpet/royalblack, +/area/ruin/space/has_grav/powered/virtual_domain) +"pl" = ( +/obj/machinery/atmospherics/components/tank/air{ + dir = 8 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"pz" = ( +/obj/machinery/computer/security{ + desc = "Used to access interrogation room camera."; + dir = 8; + name = "Ship cameras console"; + network = list("fsc","fsci"); + screen_loc = "" + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"pH" = ( +/obj/structure/table/reinforced, +/obj/item/toy/plush/nukeplushie, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"pM" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"pS" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 6 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"pU" = ( +/obj/machinery/shower/directional/north, +/obj/machinery/light/directional/south, +/turf/open/floor/iron, +/area/ruin/space/has_grav/powered/virtual_domain) +"qf" = ( +/obj/structure/table/optable, +/obj/machinery/light/small/directional/north, +/turf/open/floor/plastic, +/area/ruin/space/has_grav/powered/virtual_domain) +"qx" = ( +/turf/open/space/basic, +/area/space) +"qU" = ( +/obj/structure/sign/poster/contraband/c20r, +/turf/closed/wall/r_wall/syndicate, +/area/ruin/space/has_grav/powered/virtual_domain) +"qY" = ( +/obj/machinery/light/small/directional/south, +/turf/open/floor/iron/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"rm" = ( +/obj/machinery/button/crematorium{ + id = "fscremate"; + pixel_x = -32 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"ru" = ( +/turf/closed/wall/r_wall/syndicate, +/area/ruin/space/has_grav/powered/virtual_domain) +"rH" = ( +/obj/machinery/airalarm/directional/north, +/obj/effect/mapping_helpers/airalarm/syndicate_access, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"rM" = ( +/obj/structure/closet/syndicate{ + anchored = 1; + desc = "A basic closet for all your villainous needs."; + locked = 1; + name = "Closet"; + req_access = list("syndicate"); + secure = 1 + }, +/obj/effect/spawner/random/contraband/armory, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"rP" = ( +/obj/effect/mob_spawn/ghost_role/human/syndicatespace, +/obj/machinery/light/small/directional/south, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"sg" = ( +/obj/machinery/ore_silo, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"sq" = ( +/obj/machinery/door/window{ + name = "Control Room"; + req_access = list("syndicate") + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"sz" = ( +/obj/machinery/atmospherics/components/unary/vent_pump{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"sH" = ( +/obj/structure/displaycase{ + req_access = list("syndicate"); + start_showpiece_type = /obj/item/gun/ballistic/automatic/pistol/deagle/camo + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"sK" = ( +/obj/structure/closet/crate/secure/gear{ + req_access = list("syndicate") + }, +/obj/item/stack/sheet/mineral/titanium{ + amount = 40 + }, +/obj/item/stack/sheet/mineral/uranium{ + amount = 15 + }, +/turf/open/floor/pod/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"sL" = ( +/obj/structure/chair/comfy, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"sM" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"tv" = ( +/obj/structure/table/reinforced, +/obj/machinery/button/door{ + id = "fscaproom"; + name = "Room shutters control"; + req_access = list("syndicate") + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"tI" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"uP" = ( +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"vp" = ( +/obj/structure/table/reinforced, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"vD" = ( +/obj/machinery/portable_atmospherics/canister/oxygen, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"vK" = ( +/obj/machinery/door/airlock/grunge{ + name = "Syndicate Ship Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"vU" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"wb" = ( +/obj/machinery/atmospherics/components/unary/portables_connector/visible/layer2, +/obj/machinery/portable_atmospherics/scrubber{ + anchored = 1 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"we" = ( +/turf/closed/mineral/random/high_chance, +/area/space) +"wK" = ( +/obj/machinery/door/airlock/grunge{ + name = "Syndicate Ship Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/iron/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"wL" = ( +/obj/structure/table/reinforced, +/obj/item/storage/medkit/regular, +/obj/machinery/light/small/directional/north, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"xJ" = ( +/obj/structure/closet/syndicate{ + anchored = 1; + desc = "A basic closet for all your villainous needs."; + locked = 1; + name = "Closet"; + req_access = list("syndicate"); + secure = 1 + }, +/obj/item/ammo_box/c9mm, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"xZ" = ( +/obj/machinery/computer/camera_advanced/syndie{ + dir = 8 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"yl" = ( +/obj/machinery/door/airlock/grunge{ + name = "Captain's Room" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/poddoor{ + id = "fscaproom"; + name = "Captain's Blast Door"; + state_open = 1 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"yD" = ( +/mob/living/basic/syndicate/ranged/smg/space/stormtrooper, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"yJ" = ( +/obj/structure/table/reinforced, +/obj/machinery/atmospherics/components/unary/vent_scrubber/layer2, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"yR" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"yT" = ( +/obj/item/ai_module/core/full/cybersun, +/obj/structure/table/reinforced, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"yV" = ( +/obj/structure/table/reinforced, +/obj/item/assembly/prox_sensor, +/obj/item/assembly/prox_sensor, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"yZ" = ( +/turf/closed/mineral, +/area/space) +"zi" = ( +/obj/machinery/vending/cigarette/syndicate, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"zt" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/components/unary/vent_scrubber/layer2{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"Aa" = ( +/obj/structure/chair/comfy/shuttle, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"AN" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 4 + }, +/mob/living/basic/syndicate/ranged/smg/space/stormtrooper, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Bm" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/syndicate, +/area/ruin/space/has_grav/powered/virtual_domain) +"BK" = ( +/obj/structure/lattice/catwalk, +/obj/structure/cable, +/turf/open/space/basic, +/area/space) +"BN" = ( +/obj/structure/transit_tube/crossing, +/turf/template_noop, +/area/virtual_domain/safehouse) +"Cf" = ( +/obj/machinery/light/directional/south, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Ci" = ( +/obj/structure/closet/syndicate{ + anchored = 1; + desc = "A basic closet for all your villainous needs."; + locked = 1; + name = "Closet"; + req_access = list("syndicate"); + secure = 1 + }, +/obj/item/crowbar/red, +/obj/item/ammo_box/magazine/m9mm_aps, +/obj/item/ammo_box/magazine/m9mm_aps, +/turf/open/floor/carpet/royalblack, +/area/ruin/space/has_grav/powered/virtual_domain) +"Cn" = ( +/obj/machinery/camera/xray/directional/east{ + c_tag = "Conference room"; + network = list("fsc"); + screen_loc = "" + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"CK" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 4 + }, +/mob/living/basic/syndicate/ranged/smg/pilot, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"CR" = ( +/obj/structure/closet/syndicate{ + anchored = 1; + desc = "A basic closet for all your villainous needs."; + locked = 1; + name = "Closet"; + req_access = list("syndicate"); + secure = 1 + }, +/obj/item/coin/antagtoken, +/obj/item/dnainjector/thermal, +/obj/item/storage/box/firingpins/syndicate, +/obj/item/storage/box/firingpins/syndicate, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"De" = ( +/obj/machinery/door/airlock/grunge{ + name = "Syndicate Ship Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"Dj" = ( +/obj/structure/table/reinforced, +/obj/item/ammo_box/magazine/smgm45, +/obj/item/ammo_box/magazine/smgm45, +/obj/item/ammo_box/magazine/smgm45, +/obj/item/gun/ballistic/automatic/c20r/unrestricted, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"DA" = ( +/obj/structure/closet/crate/secure/gear{ + req_access = list("syndicate") + }, +/obj/effect/spawner/random/maintenance, +/obj/effect/spawner/random/maintenance, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"EB" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"EX" = ( +/mob/living/basic/syndicate/ranged/shotgun/space/stormtrooper, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Fp" = ( +/obj/structure/tank_dispenser/oxygen, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"FN" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Gn" = ( +/obj/structure/chair/comfy{ + dir = 1 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Gs" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"GB" = ( +/obj/structure/cable, +/obj/machinery/door/airlock/external/ruin{ + name = "Syndicate Ship Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"GZ" = ( +/obj/machinery/door/airlock/external/ruin{ + name = "Syndicate Ship Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Hq" = ( +/turf/closed/indestructible/binary, +/area/space) +"HU" = ( +/obj/machinery/door/airlock/grunge{ + name = "Bridge" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"Ia" = ( +/obj/effect/mob_spawn/ghost_role/human/syndicatespace/captain, +/turf/open/floor/carpet/royalblack, +/area/ruin/space/has_grav/powered/virtual_domain) +"Id" = ( +/obj/machinery/power/shuttle_engine/huge{ + dir = 8 + }, +/turf/open/space/basic, +/area/ruin/space/has_grav/powered/virtual_domain) +"If" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 9 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"Ig" = ( +/obj/machinery/porta_turret/syndicate/energy{ + dir = 4; + name = "Syndicate Ship Turret"; + on = 0; + shot_delay = 10 + }, +/turf/closed/wall/r_wall/syndicate/nodiagonal, +/area/ruin/space/has_grav/powered/virtual_domain) +"Im" = ( +/obj/structure/table/reinforced, +/obj/item/ammo_box/c9mm, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Io" = ( +/obj/effect/landmark/bitrunning/cache_spawn, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"IC" = ( +/obj/structure/table/reinforced, +/obj/item/paper, +/obj/item/pen, +/turf/open/floor/carpet/royalblack, +/area/ruin/space/has_grav/powered/virtual_domain) +"IH" = ( +/obj/machinery/door/airlock/external/ruin{ + name = "Syndicate Ship Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/structure/cable, +/obj/structure/fans/tiny, +/turf/open/floor/plating, +/area/ruin/space/has_grav/powered/virtual_domain) +"IV" = ( +/obj/machinery/door/airlock/grunge{ + name = "Syndicate Ship Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/plating, +/area/ruin/space/has_grav/powered/virtual_domain) +"Jg" = ( +/obj/machinery/light/small/directional/south, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"Jz" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 5 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"JA" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"JN" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 5 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"JP" = ( +/obj/structure/sink/directional/south, +/turf/open/floor/iron/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"Kz" = ( +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"Lk" = ( +/obj/structure/transit_tube/crossing, +/turf/closed/mineral/random, +/area/space) +"Lo" = ( +/obj/structure/filingcabinet, +/obj/machinery/door/window{ + dir = 8; + name = "Syndicate Interior Door"; + req_access = list("syndicate") + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"Mc" = ( +/obj/structure/closet/syndicate{ + anchored = 1; + desc = "A basic closet for all your villainous needs."; + locked = 1; + name = "Closet"; + req_access = list("syndicate"); + secure = 1 + }, +/obj/item/crowbar/red, +/obj/item/ammo_box/magazine/m9mm, +/obj/item/ammo_box/magazine/m9mm, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Mm" = ( +/obj/structure/closet/syndicate{ + anchored = 1; + desc = "A basic closet for all your villainous needs."; + locked = 1; + name = "Closet"; + req_access = list("syndicate"); + secure = 1 + }, +/obj/item/clothing/head/hats/hos/beret/syndicate, +/obj/item/clothing/suit/armor/vest/capcarapace/syndicate, +/obj/item/clothing/mask/gas/syndicate, +/obj/item/clothing/under/syndicate, +/obj/item/clothing/under/syndicate/skirt, +/obj/item/clothing/gloves/combat, +/obj/item/clothing/shoes/combat, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"MR" = ( +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/obj/machinery/light/small/directional/south, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"Nm" = ( +/obj/structure/closet/crate/secure/gear{ + req_access = list("syndicate") + }, +/turf/open/floor/pod/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"Nr" = ( +/obj/structure/closet/crate/secure/gear{ + req_access = list("syndicate") + }, +/obj/item/stack/sheet/mineral/gold{ + amount = 30 + }, +/obj/item/stack/sheet/mineral/silver{ + amount = 30 + }, +/obj/machinery/light/small/directional/south, +/turf/open/floor/pod/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"Nt" = ( +/obj/structure/table/reinforced, +/obj/machinery/atmospherics/components/unary/vent_pump, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Of" = ( +/obj/structure/closet/crate/secure/gear{ + req_access = list("syndicate") + }, +/obj/item/disk/surgery/forgottenship, +/turf/open/floor/pod/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"Ox" = ( +/obj/machinery/atmospherics/components/unary/vent_pump, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"OH" = ( +/obj/structure/cable, +/obj/structure/table/reinforced, +/obj/item/storage/toolbox/syndicate, +/obj/item/storage/toolbox/syndicate, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"OI" = ( +/obj/structure/chair/comfy/shuttle{ + dir = 1 + }, +/obj/structure/cable, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"PR" = ( +/obj/machinery/door/password/voice/sfc{ + password = null + }, +/obj/structure/fans/tiny, +/obj/machinery/door/airlock/grunge{ + desc = "Vault airlock preventing air from going out."; + name = "Syndicate Vault Airlock" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/turf/open/floor/pod/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"Qg" = ( +/obj/machinery/suit_storage_unit/syndicate{ + helmet_type = /obj/item/clothing/head/helmet/space/syndicate/black; + suit_type = /obj/item/clothing/suit/space/syndicate/black + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Qi" = ( +/obj/item/stack/sheet/mineral/uranium{ + amount = 15 + }, +/obj/structure/cable, +/obj/machinery/light/small/directional/north, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"QF" = ( +/obj/structure/table/reinforced, +/obj/item/dualsaber/green, +/obj/machinery/light/small/directional/east, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"QG" = ( +/obj/structure/tank_dispenser/oxygen, +/turf/closed/mineral/random, +/area/space) +"QX" = ( +/mob/living/basic/syndicate/ranged/space/stormtrooper, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Ra" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber/layer2, +/obj/machinery/light/small/directional/north, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"RQ" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"RU" = ( +/obj/machinery/suit_storage_unit/syndicate, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Sc" = ( +/obj/structure/cable, +/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, +/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{ + dir = 4 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Sd" = ( +/obj/structure/closet/syndicate{ + anchored = 1; + desc = "A basic closet for all your villainous needs."; + locked = 1; + name = "Closet"; + req_access = list("syndicate"); + secure = 1 + }, +/obj/item/crowbar/red, +/obj/item/ammo_box/magazine/m9mm, +/obj/item/ammo_box/magazine/m9mm, +/obj/machinery/light/small/directional/north, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Sq" = ( +/obj/machinery/power/smes, +/obj/structure/cable, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"Sv" = ( +/obj/structure/closet/crate/secure/gear{ + req_access = list("syndicate") + }, +/obj/effect/spawner/random/food_or_drink/donkpockets, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Sz" = ( +/turf/open/floor/iron/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"SX" = ( +/obj/machinery/vending/medical/syndicate_access/cybersun, +/turf/open/floor/plastic, +/area/ruin/space/has_grav/powered/virtual_domain) +"TB" = ( +/turf/closed/indestructible/syndicate, +/area/ruin/space/has_grav/powered/virtual_domain) +"UQ" = ( +/obj/structure/sign/poster/contraband/syndicate_recruitment, +/turf/closed/wall/r_wall/syndicate, +/area/ruin/space/has_grav/powered/virtual_domain) +"Vk" = ( +/obj/machinery/porta_turret/syndicate/energy{ + dir = 4; + name = "Syndicate Ship Turret"; + on = 0; + shot_delay = 10 + }, +/turf/closed/wall/r_wall/syndicate, +/area/ruin/space/has_grav/powered/virtual_domain) +"Vq" = ( +/obj/structure/transit_tube/station/dispenser/reverse{ + dir = 8 + }, +/turf/template_noop, +/area/virtual_domain/safehouse) +"Wd" = ( +/obj/structure/sign/poster/contraband/tools, +/turf/closed/wall/r_wall/syndicate, +/area/ruin/space/has_grav/powered/virtual_domain) +"Wy" = ( +/obj/structure/closet/crate/secure/gear{ + req_access = list("syndicate") + }, +/obj/item/stack/ore/plasma{ + amount = 19 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"WR" = ( +/obj/machinery/power/port_gen/pacman/super{ + anchored = 1 + }, +/obj/structure/cable, +/turf/open/floor/mineral/plastitanium/red, +/area/ruin/space/has_grav/powered/virtual_domain) +"Xp" = ( +/turf/open/space/basic, +/area/ruin/space/has_grav/powered/virtual_domain) +"XS" = ( +/obj/machinery/light/directional/north, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Yb" = ( +/obj/structure/closet/crate/secure/gear{ + req_access = list("syndicate") + }, +/obj/item/clothing/head/helmet/space/syndicate/black/engie, +/obj/item/clothing/suit/space/syndicate/black/engie, +/turf/open/floor/pod/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"Yi" = ( +/obj/effect/landmark/bitrunning/cache_spawn, +/turf/open/floor/plastic, +/area/ruin/space/has_grav/powered/virtual_domain) +"Yj" = ( +/obj/structure/closet/crate/secure/gear{ + req_access = list("syndicate") + }, +/obj/item/stack/ore/diamond{ + amount = 3 + }, +/turf/open/floor/mineral/plastitanium, +/area/ruin/space/has_grav/powered/virtual_domain) +"Yk" = ( +/obj/machinery/door/airlock/grunge{ + name = "Captain's Room" + }, +/obj/effect/mapping_helpers/airlock/access/all/syndicate/general, +/obj/machinery/door/poddoor{ + id = "fscaproom"; + name = "Captain's Blast Door"; + state_open = 1 + }, +/turf/open/floor/carpet/royalblack, +/area/ruin/space/has_grav/powered/virtual_domain) +"Yr" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"Yu" = ( +/obj/structure/chair/comfy/black, +/turf/open/floor/carpet/royalblack, +/area/ruin/space/has_grav/powered/virtual_domain) +"YV" = ( +/obj/structure/sink/directional/south, +/obj/structure/mirror/directional/west, +/turf/open/floor/iron/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"Za" = ( +/obj/machinery/computer/operating, +/turf/open/floor/plastic, +/area/ruin/space/has_grav/powered/virtual_domain) +"Zb" = ( +/turf/open/floor/plastic, +/area/ruin/space/has_grav/powered/virtual_domain) +"ZA" = ( +/obj/machinery/power/shuttle_engine/propulsion{ + dir = 8 + }, +/turf/open/space/basic, +/area/ruin/space/has_grav/powered/virtual_domain) + +(1,1,1) = {" +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +"} +(2,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(3,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(4,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(5,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(6,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(7,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(8,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +we +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(9,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(10,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Xp +Xp +Id +qx +qx +Xp +Xp +Id +qx +qx +Xp +Xp +Id +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(11,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Xp +Xp +Xp +qx +qx +Xp +Xp +Xp +qx +qx +Xp +Xp +Xp +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(12,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +ZA +Xp +Xp +Xp +ZA +ZA +Xp +Xp +Xp +ZA +ZA +Xp +Xp +Xp +ZA +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +we +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(13,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +ru +ru +ru +ru +ru +ru +ru +ru +ru +ru +ru +ru +ru +ru +ru +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +we +we +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(14,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +Vk +ru +Sv +vD +uP +uP +Yj +vD +uP +Wy +DA +uP +QX +vD +cc +ru +Vk +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(15,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +Io +uP +uP +QX +lN +uP +uP +uP +uP +uP +lN +uP +uP +uP +uP +hA +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(16,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +ru +ru +ru +ru +ru +ru +ru +IV +ru +ru +ru +IV +ru +ru +ru +ru +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(17,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +ru +vp +ru +Ia +Ci +ru +Sq +di +WR +ru +yV +Gn +uP +Mc +uP +ru +qx +qx +qx +qx +qx +qx +qx +qx +qx +nB +we +nB +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(18,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +vp +Jg +ru +bh +cR +ru +Qi +sz +Kz +ru +Mc +gD +yD +uP +rP +ru +qx +qx +qx +qx +qx +qx +qx +nB +nB +nB +nB +nB +nB +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(19,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +sH +Kz +yl +oZ +bh +Yk +pS +RQ +Jz +vK +uP +uP +uP +sL +hy +ru +qx +qx +qx +qx +qx +qx +nB +nB +TB +TB +TB +TB +nB +nB +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(20,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +CR +Kz +ru +bh +bh +Yk +pM +zt +pM +vK +uP +uP +EX +sL +Im +ru +qx +qx +qx +qx +qx +nB +nB +TB +TB +Yb +Yb +TB +Bm +nB +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(21,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +yT +Kz +ru +Yu +IC +ru +mD +JN +MR +ru +Sd +gD +uP +uP +gD +ru +qx +qx +qx +qx +nB +QG +nB +TB +aN +bG +bG +sK +TB +nB +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(22,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +Ig +ru +Lo +ru +tv +ki +nU +wb +EB +pl +ru +hD +Gn +uP +Mc +ru +Ig +qx +qx +qx +qx +nB +we +nB +TB +iU +bG +bG +Nr +TB +nB +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(23,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +ru +ru +ru +ru +ru +ru +ru +cy +ru +ru +ru +ru +ru +ru +ru +qx +qx +qx +qx +qx +qx +nB +nB +TB +Nm +bG +bG +Of +TB +nB +nB +qx +qx +qx +qx +qx +qx +qx +sM +sM +sM +sM +sM +kJ +qx +Hq +"} +(24,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +ru +Za +Yi +Zb +SX +ru +uP +yR +uP +ru +YV +Sz +jJ +fG +ru +qx +qx +qx +qx +qx +nB +nB +nB +TB +TB +PR +TB +TB +TB +nB +nB +nB +qx +qx +qx +qx +qx +qx +sM +sM +sM +sM +sM +sM +qx +Hq +"} +(25,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +ru +qf +Zb +ip +da +ru +Ra +Sc +uP +ru +JP +qY +ru +ru +ru +qx +qx +qx +qx +qx +nB +nB +we +ru +ru +uP +sg +ru +ru +nB +nB +nB +nB +qx +qx +qx +qx +qx +sM +sM +sM +sM +sM +sM +qx +Hq +"} +(26,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +ru +aq +cB +Zb +Zb +De +Ox +Gs +uP +wK +Sz +Sz +jJ +pU +ru +qx +qx +qx +qx +qx +qx +nB +nB +qU +Fp +uP +uP +li +cj +Lk +Lk +fd +fd +fd +fd +fd +fd +fd +BN +Vq +sM +sM +sM +sM +qx +Hq +"} +(27,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +Vk +ru +ru +ru +ru +ru +ru +ru +kh +ru +ru +ru +ru +ru +ru +ru +Vk +qx +qx +qx +qx +qx +nB +nB +ru +eB +uP +nO +uP +ru +nB +qx +qx +qx +qx +qx +qx +qx +qx +sM +sM +sM +sM +sM +sM +qx +Hq +"} +(28,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +jl +rm +ru +nk +oM +oM +oM +yR +oM +oM +oM +uP +ru +uP +Qg +ru +qx +qx +qx +qx +qx +qx +nB +ru +wL +oM +uP +dw +ru +yZ +nB +nB +nB +qx +qx +qx +qx +qx +sM +sM +sM +sM +sM +sM +qx +Hq +"} +(29,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +uP +dw +ru +rH +uP +AN +JA +iX +JA +JA +oM +uP +ru +fJ +Qg +ru +qx +qx +qx +qx +qx +qx +qx +Wd +OH +oM +uP +RU +ru +we +nB +nB +qx +qx +qx +qx +qx +qx +sM +sM +sM +sM +sM +Yr +qx +Hq +"} +(30,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +lo +uP +uP +GZ +uP +Aa +hD +yJ +bD +hD +hD +OI +oM +GB +jA +oM +dU +BK +BK +BK +BK +BK +BK +BK +IH +oM +oM +uP +RU +ru +nB +nB +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(31,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +uP +uP +dd +uP +Aa +hD +Nt +aw +hD +hD +bo +uP +dd +uP +Qg +ru +qx +qx +qx +qx +qx +qx +qx +iL +cZ +uP +uP +RU +ru +nB +nB +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(32,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +aO +uP +ru +XS +uP +uP +hD +aZ +hD +uP +uP +Cf +ru +uP +Fp +ru +qx +qx +qx +qx +qx +qx +nB +ru +ru +Dj +QF +ru +ru +nB +nB +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(33,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +Ig +ru +hD +ru +zi +uP +uP +uP +FN +Cn +uP +uP +uP +ru +hD +ru +Ig +qx +qx +qx +qx +qx +nB +nB +nB +ru +ru +ru +ru +nB +nB +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(34,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +ru +ru +ru +ru +ru +ru +ru +HU +ru +ru +ru +ru +ru +ru +ru +qx +qx +qx +qx +qx +qx +qx +nB +nB +nB +nB +we +nB +nB +nB +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(35,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +UQ +rM +xJ +Kz +Kz +tI +Kz +Kz +ct +xJ +ru +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +nB +nB +nB +nB +nB +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(36,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +ru +ru +ru +Kz +Kz +Kz +Kz +tI +Kz +Kz +Kz +Kz +ru +ru +ru +ru +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(37,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +ln +Kz +ru +iB +Kz +Kz +fV +If +Kz +Kz +Kz +nG +ru +cw +cw +ru +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(38,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +ru +Kz +dz +sq +Kz +CK +Kz +vU +mo +vU +Kz +CK +Kz +ja +Kz +Jg +ru +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(39,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +Ig +ru +Kz +ru +Kz +pz +Kz +xZ +Kz +fM +Kz +kI +Kz +ru +Mm +ru +Ig +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(40,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +ru +ru +ru +Kz +Kz +Kz +Kz +Kz +Kz +Kz +Kz +Kz +ru +ru +ru +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(41,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +ru +ru +vp +vp +pH +vp +iW +vp +vp +vp +vp +ru +ru +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(42,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Ig +hg +hg +hg +hg +hg +hg +hg +hg +hg +Ig +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +we +we +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(43,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +we +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(44,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(45,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +we +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(46,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +we +we +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(47,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +we +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(48,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(49,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(50,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(51,1,1) = {" +Hq +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +qx +Hq +"} +(52,1,1) = {" +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +Hq +"} diff --git a/_maps/virtual_domains/test_only.dmm b/_maps/virtual_domains/test_only.dmm new file mode 100644 index 00000000000000..22b647188b6e16 --- /dev/null +++ b/_maps/virtual_domains/test_only.dmm @@ -0,0 +1,52 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/open/floor, +/area/virtual_domain/powered) +"D" = ( +/obj/effect/mob_spawn/corpse/human/miner, +/turf/open/floor, +/area/virtual_domain/powered) +"I" = ( +/mob/living/basic/pet/dog/corgi, +/turf/open/floor, +/area/virtual_domain/powered) +"U" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/open/floor, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +I +a +a +a +U +"} +(2,1,1) = {" +D +a +a +a +a +"} +(3,1,1) = {" +a +a +a +a +a +"} +(4,1,1) = {" +a +a +a +a +a +"} +(5,1,1) = {" +a +a +a +a +a +"} diff --git a/_maps/virtual_domains/vaporwave.dmm b/_maps/virtual_domains/vaporwave.dmm new file mode 100644 index 00000000000000..984bbbe291489d --- /dev/null +++ b/_maps/virtual_domains/vaporwave.dmm @@ -0,0 +1,1017 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"aA" = ( +/obj/machinery/light/small/directional/north, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating{ + initial_gas_mix = "TEMP=2.7" + }, +/area/ruin/space/has_grav/powered/virtual_domain) +"bs" = ( +/obj/effect/turf_decal/sand, +/turf/open/floor/iron/airless, +/area/ruin/space/has_grav/powered/virtual_domain) +"bF" = ( +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating{ + initial_gas_mix = "TEMP=2.7" + }, +/area/ruin/space/has_grav/powered/virtual_domain) +"cz" = ( +/turf/open/misc/asteroid/airless, +/area/ruin/space/has_grav/powered/virtual_domain) +"cL" = ( +/obj/structure/table/reinforced, +/obj/item/reagent_containers/cup/glass/drinkingglass{ + pixel_x = 6; + pixel_y = 4 + }, +/obj/item/reagent_containers/cup/glass/drinkingglass, +/obj/item/reagent_containers/cup/glass/drinkingglass{ + pixel_x = -6; + pixel_y = 8 + }, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"df" = ( +/obj/effect/turf_decal/sand, +/turf/open/floor/iron/airless{ + icon_state = "stairs-l" + }, +/area/ruin/space/has_grav/powered/virtual_domain) +"eF" = ( +/turf/closed/indestructible/binary, +/area/space) +"fx" = ( +/obj/item/statuebust, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"fQ" = ( +/obj/structure/flora/tree/palm, +/turf/open/floor/holofloor/beach, +/area/ruin/space/has_grav/powered/virtual_domain) +"gM" = ( +/obj/structure/table/reinforced, +/obj/item/clothing/glasses/sunglasses/big{ + name = "aesthetic sunglasses" + }, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"hN" = ( +/turf/open/floor/holofloor/beach, +/area/ruin/space/has_grav/powered/virtual_domain) +"il" = ( +/obj/effect/turf_decal/sand, +/obj/effect/turf_decal/sand, +/turf/open/floor/iron/airless, +/area/ruin/space/has_grav/powered/virtual_domain) +"iP" = ( +/obj/machinery/suit_storage_unit/standard_unit, +/turf/template_noop, +/area/virtual_domain/safehouse) +"kj" = ( +/obj/structure/window/spawner/directional/east, +/obj/structure/closet/crate/secure/bitrunning/encrypted, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"ku" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"kF" = ( +/obj/effect/turf_decal/sand, +/turf/open/floor/iron/airless{ + icon_state = "stairs-r" + }, +/area/ruin/space/has_grav/powered/virtual_domain) +"ll" = ( +/obj/structure/sign/poster/contraband/clown/directional/north, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"lu" = ( +/turf/closed/wall/rust, +/area/ruin/space/has_grav/powered/virtual_domain) +"lB" = ( +/obj/item/tank/internals/emergency_oxygen, +/obj/item/tank/internals/emergency_oxygen, +/obj/item/tank/internals/emergency_oxygen, +/turf/template_noop, +/area/virtual_domain/safehouse) +"lI" = ( +/obj/structure/table/reinforced, +/obj/machinery/chem_dispenser/drinks/beer/fullupgrade, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"qm" = ( +/obj/structure/flora/tree/palm, +/obj/machinery/light/directional/west, +/turf/open/floor/holofloor/beach, +/area/ruin/space/has_grav/powered/virtual_domain) +"qu" = ( +/turf/open/floor/holofloor/beach/water, +/area/ruin/space/has_grav/powered/virtual_domain) +"rn" = ( +/obj/structure/statue/sandstone/venus{ + anchored = 1; + dir = 4 + }, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating{ + initial_gas_mix = "TEMP=2.7" + }, +/area/ruin/space/has_grav/powered/virtual_domain) +"xb" = ( +/obj/structure/chair/stool/directional/west, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"xp" = ( +/obj/structure/table/reinforced, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"xK" = ( +/turf/closed/wall, +/area/ruin/space/has_grav/powered/virtual_domain) +"ym" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/space) +"AX" = ( +/obj/effect/turf_decal/stripes/asteroid/line, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating{ + initial_gas_mix = "TEMP=2.7" + }, +/area/ruin/space/has_grav/powered/virtual_domain) +"Cq" = ( +/obj/item/instrument/eguitar, +/turf/open/floor/holofloor/beach, +/area/ruin/space/has_grav/powered/virtual_domain) +"CR" = ( +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"Dk" = ( +/obj/structure/window/spawner/directional/east, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"Es" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"Fd" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/wall/rust, +/area/ruin/space/has_grav/powered/virtual_domain) +"Hf" = ( +/obj/effect/turf_decal/sand, +/turf/open/floor/iron/airless{ + icon_state = "recharge_floor_asteroid" + }, +/area/ruin/space/has_grav/powered/virtual_domain) +"HA" = ( +/turf/open/floor/holofloor/beach/coast, +/area/ruin/space/has_grav/powered/virtual_domain) +"HV" = ( +/obj/structure/chair/comfy/black{ + dir = 4 + }, +/obj/machinery/light/small/directional/north, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"Jr" = ( +/obj/structure/window/spawner/directional/west, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"KO" = ( +/obj/structure/chair/comfy/black{ + dir = 8 + }, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"KY" = ( +/obj/effect/turf_decal/sand, +/turf/open/floor/iron/airless{ + icon_state = "stairs-m" + }, +/area/ruin/space/has_grav/powered/virtual_domain) +"LG" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"LJ" = ( +/obj/structure/lattice, +/turf/open/misc/asteroid/airless, +/area/ruin/space/has_grav/powered/virtual_domain) +"LP" = ( +/obj/structure/flora/tree/palm, +/obj/machinery/light/directional/east, +/turf/open/floor/holofloor/beach, +/area/ruin/space/has_grav/powered/virtual_domain) +"Nz" = ( +/obj/structure/window/spawner/directional/east, +/obj/structure/table/reinforced, +/obj/item/storage/fancy/cigarettes/cigars/havana, +/obj/effect/spawner/random/entertainment/lighter, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"NT" = ( +/turf/open/space/basic, +/area/space) +"Qh" = ( +/obj/structure/closet/crate/bin, +/turf/open/misc/asteroid/airless, +/area/ruin/space/has_grav/powered/virtual_domain) +"Uy" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"UE" = ( +/obj/effect/turf_decal/sand, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating{ + initial_gas_mix = "TEMP=2.7" + }, +/area/ruin/space/has_grav/powered/virtual_domain) +"UV" = ( +/obj/structure/lattice, +/turf/open/floor/plating/airless, +/area/ruin/space/has_grav/powered/virtual_domain) +"Vc" = ( +/obj/structure/flora/tree/palm, +/turf/open/misc/asteroid/airless, +/area/ruin/space/has_grav/powered/virtual_domain) +"XJ" = ( +/obj/structure/fans/tiny, +/obj/machinery/door/airlock/hatch, +/turf/open/floor/pod/dark, +/area/ruin/space/has_grav/powered/virtual_domain) +"Yo" = ( +/obj/structure/statue/sandstone/venus{ + anchored = 1; + desc = "Ugh, this is merely an ugly amateurish replica of the other statue! The letters RIPGOAT are scribbled onto the base."; + dir = 8 + }, +/obj/effect/turf_decal/sand/plating, +/turf/open/floor/plating{ + initial_gas_mix = "TEMP=2.7" + }, +/area/ruin/space/has_grav/powered/virtual_domain) +"YE" = ( +/mob/living/basic/butterfly, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) +"ZI" = ( +/obj/effect/spawner/random/structure/musician/piano/random_piano, +/obj/structure/window/spawner/directional/west, +/turf/open/floor/iron/vaporwave, +/area/ruin/space/has_grav/powered/virtual_domain) + +(1,1,1) = {" +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +"} +(2,1,1) = {" +eF +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(3,1,1) = {" +eF +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(4,1,1) = {" +eF +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(5,1,1) = {" +eF +NT +NT +NT +NT +NT +NT +cz +LJ +cz +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(6,1,1) = {" +eF +NT +NT +NT +NT +NT +cz +cz +LJ +cz +cz +LJ +cz +cz +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(7,1,1) = {" +eF +NT +NT +NT +NT +cz +cz +cz +UV +LJ +cz +UV +cz +cz +cz +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(8,1,1) = {" +eF +NT +NT +NT +NT +cz +xK +xK +lu +lu +lu +xK +lu +UE +cz +cz +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(9,1,1) = {" +eF +NT +NT +NT +LJ +Qh +xK +fQ +hN +qm +HA +qu +xK +aA +cz +cz +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(10,1,1) = {" +eF +NT +NT +NT +LJ +UV +lu +ZI +Jr +Jr +Jr +Jr +xK +bF +Vc +cz +cz +NT +NT +NT +ku +ku +ku +ku +ku +Uy +NT +eF +"} +(11,1,1) = {" +eF +NT +NT +NT +cz +cz +xK +xb +CR +CR +fx +CR +xK +Yo +il +UE +cz +NT +NT +NT +ku +iP +iP +iP +ku +ku +NT +eF +"} +(12,1,1) = {" +eF +NT +NT +NT +cz +cz +xK +ll +CR +CR +CR +CR +xK +Hf +df +il +cz +NT +NT +NT +ku +ku +ku +ku +ku +ku +NT +eF +"} +(13,1,1) = {" +eF +NT +NT +NT +cz +LJ +xK +HV +Es +CR +CR +CR +XJ +bs +KY +bs +il +NT +NT +NT +ku +ku +ku +ku +ku +ku +NT +eF +"} +(14,1,1) = {" +eF +NT +NT +NT +cz +LJ +lu +xp +gM +CR +CR +cL +xK +Hf +kF +bs +il +NT +NT +NT +ku +ku +ku +ku +ku +ku +NT +eF +"} +(15,1,1) = {" +eF +NT +NT +NT +cz +LJ +lu +KO +KO +CR +YE +lI +lu +rn +il +UE +UE +NT +NT +NT +ku +ku +ku +ku +lB +ku +NT +eF +"} +(16,1,1) = {" +eF +NT +NT +NT +LJ +UV +xK +kj +Dk +Dk +Dk +Nz +xK +AX +Vc +cz +cz +NT +NT +NT +ku +ku +ku +ku +ku +LG +NT +eF +"} +(17,1,1) = {" +eF +NT +NT +NT +cz +cz +lu +fQ +Cq +LP +HA +qu +lu +aA +cz +cz +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(18,1,1) = {" +eF +NT +NT +NT +cz +cz +xK +xK +lu +xK +lu +lu +Fd +UE +cz +cz +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(19,1,1) = {" +eF +NT +NT +NT +NT +cz +cz +cz +UV +LJ +Qh +UV +cz +cz +cz +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(20,1,1) = {" +eF +NT +NT +NT +NT +NT +NT +cz +LJ +cz +cz +LJ +cz +cz +cz +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(21,1,1) = {" +eF +NT +NT +NT +NT +NT +NT +NT +ym +cz +cz +cz +cz +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(22,1,1) = {" +eF +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(23,1,1) = {" +eF +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(24,1,1) = {" +eF +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +NT +eF +"} +(25,1,1) = {" +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +eF +"} diff --git a/_maps/virtual_domains/wendigo.dmm b/_maps/virtual_domains/wendigo.dmm new file mode 100644 index 00000000000000..17bcb48d688bfc --- /dev/null +++ b/_maps/virtual_domains/wendigo.dmm @@ -0,0 +1,1373 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/open/indestructible/necropolis{ + initial_gas_mix = "ICEMOON_ATMOS" + }, +/area/icemoon/underground/explored/virtual_domain) +"b" = ( +/turf/closed/indestructible/rock/snow/ice/ore, +/area/icemoon/underground/explored/virtual_domain) +"e" = ( +/turf/open/misc/asteroid/snow/ice/icemoon, +/area/icemoon/underground/explored/virtual_domain) +"f" = ( +/obj/structure/marker_beacon/olive, +/turf/open/indestructible/necropolis{ + initial_gas_mix = "ICEMOON_ATMOS" + }, +/area/icemoon/underground/explored/virtual_domain) +"i" = ( +/turf/closed/indestructible/binary, +/area/icemoon/underground/explored/virtual_domain) +"o" = ( +/obj/structure/marker_beacon/indigo, +/turf/open/indestructible/necropolis{ + initial_gas_mix = "ICEMOON_ATMOS" + }, +/area/icemoon/underground/explored/virtual_domain) +"p" = ( +/obj/structure/marker_beacon/bronze, +/turf/open/indestructible/necropolis{ + initial_gas_mix = "ICEMOON_ATMOS" + }, +/area/icemoon/underground/explored/virtual_domain) +"q" = ( +/obj/structure/marker_beacon/yellow, +/turf/open/indestructible/necropolis{ + initial_gas_mix = "ICEMOON_ATMOS" + }, +/area/icemoon/underground/explored/virtual_domain) +"t" = ( +/obj/structure/marker_beacon/teal, +/turf/open/indestructible/necropolis{ + initial_gas_mix = "ICEMOON_ATMOS" + }, +/area/icemoon/underground/explored/virtual_domain) +"x" = ( +/obj/structure/marker_beacon/burgundy, +/turf/open/indestructible/necropolis{ + initial_gas_mix = "ICEMOON_ATMOS" + }, +/area/icemoon/underground/explored/virtual_domain) +"A" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"E" = ( +/obj/effect/mob_spawn/corpse/human/miner, +/turf/open/misc/asteroid/snow/ice/icemoon, +/area/icemoon/underground/explored/virtual_domain) +"H" = ( +/mob/living/simple_animal/hostile/megafauna/wendigo/virtual_domain, +/turf/open/indestructible/necropolis{ + initial_gas_mix = "ICEMOON_ATMOS" + }, +/area/icemoon/underground/explored/virtual_domain) +"L" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/binary, +/area/icemoon/underground/explored/virtual_domain) +"R" = ( +/obj/item/paper/crumpled/bloody{ + default_raw_text = "for your own sake, do not enter" + }, +/turf/open/misc/asteroid/snow/ice/icemoon, +/area/icemoon/underground/explored/virtual_domain) +"S" = ( +/turf/template_noop, +/area/template_noop) +"V" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"Z" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) + +(1,1,1) = {" +S +S +S +S +S +S +i +i +i +i +i +i +i +i +i +i +i +i +i +i +i +i +i +S +S +S +S +S +S +S +S +S +S +S +S +S +S +"} +(2,1,1) = {" +S +S +S +S +S +i +i +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +i +i +S +S +S +S +S +S +S +S +S +S +S +S +S +"} +(3,1,1) = {" +S +S +S +S +i +i +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +i +i +S +S +S +S +S +S +S +S +S +S +S +S +"} +(4,1,1) = {" +S +S +S +i +i +e +e +e +b +b +b +b +b +e +e +e +b +b +b +b +b +e +e +e +i +i +S +S +S +S +S +S +S +S +S +S +S +"} +(5,1,1) = {" +S +S +i +i +e +e +e +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +e +e +e +i +i +i +i +i +i +i +i +i +i +i +L +"} +(6,1,1) = {" +S +i +i +e +e +e +b +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +b +e +e +e +i +i +e +e +e +e +e +e +e +e +i +"} +(7,1,1) = {" +i +i +e +e +e +b +b +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +b +b +e +e +e +i +e +e +e +e +e +e +e +e +i +"} +(8,1,1) = {" +i +e +e +e +b +b +b +b +b +b +a +a +a +a +a +a +a +a +a +b +b +b +b +b +b +e +e +e +e +e +e +e +e +e +e +e +i +"} +(9,1,1) = {" +i +e +e +b +b +b +b +b +b +a +a +a +a +a +a +a +a +a +a +a +b +b +b +b +b +b +e +e +e +e +e +e +e +e +e +e +i +"} +(10,1,1) = {" +i +e +e +b +b +b +b +b +a +a +a +a +a +a +a +a +a +a +a +a +a +b +b +b +b +b +e +e +e +e +e +e +e +e +e +e +i +"} +(11,1,1) = {" +i +e +E +b +b +b +b +a +a +a +a +a +a +a +a +a +a +a +a +o +a +a +b +b +b +b +e +e +e +e +e +e +e +e +e +e +i +"} +(12,1,1) = {" +i +e +e +b +b +b +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +b +b +b +e +e +e +e +e +e +e +e +e +e +i +"} +(13,1,1) = {" +i +e +e +b +b +b +a +a +a +a +q +a +a +a +a +a +a +a +a +a +a +a +a +b +b +b +e +e +e +e +e +e +e +e +e +e +i +"} +(14,1,1) = {" +i +e +e +b +b +b +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +b +b +b +e +e +e +V +V +V +V +V +Z +e +i +"} +(15,1,1) = {" +i +e +e +b +b +b +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +b +b +b +E +e +e +V +V +V +V +V +V +e +i +"} +(16,1,1) = {" +i +e +e +e +b +b +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +b +b +e +e +e +e +V +V +V +V +V +V +e +i +"} +(17,1,1) = {" +i +e +e +e +e +e +a +a +a +a +a +a +a +a +H +a +a +a +a +x +a +a +a +e +e +e +e +R +e +V +V +V +V +V +V +e +i +"} +(18,1,1) = {" +i +e +e +e +b +b +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +b +b +e +e +e +e +V +V +V +V +V +V +e +i +"} +(19,1,1) = {" +i +e +e +b +b +b +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +b +b +b +e +e +e +V +V +V +V +V +V +e +i +"} +(20,1,1) = {" +i +e +e +b +b +b +a +a +a +a +a +a +a +a +p +a +a +a +a +a +a +a +a +b +b +b +e +e +e +V +V +V +V +V +A +e +i +"} +(21,1,1) = {" +i +e +e +b +b +b +a +a +a +a +f +a +a +a +a +a +a +a +a +a +a +a +a +b +b +b +e +e +e +e +e +e +e +e +e +e +i +"} +(22,1,1) = {" +i +e +e +b +b +b +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +b +b +b +e +e +e +e +e +e +e +e +e +e +i +"} +(23,1,1) = {" +i +e +e +b +b +b +b +a +a +a +a +a +a +a +a +a +a +a +a +a +t +a +b +b +b +b +e +e +e +e +e +e +e +e +e +e +i +"} +(24,1,1) = {" +i +e +e +b +b +b +b +b +a +a +a +a +a +a +a +a +a +a +a +a +a +b +b +b +b +b +e +e +e +e +e +e +e +e +e +e +i +"} +(25,1,1) = {" +i +e +e +b +b +b +b +b +b +a +a +a +a +a +a +a +a +a +a +a +b +b +b +b +b +b +e +e +e +e +e +e +e +e +e +e +i +"} +(26,1,1) = {" +i +e +e +e +b +b +b +b +b +b +a +a +a +a +a +a +a +a +a +b +b +b +b +b +b +e +e +e +e +e +e +e +e +e +e +e +i +"} +(27,1,1) = {" +i +i +e +e +e +b +b +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +b +b +e +e +e +i +e +e +e +e +e +e +e +e +i +"} +(28,1,1) = {" +S +i +i +e +e +e +b +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +b +e +e +e +i +i +e +e +e +e +e +e +e +e +i +"} +(29,1,1) = {" +S +S +i +i +e +e +e +b +b +b +b +b +b +b +e +b +b +b +b +b +b +b +e +e +e +i +i +i +i +i +i +i +i +i +i +i +i +"} +(30,1,1) = {" +S +S +S +i +i +e +e +e +b +b +b +b +b +e +e +e +b +b +b +b +b +e +e +e +i +i +S +S +S +S +S +S +S +S +S +S +S +"} +(31,1,1) = {" +S +S +S +S +i +i +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +i +i +S +S +S +S +S +S +S +S +S +S +S +S +"} +(32,1,1) = {" +S +S +S +S +S +i +i +e +e +e +e +e +e +e +e +e +e +e +e +e +e +e +i +i +S +S +S +S +S +S +S +S +S +S +S +S +S +"} +(33,1,1) = {" +S +S +S +S +S +S +i +i +i +i +i +i +i +i +i +i +i +i +i +i +i +i +i +S +S +S +S +S +S +S +S +S +S +S +S +S +S +"} diff --git a/_maps/virtual_domains/xeno_nest.dmm b/_maps/virtual_domains/xeno_nest.dmm new file mode 100644 index 00000000000000..fcbd7cc116c91e --- /dev/null +++ b/_maps/virtual_domains/xeno_nest.dmm @@ -0,0 +1,2071 @@ +//MAP CONVERTED BY dmm2tgm.py THIS HEADER COMMENT PREVENTS RECONVERSION, DO NOT REMOVE +"a" = ( +/turf/template_noop, +/area/template_noop) +"c" = ( +/obj/structure/alien/weeds, +/obj/structure/alien/resin/wall, +/obj/structure/alien/resin/wall, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"d" = ( +/obj/structure/alien/resin/wall, +/turf/closed/indestructible/binary, +/area/ruin/space/has_grav/powered/virtual_domain) +"e" = ( +/obj/structure/alien/weeds, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"f" = ( +/obj/structure/alien/weeds, +/obj/structure/alien/egg/burst, +/obj/effect/decal/cleanable/blood, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"h" = ( +/obj/structure/alien/weeds, +/mob/living/simple_animal/hostile/alien/sentinel, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"i" = ( +/obj/structure/alien/weeds, +/obj/structure/bed/nest, +/obj/effect/decal/cleanable/blood/gibs, +/obj/effect/decal/cleanable/blood, +/obj/item/clothing/under/syndicate, +/obj/item/clothing/glasses/night, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"j" = ( +/obj/machinery/suit_storage_unit/spaceruin, +/turf/template_noop, +/area/virtual_domain/safehouse) +"k" = ( +/obj/structure/alien/weeds/node, +/obj/structure/alien/resin/wall, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"l" = ( +/obj/structure/alien/weeds, +/obj/structure/alien/resin/wall, +/turf/closed/indestructible/binary, +/area/ruin/space/has_grav/powered/virtual_domain) +"m" = ( +/obj/structure/alien/weeds, +/obj/structure/bed/nest, +/obj/structure/alien/resin/wall, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"n" = ( +/turf/template_noop, +/area/virtual_domain/safehouse) +"o" = ( +/obj/structure/alien/weeds, +/obj/effect/decal/cleanable/blood/gibs, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"p" = ( +/obj/structure/alien/weeds, +/mob/living/simple_animal/hostile/alien/drone{ + plants_off = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"q" = ( +/obj/structure/alien/resin/wall, +/turf/open/space/basic, +/area/ruin/space/has_grav/powered/virtual_domain) +"r" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/template_noop, +/area/virtual_domain/safehouse) +"s" = ( +/obj/structure/alien/weeds/node, +/mob/living/simple_animal/hostile/alien/drone{ + plants_off = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"t" = ( +/obj/structure/alien/weeds, +/obj/structure/alien/weeds, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"u" = ( +/obj/structure/alien/weeds/node, +/obj/effect/decal/cleanable/blood, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"v" = ( +/obj/effect/landmark/bitrunning/safehouse_spawn, +/turf/template_noop, +/area/virtual_domain/safehouse) +"x" = ( +/obj/structure/alien/weeds, +/obj/structure/bed/nest, +/obj/effect/landmark/bitrunning/cache_spawn, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"z" = ( +/obj/structure/alien/weeds, +/obj/structure/alien/resin/wall, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"A" = ( +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/ruin/space/has_grav/powered/virtual_domain) +"B" = ( +/obj/structure/alien/weeds, +/obj/effect/decal/cleanable/blood, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"C" = ( +/obj/structure/alien/weeds, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/ruin/space/has_grav/powered/virtual_domain) +"D" = ( +/obj/structure/alien/weeds, +/obj/structure/alien/weeds, +/turf/open/misc/asteroid/basalt/lava_land_surface/no_ruins, +/area/ruin/space/has_grav/powered/virtual_domain) +"E" = ( +/turf/closed/indestructible/binary, +/area/ruin/space/has_grav/powered/virtual_domain) +"F" = ( +/obj/structure/table/greyscale, +/obj/item/gun/energy/beam_rifle, +/obj/item/gun/energy/laser{ + pixel_x = 4; + pixel_y = -6 + }, +/obj/item/gun/energy/laser{ + pixel_x = -8; + pixel_y = 6 + }, +/turf/template_noop, +/area/virtual_domain/safehouse) +"G" = ( +/obj/structure/alien/resin/wall, +/obj/structure/alien/weeds, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"H" = ( +/obj/structure/table/greyscale, +/obj/machinery/recharger{ + pixel_x = 8; + pixel_y = 4 + }, +/obj/machinery/recharger{ + pixel_x = -8; + pixel_y = 4 + }, +/turf/template_noop, +/area/virtual_domain/safehouse) +"I" = ( +/obj/structure/alien/weeds, +/obj/structure/bed/nest, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"J" = ( +/obj/structure/alien/weeds, +/mob/living/simple_animal/hostile/alien/queen/large{ + desc = "A gigantic alien who is in charge of the hive and all of its loyal servants."; + name = "alien queen"; + pixel_x = -16; + plants_off = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"K" = ( +/obj/structure/alien/weeds, +/obj/effect/landmark/bitrunning/cache_spawn, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"L" = ( +/obj/item/storage/medkit/regular, +/obj/item/storage/medkit/regular, +/turf/template_noop, +/area/virtual_domain/safehouse) +"M" = ( +/obj/structure/alien/weeds, +/obj/structure/alien/resin/wall{ + move_force = 1000; + move_resist = 3000; + pull_force = 1000 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"N" = ( +/obj/structure/alien/weeds, +/obj/structure/bed/nest, +/obj/effect/decal/cleanable/blood/gibs, +/obj/item/clothing/under/rank/security/officer, +/obj/item/clothing/suit/armor/vest, +/obj/item/melee/baton/security/loaded, +/obj/item/clothing/head/helmet, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"O" = ( +/obj/effect/baseturf_helper/virtual_domain, +/turf/closed/indestructible/binary, +/area/ruin/space/has_grav/powered/virtual_domain) +"P" = ( +/obj/structure/alien/weeds/node, +/mob/living/simple_animal/hostile/alien, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"Q" = ( +/obj/structure/alien/resin/wall, +/obj/structure/alien/resin/wall, +/turf/closed/indestructible/binary, +/area/ruin/space/has_grav/powered/virtual_domain) +"S" = ( +/obj/structure/alien/weeds, +/mob/living/simple_animal/hostile/alien, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"T" = ( +/obj/structure/alien/weeds, +/obj/structure/alien/egg/burst, +/obj/effect/decal/cleanable/blood/gibs, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"U" = ( +/obj/structure/alien/weeds, +/obj/structure/bed/nest, +/obj/effect/decal/cleanable/blood/gibs, +/obj/item/gun/ballistic/automatic/pistol, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"V" = ( +/obj/structure/alien/weeds/node, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"W" = ( +/obj/structure/alien/weeds, +/obj/structure/alien/egg/burst, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"Y" = ( +/obj/structure/alien/weeds, +/obj/effect/decal/cleanable/blood, +/mob/living/simple_animal/hostile/alien/drone{ + plants_off = 1 + }, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) +"Z" = ( +/obj/structure/alien/weeds, +/obj/structure/bed/nest, +/obj/effect/decal/cleanable/blood/gibs, +/obj/item/tank/internals/oxygen, +/obj/item/clothing/suit/space/syndicate/orange, +/obj/item/clothing/mask/gas, +/obj/item/clothing/head/helmet/space/syndicate/orange, +/turf/open/misc/asteroid/basalt/lava_land_surface, +/area/ruin/space/has_grav/powered/virtual_domain) + +(1,1,1) = {" +a +a +a +E +E +E +E +E +E +E +E +E +E +E +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(2,1,1) = {" +a +a +a +E +E +z +z +z +z +z +z +z +z +E +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(3,1,1) = {" +a +a +a +E +E +z +e +W +W +z +e +e +z +M +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(4,1,1) = {" +a +a +a +E +z +z +e +e +e +e +p +e +W +z +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(5,1,1) = {" +a +a +a +E +z +e +e +k +z +z +z +k +z +z +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(6,1,1) = {" +a +a +a +E +z +e +e +m +K +J +o +i +z +z +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(7,1,1) = {" +a +a +a +E +z +W +h +e +e +e +B +o +e +z +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(8,1,1) = {" +a +a +a +E +z +I +o +z +e +V +e +h +W +z +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(9,1,1) = {" +a +a +a +E +z +U +u +e +z +e +e +W +z +z +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(10,1,1) = {" +a +a +a +E +z +e +o +z +e +e +e +k +W +z +E +a +a +a +a +a +a +a +E +E +E +E +E +E +E +E +E +E +a +a +a +a +a +a +a +"} +(11,1,1) = {" +a +a +a +E +z +z +e +h +e +e +h +e +e +z +E +a +a +a +a +a +a +a +E +E +E +E +z +z +z +z +E +E +a +a +a +a +a +a +a +"} +(12,1,1) = {" +a +a +a +E +E +z +W +e +e +e +e +e +e +z +E +a +a +a +a +a +a +a +E +E +E +z +z +Z +I +z +z +E +a +a +a +a +a +a +a +"} +(13,1,1) = {" +a +a +a +E +E +z +z +e +e +V +e +e +z +z +E +a +a +a +a +a +a +a +E +E +z +z +W +o +Y +e +z +E +a +a +a +a +a +a +a +"} +(14,1,1) = {" +a +a +a +E +E +E +z +z +e +e +e +z +z +E +E +a +a +a +a +E +E +E +E +E +z +I +e +V +e +W +z +E +a +a +a +a +a +a +a +"} +(15,1,1) = {" +a +a +a +a +a +E +E +z +z +z +z +z +E +E +E +E +E +E +E +E +E +E +z +z +z +e +e +e +I +z +z +E +a +a +a +a +a +a +a +"} +(16,1,1) = {" +a +a +a +a +a +a +E +z +V +V +z +E +E +E +E +E +E +E +E +E +E +z +z +e +S +e +W +z +z +z +E +E +a +a +a +a +a +a +a +"} +(17,1,1) = {" +a +a +a +a +a +a +E +z +p +e +z +z +E +z +z +z +z +z +z +z +z +z +e +e +z +z +z +z +E +E +E +E +a +a +a +a +a +a +a +"} +(18,1,1) = {" +a +a +a +a +a +a +E +z +e +e +p +z +z +z +e +e +e +e +e +e +z +z +e +z +z +E +E +E +E +E +E +E +E +E +E +E +E +E +O +"} +(19,1,1) = {" +E +E +E +E +E +E +E +z +z +e +e +e +z +e +e +e +e +e +e +V +e +e +e +z +E +E +E +E +E +E +Q +d +q +q +q +q +q +q +E +"} +(20,1,1) = {" +E +z +z +z +z +E +E +E +z +z +e +V +e +e +e +z +z +z +z +e +e +t +z +z +E +E +a +a +a +E +q +A +A +A +A +A +A +A +E +"} +(21,1,1) = {" +E +z +W +I +z +z +z +z +z +z +e +e +e +e +z +z +E +E +z +z +e +e +z +E +E +E +a +a +a +E +q +A +A +A +A +A +A +A +E +"} +(22,1,1) = {" +E +G +t +S +e +z +z +e +e +e +e +e +e +z +z +E +E +E +z +e +e +e +z +E +E +E +a +a +a +E +q +A +C +A +A +A +A +A +E +"} +(23,1,1) = {" +E +G +K +W +V +e +e +e +z +z +e +z +z +z +E +E +E +E +z +e +e +z +z +E +E +a +a +a +a +E +q +C +C +C +A +A +A +A +E +"} +(24,1,1) = {" +E +z +z +I +I +z +z +z +z +z +e +z +E +E +E +E +E +E +z +e +e +z +E +E +E +E +E +E +E +E +d +C +C +A +A +C +A +A +E +"} +(25,1,1) = {" +E +E +z +z +z +z +E +E +E +z +p +z +z +E +E +E +E +E +z +e +s +z +z +z +E +E +E +E +E +E +z +C +C +C +A +C +C +A +E +"} +(26,1,1) = {" +a +E +E +E +E +E +E +E +E +z +e +e +z +E +E +E +E +E +z +e +e +e +e +z +z +z +E +E +E +z +z +n +n +n +n +n +v +A +E +"} +(27,1,1) = {" +a +a +a +a +a +E +E +z +z +z +e +e +z +z +E +E +E +E +z +z +e +e +e +e +e +z +z +z +z +k +e +n +j +j +j +n +n +A +E +"} +(28,1,1) = {" +a +a +a +a +a +E +z +z +T +e +e +V +W +z +E +E +E +z +z +e +e +z +z +e +e +e +z +V +e +e +e +n +n +n +n +n +n +A +E +"} +(29,1,1) = {" +a +a +a +a +a +E +z +N +f +S +e +W +I +z +E +E +E +z +e +e +z +z +z +z +e +V +z +V +t +e +e +n +n +F +H +n +n +A +E +"} +(30,1,1) = {" +a +a +a +a +a +E +z +x +o +e +I +I +z +z +E +E +E +z +e +z +z +E +E +z +z +z +z +z +k +e +e +n +n +n +n +n +n +A +E +"} +(31,1,1) = {" +a +a +a +a +a +E +z +z +z +e +z +z +z +E +E +E +E +z +e +z +z +E +E +E +E +E +E +E +z +e +e +n +L +n +n +n +n +A +E +"} +(32,1,1) = {" +a +a +a +a +a +E +E +E +z +e +z +E +E +E +E +E +E +z +e +e +z +E +a +a +a +a +E +E +z +e +e +n +n +n +n +n +r +A +E +"} +(33,1,1) = {" +a +a +a +a +a +a +a +E +z +e +z +E +E +a +a +a +E +l +z +V +z +E +a +a +a +a +E +z +z +z +q +C +A +A +C +A +A +A +E +"} +(34,1,1) = {" +a +a +a +a +a +a +a +E +z +V +z +E +E +a +a +a +E +E +z +e +z +E +a +a +a +a +E +z +E +d +q +C +C +C +A +A +A +A +E +"} +(35,1,1) = {" +a +a +a +a +a +a +a +E +z +e +z +E +E +a +a +a +E +E +z +e +z +E +a +a +a +a +E +E +E +d +q +A +A +A +A +A +A +A +E +"} +(36,1,1) = {" +a +a +a +a +a +a +a +E +z +e +z +E +E +E +E +E +E +z +z +e +z +E +a +a +a +a +a +a +E +d +q +A +C +D +A +A +A +A +E +"} +(37,1,1) = {" +a +a +a +a +E +E +E +E +z +e +z +E +E +E +E +E +z +z +e +e +z +E +a +a +a +a +a +a +E +d +q +A +A +A +A +A +A +A +E +"} +(38,1,1) = {" +a +a +a +a +E +E +E +z +z +e +z +z +z +z +z +z +z +e +e +z +z +E +a +a +a +a +a +a +E +d +q +A +A +A +A +A +A +A +E +"} +(39,1,1) = {" +a +a +a +a +E +E +z +z +e +e +W +z +z +e +e +P +e +e +z +z +E +E +a +a +a +a +a +a +E +Q +q +q +q +q +q +q +q +q +E +"} +(40,1,1) = {" +a +a +a +a +E +E +z +I +p +e +e +e +e +e +z +z +z +z +z +E +E +a +a +a +a +a +a +a +E +E +E +E +E +E +E +E +E +E +E +"} +(41,1,1) = {" +a +a +a +a +E +z +z +W +e +V +e +W +z +z +z +E +E +E +E +E +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(42,1,1) = {" +a +a +a +a +E +z +W +K +e +I +I +z +z +E +E +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(43,1,1) = {" +a +a +a +a +E +c +z +z +z +z +z +z +E +E +E +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} +(44,1,1) = {" +a +a +a +a +E +E +E +E +E +E +E +E +E +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +a +"} diff --git a/code/__DEFINES/access.dm b/code/__DEFINES/access.dm index 41a26faffdc2d5..7a1e91cd408501 100644 --- a/code/__DEFINES/access.dm +++ b/code/__DEFINES/access.dm @@ -104,6 +104,8 @@ #define ACCESS_VAULT "vault" /// Access for the Quartermaster's personal quarters in mapping, as well as some other QM-related things. #define ACCESS_QM "qm" +/// Access for the bitrunning den +#define ACCESS_BIT_DEN "bit_den" /// General access for Science, allows for entry to the general hallways of Science, as well as the main lathe room. #define ACCESS_SCIENCE "science" @@ -281,6 +283,7 @@ ACCESS_ATMOSPHERICS, \ ACCESS_AUX_BASE, \ ACCESS_BAR, \ + ACCESS_BIT_DEN, \ ACCESS_BRIG, \ ACCESS_BRIG_ENTRANCE, \ ACCESS_CARGO, \ @@ -492,6 +495,7 @@ #define REGION_SUPPLY "Supply" /// Used to seed the accesses_by_region list in SSid_access. A list of all cargo regional accesses that are overseen by the HoP. #define REGION_ACCESS_SUPPLY list( \ + ACCESS_BIT_DEN, \ ACCESS_CARGO, \ ACCESS_MECH_MINING, \ ACCESS_MINERAL_STOREROOM, \ @@ -550,6 +554,7 @@ /obj/item/modular_computer/pda/heads/rd = list(REGION_COMMAND), \ /obj/item/modular_computer/pda/heads/captain = list(REGION_COMMAND), \ /obj/item/modular_computer/pda/cargo = list(REGION_SUPPLY), \ + /obj/item/modular_computer/pda/bitrunner = list(REGION_SUPPLY), \ /obj/item/modular_computer/pda/shaftminer = list(REGION_SUPPLY), \ /obj/item/modular_computer/pda/chaplain = list(REGION_GENERAL), \ /obj/item/modular_computer/pda/lawyer = list(REGION_GENERAL), \ diff --git a/code/__DEFINES/actions.dm b/code/__DEFINES/actions.dm index 066d2d60c1e10c..5bc2b161781247 100644 --- a/code/__DEFINES/actions.dm +++ b/code/__DEFINES/actions.dm @@ -8,6 +8,8 @@ #define AB_CHECK_CONSCIOUS (1<<3) ///Action button checks if user is incapacitated #define AB_CHECK_INCAPACITATED (1<<4) +///Action button checks if user is jaunting +#define AB_CHECK_PHASED (1<<5) DEFINE_BITFIELD(check_flags, list( "CHECK IF HANDS BLOCKED" = AB_CHECK_HANDS_BLOCKED, @@ -15,6 +17,7 @@ DEFINE_BITFIELD(check_flags, list( "CHECK IF LYING DOWN" = AB_CHECK_LYING, "CHECK IF CONSCIOUS" = AB_CHECK_CONSCIOUS, "CHECK IF INCAPACITATED" = AB_CHECK_INCAPACITATED, + "CHECK IF TEMPORARILY INCORPOREAL" = AB_CHECK_PHASED, )) ///Action button triggered with right click diff --git a/code/__DEFINES/actionspeed_modification.dm b/code/__DEFINES/actionspeed_modification.dm index c3d288e907fc45..1753105f1275d4 100644 --- a/code/__DEFINES/actionspeed_modification.dm +++ b/code/__DEFINES/actionspeed_modification.dm @@ -1,3 +1,5 @@ //ids #define ACTIONSPEED_ID_SANITY "sanity_component" #define ACTIONSPEED_ID_STIMULANTS "stimulant_withdrawal" + +#define ACTIONSPEED_ID_MIDAS_BLIGHT "midas_blight_debuff" diff --git a/code/__DEFINES/ai/ai.dm b/code/__DEFINES/ai/ai.dm index 467fc9d7c0f57d..83d7e7f6a5f16a 100644 --- a/code/__DEFINES/ai/ai.dm +++ b/code/__DEFINES/ai/ai.dm @@ -32,6 +32,8 @@ #define CAN_ACT_WHILE_DEAD (1<<1) /// Stop processing while in a progress bar #define PAUSE_DURING_DO_AFTER (1<<2) +/// Continue processing while in stasis +#define CAN_ACT_IN_STASIS (1<<3) //Base Subtree defines diff --git a/code/__DEFINES/ai/ai_blackboard.dm b/code/__DEFINES/ai/ai_blackboard.dm index e23a5a12dba2e4..7ed8518e66f3c6 100644 --- a/code/__DEFINES/ai/ai_blackboard.dm +++ b/code/__DEFINES/ai/ai_blackboard.dm @@ -11,6 +11,14 @@ ///How close a mob must be for us to select it as a target, if that is less than how far we can maintain it as a target #define BB_AGGRO_RANGE "BB_aggro_range" +/// Store a single or list of emotes at this key +#define BB_EMOTE_KEY "BB_emotes" +/// Chance to perform an emote per second +#define BB_EMOTE_CHANCE "BB_EMOTE_CHANCE" + +///Turf we want a mob to move to +#define BB_TRAVEL_DESTINATION "BB_travel_destination" + ///song instrument blackboard, set by instrument subtrees #define BB_SONG_INSTRUMENT "BB_SONG_INSTRUMENT" ///song lines blackboard, set by default on controllers @@ -51,6 +59,9 @@ /// Generic key for a non-specific action #define BB_GENERIC_ACTION "BB_generic_action" +/// Generic key for a shapeshifting action +#define BB_SHAPESHIFT_ACTION "BB_shapeshift_action" + ///How long have we spent with no target? #define BB_TARGETLESS_TIME "BB_targetless_time" @@ -74,8 +85,8 @@ ///List of mobs who have damaged us #define BB_BASIC_MOB_RETALIATE_LIST "BB_basic_mob_shitlist" -/// Flag to set on or off if you want your mob to prioritise running away -#define BB_BASIC_MOB_FLEEING "BB_basic_fleeing" +/// Flag to set on if you want your mob to STOP running away +#define BB_BASIC_MOB_STOP_FLEEING "BB_basic_stop_fleeing" ///list of foods this mob likes #define BB_BASIC_FOODS "BB_basic_foods" @@ -99,4 +110,4 @@ #define BB_EMOTE_HEAR "emote_hear" #define BB_EMOTE_SEE "emote_see" #define BB_EMOTE_SOUND "emote_sound" -#define BB_EMOTE_CHANCE "emote_chance" +#define BB_SPEAK_CHANCE "emote_chance" diff --git a/code/__DEFINES/ai/monsters.dm b/code/__DEFINES/ai/monsters.dm index be9a4be34cd151..2867ba4a6fc94f 100644 --- a/code/__DEFINES/ai/monsters.dm +++ b/code/__DEFINES/ai/monsters.dm @@ -147,9 +147,45 @@ /// key holds the tray we will beam #define BB_BEAMABLE_HYDROPLANT_TARGET "beamable_hydroplant_target" +//ice demons +///the list of items we are afraid of +#define BB_LIST_SCARY_ITEMS "list_scary_items" +///our teleportation ability +#define BB_DEMON_TELEPORT_ABILITY "demon_teleport_ability" +///the destination of our teleport ability +#define BB_TELEPORT_DESTINATION "teleport_destination" +///the ability to clone ourself +#define BB_DEMON_CLONE_ABILITY "demon_clone_ability" +///our slippery ice ability +#define BB_DEMON_SLIP_ABILITY "demon_slip_ability" +///the turf we are escaping too +#define BB_ESCAPE_DESTINATION "escape_destination" +///how far away we will be from our target before teleporting +#define BB_MINIMUM_DISTANCE_RANGE "minimum_distance_range" + /// Corpse we have consumed #define BB_LEGION_CORPSE "legion_corpse" /// Things our target recently said #define BB_LEGION_RECENT_LINES "legion_recent_lines" /// The creator of our legion skull #define BB_LEGION_BROOD_CREATOR "legion_brood_creator" + +//mook keys +/// our home landmark +#define BB_HOME_VILLAGE "home_village" +/// maximum distance we can be from home during a storm +#define BB_MAXIMUM_DISTANCE_TO_VILLAGE "maximum_distance_to_village" +/// stand where we deposit our ores +#define BB_MATERIAL_STAND_TARGET "material_stand_target" +/// our jump ability +#define BB_MOOK_JUMP_ABILITY "mook_jump_ability" +/// our leap ability +#define BB_MOOK_LEAP_ABILITY "mook_leap_ability" +/// the chief we must obey +#define BB_MOOK_TRIBAL_CHIEF "mook_tribal_chief" +/// the injured mook we must heal +#define BB_INJURED_MOOK "injured_mook" +/// the player we will follow and play music for +#define BB_MOOK_MUSIC_AUDIENCE "music_audience" +/// the bonfire we will light up +#define BB_MOOK_BONFIRE_TARGET "bonfire_target" diff --git a/code/__DEFINES/alerts.dm b/code/__DEFINES/alerts.dm index 43ec8199d0f7c7..6f25e61e7c5580 100644 --- a/code/__DEFINES/alerts.dm +++ b/code/__DEFINES/alerts.dm @@ -61,3 +61,12 @@ #define ALERT_TEMPERATURE "temp" #define ALERT_TEMPERATURE_HOT "temphot" #define ALERT_TEMPERATURE_COLD "tempcold" + +/** Bitrunning */ +#define ALERT_BITRUNNER_CROWBAR "bitrunning_crowbar" +#define ALERT_BITRUNNER_COMPLETED "bitrunning_complete" +#define ALERT_BITRUNNER_INTEGRITY "bitrunning_integrity" +#define ALERT_BITRUNNER_SHUTDOWN "bitrunning_shutdown" +#define ALERT_BITRUNNER_RESET "bitrunning_reset" +#define ALERT_BITRUNNER_SPAWN_CYBERCOP "bitrunning_spawn_cybercop" +#define ALERT_BITRUNNER_THREAT "bitrunning_threat" diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index 125870797ca094..8ac421f8b0a897 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -317,6 +317,7 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list( #define ANTAG_GROUP_ASHWALKERS "Ash Walkers" #define ANTAG_GROUP_BIOHAZARDS "Biohazards" #define ANTAG_GROUP_CLOWNOPS "Clown Operatives" +#define ANTAG_GROUP_CYBERAUTH "Cyber Authority" #define ANTAG_GROUP_ERT "Emergency Response Team" #define ANTAG_GROUP_HORRORS "Eldritch Horrors" #define ANTAG_GROUP_LEVIATHANS "Spaceborne Leviathans" @@ -365,3 +366,5 @@ GLOBAL_LIST_INIT(human_invader_antagonists, list( #define BATON_CUFF 2 #define BATON_PROBE 3 #define BATON_MODES 4 + +#define FREEDOM_IMPLANT_CHARGES 4 diff --git a/code/__DEFINES/aquarium.dm b/code/__DEFINES/aquarium.dm deleted file mode 100644 index 6e0a39f5040196..00000000000000 --- a/code/__DEFINES/aquarium.dm +++ /dev/null @@ -1,44 +0,0 @@ -#define AQUARIUM_ANIMATION_FISH_SWIM "fish" -#define AQUARIUM_ANIMATION_FISH_DEAD "dead" - -#define AQUARIUM_PROPERTIES_PX_MIN "px_min" -#define AQUARIUM_PROPERTIES_PX_MAX "px_max" -#define AQUARIUM_PROPERTIES_PY_MIN "py_min" -#define AQUARIUM_PROPERTIES_PY_MAX "py_max" - -#define AQUARIUM_LAYER_MODE_BOTTOM "bottom" -#define AQUARIUM_LAYER_MODE_TOP "top" -#define AQUARIUM_LAYER_MODE_AUTO "auto" - -#define FISH_ALIVE "alive" -#define FISH_DEAD "dead" - -#define FISH_SIZE_TINY_MAX 30 -#define FISH_SIZE_SMALL_MAX 50 -#define FISH_SIZE_NORMAL_MAX 90 -#define FISH_SIZE_BULKY_MAX 130 - -#define FISH_GRIND_RESULTS_WEIGHT_DIVISOR 500 -#define FISH_FILLET_NUMBER_SIZE_DIVISOR 30 - -#define NEW_FISH_BREEDING_TIMEOUT_MULT 2 -#define NEW_FISH_LAST_FEEDING_MULT 0.5 - -#define MIN_AQUARIUM_TEMP T0C -#define MAX_AQUARIUM_TEMP (T0C + 100) -#define DEFAULT_AQUARIUM_TEMP (T0C + 24) - -#define FISH_RARITY_BASIC 1000 -#define FISH_RARITY_RARE 400 -#define FISH_RARITY_VERY_RARE 200 -#define FISH_RARITY_GOOD_LUCK_FINDING_THIS 1 -#define FISH_RARITY_NOPE 0 - -#define AQUARIUM_FLUID_FRESHWATER "Freshwater" -#define AQUARIUM_FLUID_SALTWATER "Saltwater" -#define AQUARIUM_FLUID_SULPHWATEVER "Sulfuric Water" -#define AQUARIUM_FLUID_AIR "Air" -#define AQUARIUM_FLUID_ANADROMOUS "Adaptive to both Freshwater and Saltwater" -#define AQUARIUM_FLUID_ANY_WATER "Adaptive to all kind of water" - -#define AQUARIUM_COMPANY "Aquatech Ltd." diff --git a/code/__DEFINES/atom_hud.dm b/code/__DEFINES/atom_hud.dm index b2623ecd988234..ff139f13d46039 100644 --- a/code/__DEFINES/atom_hud.dm +++ b/code/__DEFINES/atom_hud.dm @@ -46,11 +46,14 @@ /// Mech camera HUD #define DIAG_CAMERA_HUD "22" -// SKYRAT EDIT ADDITION BEGIN - gun permits +// SKYRAT EDIT ADDITION BEGIN - gun permits and DNR /// ammo of guns #define AMMO_HUD "25" /// if they have a gun permit #define PERMIT_HUD "26" + +/// If they have the DNR trait +#define DNR_HUD "27" // SKYRAT EDIT ADDITION END //by default everything in the hud_list of an atom is an image @@ -70,6 +73,7 @@ #define DATA_HUD_AI_DETECT 9 #define DATA_HUD_FAN 10 #define DATA_HUD_PERMIT 11 //SKYRAT EDIT +#define DATA_HUD_DNR 12 // SKYRAT EDIT // Notification action types #define NOTIFY_JUMP "jump" @@ -92,6 +96,7 @@ #define SECHUD_ASSISTANT "hudassistant" #define SECHUD_ATMOSPHERIC_TECHNICIAN "hudatmospherictechnician" #define SECHUD_BARTENDER "hudbartender" +#define SECHUD_BITRUNNER "hudbitrunner" #define SECHUD_BOTANIST "hudbotanist" #define SECHUD_CAPTAIN "hudcaptain" #define SECHUD_CARGO_TECHNICIAN "hudcargotechnician" diff --git a/code/__DEFINES/basic_mobs.dm b/code/__DEFINES/basic_mobs.dm index 5a4aebaee23e6e..6c8a3022e8fa77 100644 --- a/code/__DEFINES/basic_mobs.dm +++ b/code/__DEFINES/basic_mobs.dm @@ -19,3 +19,10 @@ /// Above this speed we stop gliding because it looks silly #define END_GLIDE_SPEED 10 + +///mook attack status flags +#define MOOK_ATTACK_NEUTRAL 0 +#define MOOK_ATTACK_WARMUP 1 +#define MOOK_ATTACK_ACTIVE 2 +#define MOOK_ATTACK_STRIKE 3 + diff --git a/code/__DEFINES/bitrunning.dm b/code/__DEFINES/bitrunning.dm new file mode 100644 index 00000000000000..343801c477e971 --- /dev/null +++ b/code/__DEFINES/bitrunning.dm @@ -0,0 +1,20 @@ +#define BITRUNNER_COST_NONE 0 +#define BITRUNNER_COST_LOW 1 +#define BITRUNNER_COST_MEDIUM 2 +#define BITRUNNER_COST_HIGH 3 +#define BITRUNNER_COST_EXTREME 20 + +#define BITRUNNER_REWARD_MIN 1 +#define BITRUNNER_REWARD_LOW 3 +#define BITRUNNER_REWARD_MEDIUM 4 +#define BITRUNNER_REWARD_HIGH 5 +#define BITRUNNER_REWARD_EXTREME 6 + +/// Blue in ui +#define BITRUNNER_DIFFICULTY_NONE 0 +/// Yellow +#define BITRUNNER_DIFFICULTY_LOW 1 +/// Orange +#define BITRUNNER_DIFFICULTY_MEDIUM 2 +/// Red with skull +#define BITRUNNER_DIFFICULTY_HIGH 3 diff --git a/code/__DEFINES/blood.dm b/code/__DEFINES/blood.dm index 3bf4af659698a8..2c8576a2edad7d 100644 --- a/code/__DEFINES/blood.dm +++ b/code/__DEFINES/blood.dm @@ -19,3 +19,16 @@ #define BLOOD_STATE_OIL "oil" /// No blood is present #define BLOOD_STATE_NOT_BLOODY "no blood whatsoever" + +// Bitflags for mob dismemberment and gibbing +/// Mobs will drop a brain +#define DROP_BRAIN (1<<0) +/// Mobs will drop organs +#define DROP_ORGANS (1<<1) +/// Mobs will drop bodyparts (arms, legs, etc.) +#define DROP_BODYPARTS (1<<2) +/// Mobs will drop items +#define DROP_ITEMS (1<<3) + +/// Mobs will drop everything +#define DROP_ALL_REMAINS (DROP_BRAIN | DROP_ORGANS | DROP_BODYPARTS | DROP_ITEMS) diff --git a/code/__DEFINES/cargo.dm b/code/__DEFINES/cargo.dm index 747e48559f79fa..56d3896f0dc05f 100644 --- a/code/__DEFINES/cargo.dm +++ b/code/__DEFINES/cargo.dm @@ -40,6 +40,12 @@ /// The baseline unit for cargo crates. Adjusting this will change the cost of all in-game shuttles, crate export values, bounty rewards, and all supply pack import values, as they use this as their unit of measurement. #define CARGO_CRATE_VALUE 200 +/// The highest amount of orders you can have of one thing at any one time +#define CARGO_MAX_ORDER 50 + +/// Returned by /obj/docking_port/mobile/supply/proc/get_order_count to signify us going over the order limit +#define OVER_ORDER_LIMIT "GO AWAY" + /// Universal Scanner mode for export scanning. #define SCAN_EXPORTS 1 /// Universal Scanner mode for using the sales tagger. diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm index 25bd59bc8b593c..b14fd514b85e4c 100644 --- a/code/__DEFINES/colors.dm +++ b/code/__DEFINES/colors.dm @@ -93,6 +93,7 @@ #define COLOR_STRONG_MAGENTA "#B800B8" #define COLOR_PURPLE "#800080" #define COLOR_VIOLET "#B900F7" +#define COLOR_VOID_PURPLE "#53277E" #define COLOR_STRONG_VIOLET "#6927C5" #define COLOR_DARK_PURPLE "#551A8B" diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 92e7749860b28d..cc9412208fb854 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -56,10 +56,12 @@ #define BRUTELOSS (1<<0) #define FIRELOSS (1<<1) #define TOXLOSS (1<<2) -#define OXYLOSS (1<<3) -#define SHAME (1<<4) -#define MANUAL_SUICIDE (1<<5) //suicide_act will do the actual killing. -#define MANUAL_SUICIDE_NONLETHAL (1<<6) //when the suicide is conditionally lethal +#define CLONELOSS (1<<3) +#define OXYLOSS (1<<4) +#define STAMINALOSS (1<<5) +#define SHAME (1<<6) +#define MANUAL_SUICIDE (1<<7) //suicide_act will do the actual killing. +#define MANUAL_SUICIDE_NONLETHAL (1<<8) //when the suicide is conditionally lethal #define EFFECT_STUN "stun" #define EFFECT_KNOCKDOWN "knockdown" @@ -272,6 +274,8 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( #define BODY_ZONE_L_LEG "l_leg" #define BODY_ZONE_R_LEG "r_leg" +GLOBAL_LIST_INIT(arm_zones, list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + #define BODY_ZONE_PRECISE_EYES "eyes" #define BODY_ZONE_PRECISE_MOUTH "mouth" #define BODY_ZONE_PRECISE_GROIN "groin" diff --git a/code/__DEFINES/computers.dm b/code/__DEFINES/computers.dm index 1349913c1837e2..ba3294ae683301 100644 --- a/code/__DEFINES/computers.dm +++ b/code/__DEFINES/computers.dm @@ -8,3 +8,6 @@ #define CATEGORY_CONSUMABLES "Consumables" #define CATEGORY_TOYS_DRONE "Toys & Drones" #define CATEGORY_PKA "PKAs" +#define CATEGORY_BEPIS "Bepis Tech" +#define CATEGORY_BITRUNNING_FLAIR "Misc" +#define CATEGORY_BITRUNNING_TECH "Tech" diff --git a/code/__DEFINES/configuration.dm b/code/__DEFINES/configuration.dm index 81965514fcbce1..477bed243c1a25 100644 --- a/code/__DEFINES/configuration.dm +++ b/code/__DEFINES/configuration.dm @@ -20,3 +20,11 @@ #define KEY_MODE_TEXT 0 #define KEY_MODE_TYPE 1 + +// Flags for respawn config +/// Respawn not allowed +#define RESPAWN_FLAG_DISABLED 0 +/// Respawn as much as you'd like +#define RESPAWN_FLAG_FREE 1 +/// Can respawn, but not as the same character +#define RESPAWN_FLAG_NEW_CHARACTER 2 diff --git a/code/__DEFINES/dcs/signals/signals_action.dm b/code/__DEFINES/dcs/signals/signals_action.dm index 27206e483c502a..6fbf5372acdd29 100644 --- a/code/__DEFINES/dcs/signals/signals_action.dm +++ b/code/__DEFINES/dcs/signals/signals_action.dm @@ -40,8 +40,11 @@ /// From base of /datum/action/cooldown/mob_cooldown/lava_swoop/proc/swoop_attack(): () #define COMSIG_LAVA_ARENA_FAILED "mob_lava_arena_failed" -///From /datum/action/vehicle/sealed/mecha/mech_toggle_safeties/proc/update_action_icon(): () +/// From /datum/action/vehicle/sealed/mecha/mech_toggle_safeties/proc/update_action_icon(): () #define COMSIG_MECH_SAFETIES_TOGGLE "mech_safeties_toggle" /// From /datum/action/cooldown/mob_cooldown/assume_form/proc/assume_appearances(), sent to the action owner: (atom/movable/target) #define COMSIG_ACTION_DISGUISED_APPEARANCE "mob_ability_disguise_appearance" + +/// From /datum/action/cooldown/manual_heart/Activate(): () +#define COMSIG_HEART_MANUAL_PULSE "heart_manual_pulse" diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm index a2198cfb63c184..932fc008848f5a 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_attack.dm @@ -52,11 +52,13 @@ #define COMSIG_ATOM_ATTACK_ROBOT_SECONDARY "atom_attack_robot_secondary" ///from relay_attackers element: (atom/attacker, attack_flags) #define COMSIG_ATOM_WAS_ATTACKED "atom_was_attacked" -///Called before a atom gets something tilted on them. If [COMPONENT_IMMUNE_TO_TILT_AND_CRUSH] is returned in a signal, the atom will be unaffected. +///Called before a atom gets something tilted on them. If [COMPONENT_IMMUNE_TO_TILT_AND_CRUSH] is returned in a signal, the atom will be unaffected: (atom/target, atom/source) #define COMSIG_PRE_TILT_AND_CRUSH "atom_pre_tilt_and_crush" #define COMPONENT_IMMUNE_TO_TILT_AND_CRUSH (1<<0) -///Called when a atom gets something tilted on them +///Called when a atom gets something tilted on them: (atom/target, atom/source) #define COMSIG_POST_TILT_AND_CRUSH "atom_post_tilt_and_crush" +/// Called when an atom is splashed with something: (atom/source) +#define COMSIG_ATOM_SPLASHED "atom_splashed" ///The damage type of the weapon projectile is non-lethal stamina #define ATTACKER_STAMINA_ATTACK (1<<0) diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm index 5e6d7491d9423e..d26dd4e8c86821 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movable.dm @@ -66,14 +66,6 @@ #define COMSIG_MOVABLE_SET_ANCHORED "movable_set_anchored" ///from base of atom/movable/setGrabState(): (newstate) #define COMSIG_MOVABLE_SET_GRAB_STATE "living_set_grab_state" -///Called when the movable tries to change its dynamic light color setting, from base atom/movable/lighting_overlay_set_color(): (color) -#define COMSIG_MOVABLE_LIGHT_OVERLAY_SET_RANGE "movable_light_overlay_set_color" -///Called when the movable tries to change its dynamic light power setting, from base atom/movable/lighting_overlay_set_power(): (power) -#define COMSIG_MOVABLE_LIGHT_OVERLAY_SET_POWER "movable_light_overlay_set_power" -///Called when the movable tries to change its dynamic light range setting, from base atom/movable/lighting_overlay_set_range(): (range) -#define COMSIG_MOVABLE_LIGHT_OVERLAY_SET_COLOR "movable_light_overlay_set_range" -///Called when the movable tries to toggle its dynamic light LIGHTING_ON status, from base atom/movable/lighting_overlay_toggle_on(): (new_state) -#define COMSIG_MOVABLE_LIGHT_OVERLAY_TOGGLE_ON "movable_light_overlay_toggle_on" ///called when the movable's glide size is updated: (new_glide_size) #define COMSIG_MOVABLE_UPDATE_GLIDE_SIZE "movable_glide_size" ///Called when a movable is hit by a plunger in layer mode, from /obj/item/plunger/attack_atom() diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm index d7063b0df5f73d..0c9523b9c20a8b 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_movement.dm @@ -17,6 +17,9 @@ #define COMSIG_ATOM_AFTER_SHUTTLE_MOVE "movable_after_shuttle_move" ///called on a movable (NOT living) when it starts pulling (atom/movable/pulled, state, force) #define COMSIG_ATOM_START_PULL "movable_start_pull" +/// called on /atom when something attempts to pass through it (atom/movable/source, atom/movable/passing, dir) +#define COMSIG_ATOM_TRIED_PASS "atom_tried_pass" + #define COMSIG_COMPONENT_PERMIT_PASSAGE (1 << 0) ///called on /living when someone starts pulling (atom/movable/pulled, state, force) #define COMSIG_LIVING_START_PULL "living_start_pull" ///called on /living when someone is pulled (mob/living/puller) diff --git a/code/__DEFINES/dcs/signals/signals_bitrunning.dm b/code/__DEFINES/dcs/signals/signals_bitrunning.dm new file mode 100644 index 00000000000000..957e61ae303c2b --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_bitrunning.dm @@ -0,0 +1,34 @@ +/// from /obj/machinery/netpod/default_pry_open() : (mob/living/intruder) +#define COMSIG_BITRUNNER_CROWBAR_ALERT "bitrunner_crowbar" + +/// from /obj/effect/bitrunning/loot_signal: (points) +#define COMSIG_BITRUNNER_GOAL_POINT "bitrunner_goal_point" + +/// from /obj/machinery/quantum_server/on_goal_turf_entered(): (atom/entered, reward_points) +#define COMSIG_BITRUNNER_DOMAIN_COMPLETE "bitrunner_complete" + +/// from /obj/machinery/netpod/on_take_damage() +#define COMSIG_BITRUNNER_NETPOD_INTEGRITY "bitrunner_netpod_damage" + +/// from /obj/structure/hololadder and complete alert +#define COMSIG_BITRUNNER_SAFE_DISCONNECT "bitrunner_disconnect" + +/// from /obj/machinery/netpod/open_machine(), /obj/machinery/quantum_server, etc (obj/machinery/netpod) +#define COMSIG_BITRUNNER_SEVER_AVATAR "bitrunner_sever" + +/// from /obj/machinery/quantum_server/shutdown() : (mob/living) +#define COMSIG_BITRUNNER_SHUTDOWN_ALERT "bitrunner_shutdown" + +// Notifies the bitrunners +/// from /datum/antagonist/cyber_police/proc/notify() : +#define COMSIG_BITRUNNER_THREAT_CREATED "bitrunner_threat" + +// Informs the server to up the threat count +/// from event spawns: (mob/living) +#define COMSIG_BITRUNNER_SPAWN_GLITCH "bitrunner_spawn_glitch" + +/// from /obj/machinery/quantum_server/refreshParts(): (servo rating) +#define COMSIG_BITRUNNER_SERVER_UPGRADED "bitrunner_server_upgraded" + +/// from /obj/machinery/quantum_server/scrub_vdom() +#define COMSIG_BITRUNNER_DOMAIN_SCRUBBED "bitrunner_domain_scrubbed" diff --git a/code/__DEFINES/dcs/signals/signals_blob.dm b/code/__DEFINES/dcs/signals/signals_blob.dm new file mode 100644 index 00000000000000..afd4737bdd9680 --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_blob.dm @@ -0,0 +1,4 @@ +/// Signal sent when a blob overmind picked a new strain (/mob/camera/blob/overmind, /datum/blobstrain/new_strain) +#define COMSIG_BLOB_SELECTED_STRAIN "blob_selected_strain" +/// Signal sent by a blob spore when it creates a zombie (/mob/living/basic/blob_minion/spore/spore, //mob/living/basic/blob_minion/zombie/zombie) +#define COMSIG_BLOB_ZOMBIFIED "blob_zombified" diff --git a/code/__DEFINES/dcs/signals/signals_fish.dm b/code/__DEFINES/dcs/signals/signals_fish.dm index 281c73adb522f7..a40e731fc7bf63 100644 --- a/code/__DEFINES/dcs/signals/signals_fish.dm +++ b/code/__DEFINES/dcs/signals/signals_fish.dm @@ -24,8 +24,13 @@ #define COMSIG_FISHING_ROD_CAST "fishing_rod_cast" #define FISHING_ROD_CAST_HANDLED (1 << 0) -/// Sent when fishing line is snapped -#define COMSIG_FISHING_LINE_SNAPPED "fishing_line_interrupted" +/// From /datum/fish_source/proc/dispense_reward(), not set if the reward is a dud: (reward, user) +#define COMSIG_FISHING_ROD_CAUGHT_FISH "fishing_rod_caught_fish" +/// From /obj/item/fishing_rod/proc/hook_item(): (reward, user) +#define COMSIG_FISHING_ROD_HOOKED_ITEM "fishing_rod_hooked_item" /// Sent when the challenge is to be interrupted: (reason) #define COMSIG_FISHING_SOURCE_INTERRUPT_CHALLENGE "fishing_spot_interrupt_challenge" + +/// From /obj/item/fish_analyzer/proc/analyze_status: (fish, user) +#define COMSIG_FISH_ANALYZER_ANALYZE_STATUS "fish_analyzer_analyze_status" diff --git a/code/__DEFINES/dcs/signals/signals_global.dm b/code/__DEFINES/dcs/signals/signals_global.dm index c75b169b90dc52..9ccd3fd72670e6 100644 --- a/code/__DEFINES/dcs/signals/signals_global.dm +++ b/code/__DEFINES/dcs/signals/signals_global.dm @@ -77,8 +77,8 @@ /// global signal sent when a nuclear device is detonating (/obj/machinery/nuclearbomb/nuke/exploding_nuke) #define COMSIG_GLOB_NUKE_DEVICE_DETONATING "!nuclear_device_detonating" -/// Global signal sent when a light mechanism is completed (try_id) -#define COMSIG_GLOB_LIGHT_MECHANISM_COMPLETED "!light_mechanism_completed" +/// Global signal sent when a puzzle piece is completed (light mechanism, etc.) (try_id) +#define COMSIG_GLOB_PUZZLE_COMPLETED "!puzzle_completed" /// Global signal called after the station changes its name. /// (new_name, old_name) diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm index 677a65a7be1736..ad0e6e359b1e76 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_carbon.dm @@ -36,8 +36,13 @@ #define COMSIG_BODYPART_ATTACHED "bodypart_removed" ///from base of /obj/item/bodypart/proc/try_attach_limb(): (new_limb, special) #define COMSIG_CARBON_POST_ATTACH_LIMB "carbon_post_attach_limb" -#define COMSIG_BODYPART_GAUZED "bodypart_gauzed" // from /obj/item/bodypart/proc/apply_gauze(/obj/item/stack/gauze) -#define COMSIG_BODYPART_GAUZE_DESTROYED "bodypart_degauzed" // from [/obj/item/bodypart/proc/seep_gauze] when it runs out of absorption +///from /obj/item/bodypart/proc/receive_damage, sent from the limb owner (limb, brute, burn) +#define COMSIG_CARBON_LIMB_DAMAGED "carbon_limb_damaged" + #define COMPONENT_PREVENT_LIMB_DAMAGE (1 << 0) +/// from /obj/item/bodypart/proc/apply_gauze(/obj/item/stack/gauze): (/obj/item/stack/medical/gauze/applied_gauze, /obj/item/stack/medical/gauze/stack_used) +#define COMSIG_BODYPART_GAUZED "bodypart_gauzed" +/// from /obj/item/stack/medical/gauze/Destroy(): (/obj/item/stack/medical/gauze/removed_gauze) +#define COMSIG_BODYPART_UNGAUZED "bodypart_ungauzed" /// Called from bodypart changing owner, which could be on attach or detachment. Either argument can be null. (mob/living/carbon/new_owner, mob/living/carbon/old_owner) #define COMSIG_BODYPART_CHANGED_OWNER "bodypart_changed_owner" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm index 273b9f216c7404..b70f7f9013dbaa 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -42,6 +42,8 @@ #define COMSIG_LIVING_TRY_SYRINGE "living_try_syringe" ///From living/Life(). (deltatime, times_fired) #define COMSIG_LIVING_LIFE "living_life" + /// Block the Life() proc from proceeding... this should really only be done in some really wacky situations. + #define COMPONENT_LIVING_CANCEL_LIFE_PROCESSING (1<<0) ///From living/set_resting(): (new_resting, silent, instant) #define COMSIG_LIVING_RESTING "living_resting" @@ -55,12 +57,41 @@ ///from base of element/bane/activate(): (item/weapon, mob/user) #define COMSIG_OBJECT_ON_BANING "obj_on_baning" +// adjust_x_loss messages sent from /mob/living/proc/adjust[x]Loss +/// Returned from all the following messages if you actually aren't going to apply any change +#define COMPONENT_IGNORE_CHANGE (1<<0) +// Each of these messages sends the damagetype even though it is inferred by the signal so you can pass all of them to the same proc if required +/// Send when bruteloss is modified (type, amount, forced) +#define COMSIG_LIVING_ADJUST_BRUTE_DAMAGE "living_adjust_brute_damage" +/// Send when fireloss is modified (type, amount, forced) +#define COMSIG_LIVING_ADJUST_BURN_DAMAGE "living_adjust_burn_damage" +/// Send when oxyloss is modified (type, amount, forced) +#define COMSIG_LIVING_ADJUST_OXY_DAMAGE "living_adjust_oxy_damage" +/// Send when toxloss is modified (type, amount, forced) +#define COMSIG_LIVING_ADJUST_TOX_DAMAGE "living_adjust_tox_damage" +/// Send when cloneloss is modified (type, amount, forced) +#define COMSIG_LIVING_ADJUST_CLONE_DAMAGE "living_adjust_clone_damage" +/// Send when staminaloss is modified (type, amount, forced) +#define COMSIG_LIVING_ADJUST_STAMINA_DAMAGE "living_adjust_stamina_damage" + +/// List of signals sent when you receive any damage except stamina +#define COMSIG_LIVING_ADJUST_STANDARD_DAMAGE_TYPES list(\ + COMSIG_LIVING_ADJUST_BRUTE_DAMAGE,\ + COMSIG_LIVING_ADJUST_BURN_DAMAGE,\ + COMSIG_LIVING_ADJUST_CLONE_DAMAGE,\ + COMSIG_LIVING_ADJUST_OXY_DAMAGE,\ + COMSIG_LIVING_ADJUST_TOX_DAMAGE,\ +) +/// List of signals sent when you receive any kind of damage at all +#define COMSIG_LIVING_ADJUST_ALL_DAMAGE_TYPES (COMSIG_LIVING_ADJUST_STANDARD_DAMAGE_TYPES + COMSIG_LIVING_ADJUST_STAMINA_DAMAGE) + + /// from base of mob/living/updatehealth() #define COMSIG_LIVING_HEALTH_UPDATE "living_health_update" ///from base of mob/living/death(): (gibbed) #define COMSIG_LIVING_DEATH "living_death" -///from base of mob/living/gib(): (no_brain, no_organs, no_bodyparts) +///from base of mob/living/gib(): (drop_bitflags) ///Note that it is fired regardless of whether the mob was dead beforehand or not. #define COMSIG_LIVING_GIBBED "living_gibbed" @@ -106,6 +137,10 @@ #define COMSIG_LIVING_UNARMED_ATTACK "living_unarmed_attack" ///From base of mob/living/MobBump() (mob/living) #define COMSIG_LIVING_MOB_BUMP "living_mob_bump" +///From base of mob/living/Bump() (turf/closed) +#define COMSIG_LIVING_WALL_BUMP "living_wall_bump" +///From base of turf/closed/Exited() (turf/closed) +#define COMSIG_LIVING_WALL_EXITED "living_wall_exited" ///From base of mob/living/ZImpactDamage() (mob/living, levels, turf/t) #define COMSIG_LIVING_Z_IMPACT "living_z_impact" #define NO_Z_IMPACT_DAMAGE (1<<0) @@ -179,3 +214,10 @@ /// From /datum/ai/behavior/climb_tree/perform() : (mob/living/basic/living_pawn) #define COMSIG_LIVING_CLIMB_TREE "living_climb_tree" + +/// Sent on a mob from /datum/component/mob_chain when component is attached with it as the "front" : (mob/living/basic/tail) +#define COMSIG_MOB_GAINED_CHAIN_TAIL "living_gained_chain_tail" +/// Sent on a mob from /datum/component/mob_chain when component is detached from it as the "front" : (mob/living/basic/tail) +#define COMSIG_MOB_LOST_CHAIN_TAIL "living_detached_chain_tail" +/// Sent from a 'contract chain' button on a mob chain +#define COMSIG_MOB_CHAIN_CONTRACT "living_chain_contracted" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm index d4c3c659c68cc5..51211f5ad6d7b3 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_main.dm @@ -7,6 +7,8 @@ #define COMSIG_MOB_LOGIN "mob_login" ///from base of /mob/Logout(): () #define COMSIG_MOB_LOGOUT "mob_logout" +///from base of /mob/mind_initialize +#define COMSIG_MOB_MIND_INITIALIZED "mob_mind_inited" ///from base of mob/set_stat(): (new_stat, old_stat) #define COMSIG_MOB_STATCHANGE "mob_statchange" ///from base of mob/reagent_check(): (datum/reagent/chem, seconds_per_tick, times_fired) @@ -29,6 +31,9 @@ /// From base of /mob/living/simple_animal/bot/proc/bot_step() #define COMSIG_MOB_BOT_STEP "mob_bot_step" +/// From base of /mob/proc/update_held_items +#define COMSIG_MOB_UPDATE_HELD_ITEMS "mob_update_held_items" + /// From base of /client/Move(): (list/move_args) #define COMSIG_MOB_CLIENT_PRE_LIVING_MOVE "mob_client_pre_living_move" /// Should we stop the current living movement attempt diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_spawner.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_spawner.dm index a5f66788b868d9..6ff8b1e8d61d40 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_spawner.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_spawner.dm @@ -1,3 +1,6 @@ // signals for use by mob spawners /// called when a spawner spawns a mob #define COMSIG_SPAWNER_SPAWNED "spawner_spawned" + +/// called when a ghost clicks a spawner role: (mob/living) +#define COMSIG_GHOSTROLE_SPAWNED "ghostrole_spawned" diff --git a/code/__DEFINES/drone.dm b/code/__DEFINES/drone.dm index 8907d172194cdd..0d31e3caf411dc 100644 --- a/code/__DEFINES/drone.dm +++ b/code/__DEFINES/drone.dm @@ -2,9 +2,8 @@ /// If drones are blacklisted from certain sensitive machines GLOBAL_VAR_INIT(drone_machine_blacklist_enabled, FALSE) -#define DRONE_HANDS_LAYER 1 -#define DRONE_HEAD_LAYER 2 -#define DRONE_TOTAL_LAYERS 2 +#define DRONE_HEAD_LAYER 1 +#define DRONE_TOTAL_LAYERS 1 /// Message displayed when new drone spawns in drone network #define DRONE_NET_CONNECT span_notice("DRONE NETWORK: [name] connected.") diff --git a/code/__DEFINES/dynamic.dm b/code/__DEFINES/dynamic.dm index f07b7e20b0fcb8..07c833cdc4947f 100644 --- a/code/__DEFINES/dynamic.dm +++ b/code/__DEFINES/dynamic.dm @@ -32,3 +32,9 @@ #define ROUNDSTART_RULESET "Roundstart" #define LATEJOIN_RULESET "Latejoin" #define MIDROUND_RULESET "Midround" + +#define RULESET_NOT_FORCED "not forced" +/// Ruleset should run regardless of population and threat available +#define RULESET_FORCE_ENABLED "force enabled" +/// Ruleset should not run regardless of population and threat available +#define RULESET_FORCE_DISABLED "force disabled" diff --git a/code/__DEFINES/economy.dm b/code/__DEFINES/economy.dm index 7e12f3904b6ec2..9d6841b56fd771 100644 --- a/code/__DEFINES/economy.dm +++ b/code/__DEFINES/economy.dm @@ -73,3 +73,30 @@ #define PAYMENT_CLINICAL "clinical" #define PAYMENT_FRIENDLY "friendly" #define PAYMENT_ANGRY "angry" + +#define MARKET_TREND_UPWARD 1 +#define MARKET_TREND_DOWNWARD -1 +#define MARKET_TREND_STABLE 0 + +#define MARKET_EVENT_PROBABILITY 1 //Probability of a market event firing, in percent. Fires once per material, every 20 seconds. + +#define MARKET_PROFIT_MODIFIER 0.8 //We don't make every sale a 1-1 of the actual buy price value, like with real life taxes and to encourage more smart trades + +/// Create quantity subtypes for stock market datums. +#define MARKET_QUANTITY_HELPERS(path) ##path/one {\ + amount = 1; \ +} \ +##path/five {\ + amount = 5; \ +} \ +##path/ten {\ + amount = 10; \ +} \ +##path/twenty_five {\ + amount = 25; \ +} \ +##path/fifty {\ + amount = 50; \ +} + + diff --git a/code/__DEFINES/experisci.dm b/code/__DEFINES/experisci.dm index 9130e0ae565175..c74290ff5f7512 100644 --- a/code/__DEFINES/experisci.dm +++ b/code/__DEFINES/experisci.dm @@ -26,6 +26,8 @@ /// Destructive experiments which will destroy the sample #define EXPERIMENT_TRAIT_DESTRUCTIVE (1 << 0) +/// Used by scanning experiments: instead of storing refs or be a number, the list for scanned atoms is used as typecache +#define EXPERIMENT_TRAIT_TYPECACHE (1 << 1) /// Will always attempt to action every experiment eligible with a single input, /// no experiment selection required @@ -33,3 +35,7 @@ /// Experiment handlers with this flag will not automatically connect to the first techweb they find /// on initialization #define EXPERIMENT_CONFIG_NO_AUTOCONNECT (1 << 1) +/// Experiment handlers with this flag won't pester the user of objects not pertinent to the test or if no experiment is selected +#define EXPERIMENT_CONFIG_SILENT_FAIL (1 << 2) +/// Experiment handlers with this flag will bypass any delay when trying to scan something +#define EXPERIMENT_CONFIG_IMMEDIATE_ACTION (1 << 3) diff --git a/code/__DEFINES/fish.dm b/code/__DEFINES/fish.dm new file mode 100644 index 00000000000000..89b7963d91d5cc --- /dev/null +++ b/code/__DEFINES/fish.dm @@ -0,0 +1,136 @@ +/// Use in fish tables to denote miss chance. +#define FISHING_DUD "dud" + +// Baseline fishing difficulty levels +#define FISHING_DEFAULT_DIFFICULTY 15 + +/// Difficulty modifier when bait is fish's favorite +#define FAV_BAIT_DIFFICULTY_MOD -5 +/// Difficulty modifier when bait is fish's disliked +#define DISLIKED_BAIT_DIFFICULTY_MOD 15 +/// Difficulty modifier when our fisherman has the trait TRAIT_SETTLER +#define SETTLER_DIFFICULTY_MOD -5 + +#define FISH_TRAIT_MINOR_DIFFICULTY_BOOST 5 + +// These define how the fish will behave in the minigame +#define FISH_AI_DUMB "dumb" +#define FISH_AI_ZIPPY "zippy" +#define FISH_AI_SLOW "slow" + +#define ADDITIVE_FISHING_MOD "additive" +#define MULTIPLICATIVE_FISHING_MOD "multiplicative" + +// These defines are intended for use to interact with fishing hooks when going +// through the fishing rod, and not the hook itself. They could probably be +// handled differently, but for now that's how they work. It's grounds for +// a future refactor, however. +/// Fishing hook trait that signifies that it's shiny. Useful for fishes +/// that care about shiner hooks more. +#define FISHING_HOOK_SHINY (1 << 0) +/// Fishing hook trait that lessens the bounce from hitting the edges of the minigame bar. +#define FISHING_HOOK_WEIGHTED (1 << 1) +///See FISHING_MINIGAME_RULE_BIDIRECTIONAL +#define FISHING_HOOK_BIDIRECTIONAL (1 << 2) +///Prevents the user from losing the game by letting the fish get away. +#define FISHING_HOOK_NO_ESCAPE (1 << 3) +///Limits the completion loss of the minigame when the fsh is not on the bait area. +#define FISHING_HOOK_ENSNARE (1 << 4) +///Automatically kills the fish after a while, at the cost of killing it. +#define FISHING_HOOK_KILL (1 << 5) + +///Reduces the difficulty of the minigame +#define FISHING_LINE_CLOAKED (1 << 0) +///Required to cast a line on lava. +#define FISHING_LINE_REINFORCED (1 << 1) +/// Much like FISHING_HOOK_ENSNARE but for the fishing line. +#define FISHING_LINE_BOUNCY (1 << 2) + +///Keeps the bait from falling from gravity, instead allowing the player to move the bait down with right click. +#define FISHING_MINIGAME_RULE_BIDIRECTIONAL (1 << 2) +///Prevents the player from losing the minigame when the completion reaches 0 +#define FISHING_MINIGAME_RULE_NO_ESCAPE (1 << 3) +///Automatically kills the fish after a while, at the cost of killing it +#define FISHING_MINIGAME_RULE_KILL (1 << 4) +///Prevents the fishing skill from having an effect on the minigame and experience from being awarded +#define FISHING_MINIGAME_RULE_NO_EXP (1 << 5) +///If enabled, the minigame will occasionally screw around and invert the velocity of the bait +#define FISHING_MINIGAME_RULE_ANTIGRAV (1 << 6) +///Will filp the minigame hud for the duration of the effect +#define FISHING_MINIGAME_RULE_FLIP (1 << 7) + +///all the effects that are active and will last for a few seconds before triggering a cooldown +#define FISHING_MINIGAME_ACTIVE_EFFECTS (FISHING_MINIGAME_RULE_ANTIGRAV|FISHING_MINIGAME_RULE_FLIP) + +/// The default additive value for fishing hook catch weight modifiers. +#define FISHING_DEFAULT_HOOK_BONUS_ADDITIVE 0 +/// The default multiplicative value for fishing hook catch weight modifiers. +#define FISHING_DEFAULT_HOOK_BONUS_MULTIPLICATIVE 1 + +//Fish icon defines, used by fishing minigame +#define FISH_ICON_DEF "fish" +#define FISH_ICON_HOSTILE "hostile" +#define FISH_ICON_STAR "star" +#define FISH_ICON_CHUNKY "chunky" +#define FISH_ICON_SLIME "slime" +#define FISH_ICON_COIN "coin" +#define FISH_ICON_GEM "gem" +#define FISH_ICON_CRAB "crab" +#define FISH_ICON_JELLYFISH "jellyfish" +#define FISH_ICON_BONE "bone" + +#define AQUARIUM_ANIMATION_FISH_SWIM "fish" +#define AQUARIUM_ANIMATION_FISH_DEAD "dead" + +#define AQUARIUM_PROPERTIES_PX_MIN "px_min" +#define AQUARIUM_PROPERTIES_PX_MAX "px_max" +#define AQUARIUM_PROPERTIES_PY_MIN "py_min" +#define AQUARIUM_PROPERTIES_PY_MAX "py_max" + +#define AQUARIUM_LAYER_MODE_BOTTOM "bottom" +#define AQUARIUM_LAYER_MODE_TOP "top" +#define AQUARIUM_LAYER_MODE_AUTO "auto" + +#define FISH_ALIVE "alive" +#define FISH_DEAD "dead" + +///Fish size thresholds for w_class. +#define FISH_SIZE_TINY_MAX 30 +#define FISH_SIZE_SMALL_MAX 50 +#define FISH_SIZE_NORMAL_MAX 90 +#define FISH_SIZE_BULKY_MAX 130 + +///The coefficient for maximum weight/size divergence relative to the averages. +#define MAX_FISH_DEVIATION_COEFF 2.5 + +///The volume of the grind results is multiplied by the fish' weight and divided by this. +#define FISH_GRIND_RESULTS_WEIGHT_DIVISOR 500 +///The number of fillets is multiplied by the fish' size and divided by this. +#define FISH_FILLET_NUMBER_SIZE_DIVISOR 30 + +///The breeding timeout for newly instantiated fish is multiplied by this. +#define NEW_FISH_BREEDING_TIMEOUT_MULT 2 +///The last feeding timestamp of newly instantiated fish is multiplied by this: ergo, they spawn 50% hungry. +#define NEW_FISH_LAST_FEEDING_MULT 0.5 + +#define MIN_AQUARIUM_TEMP T0C +#define MAX_AQUARIUM_TEMP (T0C + 100) +#define DEFAULT_AQUARIUM_TEMP (T0C + 24) + +///How likely one's to find a given fish from random fish cases. +#define FISH_RARITY_BASIC 1000 +#define FISH_RARITY_RARE 400 +#define FISH_RARITY_VERY_RARE 200 +#define FISH_RARITY_GOOD_LUCK_FINDING_THIS 5 +#define FISH_RARITY_NOPE 0 + +///Aquarium fluid variables. The fish' required fluid has to match this, or it'll slowly die. +#define AQUARIUM_FLUID_FRESHWATER "Freshwater" +#define AQUARIUM_FLUID_SALTWATER "Saltwater" +#define AQUARIUM_FLUID_SULPHWATEVER "Sulfuric Water" +#define AQUARIUM_FLUID_AIR "Air" +#define AQUARIUM_FLUID_ANADROMOUS "Adaptive to both Freshwater and Saltwater" +#define AQUARIUM_FLUID_ANY_WATER "Adaptive to all kind of water" + +///Fluff. The name of the aquarium company shown in the fish catalog +#define AQUARIUM_COMPANY "Aquatech Ltd." diff --git a/code/__DEFINES/fishing.dm b/code/__DEFINES/fishing.dm deleted file mode 100644 index dc73623f27cabf..00000000000000 --- a/code/__DEFINES/fishing.dm +++ /dev/null @@ -1,62 +0,0 @@ -/// Use in fish tables to denote miss chance. -#define FISHING_DUD "dud" - -// Baseline fishing difficulty levels -#define FISHING_DEFAULT_DIFFICULTY 15 - -/// Difficulty modifier when bait is fish's favorite -#define FAV_BAIT_DIFFICULTY_MOD -5 -/// Difficulty modifier when bait is fish's disliked -#define DISLIKED_BAIT_DIFFICULTY_MOD 15 -/// Difficulty modifier when our fisherman has the trait TRAIT_SETTLER -#define SETTLER_DIFFICULTY_MOD -5 - - -#define FISH_TRAIT_MINOR_DIFFICULTY_BOOST 5 - -// These define how the fish will behave in the minigame -#define FISH_AI_DUMB "dumb" -#define FISH_AI_ZIPPY "zippy" -#define FISH_AI_SLOW "slow" - -#define ADDITIVE_FISHING_MOD "additive" -#define MULTIPLICATIVE_FISHING_MOD "multiplicative" - -// These defines are intended for use to interact with fishing hooks when going -// through the fishing rod, and not the hook itself. They could probably be -// handled differently, but for now that's how they work. It's grounds for -// a future refactor, however. -/// Fishing hook trait that signifies that it's shiny. Useful for fishes -/// that care about shiner hooks more. -#define FISHING_HOOK_SHINY (1 << 0) -/// Fishing hook trait that's used to make the bait more weighted, for the -/// fishing minigame itself. -#define FISHING_HOOK_WEIGHTED (1 << 1) -/** - * During the fishing minigame, it stops the bait from being pulled down by gravity, - * while also allowing the player to move it down with right-click. - */ -#define FISHING_HOOK_BIDIRECTIONAL (1 << 2) -///Prevents the user from losing the game by letting the fish get away. -#define FISHING_HOOK_NO_ESCAPE (1 << 3) -///Limits the completion loss of the minigame when the fsh is not on the bait area. -#define FISHING_HOOK_ENSNARE (1 << 4) -///Slowly damages the fish, until it dies, then it's victory. -#define FISHING_HOOK_KILL (1 << 5) - -///Reduces the difficulty of the minigame -#define FISHING_LINE_CLOAKED (1 << 0) -///Required to cast a line on lava. -#define FISHING_LINE_REINFORCED (1 << 1) -/// Much like FISHING_HOOK_ENSNARE but for the reel. -#define FISHING_LINE_BOUNCY (1 << 2) - -#define FISHING_MINIGAME_RULE_BIDIRECTIONAL (1 << 2) -#define FISHING_MINIGAME_RULE_NO_ESCAPE (1 << 3) -#define FISHING_MINIGAME_RULE_KILL (1 << 4) -#define FISHING_MINIGAME_RULE_NO_EXP (1 << 5) - -/// The default additive value for fishing hook catch weight modifiers. -#define FISHING_DEFAULT_HOOK_BONUS_ADDITIVE 0 -/// The default multiplicative value for fishing hook catch weight modifiers. -#define FISHING_DEFAULT_HOOK_BONUS_MULTIPLICATIVE 1 diff --git a/code/__DEFINES/footsteps.dm b/code/__DEFINES/footsteps.dm index d77a0e1cab3470..c8b89b082a4975 100644 --- a/code/__DEFINES/footsteps.dm +++ b/code/__DEFINES/footsteps.dm @@ -25,6 +25,7 @@ #define FOOTSTEP_MOB_SHOE "footstep_shoe" #define FOOTSTEP_MOB_HUMAN "footstep_human" //Warning: Only works on /mob/living/carbon/human #define FOOTSTEP_MOB_SLIME "footstep_slime" +#define FOOTSTEP_MOB_RUST "footstep_rust" #define FOOTSTEP_OBJ_MACHINE "footstep_machine" #define FOOTSTEP_OBJ_ROBOT "footstep_robot" diff --git a/code/__DEFINES/guardian_defines.dm b/code/__DEFINES/guardian_defines.dm index d7aae6965a756a..e7961368feee09 100644 --- a/code/__DEFINES/guardian_defines.dm +++ b/code/__DEFINES/guardian_defines.dm @@ -3,6 +3,5 @@ #define GUARDIAN_THEME_CARP "carp" #define GUARDIAN_THEME_MINER "miner" -#define GUARDIAN_COLOR_LAYER 2 -#define GUARDIAN_HANDS_LAYER 1 -#define GUARDIAN_TOTAL_LAYERS 2 +#define GUARDIAN_COLOR_LAYER 1 +#define GUARDIAN_TOTAL_LAYERS 1 diff --git a/code/__DEFINES/icon_smoothing.dm b/code/__DEFINES/icon_smoothing.dm index bc3c2011ae286c..830daef563d54c 100644 --- a/code/__DEFINES/icon_smoothing.dm +++ b/code/__DEFINES/icon_smoothing.dm @@ -27,6 +27,27 @@ DEFINE_BITFIELD(smoothing_flags, list( "SMOOTH_BORDER_OBJECT" = SMOOTH_BORDER_OBJECT, )) +/// Components of a smoothing junction +/// Redefinitions of the diagonal directions so they can be stored in one var without conflicts +#define NORTH_JUNCTION NORTH //(1<<0) +#define SOUTH_JUNCTION SOUTH //(1<<1) +#define EAST_JUNCTION EAST //(1<<2) +#define WEST_JUNCTION WEST //(1<<3) +#define NORTHEAST_JUNCTION (1<<4) +#define SOUTHEAST_JUNCTION (1<<5) +#define SOUTHWEST_JUNCTION (1<<6) +#define NORTHWEST_JUNCTION (1<<7) + +DEFINE_BITFIELD(smoothing_junction, list( + "NORTH_JUNCTION" = NORTH_JUNCTION, + "SOUTH_JUNCTION" = SOUTH_JUNCTION, + "EAST_JUNCTION" = EAST_JUNCTION, + "WEST_JUNCTION" = WEST_JUNCTION, + "NORTHEAST_JUNCTION" = NORTHEAST_JUNCTION, + "SOUTHEAST_JUNCTION" = SOUTHEAST_JUNCTION, + "SOUTHWEST_JUNCTION" = SOUTHWEST_JUNCTION, + "NORTHWEST_JUNCTION" = NORTHWEST_JUNCTION, +)) /*smoothing macros*/ diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm index f2f511c791b79e..542a909c2e9b68 100644 --- a/code/__DEFINES/inventory.dm +++ b/code/__DEFINES/inventory.dm @@ -133,6 +133,10 @@ #define FEMALE_UNIFORM_TOP_ONLY (1<<1) /// For when you don't want the "breast" effect to be applied (the one that cuts two pixels in the middle of the front of the uniform when facing east or west). #define FEMALE_UNIFORM_NO_BREASTS (1<<2) +// SKYRAT EDIT ADDITION START +/// For when you -don't- want to apply FEMALE_UNIFORM_TOP_ONLY to the digi version (which happens by default). +#define FEMALE_UNIFORM_DIGI_FULL (1<<3) +// SKYRAT EDIT ADDITION END //flags for alternate styles: These are hard sprited so don't set this if you didn't put the effort in #define NORMAL_STYLE 0 @@ -148,7 +152,7 @@ #define CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON (1<<2) ///has a sprite for monkeys #define CLOTHING_MONKEY_VARIATION (1<<3) -// SKYRAT EDIT ADDITION +// SKYRAT EDIT ADDITION START /// The sprite works fine for snouts. #define CLOTHING_SNOUTED_VARIATION (1<<4) /// The sprite works fine for snouts as-is. diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index a52d2d809e640f..136e0b922ceaf1 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -11,6 +11,9 @@ #define isweakref(D) (istype(D, /datum/weakref)) +GLOBAL_VAR_INIT(magic_appearance_detecting_image, new /image) // appearances are awful to detect safely, but this seems to be the best way ~ninjanomnom +#define isappearance(thing) (!istype(thing, /image) && !ispath(thing) && istype(GLOB.magic_appearance_detecting_image, thing)) + #define isgenerator(A) (istype(A, /generator)) //Turfs @@ -89,6 +92,7 @@ GLOBAL_LIST_INIT(turfs_pass_meteor, typecacheof(list( #define isabductor(A) (is_species(A, /datum/species/abductor)) #define isgolem(A) (is_species(A, /datum/species/golem)) #define islizard(A) (is_species(A, /datum/species/lizard)) +#define isashwalker(A) (is_species(A, /datum/species/lizard/ashwalker)) #define isplasmaman(A) (is_species(A, /datum/species/plasmaman)) #define ispodperson(A) (is_species(A, /datum/species/pod)) #define isflyperson(A) (is_species(A, /datum/species/fly)) @@ -145,10 +149,13 @@ GLOBAL_LIST_INIT(turfs_pass_meteor, typecacheof(list( #define ismining(A) (istype(A, /mob/living/simple_animal/hostile/asteroid) || istype(A, /mob/living/basic/mining)) +/// constructs, which are both simple and basic for now +#define isconstruct(A) (istype(A, /mob/living/simple_animal/hostile/construct) || istype(A, /mob/living/basic/construct)) + //Simple animals #define isanimal(A) (istype(A, /mob/living/simple_animal)) -#define isrevenant(A) (istype(A, /mob/living/simple_animal/revenant)) +#define isrevenant(A) (istype(A, /mob/living/basic/revenant)) #define isbot(A) (istype(A, /mob/living/simple_animal/bot)) @@ -172,13 +179,11 @@ GLOBAL_LIST_INIT(turfs_pass_meteor, typecacheof(list( #define isguardian(A) (istype(A, /mob/living/simple_animal/hostile/guardian)) -#define isconstruct(A) (istype(A, /mob/living/simple_animal/hostile/construct)) - #define ismegafauna(A) (istype(A, /mob/living/simple_animal/hostile/megafauna)) #define isclown(A) (istype(A, /mob/living/basic/clown)) -#define isspider(A) (istype(A, /mob/living/basic/spider/giant)) +#define isspider(A) (istype(A, /mob/living/basic/spider)) //Misc mobs @@ -278,8 +283,6 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list( #define isholoeffect(O) (istype(O, /obj/effect/holodeck_effect)) -#define isblobmonster(O) (istype(O, /mob/living/simple_animal/hostile/blob)) - #define isshuttleturf(T) (!isnull(T.depth_to_find_baseturf(/turf/baseturf_skipover/shuttle))) #define isProbablyWallMounted(O) (O.pixel_x > 20 || O.pixel_x < -20 || O.pixel_y > 20 || O.pixel_y < -20) diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index 44e67226604f85..7feca0782dc490 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -81,6 +81,7 @@ #define JOB_QUARTERMASTER "Quartermaster" #define JOB_CARGO_TECHNICIAN "Cargo Technician" #define JOB_SHAFT_MINER "Shaft Miner" +#define JOB_BITRUNNER "Bitrunner" #define JOB_CUSTOMS_AGENT "Customs Agent" // SKYRAT EDIT ADDITION //Service #define JOB_BARTENDER "Bartender" @@ -162,23 +163,23 @@ #define JOB_DISPLAY_ORDER_QUARTERMASTER 19 #define JOB_DISPLAY_ORDER_CARGO_TECHNICIAN 20 #define JOB_DISPLAY_ORDER_SHAFT_MINER 21 -#define JOB_DISPLAY_ORDER_CHIEF_MEDICAL_OFFICER 22 -#define JOB_DISPLAY_ORDER_MEDICAL_DOCTOR 23 -#define JOB_DISPLAY_ORDER_PARAMEDIC 24 -#define JOB_DISPLAY_ORDER_CHEMIST 25 -#define JOB_DISPLAY_ORDER_VIROLOGIST 26 -#define JOB_DISPLAY_ORDER_CORONER 27 -#define JOB_DISPLAY_ORDER_RESEARCH_DIRECTOR 28 -#define JOB_DISPLAY_ORDER_SCIENTIST 29 -#define JOB_DISPLAY_ORDER_ROBOTICIST 30 -#define JOB_DISPLAY_ORDER_GENETICIST 31 -#define JOB_DISPLAY_ORDER_EXP_CORPS 32 //SKYRAT EDIT ADDITON +#define JOB_DISPLAY_ORDER_BITRUNNER 22 +#define JOB_DISPLAY_ORDER_CHIEF_MEDICAL_OFFICER 23 +#define JOB_DISPLAY_ORDER_MEDICAL_DOCTOR 24 +#define JOB_DISPLAY_ORDER_PARAMEDIC 25 +#define JOB_DISPLAY_ORDER_CHEMIST 26 +#define JOB_DISPLAY_ORDER_VIROLOGIST 27 +#define JOB_DISPLAY_ORDER_CORONER 28 +#define JOB_DISPLAY_ORDER_RESEARCH_DIRECTOR 29 +#define JOB_DISPLAY_ORDER_SCIENTIST 30 +#define JOB_DISPLAY_ORDER_ROBOTICIST 31 +#define JOB_DISPLAY_ORDER_GENETICIST 32 #define JOB_DISPLAY_ORDER_HEAD_OF_SECURITY 33 #define JOB_DISPLAY_ORDER_WARDEN 34 #define JOB_DISPLAY_ORDER_DETECTIVE 35 #define JOB_DISPLAY_ORDER_SECURITY_OFFICER 36 -#define JOB_DISPLAY_ORDER_SECURITY_MEDIC 37 //SKYRAT EDIT ADDITON -#define JOB_DISPLAY_ORDER_PRISONER 38 +#define JOB_DISPLAY_ORDER_PRISONER 37 +#define JOB_DISPLAY_ORDER_SECURITY_MEDIC 38 //SKYRAT EDIT ADDITON #define JOB_DISPLAY_ORDER_CORRECTIONS_OFFICER 39 //SKYRAT EDIT ADDITON #define JOB_DISPLAY_ORDER_NANOTRASEN_CONSULTANT 40 //SKYRAT EDIT ADDITON #define JOB_DISPLAY_ORDER_BLUESHIELD 41 //SKYRAT EDIT ADDITON @@ -187,6 +188,7 @@ #define JOB_DISPLAY_ORDER_BOUNCER 44 //SKYRAT EDIT ADDITION #define JOB_DISPLAY_ORDER_ENGINEER_GUARD 45 //SKYRAT EDIT ADDITION #define JOB_DISPLAY_ORDER_CUSTOMS_AGENT 46 //SKYRAT EDIT ADDITION +#define JOB_DISPLAY_ORDER_EXP_CORPS 47 //SKYRAT EDIT ADDITON #define DEPARTMENT_UNASSIGNED "No Department" diff --git a/code/__DEFINES/magic.dm b/code/__DEFINES/magic.dm index 34ec4b6659b69b..ecc470c04e90c2 100644 --- a/code/__DEFINES/magic.dm +++ b/code/__DEFINES/magic.dm @@ -50,8 +50,7 @@ /// Whether the spell can be cast by mobs who are brains / mmis. /// When applying, bear in mind most spells will not function for brains out of the box. #define SPELL_CASTABLE_AS_BRAIN (1 << 2) -/// Whether the spell can be cast while phased, such as blood crawling, ethereal jaunting or using rod form. -#define SPELL_CASTABLE_WHILE_PHASED (1 << 3) + /// Whether the spell can be cast while the user has antimagic on them that corresponds to the spell's own antimagic flags. #define SPELL_REQUIRES_NO_ANTIMAGIC (1 << 4) /// Whether the spell requires being on the station z-level to be cast. @@ -66,7 +65,6 @@ DEFINE_BITFIELD(spell_requirements, list( "SPELL_CASTABLE_AS_BRAIN" = SPELL_CASTABLE_AS_BRAIN, - "SPELL_CASTABLE_WHILE_PHASED" = SPELL_CASTABLE_WHILE_PHASED, "SPELL_CASTABLE_WITHOUT_INVOCATION" = SPELL_CASTABLE_WITHOUT_INVOCATION, "SPELL_REQUIRES_HUMAN" = SPELL_REQUIRES_HUMAN, "SPELL_REQUIRES_MIME_VOW" = SPELL_REQUIRES_MIME_VOW, diff --git a/code/__DEFINES/materials.dm b/code/__DEFINES/materials.dm index 08b883248265b1..5fc5cc08ea2053 100644 --- a/code/__DEFINES/materials.dm +++ b/code/__DEFINES/materials.dm @@ -75,3 +75,13 @@ #define MATERIAL_SLOWDOWN_PLASTEEL (0.05) /// The slowdown value of one [SHEET_MATERIAL_AMOUNT] of alien alloy. #define MATERIAL_SLOWDOWN_ALIEN_ALLOY (0.1) + +//Stock market stock values. +/// How much quantity of a material stock exists for common materials like iron & glass. +#define MATERIAL_QUANTITY_COMMON 25000 +/// How much quantity of a material stock exists for uncommon materials like silver & titanium. +#define MATERIAL_QUANTITY_UNCOMMON 10000 +/// How much quantity of a material stock exists for rare materials like gold, uranium, & diamond. +#define MATERIAL_QUANTITY_RARE 2500 +/// How much quantity of a material stock exists for exotic materials like diamond & bluespace crystals. +#define MATERIAL_QUANTITY_EXOTIC 500 diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index f3ae254e6b8828..34c301a2171f9c 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -493,9 +493,6 @@ #define AI_CAMERA_LUMINOSITY 5 #define AI_VOX // Comment out if you don't want VOX to be enabled and have players download the voice sounds. -// /obj/item/bodypart on_mob_life() retval flag -#define BODYPART_LIFE_UPDATE_HEALTH (1<<0) - #define MAX_REVIVE_FIRE_DAMAGE 180 #define MAX_REVIVE_BRUTE_DAMAGE 180 diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm index c4300d966068c9..23c600aae70703 100644 --- a/code/__DEFINES/movespeed_modification.dm +++ b/code/__DEFINES/movespeed_modification.dm @@ -11,3 +11,5 @@ #define MOVESPEED_ID_MOB_GRAB_STATE "mob_grab_state" #define MOVESPEED_ID_MOB_WALK_RUN "mob_walk_run" + +#define MOVESPEED_ID_MIDAS_BLIGHT "midas_blight_debuff" diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index a6ba5c0ed38ae0..3fb32011a1db3b 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -34,6 +34,9 @@ /// Used for direct injection of reagents. #define INJECT (1<<4) +/// When returned by on_mob_life(), on_mob_dead(), overdose_start() or overdose_processed(), will cause the mob to updatehealth() afterwards +#define UPDATE_MOB_HEALTH 1 + // How long do mime drinks silence the drinker (if they are a mime)? #define MIMEDRINK_SILENCE_DURATION (1 MINUTES) ///Health threshold for synthflesh and rezadone to unhusk someone @@ -82,12 +85,8 @@ #define DEFAULT_REAGENT_TEMPERATURE 300 //Used in holder.dm/equlibrium.dm to set values and volume limits -///stops floating point errors causing issues with checking reagent amounts +///the minimum volume of reagents than can be operated on. #define CHEMICAL_QUANTISATION_LEVEL 0.0001 -///The smallest amount of volume allowed - prevents tiny numbers -#define CHEMICAL_VOLUME_MINIMUM 0.001 -///Round to this, to prevent extreme decimal magic and to keep reagent volumes in line with perceived values. -#define CHEMICAL_VOLUME_ROUNDING 0.01 ///Default pH for reagents datum #define CHEMICAL_NORMAL_PH 7.000 ///The maximum temperature a reagent holder can attain diff --git a/code/__DEFINES/research/anomalies.dm b/code/__DEFINES/research/anomalies.dm index 911a2958d89e3d..12a114439c7d90 100644 --- a/code/__DEFINES/research/anomalies.dm +++ b/code/__DEFINES/research/anomalies.dm @@ -32,6 +32,7 @@ GLOBAL_LIST_INIT(bioscrambler_parts_blacklist, typecacheof(list( GLOBAL_LIST_INIT(bioscrambler_organs_blacklist, typecacheof(list ( /obj/item/organ/external/pod_hair, /obj/item/organ/external/spines, + /obj/item/organ/external/wings, /obj/item/organ/external/wings/functional, /obj/item/organ/internal/alien, /obj/item/organ/internal/brain, diff --git a/code/__DEFINES/role_preferences.dm b/code/__DEFINES/role_preferences.dm index 32a5e3b8fda9eb..cd76af78f6cadd 100644 --- a/code/__DEFINES/role_preferences.dm +++ b/code/__DEFINES/role_preferences.dm @@ -27,6 +27,7 @@ #define ROLE_BLOB "Blob" #define ROLE_BLOB_INFECTION "Blob Infection" #define ROLE_CHANGELING_MIDROUND "Changeling (Midround)" +#define ROLE_CYBER_POLICE "Cyber Police" #define ROLE_FUGITIVE "Fugitive" #define ROLE_LONE_OPERATIVE "Lone Operative" #define ROLE_MALF_MIDROUND "Malf AI (Midround)" @@ -52,69 +53,69 @@ // Latejoin roles #define ROLE_HERETIC_SMUGGLER "Heretic Smuggler" #define ROLE_PROVOCATEUR "Provocateur" -#define ROLE_SYNDICATE_INFILTRATOR "Syndicate Infiltrator" #define ROLE_STOWAWAY_CHANGELING "Stowaway Changeling" +#define ROLE_SYNDICATE_INFILTRATOR "Syndicate Infiltrator" // Other roles -#define ROLE_SYNDICATE "Syndicate" -#define ROLE_REV "Revolutionary" -#define ROLE_PAI "pAI" -#define ROLE_MONKEY_HELMET "Monkey Mind Magnification Helmet" -#define ROLE_REVENANT "Revenant" -#define ROLE_BRAINWASHED "Brainwashed Victim" -#define ROLE_HYPNOTIZED "Hypnotized Victim" -#define ROLE_OVERTHROW "Syndicate Mutineer" //Role removed, left here for safety. -#define ROLE_HIVE "Hivemind Host" //Role removed, left here for safety. -#define ROLE_SENTIENCE "Sentience Potion Spawn" -#define ROLE_PYROCLASTIC_SLIME "Pyroclastic Anomaly Slime" #define ROLE_ANOMALY_GHOST "Ectoplasmic Anomaly Ghost" -#define ROLE_MIND_TRANSFER "Mind Transfer Potion" -#define ROLE_LAZARUS_GOOD "Friendly Revived Mob" -#define ROLE_LAZARUS_BAD "Slaved Revived Mob" -#define ROLE_POSIBRAIN "Posibrain" +#define ROLE_BRAINWASHED "Brainwashed Victim" +#define ROLE_DEATHSQUAD "Deathsquad" #define ROLE_DRONE "Drone" #define ROLE_EMAGGED_BOT "Malfunctioning Bot" -#define ROLE_DEATHSQUAD "Deathsquad" +#define ROLE_HIVE "Hivemind Host" //Role removed, left here for safety. +#define ROLE_HYPNOTIZED "Hypnotized Victim" #define ROLE_LAVALAND "Lavaland" +#define ROLE_LAZARUS_BAD "Slaved Revived Mob" +#define ROLE_LAZARUS_GOOD "Friendly Revived Mob" +#define ROLE_MIND_TRANSFER "Mind Transfer Potion" +#define ROLE_MONKEY_HELMET "Monkey Mind Magnification Helmet" +#define ROLE_OVERTHROW "Syndicate Mutineer" //Role removed, left here for safety. +#define ROLE_PAI "pAI" +#define ROLE_POSIBRAIN "Posibrain" +#define ROLE_PYROCLASTIC_SLIME "Pyroclastic Anomaly Slime" +#define ROLE_REV "Revolutionary" +#define ROLE_REVENANT "Revenant" +#define ROLE_SENTIENCE "Sentience Potion Spawn" +#define ROLE_SYNDICATE "Syndicate" -#define ROLE_POSITRONIC_BRAIN "Positronic Brain" -#define ROLE_FREE_GOLEM "Free Golem" -#define ROLE_SERVANT_GOLEM "Servant Golem" -#define ROLE_NUCLEAR_OPERATIVE "Nuclear Operative" #define ROLE_CLOWN_OPERATIVE "Clown Operative" -#define ROLE_WIZARD_APPRENTICE "apprentice" -#define ROLE_SLAUGHTER_DEMON "Slaughter Demon" +#define ROLE_FREE_GOLEM "Free Golem" #define ROLE_MORPH "Morph" +#define ROLE_NUCLEAR_OPERATIVE "Nuclear Operative" +#define ROLE_POSITRONIC_BRAIN "Positronic Brain" #define ROLE_SANTA "Santa" +#define ROLE_SERVANT_GOLEM "Servant Golem" +#define ROLE_SLAUGHTER_DEMON "Slaughter Demon" +#define ROLE_WIZARD_APPRENTICE "apprentice" //Spawner roles -#define ROLE_GHOST_ROLE "Ghost Role" +#define ROLE_ANCIENT_CREW "Ancient Crew" +#define ROLE_ASHWALKER "Ash Walker" +#define ROLE_BATTLECRUISER_CAPTAIN "Battlecruiser Captain" +#define ROLE_BATTLECRUISER_CREW "Battlecruiser Crew" +#define ROLE_BEACH_BUM "Beach Bum" +#define ROLE_BOT "Bot" +#define ROLE_DERELICT_DRONE "Derelict Drone" +#define ROLE_ESCAPED_PRISONER "Escaped Prisoner" #define ROLE_EXILE "Exile" #define ROLE_FUGITIVE_HUNTER "Fugitive Hunter" -#define ROLE_ESCAPED_PRISONER "Escaped Prisoner" -#define ROLE_LIFEBRINGER "Lifebringer" -#define ROLE_ASHWALKER "Ash Walker" -#define ROLE_LAVALAND_SYNDICATE "Lavaland Syndicate" +#define ROLE_GHOST_ROLE "Ghost Role" #define ROLE_HERMIT "Hermit" -#define ROLE_BEACH_BUM "Beach Bum" #define ROLE_HOTEL_STAFF "Hotel Staff" +#define ROLE_LAVALAND_SYNDICATE "Lavaland Syndicate" +#define ROLE_LIFEBRINGER "Lifebringer" +#define ROLE_MAINTENANCE_DRONE "Maintenance Drone" +#define ROLE_SKELETON "Skeleton" +#define ROLE_SPACE_BAR_PATRON "Space Bar Patron" +#define ROLE_SPACE_BARTENDER "Space Bartender" +#define ROLE_SPACE_DOCTOR "Space Doctor" +#define ROLE_SPACE_PIRATE "Space Pirate" #define ROLE_SPACE_SYNDICATE "Space Syndicate" #define ROLE_SYNDICATE_CYBERSUN "Cybersun Space Syndicate" //Ghost role syndi from Forgottenship ruin #define ROLE_SYNDICATE_CYBERSUN_CAPTAIN "Cybersun Space Syndicate Captain" //Forgottenship captain syndie -#define ROLE_SPACE_PIRATE "Space Pirate" -#define ROLE_ANCIENT_CREW "Ancient Crew" -#define ROLE_SPACE_DOCTOR "Space Doctor" -#define ROLE_SPACE_BARTENDER "Space Bartender" -#define ROLE_SPACE_BAR_PATRON "Space Bar Patron" -#define ROLE_SKELETON "Skeleton" -#define ROLE_ZOMBIE "Zombie" -#define ROLE_MAINTENANCE_DRONE "Maintenance Drone" -#define ROLE_DERELICT_DRONE "Derelict Drone" #define ROLE_SYNDICATE_DRONE "Syndicate Drone" -#define ROLE_BATTLECRUISER_CREW "Battlecruiser Crew" -#define ROLE_BATTLECRUISER_CAPTAIN "Battlecruiser Captain" #define ROLE_VENUSHUMANTRAP "Venus Human Trap" -#define ROLE_BOT "Bot" +#define ROLE_ZOMBIE "Zombie" //SKYRAT EDIT START #define ROLE_BLACK_MARKET_DEALER "Black Market Dealer" #define ROLE_DS2 "DS2 Syndicate" @@ -123,7 +124,6 @@ #define ROLE_PORT_TARKON "Port Tarkon Survivor" //SKYRAT EDIT END - /// This defines the antagonists you can operate with in the settings. /// Keys are the antagonist, values are the number of days since the player's /// first connection in order to play. @@ -149,6 +149,7 @@ GLOBAL_LIST_INIT(special_roles, list( ROLE_BLOB = 0, ROLE_BLOB_INFECTION = 0, ROLE_CHANGELING_MIDROUND = 0, + ROLE_CYBER_POLICE = 0, ROLE_FUGITIVE = 0, ROLE_LONE_OPERATIVE = 14, ROLE_MALF_MIDROUND = 0, diff --git a/code/__DEFINES/song.dm b/code/__DEFINES/song.dm index 7af269fbe219bd..782a7923ea14f9 100644 --- a/code/__DEFINES/song.dm +++ b/code/__DEFINES/song.dm @@ -13,3 +13,5 @@ ///it's what monkeys play! #define MONKEY_SONG "BPM: 200\nC4/0,14,C,A4-F2,F3,A3,F-F2,A-F,F4,G4,F,D4-Bb2-G2\nD3,G3,D-G2,G3-G2,D,D4-G3,D,B4-B2,G,B3,G-B2,B3-B2\nG4,A4,G,E4-C3,E3,G3,E-C,G-C,E,E4-G,E,C5-E-A3,C4\nA-E3,C,E4-C3,A4-C4,B4-A3-A2,C5-C4,D5-F-B3,D4,B-F3\nD,F4-D3,D4,F-B-B2,G4-D,A4-C-F3,F,C/2,B3/2,A3-C3/2\nB/2,C4,E-C3,F4,G-C,F-F3,F-C,C4/2,B/2,A-A2/2,G3/2\nF/I" +///song played by the mook bard +#define MOOK_SONG "BPM: 240\nA5,B5,C#6,D6,E6/0.17,A/0.5,A/0.25,A3/0.25\nA4/0.25,C#5/0.25,E5/0.25,A/0.25,C#/0.25,E/0.12\nC#6/0.25,C#/0.25,E6/0.25,A3/0.25,A4/0.25\nC#5/0.25,E5/0.25,A/0.25,C#/0.25,E/0.25,D/0.25\nG6/0.25,D/0.17,F6/0.17,C#6/0.5,E6/0.5,D4/0.25\nA/0.25,D5/0.25,F5/0.25,A/0.25,D/0.25,F/0.25\nD6/0.08,F6/0.08,D4/0.25,A/0.25,D5/0.25,F5/0.25\nCn4/0.2,B/0.17,D6/0.17,G5/0.5,G/0.25,B3/0.25\nD4/0.25,G4/0.25,B4/0.25,D/0.25,G/0.25,B/0.12\nB5/0.25,B/0.25,D6/0.25,G3/0.25,G4/0.25,B4/0.25\nF/0.25,G/0.25,B/0.25,F/0.25,D/0.25,F6/0.25\nC6/0.17,E/0.17,B5/0.5,D#/0.5,C4/0.25,G/0.25\nC5/0.25,E5/0.25,G/0.25,C/0.25,E/0.25,C6/0.08\nE6/0.08,C4/0.25,Dn4/0.25,E4/0.25,A5/0.17,B/0.5\nC6/0.25,F5/0.08,F4/0.08,C5/0.08,E5/0.12,G5/0.12\nC6/0.25,E6/0.25,E4/0.08,C5/0.08,B/0.17,F6/0.17\nE6/0.5,B/0.25,E4/0.08,G#4/0.08,C6/0.17,D6/0.5\nE6/0.25,A3/0.25,E4/0.25,C5/0.25,Gn3/0.25\nF5/0.12,A5/0.12,A6/0.25,F3/0.25,F4/0.12,A4/0.12\nC/0.12,F6/0.17,A6/0.17,G#6/0.5,A/0.25,F3/0.25\nF4/0.12,A4/0.12,D#5/0.12,B/0.17,G#/0.17,B6/0.5\nB5/0.25,G#/0.25,E3/0.25,E4/0.12,G#4/0.12\nDn/0.12,E6/0.08,E3/0.25,F#3/0.25,G#3/0.25\nE5/0.17,A5/0.17,E/0.5,E/0.25,A3/0.25,C#4/0.25\nE4/0.25,C#/0.25,E/0.12,A5/0.5,B/0.5,C#6/0.5\nD6/0.5,A3/0.25,C#4/0.25,E/0.25,C#/0.25,E/0.25\nE6/0.08,Gn/0.25,E4/0.25,A4/0.25,C#5/0.25,E/0.25\nA/0.25,C#/0.25,E6/0.17,E/0.5,Fn6/0.5,G6/0.5\nG3/0.25,E4/0.25,A/0.25,C#/0.25,E/0.25,A/0.25\nC#/0.25,F/0.08,A6/0.08,F3/0.25,F4/0.25,A4/0.25\nCn/0.25,F/0.25,A/0.25,C/0.25,G6/0.12,A6/0.12\nG A G F6 G3/0.25 D4/0.25 G4/0.25 B4/0.25 D/0.25\nG/0.25 B/0.25 E6/0.12 G6/0.12 F/0.71 G/0.71 F/0.71\nE3/0.25 E4/0.25 G4/0.25 B/0.25 E/0.25 G/0.25 B/0.25\nA5/0.08 E6/0.08 A3/0.25 E4/0.25 A4/0.25 C#/0.25 E/0.25 A/0.25 C#/0.25 D6/0.17 E6/0.5 F/0.25 B3/0.25 D4/0.12 F4/0.12 B4/0.12 F6/0.25 E/0.25 D6/0.25 G#3/0.25 E4/0.12 G#4/0.12 B/0.12 Cn6/0.12 D/0.25 A3/0.25 A4/0.25 C5/0.25 E5/0.25 G#3/0.25 Gn/0.25 C4/0.25 E4/0.25 A/" diff --git a/code/__DEFINES/span.dm b/code/__DEFINES/span.dm index 22cf26e19a53c8..7b23869988bd59 100644 --- a/code/__DEFINES/span.dm +++ b/code/__DEFINES/span.dm @@ -17,6 +17,7 @@ #define span_bigicon(str) ("" + str + "") #define span_binarysay(str) ("" + str + "") #define span_blob(str) ("" + str + "") +#define span_blobannounce(str) ("" + str + "") #define span_blue(str) ("" + str + "") #define span_blueteamradio(str) ("" + str + "") #define span_bold(str) ("" + str + "") diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index ea182b4088fe10..03a3bf49ebbe82 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -39,6 +39,8 @@ #define STASIS_ADMIN "stasis_admin" #define STASIS_LEGION_EATEN "stasis_eaten" +#define STASIS_NETPOD_EFFECT "stasis_netpod" + /// Causes the mob to become blind via the passed source #define become_blind(source) apply_status_effect(/datum/status_effect/grouped/blindness, source) /// Cures the mob's blindness from the passed source, removing blindness wholesale if no sources are left @@ -154,3 +156,8 @@ #define adjust_temp_blindness_up_to(duration, up_to) adjust_timed_status_effect(duration, /datum/status_effect/temporary_blindness, up_to) #define set_temp_blindness(duration) set_timed_status_effect(duration, /datum/status_effect/temporary_blindness) #define set_temp_blindness_if_lower(duration) set_timed_status_effect(duration, /datum/status_effect/temporary_blindness, TRUE) + +#define adjust_static_vision(duration) adjust_timed_status_effect(duration, /datum/status_effect/static_vision) +#define adjust_static_vision_up_to(duration, up_to) adjust_timed_status_effect(duration, /datum/status_effect/static_vision, up_to) +#define set_static_vision(duration) set_timed_status_effect(duration, /datum/status_effect/static_vision) +#define set_static_vision_if_lower(duration) set_timed_status_effect(duration, /datum/status_effect/static_vision, TRUE) diff --git a/code/__DEFINES/surgery.dm b/code/__DEFINES/surgery.dm index 61aa305c27a394..dcdd1394253026 100644 --- a/code/__DEFINES/surgery.dm +++ b/code/__DEFINES/surgery.dm @@ -24,9 +24,11 @@ #define ORGAN_UNREMOVABLE (1<<8) /// Can't be seen by scanners, doesn't anger body purists #define ORGAN_HIDDEN (1<<9) +/// Has the organ already been inserted inside someone +#define ORGAN_VIRGIN (1<<10) // SKYRAT EDIT START - Customization /// Synthetic organ granted by a species (for use for organ replacements between species) -#define ORGAN_SYNTHETIC_FROM_SPECIES (1<<10) +#define ORGAN_SYNTHETIC_FROM_SPECIES (1<<11) // SKYRAT EDIT END /// Helper to figure out if a limb is organic diff --git a/code/__DEFINES/text.dm b/code/__DEFINES/text.dm index 751fe7c2b58e4a..a0df5e24eb7e50 100644 --- a/code/__DEFINES/text.dm +++ b/code/__DEFINES/text.dm @@ -84,6 +84,10 @@ #define FLESH_SCAR_FILE "wounds/flesh_scar_desc.json" /// File location for bone wound descriptions #define BONE_SCAR_FILE "wounds/bone_scar_desc.json" +// SKYRAT EDIT ADDITION BEGIN - SYNTH WOUNDS +/// File location for metalic wound descriptions +#define METAL_SCAR_FILE "wounds/metal_scar_desc.json" +// SKYRAT EDIT ADDITION END /// File location for scar wound descriptions #define SCAR_LOC_FILE "wounds/scar_loc.json" /// File location for exodrone descriptions diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 571f67f5b7d33c..a2861434c61f60 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -172,6 +172,10 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_DEFIB_BLACKLISTED "defib_blacklisted" #define TRAIT_BADDNA "baddna" #define TRAIT_CLUMSY "clumsy" +/// Trait that means you are capable of holding items in some form +#define TRAIT_CAN_HOLD_ITEMS "can_hold_items" +/// Trait which lets you clamber over a barrier +#define TRAIT_FENCE_CLIMBER "can_climb_fences" /// means that you can't use weapons with normal trigger guards. #define TRAIT_CHUNKYFINGERS "chunkyfingers" #define TRAIT_CHUNKYFINGERS_IGNORE_BATON "chunkyfingers_ignore_baton" @@ -318,6 +322,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_BLOOD_DEFICIENCY "blood_deficiency" #define TRAIT_JOLLY "jolly" #define TRAIT_NOCRITDAMAGE "no_crit" +///Added to mob or mind, changes the icons of the fish shown in the minigame UI depending on the possible reward. +#define TRAIT_REVEAL_FISH "reveal_fish" /// Stops the mob from slipping on water, or banana peels, or pretty much anything that doesn't have [GALOSHES_DONT_HELP] set #define TRAIT_NO_SLIP_WATER "noslip_water" @@ -519,6 +525,11 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai // and emit less heat. Present on /mob or /datum/mind #define TRAIT_SUPERMATTER_SOOTHER "supermatter_soother" +/// Trait added when a revenant is visible. +#define TRAIT_REVENANT_REVEALED "revenant_revealed" +/// Trait added when a revenant has been inhibited (typically by the bane of a holy weapon) +#define TRAIT_REVENANT_INHIBITED "revenant_inhibited" + /// Trait which prevents you from becoming overweight #define TRAIT_NOFAT "cant_get_fat" @@ -889,9 +900,15 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// For clarity, this trait should always be associated/tied to a reference to the mob that suicided- not anything else. #define TRAIT_SUICIDED "committed_suicide" +/// Trait given to a living mob to prevent wizards from making it immortal +#define TRAIT_PERMANENTLY_MORTAL "permanently_mortal" + ///Trait given to a mob with a ckey currently in a temporary body, allowing people to know someone will re-enter the round later. #define TRAIT_MIND_TEMPORARILY_GONE "temporarily_gone" +/// Similar trait given to temporary bodies inhabited by players +#define TRAIT_TEMPORARY_BODY "temporary_body" + /// Trait given to mechs that can have orebox functionality on movement #define TRAIT_OREBOX_FUNCTIONAL "orebox_functional" @@ -905,6 +922,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define TRAIT_FISH_AMPHIBIOUS "fish_amphibious" ///Trait needed for the lubefish evolution #define TRAIT_FISH_FED_LUBE "fish_fed_lube" +#define TRAIT_FISH_NO_HUNGER "fish_no_hunger" // common trait sources #define TRAIT_GENERIC "generic" @@ -986,6 +1004,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define MOTOR_LACK_TRAIT "motor-lack" /// Trait associated with mafia #define MAFIA_TRAIT "mafia" +/// Trait associated with ctf +#define CTF_TRAIT "ctf" /// Trait associated with highlander #define HIGHLANDER_TRAIT "highlander" /// Trait given from playing pretend with baguettes @@ -1078,6 +1098,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// sticky nodrop sounds like a bad soundcloud rapper's name #define STICKY_NODROP "sticky-nodrop" #define SKILLCHIP_TRAIT "skillchip" +#define SKILL_TRAIT "skill" #define BUSY_FLOORBOT_TRAIT "busy-floorbot" #define PULLED_WHILE_SOFTCRIT_TRAIT "pulled-while-softcrit" #define LOCKED_BORG_TRAIT "locked-borg" @@ -1141,6 +1162,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai #define AUTOPSY_TRAIT "autopsy_trait" /// Trait given by [/datum/status_effect/blessing_of_insanity] #define MAD_WIZARD_TRAIT "mad_wizard_trait" +/// Isn't attacked harmfully by blob structures +#define TRAIT_BLOB_ALLY "blob_ally" /** * Trait granted by [/mob/living/carbon/Initialize] and diff --git a/code/__DEFINES/visual_helpers.dm b/code/__DEFINES/visual_helpers.dm index 204cc8ba03afbf..bb54c5d6b0b7a5 100644 --- a/code/__DEFINES/visual_helpers.dm +++ b/code/__DEFINES/visual_helpers.dm @@ -11,5 +11,15 @@ base_pixel_x = x; \ base_pixel_y = y; +#define SET_BASE_VISUAL_PIXEL(w, z) \ + pixel_w = w; \ + base_pixel_w = w; \ + pixel_z = z; \ + base_pixel_z = z; + +#define _SET_BASE_PIXEL_VISUAL_NO_OFFSET(w, z) \ + base_pixel_z = w; \ + base_pixel_z = z; + /// Much like [SET_BASE_PIXEL], except it will not effect pixel offsets in mapping programs #define SET_BASE_PIXEL_NOMAP(x, y) MAP_SWITCH(SET_BASE_PIXEL(x, y), _SET_BASE_PIXEL_NO_OFFSET(x, y)) diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index 40f5f84c2d186f..1cc9025b821646 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -114,6 +114,8 @@ // /mob #define VV_HK_GIB "gib" +#define VV_HK_GIVE_MOB_ACTION "give_mob_action" +#define VV_HK_REMOVE_MOB_ACTION "remove_mob_action" #define VV_HK_GIVE_SPELL "give_spell" #define VV_HK_REMOVE_SPELL "remove_spell" #define VV_HK_GIVE_DISEASE "give_disease" diff --git a/code/__DEFINES/wires.dm b/code/__DEFINES/wires.dm index 6f618ac8240326..2b4c528abc212f 100644 --- a/code/__DEFINES/wires.dm +++ b/code/__DEFINES/wires.dm @@ -37,6 +37,7 @@ #define WIRE_LIMIT "Limiter" #define WIRE_LOADCHECK "Load Check" #define WIRE_LOCKDOWN "Lockdown" +#define WIRE_MODE_SELECT "Mode Select" #define WIRE_MOTOR1 "Motor 1" #define WIRE_MOTOR2 "Motor 2" #define WIRE_OPEN "Open" diff --git a/code/__DEFINES/wounds.dm b/code/__DEFINES/wounds.dm index 19ccd843dd43ad..14067fbcd6a247 100644 --- a/code/__DEFINES/wounds.dm +++ b/code/__DEFINES/wounds.dm @@ -124,10 +124,15 @@ GLOBAL_LIST_INIT(bio_state_anatomy, list( /// Generic loss wounds. See loss.dm #define WOUND_SERIES_LOSS_BASIC "wound_series_loss_basic" -// SKYRAT EDIT ADDITION BEGIN - MUSCLE WOUNDS +// SKYRAT EDIT ADDITION BEGIN - MUSCLE AND SYNTH WOUNDS // Have to put it here so I can use it in the global list of wound series -/// See muscle.dm -#define WOUND_SERIES_MUSCLE_DAMAGE "skyrat_wound_series_muscle_damage" // We use a super high number as realistically speaking TG will never increment to this amount of wound series +/// See muscle.dm and robotic_blunt.dm +#define WOUND_SERIES_MUSCLE_DAMAGE "skyrat_wound_series_muscle_damage" + +#define WOUND_SERIES_METAL_BLUNT_BASIC "wound_series_metal_blunt_basic" +#define WOUND_SERIES_METAL_BURN_OVERHEAT "wound_series_metal_burn_basic" +#define WOUND_SERIES_WIRE_SLASH_ELECTRICAL_DAMAGE "wound_series_metal_slash_electrical_damage_basic" +#define WOUND_SERIES_WIRE_PIERCE_ELECTRICAL_DAMAGE "wound_series_metal_pierce_electrical_damage_basic" // SKYRAT EDIT ADDITION END /// A assoc list of (wound typepath -> wound_pregen_data instance). Every wound should have a pregen data. @@ -203,17 +208,23 @@ GLOBAL_LIST_INIT(wounding_types_to_series, list( WOUND_BLUNT = list( WOUND_SERIES_BONE_BLUNT_BASIC, WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT -- MUSCLE WOUNDS + WOUND_SERIES_METAL_BLUNT_BASIC, // SKYRAT EDIT ADDITION - SYNTH WOUNDS + ), WOUND_SLASH = list( WOUND_SERIES_FLESH_SLASH_BLEED, - WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT -- MUSCLE WOUNDS + WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT ADDITION - MUSCLE WOUNDS + WOUND_SERIES_WIRE_SLASH_ELECTRICAL_DAMAGE, // SKYRAT EDIT ADDITION - SYNTH WOUNDS + ), WOUND_BURN = list( WOUND_SERIES_FLESH_BURN_BASIC, + WOUND_SERIES_METAL_BURN_OVERHEAT, // SKYRAT EDIT ADDITION - SYNTH WOUNDS ), WOUND_PUNCTURE = list( WOUND_SERIES_FLESH_PUNCTURE_BLEED, - WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT -- MUSCLE WOUNDS + WOUND_SERIES_MUSCLE_DAMAGE, // SKYRAT EDIT ADDITION - MUSCLE WOUNDS + WOUND_SERIES_WIRE_PIERCE_ELECTRICAL_DAMAGE, // SKYRAT EDIT ADDITION - SYNTH WOUNDS ), )) @@ -284,7 +295,8 @@ GLOBAL_LIST_INIT(wounding_types_to_series, list( /// Assoc list of biotype -> ideal scar file to be used and grab stuff from. GLOBAL_LIST_INIT(biotypes_to_scar_file, list( "[BIO_FLESH]" = FLESH_SCAR_FILE, - "[BIO_BONE]" = BONE_SCAR_FILE + "[BIO_BONE]" = BONE_SCAR_FILE, + "[BIO_METAL]" = METAL_SCAR_FILE // SKYRAT EDIT ADDITION - METAL SCARS (see robotic_blunt.dm) )) // ~burn wound infection defines diff --git a/code/__DEFINES/~skyrat_defines/cargo_import_companies.dm b/code/__DEFINES/~skyrat_defines/cargo_import_companies.dm index efb250aa231704..d0e82f110b572e 100644 --- a/code/__DEFINES/~skyrat_defines/cargo_import_companies.dm +++ b/code/__DEFINES/~skyrat_defines/cargo_import_companies.dm @@ -6,7 +6,7 @@ #define CARGO_COMPANY_DONK (1<<4) #define CARGO_COMPANY_KAHRAMAN (1<<5) #define CARGO_COMPANY_NAKAMURA_TOOLING (1<<6) -#define CARGO_COMPANY_BOLT_NANOTRASEN (1<<7) +#define CARGO_COMPANY_SOL_DEFENSE (1<<7) #define CARGO_COMPANY_MICROSTAR (1<<8) #define CARGO_COMPANY_VITEZSTVI_AMMO (1<<9) @@ -18,7 +18,7 @@ #define DONK_CO_NAME "Donk Corporation" #define KAHRAMAN_INDUSTRIES_NAME "Kahraman Heavy Industries" #define NAKAMURA_ENGINEERING_TOOLING_NAME "Nakamura Engineering Tooling Divison" -#define BOLT_NANOTRASEN_DEFENSE_NAME "Nanotrasen-Bolt Personal Defense Coalition" +#define SOL_DEFENSE_DEFENSE_NAME "Sol Defense Imports" #define MICROSTAR_ENERGY_NAME "MicroStar Energy Weapon Coalition" #define VITEZSTVI_AMMO_NAME "Vitezstvi Ammo & Weapon Accessories" diff --git a/code/__DEFINES/~skyrat_defines/inventory.dm b/code/__DEFINES/~skyrat_defines/inventory.dm index fe2c1d7cee957d..6ff282affb3df4 100644 --- a/code/__DEFINES/~skyrat_defines/inventory.dm +++ b/code/__DEFINES/~skyrat_defines/inventory.dm @@ -3,6 +3,7 @@ #define STYLE_TAUR_PAW (1<<3) #define STYLE_TAUR_HOOF (1<<4) #define STYLE_TAUR_ALL (STYLE_TAUR_SNAKE|STYLE_TAUR_PAW|STYLE_TAUR_HOOF) +#define STYLE_DIGI (1<<5) // We don't use the HUD for these, they have their own menu. #define LEWD_SLOT_VAGINA (1<<0) diff --git a/code/__DEFINES/~skyrat_defines/manufacturer_strings.dm b/code/__DEFINES/~skyrat_defines/manufacturer_strings.dm index fd90be189d09a4..0f4b8de334843c 100644 --- a/code/__DEFINES/~skyrat_defines/manufacturer_strings.dm +++ b/code/__DEFINES/~skyrat_defines/manufacturer_strings.dm @@ -1,12 +1,13 @@ // Text for what examine blurb will come up when used with /datum/element/manufacturer_examine // Very loosely grouped based on what company makes what mainly for your viewing pleasure -#define COMPANY_CANTALAN "It has [span_purple("Cantalan Federal Arms")] etched into it." #define COMPANY_DONK "It has a [span_green("Donk Corporation")] label visible on it." #define COMPANY_BOLT "It has [span_yellow("Bolt Fabrications")] stamped onto it." #define COMPANY_NANOTRASEN "It has [span_blue("Nanotrasen Armories")] etched into it." -#define COMPANY_ARMADYNE "It has [span_red("Armadyne Corporation")] etched into it." +#define COMPANY_CARWO "It has a small [span_cyan("four pointed star")] alongside [span_cyan("Carwo Defense Systems")] etched into it." +#define COMPANY_TRAPPISTE "It has a small [span_red("pattern of five squares")] alongside [span_red("Trappiste Fabriek")] etched into it." + #define COMPANY_SCARBOROUGH "It has [span_orange("Scarborough Arms")] stamped onto it." #define COMPANY_INTERDYNE "It has [span_cyan("Interdyne Pharmaceuticals")] stamped onto it." diff --git a/code/__DEFINES/~skyrat_defines/medical_defines.dm b/code/__DEFINES/~skyrat_defines/medical_defines.dm index c32d18bbd4f981..198b5cf02c8e96 100644 --- a/code/__DEFINES/~skyrat_defines/medical_defines.dm +++ b/code/__DEFINES/~skyrat_defines/medical_defines.dm @@ -2,3 +2,8 @@ #define DAMAGED_BODYPART_BONUS_WOUNDING_BONUS 30 //After this threshold we dont get any wounding bonuses form damaged bodyparts #define DAMAGED_BODYPART_BONUS_WOUNDING_THRESHOLD 0.5 //How much extra % of wounding dmg we'll have if a bodypart is damaged enough #define DAMAGED_BODYPART_BONUS_WOUNDING_COEFF 15 //This is multiplied by the sustained damage %. Keep in mind the % limit //Currently: 15/0.5=7.5 + +/// If a synth is revived via defib, they will have a brain trauma for this amount of time. +#define SYNTH_DEFIBBED_TRAUMA_DURATION 90 SECONDS +/// If a synth is revived via defib, they will get a brain trauma of this severity. +#define SYNTH_DEFIBBED_TRAUMA_SEVERITY BRAIN_TRAUMA_SEVERE diff --git a/code/__DEFINES/~skyrat_defines/projectiles.dm b/code/__DEFINES/~skyrat_defines/projectiles.dm index dd08d26514ea03..158f3e12d1e348 100644 --- a/code/__DEFINES/~skyrat_defines/projectiles.dm +++ b/code/__DEFINES/~skyrat_defines/projectiles.dm @@ -1,29 +1,22 @@ -#define CALIBER_PEPPERBALL "pepperball" - -#define CALIBER_12MM "12mm" -#define CALIBER_473MM "473mm" -#define CALIBER_6MM "6mm" - -/// The caliber used by the Automag. -#define CALIBER_44 ".44 AMP" - -/// The caliber used by the M45A5 -#define CALIBER_460 ".460 RM JHP" - -/// The caliber used by the CFA Lynx. -#define CALIBER_42X30MM "4.2x30mm" - -/// The caliber used by the Catanheim. -#define CALIBER_A68 "a68" - /// The caliber used by the AK-25 #define CALIBER_732x29 "a732x29" -/// The caliber used by the Ripper gen2 -#define CALIBER_B577 ".577 Snider" - /// The caliber used by the Oldarms 'Mk.11.4 rifle', designed to be worse .223. #define CALIBER_223S ".223 Stinger" /// Caliber used by the giant anti materiel rifle in guncargo #define CALIBER_60STRELA ".60 Strela" + +/// Standard Sol rifle caliber +#define CALIBER_SOL40LONG ".40 Sol Long" +/// Standard Sol pistol caliber +#define CALIBER_SOL35SHORT ".35 Sol Short" + +/// Basically 20mm grenades, I'd be concerned if a grenade launcher didn't use this +#define CALIBER_980TYDHOUER ".980 Tydhouer" + +/// Large caliber pistol round for Sol hand cannons +#define CALIBER_585TRAPPISTE ".585 Trappiste" + +/// Caliber used by the pepperball gun +#define CALIBER_PEPPERBALL "pepperball" diff --git a/code/__DEFINES/~skyrat_defines/research.dm b/code/__DEFINES/~skyrat_defines/research.dm new file mode 100644 index 00000000000000..492f3ac98be705 --- /dev/null +++ b/code/__DEFINES/~skyrat_defines/research.dm @@ -0,0 +1,2 @@ +#define SCIENCE_JAWS_OF_LIFE_DESIGN_ID "jawsoflife_sci" +#define SCIENCE_DRILL_DESIGN_ID "handdrill_sci" diff --git a/code/__DEFINES/~skyrat_defines/signals.dm b/code/__DEFINES/~skyrat_defines/signals.dm index 095a5ff8b42aea..7ccaad2e592240 100644 --- a/code/__DEFINES/~skyrat_defines/signals.dm +++ b/code/__DEFINES/~skyrat_defines/signals.dm @@ -43,20 +43,6 @@ // Health signals /// /mob/living/proc/updatehealth() #define COMSIG_MOB_RUN_ARMOR "mob_run_armor" -/// /mob/living/proc/adjustBruteLoss (amount) -#define COMSIG_MOB_LOSS_BRUTE "mob_loss_brute" -/// /mob/living/proc/adjustBurnLoss (amount) -#define COMSIG_MOB_LOSS_FIRE "mob_loss_fire" -/// /mob/living/proc/adjustCloneLoss (amount) -#define COMSIG_MOB_LOSS_CLONE "mob_loss_clone" -/// /mob/living/proc/adjustToxLoss (amount) -#define COMSIG_MOB_LOSS_TOX "mob_loss_tox" -////mob/living/proc/adjustOyxLoss (amount) -#define COMSIG_MOB_LOSS_OXY "mob_loss_oxy" -////mob/living/proc/adjustStaminaLoss (amount) -#define COMSIG_MOB_LOSS_STAMINA "mob_loss_stamina" -/// /mob/living/proc/adjustOrganLoss (slot, amount) -#define COMSIG_MOB_LOSS_ORGAN "mob_loss_organ" ///from base of /turf/handle_fall(): (mob/faller) #define COMSIG_TURF_MOB_FALL "turf_mob_fall" ///from base of /obj/effect/abstract/liquid_turf/Initialize() (/obj/effect/abstract/liquid_turf/liquids) diff --git a/code/__DEFINES/~skyrat_defines/traits.dm b/code/__DEFINES/~skyrat_defines/traits.dm index 920b58a082f172..49f025e4ab0e68 100644 --- a/code/__DEFINES/~skyrat_defines/traits.dm +++ b/code/__DEFINES/~skyrat_defines/traits.dm @@ -90,3 +90,6 @@ /// Trait given to a piece of eyewear that allows the user to use NIFSoft HUDs #define TRAIT_NIFSOFT_HUD_GRANTER "nifsoft_hud_granter" + +/// Trait given to a brain that is able to accept souls from a RSD +#define TRAIT_RSD_COMPATIBLE "rsd_compatible" diff --git a/code/__HELPERS/chat.dm b/code/__HELPERS/chat.dm index e853547ec73113..fb07f2f107d010 100644 --- a/code/__HELPERS/chat.dm +++ b/code/__HELPERS/chat.dm @@ -81,3 +81,19 @@ it will be sent to all connected chats. /// Handles text formatting for item use hints in examine text #define EXAMINE_HINT(text) ("" + text + "") + +/// Sends a message to all dead and observing players, if a source is provided a follow link will be attached. +/proc/send_to_observers(message, source) + var/list/all_observers = GLOB.dead_player_list + GLOB.current_observers_list + for(var/mob/observer as anything in all_observers) + if (isnull(source)) + to_chat(observer, "[message]") + continue + var/link = FOLLOW_LINK(observer, source) + to_chat(observer, "[link] [message]") + +/// Sends a message to everyone within the list, as well as all observers. +/proc/relay_to_list_and_observers(message, list/mob_list, source) + for(var/mob/creature as anything in mob_list) + to_chat(creature, message) + send_to_observers(message, source) diff --git a/code/__HELPERS/icon_smoothing.dm b/code/__HELPERS/icon_smoothing.dm index 5f92c67a6fccaf..6a1cfd6191a3b3 100644 --- a/code/__HELPERS/icon_smoothing.dm +++ b/code/__HELPERS/icon_smoothing.dm @@ -24,27 +24,6 @@ To see an example of a diagonal wall, see '/turf/closed/wall/mineral/titanium' and its subtypes. */ -//Redefinitions of the diagonal directions so they can be stored in one var without conflicts -#define NORTH_JUNCTION NORTH //(1<<0) -#define SOUTH_JUNCTION SOUTH //(1<<1) -#define EAST_JUNCTION EAST //(1<<2) -#define WEST_JUNCTION WEST //(1<<3) -#define NORTHEAST_JUNCTION (1<<4) -#define SOUTHEAST_JUNCTION (1<<5) -#define SOUTHWEST_JUNCTION (1<<6) -#define NORTHWEST_JUNCTION (1<<7) - -DEFINE_BITFIELD(smoothing_junction, list( - "NORTH_JUNCTION" = NORTH_JUNCTION, - "SOUTH_JUNCTION" = SOUTH_JUNCTION, - "EAST_JUNCTION" = EAST_JUNCTION, - "WEST_JUNCTION" = WEST_JUNCTION, - "NORTHEAST_JUNCTION" = NORTHEAST_JUNCTION, - "SOUTHEAST_JUNCTION" = SOUTHEAST_JUNCTION, - "SOUTHWEST_JUNCTION" = SOUTHWEST_JUNCTION, - "NORTHWEST_JUNCTION" = NORTHWEST_JUNCTION, -)) - #define NO_ADJ_FOUND 0 #define ADJ_FOUND 1 #define NULLTURF_BORDER 2 @@ -55,13 +34,13 @@ GLOBAL_LIST_INIT(adjacent_direction_lookup, generate_adjacent_directions()) * Each 3x3 grid is a tile, with each X representing a direction a border object could be in IN said grid * Directions marked with A are acceptable smoothing targets, M is the example direction * The example given here is of a northfacing border object -xxx xxx xxx xxx AxA xxx -xxx xAx xxx +xxx AxA xxx +xxx AxA xxx -xAx xMx xAx +AAA MMM AAA +xxx AxA xxx xxx AxA xxx -xxx xxx xxx xxx xxx xxx xxx xxx xxx @@ -96,21 +75,20 @@ xxx xxx xxx // We'll do the two dirs to our left and right // They connect.. "below" us and on their side if(connectable_dir == NONE) - smoothable_dirs[left] = opposite | left - smoothable_dirs[right] = opposite | right + smoothable_dirs[left] = dir_to_junction(opposite | left) + smoothable_dirs[right] = dir_to_junction(opposite | right) // If it's to our right or left we'll include just the dir matching ours // Left edge touches only our left side, and so on else if (connectable_dir == left) smoothable_dirs[dir] = left else if (connectable_dir == right) smoothable_dirs[dir] = right - // If it's straight on we'll include all cardinals but us, since all 3 bits would touch us - // Turf opposite gets just our dir as the connection, the other two get our dir + theirs - // Since they touch the edges + // If it's straight on we'll include our direction as a link + // Then include the two edges on the other side as diagonals else if(connectable_dir == dir) smoothable_dirs[opposite] = dir - smoothable_dirs[left] = dir | left - smoothable_dirs[right] = dir | right + smoothable_dirs[left] = dir_to_junction(dir | left) + smoothable_dirs[right] = dir_to_junction(dir | right) // otherwise, go HOME, I don't want to encode anything for you else continue @@ -594,6 +572,39 @@ xxx xxx xxx add_overlay(new_overlays) +/// Takes a direction, turns it into all the junctions that contain it +/proc/dir_to_all_junctions(dir) + var/handback = NONE + if(dir & NORTH) + handback |= NORTH_JUNCTION | NORTHEAST_JUNCTION | NORTHWEST_JUNCTION + if(dir & SOUTH) + handback |= SOUTH_JUNCTION | SOUTHEAST_JUNCTION | SOUTHWEST_JUNCTION + if(dir & EAST) + handback |= EAST_JUNCTION | SOUTHEAST_JUNCTION | NORTHEAST_JUNCTION + if(dir & WEST) + handback |= WEST_JUNCTION | NORTHWEST_JUNCTION | SOUTHWEST_JUNCTION + return handback + +/proc/dir_to_junction(dir) + switch(dir) + if(NORTH) + return NORTH_JUNCTION + if(SOUTH) + return SOUTH_JUNCTION + if(WEST) + return WEST_JUNCTION + if(EAST) + return EAST_JUNCTION + if(NORTHWEST) + return NORTHWEST_JUNCTION + if(NORTHEAST) + return NORTHEAST_JUNCTION + if(SOUTHEAST) + return SOUTHEAST_JUNCTION + if(SOUTHWEST) + return SOUTHWEST_JUNCTION + else + return NONE /proc/reverse_ndir(ndir) switch(ndir) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index de9ed493b623e2..aa161690ceb45b 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -589,7 +589,7 @@ GLOBAL_LIST_EMPTY(species_list) #define ISADVANCEDTOOLUSER(mob) (HAS_TRAIT(mob, TRAIT_ADVANCEDTOOLUSER) && !HAS_TRAIT(mob, TRAIT_DISCOORDINATED_TOOL_USER)) -#define IS_IN_STASIS(mob) (mob.has_status_effect(/datum/status_effect/grouped/stasis)) +#define IS_IN_STASIS(mob) (mob.has_status_effect(/datum/status_effect/grouped/stasis) || mob.has_status_effect(/datum/status_effect/embryonic)) /// Gets the client of the mob, allowing for mocking of the client. /// You only need to use this if you know you're going to be mocking clients somewhere else. diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 7c8fb23f4c3718..bad17bdc28f29b 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -827,7 +827,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) parts += "Total Achievements Earned: [length(GLOB.achievements_unlocked)]!
" parts += "" return "
" diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm index aa84927af03e86..50575d24b5b205 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -216,6 +216,7 @@ GLOBAL_LIST_INIT(uncommon_loot, list(//uncommon: useful items /obj/item/stack/medical/gauze = 1, /obj/item/stack/medical/mesh = 1, /obj/item/stack/medical/suture = 1, + /obj/item/stack/medical/bandage = 1, ) = 1, list(//medical chems /obj/item/reagent_containers/cup/bottle/multiver = 1, @@ -333,6 +334,7 @@ GLOBAL_LIST_INIT(rarity_loot, list(//rare: really good items /obj/item/storage/box/hug/medical = 1, /obj/item/storage/medkit/emergency = 1, /obj/item/storage/medkit/regular = 1, + /obj/item/storage/box/bandages = 1, ) = 1, list(//medical chems /obj/item/reagent_containers/hypospray/medipen/oxandrolone = 1, diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index f87896e452123c..5ee1f4e643954d 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -52,6 +52,12 @@ GLOBAL_LIST_EMPTY(current_living_antags) /// All observers with clients that joined as observers. GLOBAL_LIST_EMPTY(current_observers_list) +/// All living mobs which can hear blob telepathy +GLOBAL_LIST_EMPTY(blob_telepathy_mobs) + +/// All "living" (because revenants are in between mortal planes or whatever) mobs that can hear revenants +GLOBAL_LIST_EMPTY(revenant_relay_mobs) + ///underages who have been reported to security for trying to buy things they shouldn't, so they can't spam GLOBAL_LIST_EMPTY(narcd_underages) diff --git a/code/_globalvars/lists/names.dm b/code/_globalvars/lists/names.dm index 018164e2c78786..01e6f3b59dc1f8 100644 --- a/code/_globalvars/lists/names.dm +++ b/code/_globalvars/lists/names.dm @@ -23,6 +23,7 @@ GLOBAL_LIST_INIT(posibrain_names, world.file2list("strings/names/posibrain.txt") GLOBAL_LIST_INIT(nightmare_names, world.file2list("strings/names/nightmare.txt")) GLOBAL_LIST_INIT(megacarp_first_names, world.file2list("strings/names/megacarp1.txt")) GLOBAL_LIST_INIT(megacarp_last_names, world.file2list("strings/names/megacarp2.txt")) +GLOBAL_LIST_INIT(cyberauth_names, world.file2list("strings/names/cyberauth.txt")) GLOBAL_LIST_INIT(verbs, world.file2list("strings/names/verbs.txt")) GLOBAL_LIST_INIT(ing_verbs, world.file2list("strings/names/ing_verbs.txt")) diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm index 2fd384e69a94f1..8239dc29231f46 100644 --- a/code/_globalvars/lists/objects.dm +++ b/code/_globalvars/lists/objects.dm @@ -31,19 +31,6 @@ GLOBAL_LIST_EMPTY(deliverybeacontags) /// List of all singularity components that exist GLOBAL_LIST_EMPTY_TYPED(singularities, /datum/component/singularity) -/// list of all /datum/chemical_reaction datums indexed by their typepath. Use this for general lookup stuff -GLOBAL_LIST(chemical_reactions_list) -/// list of all /datum/chemical_reaction datums. Used during chemical reactions. Indexed by REACTANT types -GLOBAL_LIST(chemical_reactions_list_reactant_index) -/// list of all /datum/chemical_reaction datums. Used for the reaction lookup UI. Indexed by PRODUCT type -GLOBAL_LIST(chemical_reactions_list_product_index) /// list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff -GLOBAL_LIST_INIT(chemical_reagents_list, init_chemical_reagent_list()) -/// names of reagents used by plumbing UI. -GLOBAL_LIST_INIT(chemical_name_list, init_chemical_name_list()) -/// List of all reactions with their associated product and result ids. Used for reaction lookups -GLOBAL_LIST(chemical_reactions_results_lookup_list) -/// List of all reagents that are parent types used to define a bunch of children - but aren't used themselves as anything. -GLOBAL_LIST(fake_reagent_blacklist) /// list of all /datum/tech datums indexed by id. GLOBAL_LIST_EMPTY(tech_list) /// list of all surgeries by name, associated with their path. diff --git a/code/_globalvars/lists/poll_ignore.dm b/code/_globalvars/lists/poll_ignore.dm index 4d4f10ddc8acde..1a56a44f5e5b65 100644 --- a/code/_globalvars/lists/poll_ignore.dm +++ b/code/_globalvars/lists/poll_ignore.dm @@ -5,6 +5,7 @@ #define POLL_IGNORE_ALIEN_LARVA "alien_larva" #define POLL_IGNORE_ASH_SPIRIT "ash_spirit" #define POLL_IGNORE_ASHWALKER "ashwalker" +#define POLL_IGNORE_BLOB "blob" #define POLL_IGNORE_BOTS "bots" #define POLL_IGNORE_CARGORILLA "cargorilla" #define POLL_IGNORE_CONTRACTOR_SUPPORT "contractor_support" @@ -43,6 +44,7 @@ GLOBAL_LIST_INIT(poll_ignore_desc, list( POLL_IGNORE_ALIEN_LARVA = "Xenomorph larva", POLL_IGNORE_ASH_SPIRIT = "Ash Spirit", POLL_IGNORE_ASHWALKER = "Ashwalker eggs", + POLL_IGNORE_BLOB = "Blob spores", POLL_IGNORE_BOTS = "Bots", POLL_IGNORE_CARGORILLA = "Cargorilla", POLL_IGNORE_CONTRACTOR_SUPPORT = "Contractor Support Unit", diff --git a/code/_globalvars/lists/reagents.dm b/code/_globalvars/lists/reagents.dm new file mode 100644 index 00000000000000..dec2724cfebd11 --- /dev/null +++ b/code/_globalvars/lists/reagents.dm @@ -0,0 +1,154 @@ +/// list of all /datum/chemical_reaction datums indexed by their typepath. Use this for general lookup stuff +GLOBAL_LIST(chemical_reactions_list) +/// list of all /datum/chemical_reaction datums. Used during chemical reactions. Indexed by REACTANT types +GLOBAL_LIST(chemical_reactions_list_reactant_index) +/// list of all /datum/chemical_reaction datums. Used for the reaction lookup UI. Indexed by PRODUCT type +GLOBAL_LIST(chemical_reactions_list_product_index) +/// list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff +GLOBAL_LIST_INIT(chemical_reagents_list, init_chemical_reagent_list()) +/// list of all reactions with their associated product and result ids. Used for reaction lookups +GLOBAL_LIST(chemical_reactions_results_lookup_list) +/// list of all reagents that are parent types used to define a bunch of children - but aren't used themselves as anything. +GLOBAL_LIST(fake_reagent_blacklist) +/// Turfs metalgen cant touch +GLOBAL_LIST_INIT(blacklisted_metalgen_types, typecacheof(list( + /turf/closed/indestructible, //indestructible turfs should be indestructible, metalgen transmutation to plasma allows them to be destroyed + /turf/open/indestructible +))) +/// Names of human readable reagents used by plumbing UI. +GLOBAL_LIST_INIT(chemical_name_list, init_chemical_name_list()) +/// Map of reagent names to its datum path +GLOBAL_LIST_INIT(name2reagent, build_name2reagentlist()) + +/// Initialises all /datum/reagent into a list indexed by reagent id +/proc/init_chemical_reagent_list() + var/list/reagent_list = list() + + for(var/datum/reagent/path as anything in subtypesof(/datum/reagent)) + if(path in GLOB.fake_reagent_blacklist) + continue + var/datum/reagent/target_object = new path() + target_object.mass = rand(10, 800) + reagent_list[path] = target_object + + return reagent_list + +/// Creates an list which is indexed by reagent name . used by plumbing reaction chamber and chemical filter UI +/proc/init_chemical_name_list() + var/list/name_list = list() + + for(var/X in GLOB.chemical_reagents_list) + var/datum/reagent/Reagent = GLOB.chemical_reagents_list[X] + name_list += Reagent.name + + return sort_list(name_list) + +/** + * Chemical Reactions - Initialises all /datum/chemical_reaction into a list + * It is filtered into multiple lists within a list. + * For example: + * chemical_reactions_list_reactant_index[/datum/reagent/toxin/plasma] is a list of all reactions relating to plasma + * For chemical reaction list product index - indexes reactions based off the product reagent type - see get_recipe_from_reagent_product() in helpers + * For chemical reactions list lookup list - creates a bit list of info passed to the UI. This is saved to reduce lag from new windows opening, since it's a lot of data. + */ +/proc/build_chemical_reactions_lists() + if(GLOB.chemical_reactions_list_reactant_index) + return + + //Prevent these reactions from appearing in lookup tables (UI code) + var/list/blacklist = typecacheof(/datum/chemical_reaction/randomized) + + //Randomized need to go last since they need to check against conflicts with normal recipes + var/paths = subtypesof(/datum/chemical_reaction) - typesof(/datum/chemical_reaction/randomized) + subtypesof(/datum/chemical_reaction/randomized) + GLOB.chemical_reactions_list = list() //typepath to reaction list + GLOB.chemical_reactions_list_reactant_index = list() //reagents to reaction list + GLOB.chemical_reactions_results_lookup_list = list() //UI glob + GLOB.chemical_reactions_list_product_index = list() //product to reaction list + + var/list/datum/chemical_reaction/reactions = list() + for(var/path in paths) + var/datum/chemical_reaction/reaction = new path() + reactions += reaction + + // Ok so we're gonna do a thingTM here + // I want to distribute all our reactions such that each reagent id links to as few as possible + // I get the feeling there's a canonical way of doing this, but I don't know it + // So instead, we're gonna wing it + var/list/reagent_to_react_count = list() + for(var/datum/chemical_reaction/reaction as anything in reactions) + for(var/reagent_id as anything in reaction.required_reagents) + reagent_to_react_count[reagent_id] += 1 + + var/list/reaction_lookup = GLOB.chemical_reactions_list_reactant_index + // Create filters based on a random reagent id in the required reagents list - this is used to speed up handle_reactions() + // Basically, we only really need to care about ONE reagent, at least when initially filtering, since any others are ignorable + // Doing this separately because it relies on the loop above, and this is easier to parse + for(var/datum/chemical_reaction/reaction as anything in reactions) + var/preferred_id = null + for(var/reagent_id as anything in reaction.required_reagents) + if(isnull(preferred_id)) + preferred_id = reagent_id + continue + // If we would have less then they would, take it + if(length(reaction_lookup[reagent_id]) < length(reaction_lookup[preferred_id])) + preferred_id = reagent_id + continue + // If they potentially have more then us, we take it + if(reagent_to_react_count[reagent_id] < reagent_to_react_count[preferred_id]) + preferred_id = reagent_id + continue + if (!isnull(preferred_id)) + if(!reaction_lookup[preferred_id]) + reaction_lookup[preferred_id] = list() + reaction_lookup[preferred_id] += reaction + + for(var/datum/chemical_reaction/reaction as anything in reactions) + var/list/product_ids = list() + var/list/reagents = list() + var/list/product_names = list() + var/bitflags = reaction.reaction_tags + + if(!length(reaction.required_reagents)) //Skip impossible reactions + continue + + GLOB.chemical_reactions_list[reaction.type] = reaction + + for(var/reagent_path in reaction.required_reagents) + var/datum/reagent/reagent = find_reagent_object_from_type(reagent_path) + if(!istype(reagent)) + stack_trace("Invalid reagent found in [reaction] required_reagents: [reagent_path]") + continue + reagents += list(list("name" = reagent.name, "id" = reagent.type)) + + for(var/product in reaction.results) + var/datum/reagent/reagent = find_reagent_object_from_type(product) + if(!istype(reagent)) + stack_trace("Invalid reagent found in [reaction] results: [product]") + continue + product_names += reagent.name + product_ids += product + + var/product_name + if(!length(product_names)) + var/list/names = splittext("[reaction.type]", "/") + product_name = names[names.len] + else + product_name = product_names[1] + + if(!is_type_in_typecache(reaction.type, blacklist)) + //Master list of ALL reactions that is used in the UI lookup table. This is expensive to make, and we don't want to lag the server by creating it on UI request, so it's cached to send to UIs instantly. + GLOB.chemical_reactions_results_lookup_list += list(list("name" = product_name, "id" = reaction.type, "bitflags" = bitflags, "reactants" = reagents)) + + // Create filters based on each reagent id in the required reagents list - this is specifically for finding reactions from product(reagent) ids/typepaths. + for(var/id in product_ids) + if(!GLOB.chemical_reactions_list_product_index[id]) + GLOB.chemical_reactions_list_product_index[id] = list() + GLOB.chemical_reactions_list_product_index[id] += reaction + +/// Builds map of reagent name to its datum path +/proc/build_name2reagentlist() + . = list() + for (var/datum/reagent/R as anything in subtypesof(/datum/reagent)) + var/name = initial(R.name) + if (length(name)) + .[ckey(name)] = R diff --git a/code/_globalvars/phobias.dm b/code/_globalvars/phobias.dm index a913410214da73..b37c61bc6815fd 100644 --- a/code/_globalvars/phobias.dm +++ b/code/_globalvars/phobias.dm @@ -72,7 +72,6 @@ GLOBAL_LIST_INIT(phobia_mobs, list( "doctors" = typecacheof(list(/mob/living/simple_animal/bot/medbot)), "heresy" = typecacheof(list( /mob/living/basic/heretic_summon, - /mob/living/simple_animal/hostile/heretic_summon, )), "insects" = typecacheof(list( /mob/living/basic/cockroach, @@ -92,18 +91,18 @@ GLOBAL_LIST_INIT(phobia_mobs, list( "the supernatural" = typecacheof(list( /mob/dead/observer, /mob/living/basic/bat, + /mob/living/basic/construct, /mob/living/basic/demon, /mob/living/basic/faithless, /mob/living/basic/ghost, /mob/living/basic/heretic_summon, + /mob/living/basic/revenant, /mob/living/simple_animal/bot/mulebot/paranormal, /mob/living/simple_animal/hostile/construct, /mob/living/simple_animal/hostile/dark_wizard, - /mob/living/simple_animal/hostile/heretic_summon, /mob/living/simple_animal/hostile/skeleton, /mob/living/simple_animal/hostile/wizard, /mob/living/simple_animal/hostile/zombie, - /mob/living/simple_animal/revenant, /mob/living/simple_animal/shade, )), )) diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index d35c97ef68a967..da03288a0ca7e0 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -30,6 +30,8 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_CHUNKYFINGERS" = TRAIT_CHUNKYFINGERS, "TRAIT_CHUNKYFINGERS_IGNORE_BATON" = TRAIT_CHUNKYFINGERS_IGNORE_BATON, "TRAIT_FIST_MINING" = TRAIT_FIST_MINING, + "TRAIT_CAN_HOLD_ITEMS" = TRAIT_CAN_HOLD_ITEMS, + "TRAIT_FENCE_CLIMBER" = TRAIT_FENCE_CLIMBER, "TRAIT_DUMB" = TRAIT_DUMB, "TRAIT_ADVANCEDTOOLUSER" = TRAIT_ADVANCEDTOOLUSER, "TRAIT_DISCOORDINATED_TOOL_USER" = TRAIT_DISCOORDINATED_TOOL_USER, @@ -272,6 +274,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_FISH_TOXIN_IMMUNE" = TRAIT_FISH_TOXIN_IMMUNE, "TRAIT_FISH_CROSSBREEDER" = TRAIT_FISH_CROSSBREEDER, "TRAIT_FISH_FED_LUBE" = TRAIT_FISH_FED_LUBE, + "TRAIT_FISH_NO_HUNGER" = TRAIT_FISH_NO_HUNGER, ), )) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 95697862b3c96c..3d632a99f7389b 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -73,10 +73,6 @@ if(world.time <= next_move) return - if(aicamera.in_camera_mode) - aicamera.toggle_camera_mode(sound = FALSE) - aicamera.captureimage(pixel_turf, usr) - return if(waypoint_mode) waypoint_mode = 0 set_waypoint(A) diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 92340c59bc90e1..8cc8603f552c49 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -48,11 +48,6 @@ face_atom(A) // change direction to face what you clicked on - if(aicamera.in_camera_mode) //Cyborg picture taking - aicamera.toggle_camera_mode(sound = FALSE) - aicamera.captureimage(A, usr) - return - var/obj/item/W = get_active_held_item() if(!W && get_dist(src,A) <= interaction_range) diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index afedfa5befe6ef..79f857e8cbef07 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -26,7 +26,7 @@ screens -= category - if(animated) + if(!QDELETED(src) && animated) animate(screen, alpha = 0, time = animated) addtimer(CALLBACK(src, PROC_REF(clear_fullscreen_after_animate), screen), animated, TIMER_CLIENT_TIME) else @@ -216,3 +216,10 @@ layer = LIGHTING_ABOVE_ALL blend_mode = BLEND_ADD show_when_dead = TRUE + +/atom/movable/screen/fullscreen/static_vision + icon = 'icons/hud/screen_gen.dmi' + screen_loc = "WEST,SOUTH to EAST,NORTH" + icon_state = "noise" + color = "#04a8d1" + alpha = 80 diff --git a/code/_onclick/hud/generic_dextrous.dm b/code/_onclick/hud/generic_dextrous.dm index bf09fa33717139..64ad896d57a1f5 100644 --- a/code/_onclick/hud/generic_dextrous.dm +++ b/code/_onclick/hud/generic_dextrous.dm @@ -43,7 +43,7 @@ using.icon = ui_style static_inventory += using - mymob.canon_client.clear_screen() + mymob.canon_client?.clear_screen() for(var/atom/movable/screen/inventory/inv in (static_inventory + toggleable_inventory)) if(inv.slot_id) diff --git a/code/_onclick/hud/screentip.dm b/code/_onclick/hud/screentip.dm index 107f4ce1be523c..94b8f591f650f8 100644 --- a/code/_onclick/hud/screentip.dm +++ b/code/_onclick/hud/screentip.dm @@ -14,7 +14,7 @@ /atom/movable/screen/screentip/proc/update_view(datum/source) SIGNAL_HANDLER - if(!hud || !hud.mymob.canon_client.view_size) //Might not have been initialized by now + if(!hud || !hud.mymob.canon_client?.view_size) //Might not have been initialized by now return maptext_width = view_to_pixels(hud.mymob.canon_client.view_size.getView())[1] diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 1868057d82c18c..ed1cdc57b76147 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -287,34 +287,13 @@ /atom/proc/attack_pai_secondary(mob/user, list/modifiers) return SECONDARY_ATTACK_CALL_NORMAL -/* - Simple animals -*/ - -/mob/living/simple_animal/resolve_unarmed_attack(atom/attack_target, list/modifiers) - if(dextrous && (isitem(attack_target) || !combat_mode)) - attack_target.attack_hand(src, modifiers) - update_held_items() - else - return ..() - -/mob/living/simple_animal/resolve_right_click_attack(atom/target, list/modifiers) - if(dextrous && (isitem(target) || !combat_mode)) - . = target.attack_hand_secondary(src, modifiers) - update_held_items() - else - return ..() - /* Hostile animals */ /mob/living/simple_animal/hostile/resolve_unarmed_attack(atom/attack_target, list/modifiers) GiveTarget(attack_target) - if(dextrous && (isitem(attack_target) || !combat_mode)) - return ..() - else - INVOKE_ASYNC(src, PROC_REF(AttackingTarget), attack_target) + return ..() #undef LIVING_UNARMED_ATTACK_BLOCKED diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index b5fc855da3196c..16791b7fd7e623 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -262,10 +262,25 @@ /datum/config_entry/string/hostedby -/datum/config_entry/flag/norespawn - +/// Determines if a player can respawn after dying. +/// 0 / RESPAWN_FLAG_DISABLED = Cannot respawn (default) +/// 1 / RESPAWN_FLAG_FREE = Can respawn +/// 2 / RESPAWN_FLAG_NEW_CHARACTER = Can respawn if choosing a different character +/datum/config_entry/flag/allow_respawn + default = RESPAWN_FLAG_DISABLED + +/datum/config_entry/flag/allow_respawn/ValidateAndSet(str_val) + if(!VASProcCallGuard(str_val)) + return FALSE + var/val_as_num = text2num(str_val) + if(val_as_num in list(RESPAWN_FLAG_DISABLED, RESPAWN_FLAG_FREE, RESPAWN_FLAG_NEW_CHARACTER)) + config_entry_value = val_as_num + return TRUE + return FALSE + +/// Determines how long (in deciseconds) before a player is allowed to respawn. /datum/config_entry/number/respawn_delay - default = 0 + default = 0 SECONDS /datum/config_entry/flag/usewhitelist diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index 488debb48e5a8a..1de3f900c8ca08 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -452,7 +452,7 @@ SUBSYSTEM_DEF(air) border += item net.air.volume += item.volume - item.parent = net + item.replace_pipenet(item.parent, net) if(item.air_temporary) net.air.merge(item.air_temporary) diff --git a/code/controllers/subsystem/economy.dm b/code/controllers/subsystem/economy.dm index e396bcb8445632..511a438bf9a60c 100644 --- a/code/controllers/subsystem/economy.dm +++ b/code/controllers/subsystem/economy.dm @@ -123,6 +123,8 @@ SUBSYSTEM_DEF(economy) var/effective_mailcount = round(living_player_count()/(inflation_value - 0.5)) //More mail at low inflation, and vis versa. mail_waiting += clamp(effective_mailcount, 1, MAX_MAIL_PER_MINUTE * seconds_per_tick) + SSstock_market.news_string = "" + /** * Handy proc for obtaining a department's bank account, given the department ID, AKA the define assigned for what department they're under. */ @@ -173,7 +175,7 @@ SUBSYSTEM_DEF(economy) fluff_string = ", but company countermeasures protect YOU from being affected!" else fluff_string = ", and company countermeasures are failing to protect YOU from being affected. We're all doomed!" - earning_report = "Sector Economic Report

Sector vendor prices is currently at [SSeconomy.inflation_value()*100]%[fluff_string]

The station spending power is currently [station_total] Credits, and the crew's targeted allowance is at [station_target] Credits.

That's all from the Nanotrasen Economist Division." + earning_report = "Sector Economic Report

Sector vendor prices is currently at [SSeconomy.inflation_value()*100]%[fluff_string]

The station spending power is currently [station_total] Credits, and the crew's targeted allowance is at [station_target] Credits.

[SSstock_market.news_string] That's all from the Nanotrasen Economist Division." GLOB.news_network.submit_article(earning_report, "Station Earnings Report", "Station Announcements", null, update_alert = FALSE) return TRUE diff --git a/code/controllers/subsystem/id_access.dm b/code/controllers/subsystem/id_access.dm index 963957741f2021..86f2e124a8f422 100644 --- a/code/controllers/subsystem/id_access.dm +++ b/code/controllers/subsystem/id_access.dm @@ -329,6 +329,7 @@ SUBSYSTEM_DEF(id_access) desc_by_access["[ACCESS_CENT_SPECOPS]"] = "Code Black" desc_by_access["[ACCESS_CENT_CAPTAIN]"] = "Code Gold" desc_by_access["[ACCESS_CENT_BAR]"] = "Code Scotch" + desc_by_access["[ACCESS_BIT_DEN]"] = "Bitrunner Den" desc_by_access["[ACCESS_BARBER]"] = "Barber" // SKYRAT EDIT ADD - BARBER UPDATE /** diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 976b4bab24923f..8376059e910375 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -1,5 +1,3 @@ -#define VERY_LATE_ARRIVAL_TOAST_PROB 20 - SUBSYSTEM_DEF(job) name = "Jobs" init_order = INIT_ORDER_JOBS @@ -546,21 +544,16 @@ SUBSYSTEM_DEF(job) /datum/controller/subsystem/job/proc/EquipRank(mob/living/equipping, datum/job/job, client/player_client) // SKYRAT EDIT ADDITION BEGIN - ALTERNATIVE_JOB_TITLES // The alt job title, if user picked one, or the default - var/chosen_title = player_client?.prefs.alt_job_titles[job.title] || job.title - var/default_title = job.title - // SKYRAT EDIT ADDITION END - job.title + var/alt_title = player_client?.prefs.alt_job_titles[job.title] + // SKYRAT EDIT ADDITION END equipping.job = job.title SEND_SIGNAL(equipping, COMSIG_JOB_RECEIVED, job) - equipping.mind?.set_assigned_role_with_greeting(job, player_client) - if(player_client) - to_chat(player_client, span_infoplain("You are the [chosen_title].")) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - Original: to_chat(player_client, span_infoplain("You are the [job.title].")) - - equipping.on_job_equipping(job, player_client?.prefs) //SKYRAT EDIT CHANGE - - job.announce_job(equipping, chosen_title) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - Original: job.announce_job(equipping) + equipping.mind?.set_assigned_role_with_greeting(job, player_client, alt_title) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: equipping.mind?.set_assigned_role_with_greeting(job, player_client) + equipping.on_job_equipping(job, player_client?.prefs, player_client) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: equipping.on_job_equipping(job) + job.announce_job(equipping, alt_title) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: job.announce_job(equipping) if(player_client?.holder) if(CONFIG_GET(flag/auto_deadmin_players) || (player_client.prefs?.toggles & DEADMIN_ALWAYS)) @@ -568,46 +561,7 @@ SUBSYSTEM_DEF(job) else handle_auto_deadmin_roles(player_client, job.title) - - if(player_client) - to_chat(player_client, span_infoplain("As the [chosen_title == job.title ? chosen_title : "[chosen_title] ([job.title])"] you answer directly to [job.supervisors]. Special circumstances may change this.")) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - Original: to_chat(player_client, span_infoplain("As the [job.title] you answer directly to [job.supervisors]. Special circumstances may change this.")) - - job.radio_help_message(equipping) - - if(player_client) - if(job.req_admin_notify) - to_chat(player_client, span_infoplain("You are playing a job that is important for Game Progression. \ - If you have to disconnect, please notify the admins via adminhelp.")) - if(CONFIG_GET(number/minimal_access_threshold)) - to_chat(player_client, span_boldnotice("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.")) - //SKYRAT EDIT START - ALTERNATIVE_JOB_TITLES - if(chosen_title != default_title) - to_chat(player_client, span_infoplain(span_warning("Remember that alternate titles are purely for flavor and roleplay."))) - to_chat(player_client, span_infoplain(span_doyourjobidiot("Do not use your \"[chosen_title]\" alt title as an excuse to forego your duties as a [job.title]."))) - //SKYRAT EDIT END - var/related_policy = get_policy(job.title) - if(related_policy) - to_chat(player_client, related_policy) - to_chat(player_client, span_boldnotice("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(ishuman(equipping)) - var/mob/living/carbon/human/wageslave = equipping - wageslave.add_mob_memory(/datum/memory/key/account, remembered_id = wageslave.account_id) - - setup_alt_job_items(wageslave, job, player_client) // SKYRAT EDIT ADDITION - ALTERNATIVE_JOB_TITLES - - if(EMERGENCY_PAST_POINT_OF_NO_RETURN && prob(VERY_LATE_ARRIVAL_TOAST_PROB)) - // SKYRAT EDIT CHANGE START - Lizards - if(islizard(equipping)) - equipping.equip_to_slot_or_del(new /obj/item/food/breadslice/root(equipping), ITEM_SLOT_MASK) - else - equipping.equip_to_slot_or_del(new /obj/item/food/griddle_toast(equipping), ITEM_SLOT_MASK) - // SKYRAT EDIT CHANGE END - Lizards - + setup_alt_job_items(equipping, job, player_client) // SKYRAT EDIT ADDITION - ALTERNATIVE_JOB_TITLES job.after_spawn(equipping, player_client) /datum/controller/subsystem/job/proc/handle_auto_deadmin_roles(client/C, rank) @@ -1010,5 +964,3 @@ SUBSYSTEM_DEF(job) return TRUE return FALSE - -#undef VERY_LATE_ARRIVAL_TOAST_PROB diff --git a/code/controllers/subsystem/movement/movement_types.dm b/code/controllers/subsystem/movement/movement_types.dm index 7067b3abbfc7bf..6ff9d39d5313f4 100644 --- a/code/controllers/subsystem/movement/movement_types.dm +++ b/code/controllers/subsystem/movement/movement_types.dm @@ -384,7 +384,7 @@ src.simulated_only = simulated_only src.avoid = avoid src.skip_first = skip_first - movement_path = initial_path.Copy() + movement_path = initial_path?.Copy() if(isidcard(id)) RegisterSignal(id, COMSIG_QDELETING, PROC_REF(handle_no_id)) //I prefer erroring to harddels. If this breaks anything consider making id info into a datum or something diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm index 6e6fc6547e2e71..c34d97b28f9c45 100644 --- a/code/controllers/subsystem/processing/quirks.dm +++ b/code/controllers/subsystem/processing/quirks.dm @@ -15,7 +15,7 @@ GLOBAL_LIST_INIT_TYPED(quirk_blacklist, /list/datum/quirk, list( list(/datum/quirk/prosthetic_limb, /datum/quirk/quadruple_amputee, /datum/quirk/body_purist), list(/datum/quirk/prosthetic_organ, /datum/quirk/tin_man, /datum/quirk/body_purist), list(/datum/quirk/quadruple_amputee, /datum/quirk/paraplegic, /datum/quirk/hemiplegic), - list(/datum/quirk/quadruple_amputee, /datum/quirk/frail), + //list(/datum/quirk/quadruple_amputee, /datum/quirk/frail), // SKYRAT EDIT REMOVAL- Since we have synth wounds now, frail has a large downside for prosthetics and such list(/datum/quirk/social_anxiety, /datum/quirk/mute), list(/datum/quirk/mute, /datum/quirk/softspoken), list(/datum/quirk/poor_aim, /datum/quirk/bighands), diff --git a/code/controllers/subsystem/research.dm b/code/controllers/subsystem/research.dm index 7f0b52d471bc84..1cc3468fb7db48 100644 --- a/code/controllers/subsystem/research.dm +++ b/code/controllers/subsystem/research.dm @@ -313,6 +313,8 @@ SUBSYSTEM_DEF(research) */ /datum/controller/subsystem/research/proc/get_available_servers(turf/location) var/list/local_servers = list() + if(!location) + return local_servers for (var/datum/techweb/individual_techweb as anything in techwebs) var/list/servers = find_valid_servers(location, individual_techweb) if(length(servers)) diff --git a/code/controllers/subsystem/stock_market.dm b/code/controllers/subsystem/stock_market.dm new file mode 100644 index 00000000000000..7c2cb71dc4972b --- /dev/null +++ b/code/controllers/subsystem/stock_market.dm @@ -0,0 +1,154 @@ + +SUBSYSTEM_DEF(stock_market) + name = "Stock Market" + wait = 20 SECONDS + init_order = INIT_ORDER_DEFAULT + runlevels = RUNLEVEL_GAME + + /// Associated list of materials and their prices at the given time. + var/list/materials_prices = list() + /// Associated list of materials alongside their market trends. 1 is up, 0 is stable, -1 is down. + var/list/materials_trends = list() + /// Associated list of materials alongside the life of it's current trend. After it's life is up, it will change to a new trend. + var/list/materials_trend_life = list() + /// Associated list of materials alongside their available quantity. This is used to determine how much of a material is available to buy, and how much buying and selling affects the price. + var/list/materials_quantity = list() + /// HTML string that is used to display the market events to the player. + var/news_string = "" + +/datum/controller/subsystem/stock_market/Initialize() + for(var/datum/material/possible_market as anything in subtypesof(/datum/material)) // I need to make this work like this, but lets hardcode it for now + if(initial(possible_market.tradable)) + materials_prices += possible_market + materials_prices[possible_market] = initial(possible_market.value_per_unit) * SHEET_MATERIAL_AMOUNT + + materials_trends += possible_market + materials_trends[possible_market] = rand(MARKET_TREND_DOWNWARD,MARKET_TREND_UPWARD) //aka -1 to 1 + + materials_trend_life += possible_market + materials_trend_life[possible_market] = rand(1,10) + + materials_quantity += possible_market + materials_quantity[possible_market] = initial(possible_market.tradable_base_quantity) + (rand(-initial(possible_market.tradable_base_quantity) * 0.5, initial(possible_market.tradable_base_quantity) * 0.5)) + return SS_INIT_SUCCESS +/datum/controller/subsystem/stock_market/fire(resumed) + for(var/datum/material/market as anything in materials_prices) + handle_trends_and_price(market) + +/** + * Handles shifts in the cost of materials, and in what direction the material is most likely to move. + */ +/datum/controller/subsystem/stock_market/proc/handle_trends_and_price(datum/material/mat) + if(prob(MARKET_EVENT_PROBABILITY)) + handle_market_event(mat) + return + var/trend = materials_trends[mat] + var/trend_life = materials_trend_life[mat] + + var/price_units = materials_prices[mat] + var/price_minimum = round(initial(mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 0.5) + if(!isnull(initial(mat.minimum_value_override))) + price_minimum = round(initial(mat.minimum_value_override) * SHEET_MATERIAL_AMOUNT) + var/price_maximum = round(initial(mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 3) + var/price_baseline = initial(mat.value_per_unit) * SHEET_MATERIAL_AMOUNT + + var/stock_quantity = materials_quantity[mat] + + if(HAS_TRAIT(SSeconomy, TRAIT_MARKET_CRASHING)) //We hardset to the worst possible price and lowest possible impact if sold + materials_prices[mat] = price_minimum + materials_quantity[mat] = stock_quantity * 2 + materials_trends[mat] = MARKET_TREND_DOWNWARD + trend_life = materials_trend_life[mat] = 1 + return + + if(trend_life == 0) + ///We want to scale our trend so that if we're closer to our minimum or maximum price, we're more likely to trend the other way. + if((price_units < price_baseline)) + var/chance_swap = 100 - ((clamp((price_units - price_minimum), 1, 1000) / (price_baseline - price_minimum))*100) + if(prob(chance_swap)) + materials_trends[mat] = MARKET_TREND_UPWARD + else + materials_trends[mat] = MARKET_TREND_STABLE + else if((price_units > price_baseline)) + var/chance_swap = 100 - ((clamp((price_units - price_maximum), 1, 1000) / (price_maximum - price_baseline))*100) + if(prob(chance_swap)) + materials_trends[mat] = MARKET_TREND_DOWNWARD + else + materials_trends[mat] = MARKET_TREND_STABLE + materials_trend_life[mat] = rand(3,10) // Change our trend life for x number of cycles + else + materials_trend_life[mat] -= 1 + + var/price_change = 0 + var/quantity_change = 0 + switch(trend) + if(MARKET_TREND_UPWARD) + price_change = ROUND_UP(gaussian(price_units * 0.1, price_baseline * 0.05)) //If we don't ceil, small numbers will get trapped at low values + quantity_change = -round(gaussian(stock_quantity * 0.1, stock_quantity * 0.05)) + if(MARKET_TREND_STABLE) + price_change = round(gaussian(0, price_baseline * 0.01)) + quantity_change = round(gaussian(0, stock_quantity * 0.01)) + if(MARKET_TREND_DOWNWARD) + price_change = -ROUND_UP(gaussian(price_units * 0.1, price_baseline * 0.05)) + quantity_change = round(gaussian(stock_quantity * 0.1, stock_quantity * 0.05)) + materials_prices[mat] = round(clamp(price_units + price_change, price_minimum, price_maximum)) + materials_quantity[mat] = round(clamp(stock_quantity + quantity_change, 0, initial(mat.tradable_base_quantity) * 2)) + +/** + * Market events are a way to spice up the market and make it more interesting. + * Randomly one will occur to a random material, and it will change the price of that material more drastically, or reset it to a stable price. + * Events are also broadcast to the newscaster as a fun little fluff piece. Good way to tell some lore as well, or just make a joke. + */ +/datum/controller/subsystem/stock_market/proc/handle_market_event(datum/material/mat) + + var/company_name = list( // Pick a random company name from the list, I let copilot make a few up for me which is why some suck + "Nakamura Engineering", + "Robust Industries, LLC", + "MODular Solutions", + "SolGov", + "Australicus Industrial Mining", + "Vey-Medical", + "Aussec Armory", + "Dreamland Robotics" + ) + var/circumstance + var/event = rand(1,3) + + var/price_units = materials_prices[mat] + var/price_minimum = round(initial(mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 0.5) + if(!isnull(initial(mat.minimum_value_override))) + price_minimum = round(initial(mat.minimum_value_override) * SHEET_MATERIAL_AMOUNT) + var/price_maximum = round(initial(mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 3) + var/price_baseline = initial(mat.value_per_unit) * SHEET_MATERIAL_AMOUNT + + switch(event) + if(1) //Reset to stable + materials_prices[mat] = price_baseline + materials_trends[mat] = MARKET_TREND_STABLE + materials_trend_life[mat] = 1 + circumstance = pick(list( + "[pick(company_name)] has been bought out by a private investment firm. As a result, [initial(mat.name)] is now stable at [materials_prices[mat]] cr.", + "Due to a corporate restructuring, the largest supplier of [initial(mat.name)] has had the price changed to [materials_prices[mat]] cr.", + "[initial(mat.name)] is now under a monopoly by [pick(company_name)]. The price has been changed to [materials_prices[mat]] cr accordingly." + )) + if(2) //Big boost + materials_prices[mat] += round(gaussian(price_units * 0.5, price_units * 0.1)) + materials_prices[mat] = clamp(materials_prices[mat], price_minimum, price_maximum) + materials_trends[mat] = MARKET_TREND_UPWARD + materials_trend_life[mat] = rand(1,5) + circumstance = pick(list( + "[pick(company_name)] has just released a new product that uses [initial(mat.name)]! As a result, the price has been raised to [materials_prices[mat]] cr.", + "Due to [pick(company_name)] finding a new property of [initial(mat.name)], its price has been raised to [materials_prices[mat]] cr.", + "A study has found that [initial(mat.name)] may run out within the next 100 years. The price has raised to [materials_prices[mat]] cr due to panic." + )) + if(3) //Big drop + materials_prices[mat] -= round(gaussian(price_units * 1.5, price_units * 0.1)) + materials_prices[mat] = clamp(materials_prices[mat], price_minimum, price_maximum) + materials_trends[mat] = MARKET_TREND_DOWNWARD + materials_trend_life[mat] = rand(1,5) + circumstance = pick(list( + "[pick(company_name)]'s latest product has seen major controversy, and as a result, the price of [initial(mat.name)] has dropped to [materials_prices[mat]] cr.", + "Due to a new competitor, the price of [initial(mat.name)] has dropped to [materials_prices[mat]] cr.", + "[initial(mat.name)] has been found to be a carcinogen. The price has dropped to [materials_prices[mat]] cr due to panic." + )) + news_string += circumstance + "
" // Add the event to the news_string, formatted for newscasters. diff --git a/code/datums/actions/action.dm b/code/datums/actions/action.dm index b43220fb7d4b4a..d81c72cc920080 100644 --- a/code/datums/actions/action.dm +++ b/code/datums/actions/action.dm @@ -96,13 +96,15 @@ if(check_flags & AB_CHECK_CONSCIOUS) RegisterSignal(owner, COMSIG_MOB_STATCHANGE, PROC_REF(update_status_on_signal)) if(check_flags & AB_CHECK_INCAPACITATED) - RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED), PROC_REF(update_status_on_signal)) + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED), SIGNAL_REMOVETRAIT(TRAIT_INCAPACITATED)), PROC_REF(update_status_on_signal)) if(check_flags & AB_CHECK_IMMOBILE) - RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED), PROC_REF(update_status_on_signal)) + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED), SIGNAL_REMOVETRAIT(TRAIT_IMMOBILIZED)), PROC_REF(update_status_on_signal)) if(check_flags & AB_CHECK_HANDS_BLOCKED) - RegisterSignal(owner, SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), PROC_REF(update_status_on_signal)) + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), SIGNAL_REMOVETRAIT(TRAIT_HANDS_BLOCKED)), PROC_REF(update_status_on_signal)) if(check_flags & AB_CHECK_LYING) RegisterSignal(owner, COMSIG_LIVING_SET_BODY_POSITION, PROC_REF(update_status_on_signal)) + if(check_flags & AB_CHECK_PHASED) + RegisterSignals(owner, list(SIGNAL_ADDTRAIT(TRAIT_MAGICALLY_PHASED), SIGNAL_REMOVETRAIT(TRAIT_MAGICALLY_PHASED)), PROC_REF(update_status_on_signal)) if(owner_has_control) GiveAction(grant_to) @@ -115,7 +117,7 @@ if(!hud.mymob) continue HideFrom(hud.mymob) - LAZYREMOVE(remove_from.actions, src) // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared + LAZYREMOVE(remove_from?.actions, src) // We aren't always properly inserted into the viewers list, gotta make sure that action's cleared viewers = list() if(owner) @@ -130,6 +132,11 @@ SIGNAL_ADDTRAIT(TRAIT_HANDS_BLOCKED), SIGNAL_ADDTRAIT(TRAIT_IMMOBILIZED), SIGNAL_ADDTRAIT(TRAIT_INCAPACITATED), + SIGNAL_ADDTRAIT(TRAIT_MAGICALLY_PHASED), + SIGNAL_REMOVETRAIT(TRAIT_HANDS_BLOCKED), + SIGNAL_REMOVETRAIT(TRAIT_IMMOBILIZED), + SIGNAL_REMOVETRAIT(TRAIT_INCAPACITATED), + SIGNAL_REMOVETRAIT(TRAIT_MAGICALLY_PHASED), )) if(target == owner) @@ -174,6 +181,10 @@ if (feedback) owner.balloon_alert(owner, "unconscious!") return FALSE + if((check_flags & AB_CHECK_PHASED) && HAS_TRAIT(owner, TRAIT_MAGICALLY_PHASED)) + if (feedback) + owner.balloon_alert(owner, "incorporeal!") + return FALSE return TRUE /// Builds / updates all buttons we have shared or given out diff --git a/code/datums/actions/mobs/lava_swoop.dm b/code/datums/actions/mobs/lava_swoop.dm index 9c305ceb13b41f..7532ccfda08823 100644 --- a/code/datums/actions/mobs/lava_swoop.dm +++ b/code/datums/actions/mobs/lava_swoop.dm @@ -147,7 +147,7 @@ if(isindestructiblefloor(T)) continue if(!isindestructiblewall(T)) - T.ChangeTurf(/turf/open/misc/asteroid/basalt/lava_land_surface, flags = CHANGETURF_INHERIT_AIR) + T.TerraformTurf(/turf/open/misc/asteroid/basalt/lava_land_surface, flags = CHANGETURF_INHERIT_AIR) else indestructible_turfs += T SLEEP_CHECK_DEATH(1 SECONDS, owner) // give them a bit of time to realize what attack is actually happening diff --git a/code/datums/actions/mobs/open_mob_commands.dm b/code/datums/actions/mobs/open_mob_commands.dm index 008e7c4dc1bb7c..e7ffd104effbe0 100644 --- a/code/datums/actions/mobs/open_mob_commands.dm +++ b/code/datums/actions/mobs/open_mob_commands.dm @@ -5,6 +5,7 @@ overlay_icon_state = "bg_heretic_border" button_icon = 'icons/mob/actions/actions_ecult.dmi' button_icon_state = "stargazer_menu" + check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED | AB_CHECK_PHASED /// Weakref for storing our stargazer var/datum/weakref/our_mob diff --git a/code/datums/ai/basic_mobs/base_basic_controller.dm b/code/datums/ai/basic_mobs/base_basic_controller.dm index 3eb79a815ad50e..cd025b28bcb2bd 100644 --- a/code/datums/ai/basic_mobs/base_basic_controller.dm +++ b/code/datums/ai/basic_mobs/base_basic_controller.dm @@ -18,7 +18,10 @@ if(!isliving(pawn)) return var/mob/living/living_pawn = pawn - if(!(ai_traits & CAN_ACT_WHILE_DEAD) && IS_DEAD_OR_INCAP(living_pawn)) + var/incap_flags = NONE + if (ai_traits & CAN_ACT_IN_STASIS) + incap_flags |= IGNORE_STASIS + if(!(ai_traits & CAN_ACT_WHILE_DEAD) && (living_pawn.incapacitated(incap_flags) || living_pawn.stat)) return FALSE if(ai_traits & PAUSE_DURING_DO_AFTER && LAZYLEN(living_pawn.do_afters)) return FALSE diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/find_mineable_wall.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/find_mineable_wall.dm deleted file mode 100644 index ad5749c9161116..00000000000000 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/find_mineable_wall.dm +++ /dev/null @@ -1,33 +0,0 @@ -//behavior to find mineable mineral walls -/datum/ai_behavior/find_mineral_wall - -/datum/ai_behavior/find_mineral_wall/perform(seconds_per_tick, datum/ai_controller/controller, found_wall_key) - . = ..() - var/mob/living_pawn = controller.pawn - - for(var/turf/closed/mineral/potential_wall in oview(9, living_pawn)) - if(!check_if_mineable(controller, potential_wall)) //check if its surrounded by walls - continue - controller.set_blackboard_key(found_wall_key, potential_wall) //closest wall first! - finish_action(controller, TRUE) - return - - finish_action(controller, FALSE) - -/datum/ai_behavior/find_mineral_wall/proc/check_if_mineable(datum/ai_controller/controller, turf/target_wall) - var/mob/living/source = controller.pawn - var/direction_to_turf = get_dir(target_wall, source) - if(!ISDIAGONALDIR(direction_to_turf)) - return TRUE - var/list/directions_to_check = list() - for(var/direction_check in GLOB.cardinals) - if(direction_check & direction_to_turf) - directions_to_check += direction_check - - for(var/direction in directions_to_check) - var/turf/test_turf = get_step(target_wall, direction) - if(isnull(test_turf)) - continue - if(!test_turf.is_blocked_turf(ignore_atoms = list(source))) - return TRUE - return FALSE diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm index bd86260ee89ce6..551cb12f3b1458 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/run_away_from_target.dm @@ -19,13 +19,13 @@ /datum/ai_behavior/run_away_from_target/perform(seconds_per_tick, datum/ai_controller/controller, target_key, hiding_location_key) . = ..() - if (!controller.blackboard[BB_BASIC_MOB_FLEEING]) + if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING]) return var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key] if (QDELETED(target) || !can_see(controller.pawn, target, run_distance)) finish_action(controller, succeeded = TRUE, target_key = target_key, hiding_location_key = hiding_location_key) return - if (get_dist(controller.pawn, controller.current_movement_target) >= required_distance) + if (get_dist(controller.pawn, controller.current_movement_target) > required_distance) return // Still heading over if (plot_path_away_from(controller, target)) return diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm index 04cb9b171ddb60..ba167b34f29514 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/targeted_mob_ability.dm @@ -11,7 +11,8 @@ finish_action(controller, FALSE, ability_key, target_key) return var/mob/pawn = controller.pawn - var/result = ability.InterceptClickOn(pawn, null, target) + pawn.face_atom(target) + var/result = ability.Trigger(target = target) finish_action(controller, result, ability_key, target_key) /datum/ai_behavior/targeted_mob_ability/finish_action(datum/ai_controller/controller, succeeded, ability_key, target_key) diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/targetting.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/targetting.dm index 0b9e31db667e15..376f62a5855b53 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/targetting.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/targetting.dm @@ -23,7 +23,8 @@ var/aggro_range = controller.blackboard[aggro_range_key] || vision_range controller.clear_blackboard_key(target_key) - var/list/potential_targets = hearers(aggro_range, controller.pawn) - living_mob //Remove self, so we don't suicide + + var/list/potential_targets = hearers(aggro_range, get_turf(controller.pawn)) - living_mob //Remove self, so we don't suicide for(var/HM in typecache_filter_list(range(aggro_range, living_mob), hostile_machines)) //Can we see any hostile machines? if(can_see(living_mob, HM, aggro_range)) diff --git a/code/datums/ai/basic_mobs/basic_ai_behaviors/travel_towards.dm b/code/datums/ai/basic_mobs/basic_ai_behaviors/travel_towards.dm index bbc1a43e322482..55f6ef4c4c00e6 100644 --- a/code/datums/ai/basic_mobs/basic_ai_behaviors/travel_towards.dm +++ b/code/datums/ai/basic_mobs/basic_ai_behaviors/travel_towards.dm @@ -6,6 +6,8 @@ /datum/ai_behavior/travel_towards required_distance = 0 behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION + /// If true we will get rid of our target on completion + var/clear_target = FALSE /datum/ai_behavior/travel_towards/setup(datum/ai_controller/controller, target_key) . = ..() @@ -16,7 +18,15 @@ /datum/ai_behavior/travel_towards/perform(seconds_per_tick, datum/ai_controller/controller, target_key) . = ..() - finish_action(controller, TRUE) + finish_action(controller, TRUE, target_key) + +/datum/ai_behavior/travel_towards/finish_action(datum/ai_controller/controller, succeeded, target_key) + . = ..() + if (clear_target) + controller.clear_blackboard_key(target_key) + +/datum/ai_behavior/travel_towards/stop_on_arrival + clear_target = TRUE /** * # Travel Towards Atom diff --git a/code/datums/ai/basic_mobs/basic_subtrees/climb_tree.dm b/code/datums/ai/basic_mobs/basic_subtrees/climb_tree.dm index 1beab6ec907459..bad349030f1b46 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/climb_tree.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/climb_tree.dm @@ -1,4 +1,5 @@ /datum/ai_planning_subtree/climb_trees + operational_datums = list(/datum/component/tree_climber) ///chance to climb a tree var/climb_chance = 35 diff --git a/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm index 8d1391f7c7dda5..4f901745eeea5e 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/flee_target.dm @@ -10,7 +10,7 @@ /datum/ai_planning_subtree/flee_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) . = ..() var/atom/flee_from = controller.blackboard[target_key] - if (!controller.blackboard[BB_BASIC_MOB_FLEEING] || QDELETED(flee_from)) + if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING] || QDELETED(flee_from)) return var/flee_distance = controller.blackboard[BB_BASIC_MOB_FLEE_DISTANCE] || DEFAULT_BASIC_FLEE_DISTANCE if (get_dist(controller.pawn, flee_from) >= flee_distance) diff --git a/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm b/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm index c09e7cdbf75f98..2a85e9e902b2cc 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/maintain_distance.dm @@ -8,6 +8,8 @@ var/maximum_distance = 6 /// How far do we look for our target? var/view_distance = 10 + /// the run away behavior we will use + var/run_away_behavior = /datum/ai_behavior/step_away /datum/ai_planning_subtree/maintain_distance/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) . = ..() @@ -16,12 +18,15 @@ return // Don't run away from cucumbers, they're not snakes var/range = get_dist(controller.pawn, target) if (range < minimum_distance) - controller.queue_behavior(/datum/ai_behavior/step_away, target_key) + controller.queue_behavior(run_away_behavior, target_key, minimum_distance) return if (range > maximum_distance) controller.queue_behavior(/datum/ai_behavior/pursue_to_range, target_key, maximum_distance) return +/datum/ai_planning_subtree/maintain_distance/cover_minimum_distance + run_away_behavior = /datum/ai_behavior/cover_minimum_distance + /// Take one step away /datum/ai_behavior/step_away behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION @@ -80,3 +85,32 @@ if (!QDELETED(current_target) && get_dist(controller.pawn, current_target) > range) return finish_action(controller, succeeded = TRUE) + +///instead of taking a single step, we cover the entire distance +/datum/ai_behavior/cover_minimum_distance + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION + required_distance = 0 + action_cooldown = 0.2 SECONDS + +/datum/ai_behavior/cover_minimum_distance/setup(datum/ai_controller/controller, target_key, minimum_distance) + . = ..() + var/atom/target = controller.blackboard[target_key] + if(QDELETED(target)) + return FALSE + var/required_distance = minimum_distance - get_dist(controller.pawn, target) //the distance we need to move + var/distance = 0 + var/turf/chosen_turf + for(var/turf/open/potential_turf in oview(required_distance, controller.pawn)) + var/new_distance_from_target = get_dist(potential_turf, target) + if(potential_turf.is_blocked_turf()) + continue + if(new_distance_from_target > distance) + chosen_turf = potential_turf + distance = new_distance_from_target + if(isnull(chosen_turf)) + return FALSE + set_movement_target(controller, target = chosen_turf) + +/datum/ai_behavior/cover_minimum_distance/perform(seconds_per_tick, datum/ai_controller/controller, target_key) + . = ..() + finish_action(controller, succeeded = TRUE) diff --git a/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm b/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm new file mode 100644 index 00000000000000..3c03702b69947b --- /dev/null +++ b/code/datums/ai/basic_mobs/basic_subtrees/mine_walls.dm @@ -0,0 +1,73 @@ +//behavior to find mineable mineral walls + +/datum/ai_planning_subtree/mine_walls + var/find_wall_behavior = /datum/ai_behavior/find_mineral_wall + +/datum/ai_planning_subtree/mine_walls/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if(controller.blackboard_key_exists(BB_TARGET_MINERAL_WALL)) + controller.queue_behavior(/datum/ai_behavior/mine_wall, BB_TARGET_MINERAL_WALL) + return SUBTREE_RETURN_FINISH_PLANNING + controller.queue_behavior(find_wall_behavior, BB_TARGET_MINERAL_WALL) + +/datum/ai_behavior/mine_wall + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION + action_cooldown = 15 SECONDS + +/datum/ai_behavior/mine_wall/setup(datum/ai_controller/controller, target_key) + . = ..() + var/turf/target = controller.blackboard[target_key] + if(QDELETED(target)) + return FALSE + set_movement_target(controller, target) + +/datum/ai_behavior/mine_wall/perform(seconds_per_tick, datum/ai_controller/controller, target_key) + . = ..() + var/mob/living/basic/living_pawn = controller.pawn + var/turf/closed/mineral/target = controller.blackboard[target_key] + var/is_gibtonite_turf = istype(target, /turf/closed/mineral/gibtonite) + if(QDELETED(target)) + finish_action(controller, FALSE, target_key) + return + living_pawn.melee_attack(target) + if(is_gibtonite_turf) + living_pawn.manual_emote("sighs...") //accept whats about to happen to us + + finish_action(controller, TRUE, target_key) + return + +/datum/ai_behavior/mine_wall/finish_action(datum/ai_controller/controller, success, target_key) + . = ..() + controller.clear_blackboard_key(target_key) + +/datum/ai_behavior/find_mineral_wall + +/datum/ai_behavior/find_mineral_wall/perform(seconds_per_tick, datum/ai_controller/controller, found_wall_key) + . = ..() + var/mob/living_pawn = controller.pawn + + for(var/turf/closed/mineral/potential_wall in oview(9, living_pawn)) + if(!check_if_mineable(controller, potential_wall)) //check if its surrounded by walls + continue + controller.set_blackboard_key(found_wall_key, potential_wall) //closest wall first! + finish_action(controller, TRUE) + return + + finish_action(controller, FALSE) + +/datum/ai_behavior/find_mineral_wall/proc/check_if_mineable(datum/ai_controller/controller, turf/target_wall) + var/mob/living/source = controller.pawn + var/direction_to_turf = get_dir(target_wall, source) + if(!ISDIAGONALDIR(direction_to_turf)) + return TRUE + var/list/directions_to_check = list() + for(var/direction_check in GLOB.cardinals) + if(direction_check & direction_to_turf) + directions_to_check += direction_check + + for(var/direction in directions_to_check) + var/turf/test_turf = get_step(target_wall, direction) + if(isnull(test_turf)) + continue + if(!test_turf.is_blocked_turf(ignore_atoms = list(source))) + return TRUE + return FALSE diff --git a/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm b/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm index 1ff752d925ffa4..be395f3dfe49d2 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/ranged_skirmish.dm @@ -4,28 +4,28 @@ /// Blackboard key holding target atom var/target_key = BB_BASIC_MOB_CURRENT_TARGET /// What AI behaviour do we actually run? - var/datum/ai_behavior/ranged_skirmish/attack_behavior = /datum/ai_behavior/ranged_skirmish + var/attack_behavior = /datum/ai_behavior/ranged_skirmish + /// If target is further away than this we don't fire + var/max_range = 9 + /// If target is closer than this we don't fire + var/min_range = 2 /datum/ai_planning_subtree/ranged_skirmish/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) . = ..() if(!controller.blackboard_key_exists(target_key)) return - controller.queue_behavior(attack_behavior, target_key, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION) + controller.queue_behavior(attack_behavior, target_key, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION, max_range, min_range) /// How often will we try to perform our ranged attack? /datum/ai_behavior/ranged_skirmish action_cooldown = 1 SECONDS - /// If target is further away than this we don't fire - var/max_range = 9 - /// If target is closer than this we don't fire - var/min_range = 2 -/datum/ai_behavior/ranged_skirmish/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) +/datum/ai_behavior/ranged_skirmish/setup(datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key, max_range, min_range) . = ..() var/atom/target = controller.blackboard[hiding_location_key] || controller.blackboard[target_key] return !QDELETED(target) -/datum/ai_behavior/ranged_skirmish/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) +/datum/ai_behavior/ranged_skirmish/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key, max_range, min_range) . = ..() var/atom/target = controller.blackboard[target_key] if (QDELETED(target)) diff --git a/code/datums/ai/basic_mobs/basic_subtrees/run_emote.dm b/code/datums/ai/basic_mobs/basic_subtrees/run_emote.dm new file mode 100644 index 00000000000000..6f2f5cdc2035c0 --- /dev/null +++ b/code/datums/ai/basic_mobs/basic_subtrees/run_emote.dm @@ -0,0 +1,33 @@ +/// Intermittently run an emote +/datum/ai_planning_subtree/run_emote + var/emote_key = BB_EMOTE_KEY + var/emote_chance_key = BB_EMOTE_CHANCE + +/datum/ai_planning_subtree/run_emote/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/emote_chance = controller.blackboard[emote_chance_key] || 0 + if (!SPT_PROB(emote_chance, seconds_per_tick)) + return + controller.queue_behavior(/datum/ai_behavior/run_emote, emote_key) + +/// Emote from a blackboard key +/datum/ai_behavior/run_emote + +/datum/ai_behavior/run_emote/perform(seconds_per_tick, datum/ai_controller/controller, emote_key) + var/mob/living/living_pawn = controller.pawn + if (!isliving(living_pawn)) + finish_action(controller, FALSE) + return + + var/list/emote_list = controller.blackboard[emote_key] + var/emote + if (islist(emote_list)) + emote = length(emote_list) ? pick(emote_list) : null + else + emote = emote_list + + if(isnull(emote)) + finish_action(controller, FALSE) + return + + living_pawn.emote(emote) + finish_action(controller, TRUE) diff --git a/code/datums/ai/basic_mobs/basic_subtrees/shapechange_ambush.dm b/code/datums/ai/basic_mobs/basic_subtrees/shapechange_ambush.dm new file mode 100644 index 00000000000000..ff01eb804ff711 --- /dev/null +++ b/code/datums/ai/basic_mobs/basic_subtrees/shapechange_ambush.dm @@ -0,0 +1,41 @@ +/// Shapeshift when we have no target, until someone has been nearby for long enough +/datum/ai_planning_subtree/shapechange_ambush + operational_datums = list(/datum/component/ai_target_timer) + /// Key where we keep our ability + var/ability_key = BB_SHAPESHIFT_ACTION + /// Key where we keep our target + var/target_key = BB_BASIC_MOB_CURRENT_TARGET + /// How long to lull our target into a false sense of security + var/minimum_target_time = 8 SECONDS + +/datum/ai_planning_subtree/shapechange_ambush/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/mob/living/living_pawn = controller.pawn + var/is_shifted = ismob(living_pawn.loc) + var/has_target = controller.blackboard_key_exists(target_key) + var/datum/action/cooldown/using_action = controller.blackboard[ability_key] + + if (!is_shifted) + if (has_target) + return // We're busy + + if (using_action?.IsAvailable()) + controller.queue_behavior(/datum/ai_behavior/use_mob_ability/shapeshift, BB_SHAPESHIFT_ACTION) // Shift + return SUBTREE_RETURN_FINISH_PLANNING + + if (!has_target || !using_action?.IsAvailable()) + return SUBTREE_RETURN_FINISH_PLANNING // Lie in wait + var/time_on_target = controller.blackboard[BB_BASIC_MOB_HAS_TARGET_TIME] || 0 + if (time_on_target < minimum_target_time) + return // Wait a bit longer + controller.queue_behavior(/datum/ai_behavior/use_mob_ability/shapeshift, BB_SHAPESHIFT_ACTION) // Surprise! + +/// Selects a random shapeshift ability before shifting +/datum/ai_behavior/use_mob_ability/shapeshift + +/datum/ai_behavior/use_mob_ability/shapeshift/setup(datum/ai_controller/controller, ability_key) + var/datum/action/cooldown/spell/shapeshift/using_action = controller.blackboard[ability_key] + if (!using_action?.IsAvailable()) + return FALSE + if (isnull(using_action.shapeshift_type)) // If we don't have a shape then pick one, AI can't use context wheels + using_action.shapeshift_type = pick(using_action.possible_shapes) + return ..() diff --git a/code/datums/ai/basic_mobs/basic_subtrees/simple_find_nearest_target_to_flee.dm b/code/datums/ai/basic_mobs/basic_subtrees/simple_find_nearest_target_to_flee.dm index 42a361c25cd865..3fe1ada33ba994 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/simple_find_nearest_target_to_flee.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/simple_find_nearest_target_to_flee.dm @@ -3,7 +3,7 @@ /datum/ai_planning_subtree/simple_find_nearest_target_to_flee/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) . = ..() - if (!controller.blackboard[BB_BASIC_MOB_FLEEING]) + if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING]) return controller.queue_behavior(/datum/ai_behavior/find_potential_targets/nearest, BB_BASIC_MOB_CURRENT_TARGET, BB_TARGETTING_DATUM, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION) @@ -13,7 +13,7 @@ /datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) . = ..() - if (!controller.blackboard[BB_BASIC_MOB_FLEEING]) + if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING]) return controller.queue_behavior(/datum/ai_behavior/target_from_retaliate_list/nearest, BB_BASIC_MOB_RETALIATE_LIST, BB_BASIC_MOB_CURRENT_TARGET, targeting_key, BB_BASIC_MOB_CURRENT_TARGET_HIDING_LOCATION) diff --git a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm index 52f4a3459bf914..7a3d5470b1a435 100644 --- a/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm +++ b/code/datums/ai/basic_mobs/basic_subtrees/speech_subtree.dm @@ -228,6 +228,6 @@ emote_see = speech_lines[BB_EMOTE_SEE] || list() emote_hear = speech_lines[BB_EMOTE_HEAR] || list() sound = speech_lines[BB_EMOTE_SOUND] || list() - speech_chance = speech_lines[BB_EMOTE_CHANCE] ? speech_lines[BB_EMOTE_CHANCE] : initial(speech_chance) + speech_chance = speech_lines[BB_SPEAK_CHANCE] ? speech_lines[BB_SPEAK_CHANCE] : initial(speech_chance) return ..() diff --git a/code/datums/ai/basic_mobs/basic_subtrees/teleport_away_from_target.dm b/code/datums/ai/basic_mobs/basic_subtrees/teleport_away_from_target.dm new file mode 100644 index 00000000000000..dadba992e9f105 --- /dev/null +++ b/code/datums/ai/basic_mobs/basic_subtrees/teleport_away_from_target.dm @@ -0,0 +1,56 @@ +///behavior to activate ability to escape from target +/datum/ai_planning_subtree/teleport_away_from_target + ///minimum distance away from the target before we execute behavior + var/minimum_distance = 2 + ///the ability we will execute + var/ability_key + +/datum/ai_planning_subtree/teleport_away_from_target/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if(!controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET)) + return + var/atom/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] + var/distance_from_target = get_dist(target, controller.pawn) + if(distance_from_target >= minimum_distance) + controller.clear_blackboard_key(BB_ESCAPE_DESTINATION) + return + var/datum/action/cooldown/ability = controller.blackboard[ability_key] + if(!ability?.IsAvailable()) + return + var/turf/location_turf = controller.blackboard[BB_ESCAPE_DESTINATION] + + if(isnull(location_turf)) + controller.queue_behavior(/datum/ai_behavior/find_furthest_turf_from_target, BB_BASIC_MOB_CURRENT_TARGET, BB_ESCAPE_DESTINATION, minimum_distance) + return SUBTREE_RETURN_FINISH_PLANNING + + if(get_dist(location_turf, target) < minimum_distance || !can_see(controller.pawn, location_turf)) //target moved close too close or we moved too far since finding the target turf + controller.clear_blackboard_key(BB_ESCAPE_DESTINATION) + return + + controller.queue_behavior(/datum/ai_behavior/targeted_mob_ability/and_clear_target, ability_key, BB_ESCAPE_DESTINATION) + +///find furtherst turf target so we may teleport to it +/datum/ai_behavior/find_furthest_turf_from_target + +/datum/ai_behavior/find_furthest_turf_from_target/perform(seconds_per_tick, datum/ai_controller/controller, target_key, set_key, range) + var/mob/living/living_target = controller.blackboard[target_key] + if(QDELETED(living_target)) + return + + var/distance = 0 + var/turf/chosen_turf + for(var/turf/open/potential_destination in oview(range, living_target)) + if(potential_destination.is_blocked_turf()) + continue + var/new_distance_to_target = get_dist(potential_destination, living_target) + if(new_distance_to_target > distance) + chosen_turf = potential_destination + distance = new_distance_to_target + if(distance == range) + break //we have already found the max distance + + if(isnull(chosen_turf)) + finish_action(controller, FALSE) + return + + controller.set_blackboard_key(set_key, chosen_turf) + finish_action(controller, TRUE) diff --git a/code/datums/ai/basic_mobs/basic_subtrees/travel_to_point.dm b/code/datums/ai/basic_mobs/basic_subtrees/travel_to_point.dm new file mode 100644 index 00000000000000..9ce7cc95c07da6 --- /dev/null +++ b/code/datums/ai/basic_mobs/basic_subtrees/travel_to_point.dm @@ -0,0 +1,18 @@ +/// Simply walk to a location +/datum/ai_planning_subtree/travel_to_point + /// Blackboard key where we travel a place we walk to + var/location_key = BB_TRAVEL_DESTINATION + /// What do we do in order to travel + var/travel_behaviour = /datum/ai_behavior/travel_towards + +/datum/ai_planning_subtree/travel_to_point/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + . = ..() + var/atom/target = controller.blackboard[location_key] + if (QDELETED(target)) + return + controller.queue_behavior(travel_behaviour, location_key) + return SUBTREE_RETURN_FINISH_PLANNING + + +/datum/ai_planning_subtree/travel_to_point/and_clear_target + travel_behaviour = /datum/ai_behavior/travel_towards/stop_on_arrival diff --git a/code/datums/ai/basic_mobs/targetting_datums/basic_targetting_datum.dm b/code/datums/ai/basic_mobs/targetting_datums/basic_targetting_datum.dm index 570088ce4d6e2c..978d7b7f8a75c2 100644 --- a/code/datums/ai/basic_mobs/targetting_datums/basic_targetting_datum.dm +++ b/code/datums/ai/basic_mobs/targetting_datums/basic_targetting_datum.dm @@ -26,7 +26,7 @@ if(isnull(our_controller)) return FALSE - if(isturf(the_target) || !the_target) // bail out on invalids + if(isturf(the_target) || isnull(the_target)) // bail out on invalids return FALSE if(isobj(the_target.loc)) @@ -35,6 +35,8 @@ return FALSE if(ismob(the_target)) //Target is in godmode, ignore it. + if(living_mob.loc == the_target) + return FALSE // We've either been eaten or are shapeshifted, let's assume the latter because we're still alive var/mob/M = the_target if(M.status_flags & GODMODE) return FALSE @@ -45,7 +47,7 @@ if(living_mob.see_invisible < the_target.invisibility) //Target's invisible to us, forget it return FALSE - if(isturf(the_target.loc) && living_mob.z != the_target.z) // z check will always fail if target is in a mech + if(isturf(living_mob.loc) && isturf(the_target.loc) && living_mob.z != the_target.z) // z check will always fail if target is in a mech or pawn is shapeshifted or jaunting return FALSE if(isliving(the_target)) //Targeting vs living mobs diff --git a/code/datums/ai/basic_mobs/targetting_datums/with_object.dm b/code/datums/ai/basic_mobs/targetting_datums/with_object.dm new file mode 100644 index 00000000000000..039027b6aa5922 --- /dev/null +++ b/code/datums/ai/basic_mobs/targetting_datums/with_object.dm @@ -0,0 +1,39 @@ +/** + * Find mobs who are holding the configurable object type + * + * This is an extension of basic targeting behaviour, that allows you to + * only target the mob if they have a specific item in their hand. + * + */ +/datum/targetting_datum/basic/holding_object + // We will find mobs who are holding this object in their hands + var/object_type_path = null + +/** + * Create an instance of the holding object targeting datum + * + * * object_type_path Pass an object type path, this will be compared to the items + * in targets hands to filter the target list. + */ +/datum/targetting_datum/basic/holding_object/New(object_type_path) + if (!ispath(object_type_path)) + stack_trace("trying to create an item targeting datum with no valid typepath") + // Leaving object type as null will make this basically a noop + return + src.object_type_path = object_type_path + +///Returns true or false depending on if the target can be attacked by the mob +/datum/targetting_datum/basic/holding_object/can_attack(mob/living/living_mob, atom/target, vision_range, check_faction = FALSE) + if (object_type_path == null) + return FALSE // no op + if(!ismob(target)) + return FALSE // no hands no problems + + // Look at me, type casting like a grown up + var/mob/targetmob = target + // Check if our parent behaviour agrees we can attack this target (we ignore faction by default) + var/can_attack = ..() + if(can_attack && targetmob.is_holding_item_of_type(object_type_path)) + return TRUE // they have the item + // No valid target + return FALSE diff --git a/code/datums/ai/dog/dog_controller.dm b/code/datums/ai/dog/dog_controller.dm index 5a42cb43a1eb2c..6883642b689184 100644 --- a/code/datums/ai/dog/dog_controller.dm +++ b/code/datums/ai/dog/dog_controller.dm @@ -20,6 +20,8 @@ BB_DOG_HARASS_HARM = TRUE, BB_VISION_RANGE = AI_DOG_VISION_RANGE, BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends(), + // Find nearby mobs with tongs in hand. + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/holding_object(/obj/item/kitchen/tongs), BB_BABIES_PARTNER_TYPES = list(/mob/living/basic/pet/dog), BB_BABIES_CHILD_TYPES = list(/mob/living/basic/pet/dog/corgi/puppy = 95, /mob/living/basic/pet/dog/corgi/puppy/void = 5), ) @@ -29,6 +31,10 @@ /datum/ai_planning_subtree/make_babies, // Ian WILL prioritise sex over following your instructions /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/dog_harassment, + // Find targets to run away from (uses the targetting datum from above) + /datum/ai_planning_subtree/simple_find_target, + // Flee from that target + /datum/ai_planning_subtree/flee_target, ) /datum/ai_controller/basic_controller/dog/corgi/get_access() diff --git a/code/datums/ai/hunting_behavior/hunting_behaviors.dm b/code/datums/ai/hunting_behavior/hunting_behaviors.dm index 036176dc85ea09..468cfed33fb98e 100644 --- a/code/datums/ai/hunting_behavior/hunting_behaviors.dm +++ b/code/datums/ai/hunting_behavior/hunting_behaviors.dm @@ -93,9 +93,7 @@ var/mob/living/hunter = controller.pawn var/atom/hunted = controller.blackboard[hunting_target_key] - if(isnull(hunted)) - //Target is gone for some reason. forget about this task! - controller[hunting_target_key] = null + if(QDELETED(hunted)) finish_action(controller, FALSE, hunting_target_key) else target_caught(hunter, hunted) @@ -136,7 +134,7 @@ /datum/ai_behavior/hunt_target/use_ability_on_target/perform(seconds_per_tick, datum/ai_controller/controller, hunting_target_key, hunting_cooldown_key) var/datum/action/cooldown/ability = controller.blackboard[ability_key] - if(QDELETED(ability) || !ability.IsAvailable()) + if(!ability?.IsAvailable()) finish_action(controller, FALSE, hunting_target_key) return ..() diff --git a/code/datums/ai/hunting_behavior/hunting_corpses.dm b/code/datums/ai/hunting_behavior/hunting_corpses.dm new file mode 100644 index 00000000000000..e720e4da947afa --- /dev/null +++ b/code/datums/ai/hunting_behavior/hunting_corpses.dm @@ -0,0 +1,17 @@ +/// Find and attack corpses +/datum/ai_planning_subtree/find_and_hunt_target/corpses + finding_behavior = /datum/ai_behavior/find_hunt_target/corpses + hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target + hunt_targets = list(/mob/living) + +/// Find nearby dead mobs +/datum/ai_behavior/find_hunt_target/corpses + +/datum/ai_behavior/find_hunt_target/corpses/valid_dinner(mob/living/source, mob/living/dinner, radius) + if (!isliving(dinner) || dinner.stat != DEAD) + return FALSE + return can_see(source, dinner, radius) + +/// Find and attack specifically human corpses +/datum/ai_planning_subtree/find_and_hunt_target/corpses/human + hunt_targets = list(/mob/living/carbon/human) diff --git a/code/datums/ai/idle_behaviors/idle_random_walk.dm b/code/datums/ai/idle_behaviors/idle_random_walk.dm index d5a3972a3d0270..d99957f419bb16 100644 --- a/code/datums/ai/idle_behaviors/idle_random_walk.dm +++ b/code/datums/ai/idle_behaviors/idle_random_walk.dm @@ -24,3 +24,44 @@ if (!controller.blackboard_key_exists(target_key)) return return ..() + +/// walk randomly however stick near a target +/datum/idle_behavior/walk_near_target + /// chance to walk + var/walk_chance = 25 + /// distance we are to target + var/minimum_distance = 20 + /// key that holds target + var/target_key + +/datum/idle_behavior/walk_near_target/perform_idle_behavior(seconds_per_tick, datum/ai_controller/controller) + . = ..() + var/mob/living/living_pawn = controller.pawn + if(LAZYLEN(living_pawn.do_afters)) + return + + if(!SPT_PROB(walk_chance, seconds_per_tick) || !(living_pawn.mobility_flags & MOBILITY_MOVE) || !isturf(living_pawn.loc) || living_pawn.pulledby) + return + + var/atom/target = controller.blackboard[target_key] + var/distance = get_dist(target, living_pawn) + if(isnull(target) || distance > minimum_distance) //if we are too far away from target, just walk randomly + var/move_dir = pick(GLOB.alldirs) + living_pawn.Move(get_step(living_pawn, move_dir), move_dir) + return + + var/list/possible_turfs = list() + for(var/direction in GLOB.alldirs) + var/turf/possible_step = get_step(living_pawn, direction) + if(get_dist(possible_step, target) > minimum_distance) + continue + if(possible_step.is_blocked_turf()) + continue + possible_turfs += possible_step + + if(!length(possible_turfs)) + return + + var/turf/picked_turf = pick(possible_turfs) + + living_pawn.Move(picked_turf, get_dir(living_pawn, picked_turf)) diff --git a/code/datums/ai/movement/ai_movement_jps.dm b/code/datums/ai/movement/ai_movement_jps.dm index 3523da7ecec22e..da46735ec363d0 100644 --- a/code/datums/ai/movement/ai_movement_jps.dm +++ b/code/datums/ai/movement/ai_movement_jps.dm @@ -2,7 +2,7 @@ * This movement datum represents smart-pathing */ /datum/ai_movement/jps - max_pathing_attempts = 4 + max_pathing_attempts = 20 /datum/ai_movement/jps/start_moving_towards(datum/ai_controller/controller, atom/current_movement_target, min_distance) . = ..() @@ -12,13 +12,13 @@ var/datum/move_loop/loop = SSmove_manager.jps_move(moving, current_movement_target, delay, - repath_delay = 2 SECONDS, + repath_delay = 0.5 SECONDS, max_path_length = AI_MAX_PATH_LENGTH, minimum_distance = controller.get_minimum_distance(), id = controller.get_access(), subsystem = SSai_movement, extra_info = controller, - initial_path = controller.blackboard[BB_PATH_TO_USE]) + ) RegisterSignal(loop, COMSIG_MOVELOOP_PREPROCESS_CHECK, PROC_REF(pre_move)) RegisterSignal(loop, COMSIG_MOVELOOP_POSTPROCESS, PROC_REF(post_move)) diff --git a/code/datums/alarm.dm b/code/datums/alarm.dm index b266362f3ca950..e25f96b95a5b0f 100644 --- a/code/datums/alarm.dm +++ b/code/datums/alarm.dm @@ -201,4 +201,5 @@ for(var/area_name as anything in alarms_of_type) var/list/alarm_packet = alarms_of_type[area_name] var/list/cameras = alarm_packet[2] - cameras -= source // REF FOUND AND CLEARED BOYSSSS + if(cameras) + cameras -= source // REF FOUND AND CLEARED BOYSSSS diff --git a/code/datums/armor/_armor.dm b/code/datums/armor/_armor.dm index c6dbf1d5fdd66c..bfd15af4189245 100644 --- a/code/datums/armor/_armor.dm +++ b/code/datums/armor/_armor.dm @@ -62,6 +62,7 @@ GLOBAL_LIST_INIT(armor_by_type, generate_armor_type_cache()) return FALSE /datum/armor/vv_get_dropdown() + SHOULD_CALL_PARENT(FALSE) return list("", "MUST MODIFY ARMOR VALUES ON THE PARENT ATOM") /datum/armor/CanProcCall(procname) diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm index 4c7b6a46100ecb..f2120505f72f4b 100644 --- a/code/datums/brain_damage/split_personality.dm +++ b/code/datums/brain_damage/split_personality.dm @@ -11,6 +11,8 @@ var/initialized = FALSE //to prevent personalities deleting themselves while we wait for ghosts var/mob/living/split_personality/stranger_backseat //there's two so they can swap without overwriting var/mob/living/split_personality/owner_backseat + ///The role to display when polling ghost + var/poll_role = "split personality" /datum/brain_trauma/severe/split_personality/on_gain() var/mob/living/M = owner @@ -33,7 +35,7 @@ /datum/brain_trauma/severe/split_personality/proc/get_ghost() set waitfor = FALSE - var/list/mob/dead/observer/candidates = poll_candidates_for_mob("Do you want to play as [owner.real_name]'s split personality?", ROLE_PAI, null, 7.5 SECONDS, stranger_backseat, POLL_IGNORE_SPLITPERSONALITY) + var/list/mob/dead/observer/candidates = poll_candidates_for_mob("Do you want to play as [owner.real_name]'s [poll_role]?", ROLE_PAI, null, 7.5 SECONDS, stranger_backseat, POLL_IGNORE_SPLITPERSONALITY) if(LAZYLEN(candidates)) var/mob/dead/observer/C = pick(candidates) stranger_backseat.key = C.key @@ -238,5 +240,53 @@ if(objective) to_chat(src, span_notice("Your master left you an objective: [objective]. Follow it at all costs when in control.")) +/datum/brain_trauma/severe/split_personality/blackout + name = "Alcohol-Induced CNS Impairment" + desc = "Patient's CNS has been temporarily impaired by imbibed alcohol, blocking memory formation, and causing reduced cognition and stupefaction." + scan_desc = "alcohol-induced CNS impairment" + gain_text = span_warning("Crap, that was one drink too many. You black out...") + lose_text = "You wake up very, very confused and hungover. All you can remember is drinking a lot of alcohol... what happened?" + poll_role = "blacked out drunkard" + /// Duration of effect, tracked in seconds, not deciseconds. qdels when reaching 0. + var/duration_in_seconds = 180 + +/datum/brain_trauma/severe/split_personality/blackout/on_gain() + . = ..() + RegisterSignal(owner, COMSIG_ATOM_SPLASHED, PROC_REF(on_splashed)) + +/datum/brain_trauma/severe/split_personality/blackout/on_lose() + . = ..() + owner.add_mood_event("hang_over", /datum/mood_event/hang_over) + UnregisterSignal(owner, COMSIG_ATOM_SPLASHED) + +/datum/brain_trauma/severe/split_personality/blackout/proc/on_splashed() + SIGNAL_HANDLER + if(prob(20))//we don't want every single splash to wake them up now do we + qdel(src) + +/datum/brain_trauma/severe/split_personality/blackout/on_life(seconds_per_tick, times_fired) + if(current_controller == OWNER) + switch_personalities() + if(owner.stat == DEAD) + if(current_controller != OWNER) + switch_personalities(TRUE) + qdel(src) + return + if(duration_in_seconds <= 0) + qdel(src) + return + duration_in_seconds -= seconds_per_tick + +/mob/living/split_personality/blackout + name = "blacked-out drunkard" + real_name = "drunken consciousness" + +/mob/living/split_personality/blackout/Login() + . = ..() + if(!. || !client) + return FALSE + to_chat(src, span_notice("You're the incredibly inebriated leftovers of your host's consciousness! Make sure to act the part and leave a trail of confusion and chaos in your wake.")) + to_chat(src, span_boldwarning("Do not commit suicide or put the body in danger, you have a minor liscense to grief just like a clown, do not kill anyone or create a situation leading to the body being in danger or in harm ways. While you're drunk, you're not suicidal.")) + #undef OWNER #undef STRANGER diff --git a/code/datums/components/bakeable.dm b/code/datums/components/bakeable.dm index 5aa60cd89a7096..b4cde3c5752e97 100644 --- a/code/datums/components/bakeable.dm +++ b/code/datums/components/bakeable.dm @@ -14,7 +14,10 @@ /// REF() to the mind which placed us in an oven var/who_baked_us -/datum/component/bakeable/Initialize(bake_result, required_bake_time, positive_result, use_large_steam_sprite) + /// Reagents that should be added to the result + var/list/added_reagents + +/datum/component/bakeable/Initialize(bake_result, required_bake_time, positive_result, use_large_steam_sprit, list/added_reagents) . = ..() if(!isitem(parent)) //Only items support baking at the moment return COMPONENT_INCOMPATIBLE @@ -22,6 +25,7 @@ src.bake_result = bake_result src.required_bake_time = required_bake_time src.positive_result = positive_result + src.added_reagents = added_reagents // Inherit the new values passed to the component /datum/component/bakeable/InheritComponent(datum/component/bakeable/new_comp, original, bake_result, required_bake_time, positive_result, use_large_steam_sprite) @@ -67,8 +71,11 @@ var/atom/original_object = parent var/obj/item/plate/oven_tray/used_tray = original_object.loc var/atom/baked_result = new bake_result(used_tray) - baked_result.reagents.clear_reagents() - original_object.reagents?.trans_to(baked_result, original_object.reagents.total_volume) + if(baked_result.reagents && positive_result) //make space and tranfer reagents if it has any & the resulting item isn't bad food or other bad baking result + baked_result.reagents.clear_reagents() + original_object.reagents.trans_to(baked_result, original_object.reagents.total_volume) + if(added_reagents) // Add any new reagents that should be added + baked_result.reagents.add_reagent_list(added_reagents) if(who_baked_us) ADD_TRAIT(baked_result, TRAIT_FOOD_CHEF_MADE, who_baked_us) diff --git a/code/datums/components/basic_inhands.dm b/code/datums/components/basic_inhands.dm new file mode 100644 index 00000000000000..ac50f618861f23 --- /dev/null +++ b/code/datums/components/basic_inhands.dm @@ -0,0 +1,50 @@ +/** + * Basic handling for showing held items in a mob's hands + */ +/datum/component/basic_inhands + /// Layer index we show our inhands upon + var/display_layer + /// Y offset to apply to inhands + var/y_offset + /// X offset to apply to inhands, is inverted for the left hand + var/x_offset + /// What overlays are we currently showing? + var/list/cached_overlays + +/datum/component/basic_inhands/Initialize(display_layer = 1, y_offset = 0, x_offset = 0) + . = ..() + if (!isliving(parent)) + return COMPONENT_INCOMPATIBLE + src.display_layer = display_layer + src.y_offset = y_offset + src.x_offset = x_offset + cached_overlays = list() + +/datum/component/basic_inhands/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_updated_overlays)) + RegisterSignal(parent, COMSIG_MOB_UPDATE_HELD_ITEMS, PROC_REF(on_updated_held_items)) + +/datum/component/basic_inhands/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, list(COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_MOB_UPDATE_HELD_ITEMS)) + +/// When your overlays update, add your held overlays +/datum/component/basic_inhands/proc/on_updated_overlays(atom/parent_atom, list/overlays) + SIGNAL_HANDLER + overlays += cached_overlays + +/// When your number of held items changes, regenerate held icons +/datum/component/basic_inhands/proc/on_updated_held_items(mob/living/holding_mob) + SIGNAL_HANDLER + var/list/held_overlays = list() + for(var/obj/item/held in holding_mob.held_items) + var/is_right = holding_mob.get_held_index_of_item(held) % 2 == 0 + var/icon_file = is_right ? held.righthand_file : held.lefthand_file + var/mutable_appearance/held_overlay = held.build_worn_icon(default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE) + held_overlay.pixel_y += y_offset + held_overlay.pixel_x += x_offset * (is_right ? 1 : -1) + held_overlays += held_overlay + + cached_overlays = held_overlays + holding_mob.update_appearance(UPDATE_OVERLAYS) diff --git a/code/datums/components/blob_minion.dm b/code/datums/components/blob_minion.dm new file mode 100644 index 00000000000000..8261a7ad1fdc3e --- /dev/null +++ b/code/datums/components/blob_minion.dm @@ -0,0 +1,154 @@ +/** + * Common behaviour shared by things which are minions to a blob + */ +/datum/component/blob_minion + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS + /// Overmind who is our boss + var/mob/camera/blob/overmind + /// Callback to run if overmind strain changes + var/datum/callback/on_strain_changed + +/datum/component/blob_minion/Initialize(mob/camera/blob/overmind, datum/callback/on_strain_changed) + . = ..() + if (!isliving(parent)) + return COMPONENT_INCOMPATIBLE + src.on_strain_changed = on_strain_changed + register_overlord(overmind) + +/datum/component/blob_minion/InheritComponent(datum/component/new_comp, i_am_original, mob/camera/blob/overmind, datum/callback/on_strain_changed) + if (!isnull(on_strain_changed)) + src.on_strain_changed = on_strain_changed + register_overlord(overmind) + +/datum/component/blob_minion/proc/register_overlord(mob/camera/blob/overmind) + if (isnull(overmind)) + return + src.overmind = overmind + overmind.register_new_minion(parent) + RegisterSignal(overmind, COMSIG_QDELETING, PROC_REF(overmind_deleted)) + RegisterSignal(overmind, COMSIG_BLOB_SELECTED_STRAIN, PROC_REF(overmind_properties_changed)) + overmind_properties_changed(overmind, overmind.blobstrain) + +/// Our overmind is gone, uh oh! +/datum/component/blob_minion/proc/overmind_deleted() + SIGNAL_HANDLER + overmind = null + overmind_properties_changed() + +/// Our overmind has changed colour and properties +/datum/component/blob_minion/proc/overmind_properties_changed(mob/camera/blob/overmind, datum/blobstrain/new_strain) + SIGNAL_HANDLER + var/mob/living/living_parent = parent + living_parent.update_appearance(UPDATE_ICON) + on_strain_changed?.Invoke(overmind, new_strain) + +/datum/component/blob_minion/RegisterWithParent() + var/mob/living/living_parent = parent + living_parent.pass_flags |= PASSBLOB + living_parent.faction |= ROLE_BLOB + ADD_TRAIT(parent, TRAIT_BLOB_ALLY, REF(src)) + remove_verb(parent, /mob/living/verb/pulled) // No dragging people into the blob + RegisterSignal(parent, COMSIG_MOB_MIND_INITIALIZED, PROC_REF(on_mind_init)) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_ICON, PROC_REF(on_update_appearance)) + RegisterSignal(parent, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(on_update_status_tab)) + RegisterSignal(parent, COMSIG_ATOM_BLOB_ACT, PROC_REF(on_blob_touched)) + RegisterSignal(parent, COMSIG_ATOM_FIRE_ACT, PROC_REF(on_burned)) + RegisterSignal(parent, COMSIG_ATOM_TRIED_PASS, PROC_REF(on_attempted_pass)) + RegisterSignal(parent, COMSIG_MOVABLE_SPACEMOVE, PROC_REF(on_space_move)) + RegisterSignal(parent, COMSIG_LIVING_TRY_SPEECH, PROC_REF(on_try_speech)) + RegisterSignal(parent, COMSIG_MOB_CHANGED_TYPE, PROC_REF(on_transformed)) + living_parent.update_appearance(UPDATE_ICON) + GLOB.blob_telepathy_mobs |= parent + +/datum/component/blob_minion/UnregisterFromParent() + if (!isnull(overmind)) + overmind.blob_mobs -= parent + var/mob/living/living_parent = parent + living_parent.pass_flags &= ~PASSBLOB + living_parent.faction -= ROLE_BLOB + REMOVE_TRAIT(parent, TRAIT_BLOB_ALLY, REF(src)) + add_verb(parent, /mob/living/verb/pulled) + UnregisterSignal(parent, list( + COMSIG_ATOM_BLOB_ACT, + COMSIG_ATOM_FIRE_ACT, + COMSIG_ATOM_TRIED_PASS, + COMSIG_ATOM_UPDATE_ICON, + COMSIG_LIVING_TRY_SPEECH, + COMSIG_MOB_CHANGED_TYPE, + COMSIG_MOB_GET_STATUS_TAB_ITEMS, + COMSIG_MOB_MIND_INITIALIZED, + COMSIG_MOVABLE_SPACEMOVE, + )) + GLOB.blob_telepathy_mobs -= parent + +/// Become blobpilled when we gain a mind +/datum/component/blob_minion/proc/on_mind_init(mob/living/minion, datum/mind/new_mind) + SIGNAL_HANDLER + if (isnull(overmind)) + return + var/datum/antagonist/blob_minion/minion_motive = new(overmind) + new_mind.add_antag_datum(minion_motive) + +/// When our icon is updated, update our colour too +/datum/component/blob_minion/proc/on_update_appearance(mob/living/minion) + SIGNAL_HANDLER + if(isnull(overmind)) + minion.remove_atom_colour(FIXED_COLOUR_PRIORITY) + return + minion.add_atom_colour(overmind.blobstrain.color, FIXED_COLOUR_PRIORITY) + +/// When our icon is updated, update our colour too +/datum/component/blob_minion/proc/on_update_status_tab(mob/living/minion, list/status_items) + SIGNAL_HANDLER + if (isnull(overmind)) + return + status_items += "Blobs to Win: [length(overmind.blobs_legit)]/[overmind.blobwincount]" + +/// If we feel the gentle caress of a blob, we feel better +/datum/component/blob_minion/proc/on_blob_touched(mob/living/minion) + SIGNAL_HANDLER + if(minion.stat == DEAD || minion.health >= minion.maxHealth) + return COMPONENT_CANCEL_BLOB_ACT // Don't hurt us in order to heal us + for(var/i in 1 to 2) + var/obj/effect/temp_visual/heal/heal_effect = new /obj/effect/temp_visual/heal(get_turf(parent)) // hello yes you are being healed + heal_effect.color = isnull(overmind) ? COLOR_BLACK : overmind.blobstrain.complementary_color + minion.heal_overall_damage(minion.maxHealth * BLOBMOB_HEALING_MULTIPLIER) + return COMPONENT_CANCEL_BLOB_ACT + +/// If we feel the fearsome bite of open flame, we feel worse +/datum/component/blob_minion/proc/on_burned(mob/living/minion, exposed_temperature, exposed_volume) + SIGNAL_HANDLER + if(isnull(exposed_temperature)) + minion.adjustFireLoss(5) + return + minion.adjustFireLoss(clamp(0.01 * exposed_temperature, 1, 5)) + +/// Someone is attempting to move through us, allow it if it is a blob tile +/datum/component/blob_minion/proc/on_attempted_pass(mob/living/minion, atom/movable/incoming) + SIGNAL_HANDLER + if(istype(incoming, /obj/structure/blob)) + return COMSIG_COMPONENT_PERMIT_PASSAGE + +/// If we're near a blob, stop drifting +/datum/component/blob_minion/proc/on_space_move(mob/living/minion) + SIGNAL_HANDLER + var/obj/structure/blob/blob_handhold = locate() in range(1, parent) + if (!isnull(blob_handhold)) + return COMSIG_MOVABLE_STOP_SPACEMOVE + +/// We only speak telepathically to blobs +/datum/component/blob_minion/proc/on_try_speech(mob/living/minion, message, ignore_spam, forced) + SIGNAL_HANDLER + var/spanned_message = minion.say_quote(message) + var/rendered = span_blob("\[Blob Telepathy\] [minion.real_name] [spanned_message]") + relay_to_list_and_observers(rendered, GLOB.blob_telepathy_mobs, minion) + return COMPONENT_CANNOT_SPEAK + +/// Called when a blob minion is transformed into something else, hopefully a spore into a zombie +/datum/component/blob_minion/proc/on_transformed(mob/living/minion, mob/living/replacement) + SIGNAL_HANDLER + overmind?.assume_direct_control(replacement) + +/datum/component/blob_minion/PostTransfer() + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm index 0ed00e7dd94ef6..689de30db378a8 100644 --- a/code/datums/components/butchering.dm +++ b/code/datums/components/butchering.dm @@ -99,50 +99,75 @@ * * Arguments: * - [butcher][/mob/living]: The mob doing the butchering - * - [meat][/mob/living]: The mob being butchered + * - [target][/mob/living]: The mob being butchered */ -/datum/component/butchering/proc/on_butchering(atom/butcher, mob/living/meat) +/datum/component/butchering/proc/on_butchering(atom/butcher, mob/living/target) var/list/results = list() - var/turf/T = meat.drop_location() - var/final_effectiveness = effectiveness - meat.butcher_difficulty + var/turf/location = target.drop_location() + var/final_effectiveness = effectiveness - target.butcher_difficulty var/bonus_chance = max(0, (final_effectiveness - 100) + bonus_modifier) //so 125 total effectiveness = 25% extra chance - for(var/V in meat.butcher_results) - var/obj/bones = V - var/amount = meat.butcher_results[bones] + + for(var/result_typepath in target.butcher_results) + var/obj/remains = result_typepath + var/amount = target.butcher_results[remains] for(var/_i in 1 to amount) if(!prob(final_effectiveness)) if(butcher) - to_chat(butcher, span_warning("You fail to harvest some of the [initial(bones.name)] from [meat].")) + to_chat(butcher, span_warning("You fail to harvest some of the [initial(remains.name)] from [target].")) continue if(prob(bonus_chance)) if(butcher) - to_chat(butcher, span_info("You harvest some extra [initial(bones.name)] from [meat]!")) - results += new bones (T) - results += new bones (T) + to_chat(butcher, span_info("You harvest some extra [initial(remains.name)] from [target]!")) + results += new remains (location) + results += new remains (location) - meat.butcher_results.Remove(bones) //in case you want to, say, have it drop its results on gib + target.butcher_results.Remove(remains) //in case you want to, say, have it drop its results on gib - for(var/V in meat.guaranteed_butcher_results) - var/obj/sinew = V - var/amount = meat.guaranteed_butcher_results[sinew] + for(var/guaranteed_result_typepath in target.guaranteed_butcher_results) + var/obj/guaranteed_remains = guaranteed_result_typepath + var/amount = target.guaranteed_butcher_results[guaranteed_remains] for(var/i in 1 to amount) - results += new sinew (T) - meat.guaranteed_butcher_results.Remove(sinew) + results += new guaranteed_remains (location) + target.guaranteed_butcher_results.Remove(guaranteed_remains) for(var/obj/item/carrion in results) var/list/meat_mats = carrion.has_material_type(/datum/material/meat) if(!length(meat_mats)) continue - carrion.set_custom_materials((carrion.custom_materials - meat_mats) + list(GET_MATERIAL_REF(/datum/material/meat/mob_meat, meat) = counterlist_sum(meat_mats))) + carrion.set_custom_materials((carrion.custom_materials - meat_mats) + list(GET_MATERIAL_REF(/datum/material/meat/mob_meat, target) = counterlist_sum(meat_mats))) + + // transfer delicious reagents to meat + if(target.reagents) + var/meat_produced = 0 + for(var/obj/item/food/meat/slab/target_meat in results) + meat_produced += 1 + for(var/obj/item/food/meat/slab/target_meat in results) + target.reagents.trans_to(target_meat, target.reagents.total_volume / meat_produced, remove_blacklisted = TRUE) + + // dont forget yummy diseases either! + if(iscarbon(target)) + var/mob/living/carbon/host_target = target + var/list/diseases = host_target.get_static_viruses() + if(LAZYLEN(diseases)) + var/list/datum/disease/diseases_to_add = list() + for(var/datum/disease/disease as anything in diseases) + // admin or special viruses that should not be reproduced + if(disease.spread_flags & (DISEASE_SPREAD_SPECIAL | DISEASE_SPREAD_NON_CONTAGIOUS)) + continue + + diseases_to_add += disease + if(LAZYLEN(diseases_to_add)) + for(var/obj/diseased_remains in results) + diseased_remains.AddComponent(/datum/component/infective, diseases_to_add) if(butcher) - butcher.visible_message(span_notice("[butcher] butchers [meat]."), \ - span_notice("You butcher [meat].")) - butcher_callback?.Invoke(butcher, meat) - meat.harvest(butcher) - meat.log_message("has been butchered by [key_name(butcher)]", LOG_ATTACK) - meat.gib(FALSE, FALSE, TRUE) + butcher.visible_message(span_notice("[butcher] butchers [target]."), \ + span_notice("You butcher [target].")) + butcher_callback?.Invoke(butcher, target) + target.harvest(butcher) + target.log_message("has been butchered by [key_name(butcher)]", LOG_ATTACK) + target.gib(DROP_BRAIN|DROP_ORGANS) ///Enables the butchering mechanic for the mob who has equipped us. /datum/component/butchering/proc/enable_butchering(datum/source) @@ -207,9 +232,9 @@ )) ///When we are ready to drill through a mob -/datum/component/butchering/mecha/proc/on_drill(datum/source, obj/vehicle/sealed/mecha/chassis, mob/living/meat) +/datum/component/butchering/mecha/proc/on_drill(datum/source, obj/vehicle/sealed/mecha/chassis, mob/living/target) SIGNAL_HANDLER - INVOKE_ASYNC(src, PROC_REF(on_butchering), chassis, meat) + INVOKE_ASYNC(src, PROC_REF(on_butchering), chassis, target) /datum/component/butchering/wearable diff --git a/code/datums/components/chasm.dm b/code/datums/components/chasm.dm index fc93123921c0dd..18420016c543fd 100644 --- a/code/datums/components/chasm.dm +++ b/code/datums/components/chasm.dm @@ -8,28 +8,29 @@ /// List of refs to falling objects -> how many levels deep we've fallen var/static/list/falling_atoms = list() var/static/list/forbidden_types = typecacheof(list( - /obj/singularity, - /obj/energy_ball, - /obj/narsie, /obj/docking_port, - /obj/structure/lattice, - /obj/structure/stone_tile, - /obj/projectile, - /obj/effect/projectile, - /obj/effect/portal, /obj/effect/abstract, + /obj/effect/collapse, + /obj/effect/constructing_effect, + /obj/effect/dummy/phased_mob, + /obj/effect/ebeam, + /obj/effect/fishing_lure, /obj/effect/hotspot, /obj/effect/landmark, - /obj/effect/temp_visual, /obj/effect/light_emitter/tendril, - /obj/effect/collapse, - /obj/effect/particle_effect/ion_trails, - /obj/effect/dummy/phased_mob, /obj/effect/mapping_helpers, + /obj/effect/particle_effect/ion_trails, + /obj/effect/portal, + /obj/effect/projectile, + /obj/effect/spectre_of_resurrection, + /obj/effect/temp_visual, /obj/effect/wisp, - /obj/effect/ebeam, - /obj/effect/fishing_lure, - /obj/effect/constructing_effect, + /obj/energy_ball, + /obj/narsie, + /obj/projectile, + /obj/singularity, + /obj/structure/lattice, + /obj/structure/stone_tile, )) /datum/component/chasm/Initialize(turf/target, mapload) diff --git a/code/datums/components/crafting/ranged_weapon.dm b/code/datums/components/crafting/ranged_weapon.dm index a8d631c6266e0e..94a943b42c8fd0 100644 --- a/code/datums/components/crafting/ranged_weapon.dm +++ b/code/datums/components/crafting/ranged_weapon.dm @@ -222,18 +222,19 @@ time = 30 SECONDS //contemplate for a bit category = CAT_WEAPON_RANGED -/datum/crafting_recipe/deagle_prime //When you factor in the makarov (7 tc), the toolbox (1 tc), and the emag (3 tc), this comes to a total of 17 TC or thereabouts. Igorning the 20k pricetag, obviously. +/datum/crafting_recipe/deagle_prime //When you factor in the makarov (7 tc), the toolbox (1 tc), and the emag (3 tc), this comes to a total of 18 TC or thereabouts. Igorning the 20k pricetag, obviously. name = "Regal Condor" always_available = FALSE - result = /obj/item/gun/ballistic/automatic/pistol/deagle/regal/no_mag + result = /obj/item/gun/ballistic/automatic/pistol/deagle/regal reqs = list( /obj/item/gun/ballistic/automatic/pistol = 1, /obj/item/stack/sheet/mineral/gold = 25, /obj/item/stack/sheet/mineral/silver = 25, /obj/item/food/donkpocket = 1, - /obj/item/stack/telecrystal = 3, + /obj/item/stack/telecrystal = 4, /obj/item/clothing/head/costume/crown/fancy = 1, //the captain's crown /obj/item/storage/toolbox/syndicate = 1, + /obj/item/stack/sheet/iron = 10, ) tool_behaviors = list(TOOL_SCREWDRIVER) tool_paths = list( @@ -249,18 +250,22 @@ blacklist += subtypesof(/obj/item/gun/ballistic/automatic/pistol) /datum/crafting_recipe/deagle_prime_mag - name = "Regal Condor Magazine (10mm)" + name = "Regal Condor Magazine (10mm Reaper)" always_available = FALSE - result = /obj/item/ammo_box/magazine/r10mm/empty + result = /obj/item/ammo_box/magazine/r10mm reqs = list( /obj/item/stack/sheet/iron = 10, - /obj/item/stack/telecrystal = 2, + /obj/item/stack/sheet/mineral/gold = 10, + /obj/item/stack/sheet/mineral/silver = 10, + /obj/item/stack/sheet/mineral/plasma = 10, + /obj/item/food/donkpocket = 1, //Station mass murder, as sponsored by Donk Co. ) tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WELDER) tool_paths = list( /obj/item/clothing/under/syndicate, /obj/item/clothing/mask/gas/syndicate, - /obj/item/card/emag + /obj/item/card/emag, + /obj/item/gun/ballistic/automatic/pistol/deagle/regal ) time = 5 SECONDS category = CAT_WEAPON_RANGED diff --git a/code/datums/components/crafting/tools.dm b/code/datums/components/crafting/tools.dm index cc2d510bd255dd..f126bdff53873b 100644 --- a/code/datums/components/crafting/tools.dm +++ b/code/datums/components/crafting/tools.dm @@ -46,3 +46,12 @@ ) result = /obj/item/pickaxe/improvised category = CAT_TOOLS + +/datum/crafting_recipe/bandage + name = "Makeshift Bandage" + reqs = list( + /obj/item/stack/sheet/cloth = 3, + /datum/reagent/medicine/c2/libital = 10, + ) + result = /obj/item/stack/medical/bandage/makeshift + category = CAT_TOOLS diff --git a/code/datums/components/cult_ritual_item.dm b/code/datums/components/cult_ritual_item.dm index 561789d1b6deeb..7565268cef6dfc 100644 --- a/code/datums/components/cult_ritual_item.dm +++ b/code/datums/components/cult_ritual_item.dm @@ -304,7 +304,7 @@ ) if(cultist.blood_volume) - cultist.apply_damage(initial(rune_to_scribe.scribe_damage), BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM), wound_bonus = CANT_WOUND) // *cuts arm* *bone explodes* ever have one of those days? + cultist.apply_damage(initial(rune_to_scribe.scribe_damage), BRUTE, pick(GLOB.arm_zones), wound_bonus = CANT_WOUND) // *cuts arm* *bone explodes* ever have one of those days? var/scribe_mod = initial(rune_to_scribe.scribe_delay) if(!initial(rune_to_scribe.no_scribe_boost) && (our_turf.type in turfs_that_boost_us)) @@ -357,7 +357,7 @@ if(!check_if_in_ritual_site(cultist, cult_team)) return FALSE var/area/summon_location = get_area(cultist) - priority_announce("Figments from an eldritch god are being summoned by [cultist.real_name] into [summon_location.get_original_area_name()] from an unknown dimension. Disrupt the ritual at all costs!", "Central Command Higher Dimensional Affairs", ANNOUNCER_SPANOMALIES, has_important_message = TRUE) + priority_announce("Figments from an eldritch god are being summoned by [cultist.real_name] into [summon_location.get_original_area_name()] from an unknown dimension. Disrupt the ritual at all costs!", "Central Command Higher Dimensional Affairs", sound = 'sound/ambience/antag/bloodcult/bloodcult_scribe.ogg', has_important_message = TRUE) for(var/shielded_turf in spiral_range_turfs(1, cultist, 1)) LAZYADD(shields, new /obj/structure/emergency_shield/cult/narsie(shielded_turf)) diff --git a/code/datums/components/damage_aura.dm b/code/datums/components/damage_aura.dm index 2438eca8d7918a..6eec1903eefc85 100644 --- a/code/datums/components/damage_aura.dm +++ b/code/datums/components/damage_aura.dm @@ -91,14 +91,16 @@ /// What effect the damage aura has if it has an owner. /datum/component/damage_aura/proc/owner_effect(mob/living/owner_mob, seconds_per_tick) - owner_mob.adjustStaminaLoss(-20 * seconds_per_tick, updating_stamina = FALSE) - owner_mob.adjustBruteLoss(-1 * seconds_per_tick, updating_health = FALSE) - owner_mob.adjustFireLoss(-1 * seconds_per_tick, updating_health = FALSE) - owner_mob.adjustToxLoss(-1 * seconds_per_tick, updating_health = FALSE, forced = TRUE) - owner_mob.adjustOxyLoss(-1 * seconds_per_tick, updating_health = FALSE) + var/need_mob_update = FALSE + need_mob_update += owner_mob.adjustStaminaLoss(-20 * seconds_per_tick, updating_stamina = FALSE) + need_mob_update += owner_mob.adjustBruteLoss(-1 * seconds_per_tick, updating_health = FALSE) + need_mob_update += owner_mob.adjustFireLoss(-1 * seconds_per_tick, updating_health = FALSE) + need_mob_update += owner_mob.adjustToxLoss(-1 * seconds_per_tick, updating_health = FALSE, forced = TRUE) + need_mob_update += owner_mob.adjustOxyLoss(-1 * seconds_per_tick, updating_health = FALSE) if (owner_mob.blood_volume < BLOOD_VOLUME_NORMAL) owner_mob.blood_volume += 2 * seconds_per_tick - owner_mob.updatehealth() + if(need_mob_update) + owner_mob.updatehealth() /datum/component/damage_aura/process(seconds_per_tick) var/should_show_effect = COOLDOWN_FINISHED(src, last_damage_effect_time) diff --git a/code/datums/components/death_linked.dm b/code/datums/components/death_linked.dm new file mode 100644 index 00000000000000..c20c810019564e --- /dev/null +++ b/code/datums/components/death_linked.dm @@ -0,0 +1,30 @@ +/** + * ## Death link component + * + * When the owner of this component dies it also gibs a linked mob + */ +/datum/component/death_linked + ///The mob that also dies when the user dies + var/datum/weakref/linked_mob + +/datum/component/death_linked/Initialize(mob/living/target_mob) + . = ..() + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + if(isnull(target_mob)) + stack_trace("[type] added to [parent] with no linked mob.") + src.linked_mob = WEAKREF(target_mob) + +/datum/component/death_linked/RegisterWithParent() + . = ..() + RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(on_death)) + +/datum/component/death_linked/UnregisterFromParent() + . = ..() + UnregisterSignal(parent, COMSIG_LIVING_DEATH) + +///signal called by the stat of the target changing +/datum/component/death_linked/proc/on_death(mob/living/target, gibbed) + SIGNAL_HANDLER + var/mob/living/linked_mob_resolved = linked_mob?.resolve() + linked_mob_resolved?.gib(DROP_ALL_REMAINS) diff --git a/code/datums/components/fishing_spot.dm b/code/datums/components/fishing_spot.dm index 3f230b8754dbe0..f88c27a7135306 100644 --- a/code/datums/components/fishing_spot.dm +++ b/code/datums/components/fishing_spot.dm @@ -12,6 +12,7 @@ fish_source = configuration else return COMPONENT_INCOMPATIBLE + fish_source.on_fishing_spot_init() RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(handle_attackby)) RegisterSignal(parent, COMSIG_FISHING_ROD_CAST, PROC_REF(handle_cast)) diff --git a/code/datums/components/focused_attacker.dm b/code/datums/components/focused_attacker.dm new file mode 100644 index 00000000000000..eda6bd1797912e --- /dev/null +++ b/code/datums/components/focused_attacker.dm @@ -0,0 +1,71 @@ +/** + * Increases our attack damage every time we attack the same target + * Not compatible with any other component or status effect which modifies attack damage + */ +/datum/component/focused_attacker + /// Amount of damage we gain per attack + var/gain_per_attack + /// Maximum amount by which we can increase our attack power + var/maximum_gain + /// The last thing we attacked + var/atom/last_target + +/datum/component/focused_attacker/Initialize(gain_per_attack = 5, maximum_gain = 25) + . = ..() + if (!isliving(parent) && !isitem(parent)) + return COMPONENT_INCOMPATIBLE + src.maximum_gain = maximum_gain + src.gain_per_attack = gain_per_attack + +/datum/component/focused_attacker/Destroy(force, silent) + if (!isnull(last_target)) + UnregisterSignal(last_target, COMSIG_QDELETING) + return ..() + +/datum/component/focused_attacker/RegisterWithParent() + if (isliving(parent)) + RegisterSignals(parent, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HUMAN_MELEE_UNARMED_ATTACK), PROC_REF(pre_mob_attack)) + else + RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(pre_item_attack)) + +/datum/component/focused_attacker/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_ITEM_PRE_ATTACK)) + +/// Before a mob attacks, try increasing its attack power +/datum/component/focused_attacker/proc/pre_mob_attack(mob/living/attacker, atom/target) + SIGNAL_HANDLER + if (isnull(target) || isturf(target)) + return + if (target == last_target) + if (attacker.melee_damage_lower - initial(attacker.melee_damage_lower) >= maximum_gain) + return + attacker.melee_damage_lower += gain_per_attack + attacker.melee_damage_upper += gain_per_attack + return + + attacker.melee_damage_lower = initial(attacker.melee_damage_lower) + attacker.melee_damage_upper = initial(attacker.melee_damage_upper) + register_new_target(target) + +/// Before an item attacks, try increasing its attack power +/datum/component/focused_attacker/proc/pre_item_attack(obj/item/weapon, atom/target, mob/user, params) + SIGNAL_HANDLER + if (target == last_target) + if (weapon.force - initial(weapon.force) < maximum_gain) + weapon.force += gain_per_attack + return + + weapon.force = initial(weapon.force) + register_new_target(target) + +/// Register a new target +/datum/component/focused_attacker/proc/register_new_target(atom/target) + if (!isnull(last_target)) + UnregisterSignal(last_target, COMSIG_QDELETING) + last_target = target + RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_target_deleted)) + +/// Drop our target ref on deletion +/datum/component/focused_attacker/proc/on_target_deleted(target) + SIGNAL_HANDLER + last_target = null diff --git a/code/datums/components/fullauto.dm b/code/datums/components/fullauto.dm index d02f090ae202fa..8663de5adc6913 100644 --- a/code/datums/components/fullauto.dm +++ b/code/datums/components/fullauto.dm @@ -8,8 +8,12 @@ var/turf/target_loc //For dealing with locking on targets due to BYOND engine limitations (the mouse input only happening when mouse moves). var/autofire_stat = AUTOFIRE_STAT_IDLE var/mouse_parameters - var/autofire_shot_delay = 0.3 SECONDS //Time between individual shots. - var/mouse_status = AUTOFIRE_MOUSEUP //This seems hacky but there can be two MouseDown() without a MouseUp() in between if the user holds click and uses alt+tab, printscreen or similar. + /// Time between individual shots. + var/autofire_shot_delay = 0.3 SECONDS + /// This seems hacky but there can be two MouseDown() without a MouseUp() in between if the user holds click and uses alt+tab, printscreen or similar. + var/mouse_status = AUTOFIRE_MOUSEUP + /// Should dual wielding be allowed? + var/allow_akimbo ///windup autofire vars ///Whether the delay between shots increases over time, simulating a spooling weapon @@ -26,7 +30,7 @@ var/timerid COOLDOWN_DECLARE(next_shot_cd) -/datum/component/automatic_fire/Initialize(autofire_shot_delay, windup_autofire, windup_autofire_reduction_multiplier, windup_autofire_cap, windup_spindown) +/datum/component/automatic_fire/Initialize(autofire_shot_delay, windup_autofire, windup_autofire_reduction_multiplier, windup_autofire_cap, windup_spindown, allow_akimbo = TRUE) . = ..() if(!isgun(parent)) return COMPONENT_INCOMPATIBLE @@ -34,6 +38,7 @@ RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(wake_up)) if(autofire_shot_delay) src.autofire_shot_delay = autofire_shot_delay + src.allow_akimbo = allow_akimbo if(windup_autofire) src.windup_autofire = windup_autofire src.windup_autofire_reduction_multiplier = windup_autofire_reduction_multiplier @@ -256,7 +261,7 @@ if(HAS_TRAIT(shooter, TRAIT_DOUBLE_TAP)) next_delay = round(next_delay * 0.5) COOLDOWN_START(src, next_shot_cd, next_delay) - if(SEND_SIGNAL(parent, COMSIG_AUTOFIRE_SHOT, target, shooter, mouse_parameters) & COMPONENT_AUTOFIRE_SHOT_SUCCESS) + if(SEND_SIGNAL(parent, COMSIG_AUTOFIRE_SHOT, target, shooter, allow_akimbo, mouse_parameters) & COMPONENT_AUTOFIRE_SHOT_SUCCESS) return TRUE stop_autofiring() return FALSE @@ -288,21 +293,21 @@ return COMPONENT_AUTOFIRE_ONMOUSEDOWN_BYPASS -/obj/item/gun/proc/do_autofire(datum/source, atom/target, mob/living/shooter, params) +/obj/item/gun/proc/do_autofire(datum/source, atom/target, mob/living/shooter, allow_akimbo, params) SIGNAL_HANDLER if(semicd || shooter.incapacitated()) return NONE if(!can_shoot()) shoot_with_empty_chamber(shooter) return NONE - INVOKE_ASYNC(src, PROC_REF(do_autofire_shot), source, target, shooter, params) + INVOKE_ASYNC(src, PROC_REF(do_autofire_shot), source, target, shooter, allow_akimbo, params) return COMPONENT_AUTOFIRE_SHOT_SUCCESS //All is well, we can continue shooting. -/obj/item/gun/proc/do_autofire_shot(datum/source, atom/target, mob/living/shooter, params) +/obj/item/gun/proc/do_autofire_shot(datum/source, atom/target, mob/living/shooter, allow_akimbo, params) var/obj/item/gun/akimbo_gun = shooter.get_inactive_held_item() var/bonus_spread = 0 - if(istype(akimbo_gun) && weapon_weight < WEAPON_MEDIUM) + if(istype(akimbo_gun) && weapon_weight < WEAPON_MEDIUM && allow_akimbo) if(akimbo_gun.weapon_weight < WEAPON_MEDIUM && akimbo_gun.can_trigger_gun(shooter)) bonus_spread = dual_wield_spread addtimer(CALLBACK(akimbo_gun, TYPE_PROC_REF(/obj/item/gun, process_fire), target, shooter, TRUE, params, null, bonus_spread), 1) diff --git a/code/datums/components/grillable.dm b/code/datums/components/grillable.dm index f1fe80fe9fb536..72c2e75e8cb0e4 100644 --- a/code/datums/components/grillable.dm +++ b/code/datums/components/grillable.dm @@ -12,11 +12,10 @@ var/use_large_steam_sprite = FALSE /// REF() to the mind which placed us on the griddle var/who_placed_us + /// Reagents that should be added to the result + var/list/added_reagents - /// What type of pollutant we spread around as we are grilleed, can be none // SKYRAT EDIT ADDITION - var/pollutant_type // SKYRAT EDIT ADDITION - -/datum/component/grillable/Initialize(cook_result, required_cook_time, positive_result, use_large_steam_sprite, pollutant_type) //SKYRAT EDIT CHANGE +/datum/component/grillable/Initialize(cook_result, required_cook_time, positive_result, use_large_steam_sprite, list/added_reagents) . = ..() if(!isitem(parent)) //Only items support grilling at the moment return COMPONENT_INCOMPATIBLE @@ -25,7 +24,7 @@ src.required_cook_time = required_cook_time src.positive_result = positive_result src.use_large_steam_sprite = use_large_steam_sprite - src.pollutant_type = pollutant_type //SKYRAT EDIT ADDITION + src.added_reagents = added_reagents /datum/component/grillable/RegisterWithParent() RegisterSignal(parent, COMSIG_ITEM_GRILL_PLACED, PROC_REF(on_grill_placed)) @@ -108,10 +107,12 @@ if(original_object.custom_materials) grilled_result.set_custom_materials(original_object.custom_materials) - if(IsEdible(grilled_result)) + if(IsEdible(grilled_result) && positive_result) BLACKBOX_LOG_FOOD_MADE(grilled_result.type) grilled_result.reagents.clear_reagents() original_object.reagents?.trans_to(grilled_result, original_object.reagents.total_volume) + if(added_reagents) // Add any new reagents that should be added + grilled_result.reagents.add_reagent_list(added_reagents) SEND_SIGNAL(parent, COMSIG_ITEM_GRILLED, grilled_result) if(who_placed_us) diff --git a/code/datums/components/healing_touch.dm b/code/datums/components/healing_touch.dm index 4b953fc6289469..029b0f660ef33f 100644 --- a/code/datums/components/healing_touch.dm +++ b/code/datums/components/healing_touch.dm @@ -32,6 +32,10 @@ var/action_text /// Text to print when action completes, replaces %SOURCE% with healer and %TARGET% with healed mob var/complete_text + /// Whether to print the target's remaining health after healing (for non-carbon targets only) + var/show_health + /// Color for the healing effect + var/heal_color /datum/component/healing_touch/Initialize( heal_brute = 20, @@ -46,6 +50,8 @@ self_targetting = HEALING_TOUCH_NOT_SELF, action_text = "%SOURCE% begins healing %TARGET%", complete_text = "%SOURCE% finishes healing %TARGET%", + show_health = FALSE, + heal_color = COLOR_HEALING_CYAN, ) if (!isliving(parent)) return COMPONENT_INCOMPATIBLE @@ -62,6 +68,8 @@ src.self_targetting = self_targetting src.action_text = action_text src.complete_text = complete_text + src.show_health = show_health + src.heal_color = heal_color RegisterSignal(parent, COMSIG_LIVING_UNARMED_ATTACK, PROC_REF(try_healing)) // Players RegisterSignal(parent, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(try_healing)) // NPCs @@ -147,7 +155,11 @@ healer.visible_message(span_notice("[format_string(complete_text, healer, target)]")) target.heal_overall_damage(brute = heal_brute, burn = heal_burn, stamina = heal_stamina, required_bodytype = required_bodytype) - new /obj/effect/temp_visual/heal(get_turf(target), COLOR_HEALING_CYAN) + new /obj/effect/temp_visual/heal(get_turf(target), heal_color) + + if(show_health && !iscarbon(target)) + var/formatted_string = format_string("%TARGET% now has [target.health]/[target.maxHealth] health.", healer, target) + healer.visible_message(span_danger(formatted_string)) /// Reformats the passed string with the replacetext keys /datum/component/healing_touch/proc/format_string(string, atom/source, atom/target) diff --git a/code/datums/components/joint_damage.dm b/code/datums/components/joint_damage.dm new file mode 100644 index 00000000000000..5397bd307cab95 --- /dev/null +++ b/code/datums/components/joint_damage.dm @@ -0,0 +1,35 @@ +/* + * A component given to mobs to damage a linked mob + */ +/datum/component/joint_damage + ///the mob we will damage + var/datum/weakref/overlord_mob + ///our last health count + var/previous_health_count + +/datum/component/joint_damage/Initialize(mob/overlord_mob) + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + var/mob/living/parent_mob = parent + previous_health_count = parent_mob.health + if(overlord_mob) + src.overlord_mob = WEAKREF(overlord_mob) + +/datum/component/joint_damage/RegisterWithParent() + RegisterSignal(parent, COMSIG_LIVING_HEALTH_UPDATE, PROC_REF(damage_overlord)) + RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(damage_overlord)) + +/datum/component/joint_damage/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_LIVING_HEALTH_UPDATE, COMSIG_LIVING_DEATH)) + +/datum/component/joint_damage/Destroy() + overlord_mob = null + return ..() + +/datum/component/joint_damage/proc/damage_overlord(mob/living/source) + SIGNAL_HANDLER + + var/mob/living/overlord_to_damage = overlord_mob?.resolve() + if(!isnull(overlord_to_damage)) + overlord_to_damage.adjustBruteLoss(previous_health_count - source.health) ///damage or heal overlord + previous_health_count = source.health diff --git a/code/datums/components/manual_heart.dm b/code/datums/components/manual_heart.dm new file mode 100644 index 00000000000000..09448acfc67229 --- /dev/null +++ b/code/datums/components/manual_heart.dm @@ -0,0 +1,179 @@ +/// If a beat is missed, how long to give before the next is missed +#define MANUAL_HEART_GRACE_PERIOD 2 SECONDS + +/** + * Manual heart pumping component. Requires the holder to pump their heart manually every + * so often or die. + * + * Mainly used by the cursed heart. + */ +/datum/component/manual_heart + /// The action for pumping your heart + var/datum/action/cooldown/manual_heart/pump_action + /// Cooldown before harm is caused to the owner + COOLDOWN_DECLARE(heart_timer) + /// If true, add a screen tint on the next process + var/add_colour = TRUE + /// How long between needed pumps; you can pump one second early + var/pump_delay = 3 SECONDS + /// How much blood volume you lose every missed pump, this is a flat amount not a percentage! + var/blood_loss = BLOOD_VOLUME_NORMAL * 0.2 // 20% of normal volume, missing five pumps is instant death + + //How much to heal per pump - negative numbers harm the owner instead + /// The amount of brute damage to heal per pump + var/heal_brute = 0 + /// The amount of burn damage to heal per pump + var/heal_burn = 0 + /// The amount of oxygen damage to heal per pump + var/heal_oxy = 0 + +/datum/component/manual_heart/Initialize(pump_delay = 3 SECONDS, blood_loss = BLOOD_VOLUME_NORMAL * 0.2, heal_brute = 0, heal_burn = 0, heal_oxy = 0) + //Non-Carbon mobs can't have hearts, and should never receive this component. + if (!iscarbon(parent)) + stack_trace("Manual Heart component added to [parent] ([parent?.type]) which is not a /mob/living/carbon subtype.") + return COMPONENT_INCOMPATIBLE + + src.pump_delay = pump_delay + src.blood_loss = blood_loss + src.heal_brute = heal_brute + src.heal_burn = heal_burn + src.heal_oxy = heal_oxy + + pump_action = new(src) + +/datum/component/manual_heart/Destroy() + QDEL_NULL(pump_action) + return ..() + +/datum/component/manual_heart/RegisterWithParent() + RegisterSignal(parent, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(check_removed_organ)) + RegisterSignal(parent, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(check_added_organ)) + RegisterSignal(parent, COMSIG_HEART_MANUAL_PULSE, PROC_REF(on_pump)) + RegisterSignals(parent, list(COMSIG_LIVING_DEATH, SIGNAL_ADDTRAIT(TRAIT_NOBLOOD)), PROC_REF(pause)) + RegisterSignals(parent, list(COMSIG_LIVING_REVIVE, SIGNAL_REMOVETRAIT(TRAIT_NOBLOOD)), PROC_REF(restart)) + + pump_action.cooldown_time = pump_delay - (1 SECONDS) //you can pump up to a second early + pump_action.Grant(parent) + + var/mob/living/carbon/carbon_parent = parent + var/obj/item/organ/internal/heart/parent_heart = carbon_parent.get_organ_slot(ORGAN_SLOT_HEART) + if(parent_heart && !HAS_TRAIT(carbon_parent, TRAIT_NOBLOOD) && carbon_parent.stat != DEAD) + START_PROCESSING(SSdcs, src) + COOLDOWN_START(src, heart_timer, pump_delay) + + to_chat(parent, span_userdanger("Your heart no longer beats automatically! You have to pump it manually - otherwise you'll die!")) + +/datum/component/manual_heart/UnregisterFromParent() + UnregisterSignal(parent, list(COMSIG_CARBON_GAIN_ORGAN, COMSIG_CARBON_LOSE_ORGAN, COMSIG_HEART_MANUAL_PULSE, COMSIG_LIVING_REVIVE, COMSIG_LIVING_DEATH, SIGNAL_ADDTRAIT(TRAIT_NOBLOOD), SIGNAL_REMOVETRAIT(TRAIT_NOBLOOD))) + + to_chat(parent, span_userdanger("You feel your heart start beating normally again!")) + var/mob/living/carbon/carbon_parent = parent + if(istype(carbon_parent)) + carbon_parent.remove_client_colour(/datum/client_colour/manual_heart_blood) + +/datum/component/manual_heart/proc/restart() + SIGNAL_HANDLER + + if(!check_valid()) + return + COOLDOWN_START(src, heart_timer, pump_delay) + pump_action.build_all_button_icons(UPDATE_BUTTON_STATUS) //make sure the action button always shows as available when it is + START_PROCESSING(SSdcs, src) + +/datum/component/manual_heart/proc/pause() + SIGNAL_HANDLER + pump_action.build_all_button_icons(UPDATE_BUTTON_STATUS) + var/mob/living/carbon/carbon_parent = parent + if(istype(carbon_parent)) + carbon_parent.remove_client_colour(/datum/client_colour/manual_heart_blood) //prevents red overlay from getting stuck + STOP_PROCESSING(SSdcs, src) + +/// Worker proc that checks logic for if a pump can happen, and applies effects from doing so +/datum/component/manual_heart/proc/on_pump(mob/owner) + COOLDOWN_START(src, heart_timer, pump_delay) + playsound(owner,'sound/effects/singlebeat.ogg', 40, TRUE) + + var/mob/living/carbon/carbon_owner = owner + + if(HAS_TRAIT(carbon_owner, TRAIT_NOBLOOD)) + return + carbon_owner.blood_volume = min(carbon_owner.blood_volume + (blood_loss * 0.5), BLOOD_VOLUME_MAXIMUM) + carbon_owner.remove_client_colour(/datum/client_colour/manual_heart_blood) + add_colour = TRUE + carbon_owner.adjustBruteLoss(-heal_brute) + carbon_owner.adjustFireLoss(-heal_burn) + carbon_owner.adjustOxyLoss(-heal_oxy) + +/datum/component/manual_heart/process() + var/mob/living/carbon/carbon_parent = parent + + //If they aren't connected, don't kill them. + if(!carbon_parent.client) + COOLDOWN_START(src, heart_timer, pump_delay) + return + + if(!COOLDOWN_FINISHED(src, heart_timer)) + return + + carbon_parent.blood_volume = max(carbon_parent.blood_volume - blood_loss, 0) + to_chat(carbon_parent, span_userdanger("You have to keep pumping your blood!")) + COOLDOWN_START(src, heart_timer, MANUAL_HEART_GRACE_PERIOD) //give two full seconds before losing more blood + if(add_colour) + carbon_parent.add_client_colour(/datum/client_colour/manual_heart_blood) + add_colour = FALSE + +///If a new heart is added, start processing. +/datum/component/manual_heart/proc/check_added_organ(mob/organ_owner, obj/item/organ/new_organ) + SIGNAL_HANDLER + + var/obj/item/organ/internal/heart/new_heart = new_organ + + if(!istype(new_heart) || !check_valid()) + return + COOLDOWN_START(src, heart_timer, pump_delay) + pump_action.build_all_button_icons(UPDATE_BUTTON_STATUS) + var/mob/living/carbon/carbon_parent = parent + if(istype(carbon_parent)) + carbon_parent.remove_client_colour(/datum/client_colour/manual_heart_blood) //prevents red overlay from getting stuck + START_PROCESSING(SSdcs, src) + +///If the heart is removed, stop processing. +/datum/component/manual_heart/proc/check_removed_organ(mob/organ_owner, obj/item/organ/removed_organ) + SIGNAL_HANDLER + + var/obj/item/organ/internal/heart/removed_heart = removed_organ + + if(istype(removed_heart)) + pump_action.build_all_button_icons(UPDATE_BUTTON_STATUS) + STOP_PROCESSING(SSdcs, src) + +///Helper proc to check if processing can be restarted. +/datum/component/manual_heart/proc/check_valid() + var/mob/living/carbon/carbon_parent = parent + var/obj/item/organ/internal/heart/parent_heart = carbon_parent.get_organ_slot(ORGAN_SLOT_HEART) + return !isnull(parent_heart) && !HAS_TRAIT(carbon_parent, TRAIT_NOBLOOD) && carbon_parent.stat != DEAD + +///Action to pump your heart. Cooldown will always be set to 1 second less than the pump delay. +/datum/action/cooldown/manual_heart + name = "Pump your blood" + cooldown_time = 2 SECONDS + check_flags = NONE + button_icon = 'icons/obj/medical/organs/organs.dmi' + button_icon_state = "cursedheart-off" + +/datum/action/cooldown/manual_heart/Activate(atom/atom_target) + . = ..() + + SEND_SIGNAL(owner, COMSIG_HEART_MANUAL_PULSE) + +///The action button is only available when you're a living carbon with blood and a heart. +/datum/action/cooldown/manual_heart/IsAvailable(feedback = FALSE) + var/mob/living/carbon/heart_haver = owner + if(!istype(heart_haver) || HAS_TRAIT(heart_haver, TRAIT_NOBLOOD) || heart_haver.stat == DEAD) + return FALSE + var/obj/item/organ/internal/heart/heart_havers_heart = heart_haver.get_organ_slot(ORGAN_SLOT_HEART) + if(isnull(heart_havers_heart)) + return FALSE + return ..() + +#undef MANUAL_HEART_GRACE_PERIOD diff --git a/code/datums/components/mob_chain.dm b/code/datums/components/mob_chain.dm new file mode 100644 index 00000000000000..8312d9d5504764 --- /dev/null +++ b/code/datums/components/mob_chain.dm @@ -0,0 +1,224 @@ +/** + * Component allowing you to create a linked list of mobs. + * These mobs will follow each other and attack as one, as well as sharing damage taken. + */ +/datum/component/mob_chain + + /// If true then damage we take is passed backwards along the line + var/pass_damage_back + /// If true then we will set our icon state based on line position + var/vary_icon_state + + /// Mob in front of us in the chain + var/mob/living/front + /// Mob behind us in the chain + var/mob/living/back + +/datum/component/mob_chain/Initialize(mob/living/front, pass_damage_back = TRUE, vary_icon_state = FALSE) + . = ..() + if (!isliving(parent)) + return COMPONENT_INCOMPATIBLE + + src.front = front + src.pass_damage_back = pass_damage_back + src.vary_icon_state = vary_icon_state + if (!isnull(front)) + SEND_SIGNAL(front, COMSIG_MOB_GAINED_CHAIN_TAIL, parent) + parent.AddComponent(/datum/component/leash, owner = front, distance = 1) // Handles catching up gracefully + var/mob/living/living_parent = parent + living_parent.set_glide_size(front.glide_size) + +/datum/component/mob_chain/Destroy(force, silent) + if (!isnull(front)) + SEND_SIGNAL(front, COMSIG_MOB_LOST_CHAIN_TAIL, parent) + front = null + back = null + return ..() + +/datum/component/mob_chain/RegisterWithParent() + RegisterSignal(parent, COMSIG_MOB_GAINED_CHAIN_TAIL, PROC_REF(on_gained_tail)) + RegisterSignal(parent, COMSIG_MOB_LOST_CHAIN_TAIL, PROC_REF(on_lost_tail)) + RegisterSignal(parent, COMSIG_MOB_CHAIN_CONTRACT, PROC_REF(on_contracted)) + RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(on_death)) + RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(on_deletion)) + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) + RegisterSignal(parent, COMSIG_ATOM_CAN_BE_PULLED, PROC_REF(on_pulled)) + RegisterSignals(parent, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HUMAN_EARLY_UNARMED_ATTACK, COMSIG_MOB_ATTACK_RANGED), PROC_REF(on_attack)) + RegisterSignal(parent, COMSIG_MOVABLE_UPDATE_GLIDE_SIZE, PROC_REF(on_glide_size_changed)) + if (vary_icon_state) + RegisterSignal(parent, COMSIG_ATOM_UPDATE_ICON_STATE, PROC_REF(on_update_icon_state)) + update_mob_appearance() + if (pass_damage_back) + RegisterSignals(parent, COMSIG_LIVING_ADJUST_STANDARD_DAMAGE_TYPES, PROC_REF(on_adjust_damage)) + RegisterSignal(parent, COMSIG_LIVING_ADJUST_STAMINA_DAMAGE, PROC_REF(on_adjust_stamina)) + RegisterSignal(parent, COMSIG_CARBON_LIMB_DAMAGED, PROC_REF(on_limb_damage)) + + var/datum/action/cooldown/worm_contract/shrink = new(parent) + shrink.Grant(parent) + +/datum/component/mob_chain/UnregisterFromParent() + UnregisterSignal(parent, list( + COMSIG_ATOM_CAN_BE_PULLED, + COMSIG_ATOM_UPDATE_ICON_STATE, + COMSIG_CARBON_LIMB_DAMAGED, + COMSIG_HUMAN_EARLY_UNARMED_ATTACK, + COMSIG_LIVING_ADJUST_BRUTE_DAMAGE, + COMSIG_LIVING_ADJUST_BURN_DAMAGE, + COMSIG_LIVING_ADJUST_CLONE_DAMAGE, + COMSIG_LIVING_DEATH, + COMSIG_LIVING_ADJUST_OXY_DAMAGE, + COMSIG_LIVING_ADJUST_STAMINA_DAMAGE, + COMSIG_LIVING_ADJUST_TOX_DAMAGE, + COMSIG_LIVING_UNARMED_ATTACK, + COMSIG_MOB_ATTACK_RANGED, + COMSIG_MOB_CHAIN_CONTRACT, + COMSIG_MOB_GAINED_CHAIN_TAIL, + COMSIG_MOB_LOST_CHAIN_TAIL, + COMSIG_MOVABLE_MOVED, + COMSIG_MOVABLE_UPDATE_GLIDE_SIZE, + COMSIG_QDELETING, + )) + qdel(parent.GetComponent(/datum/component/leash)) + var/mob/living/living_parent = parent + var/datum/action/cooldown/worm_contract/shrink = locate() in living_parent.actions + qdel(shrink) + +/// Update how we look +/datum/component/mob_chain/proc/update_mob_appearance() + if (!vary_icon_state) + return + var/mob/living/body = parent + body.update_appearance(UPDATE_ICON_STATE) + +/// Called when something sets us as IT'S front +/datum/component/mob_chain/proc/on_gained_tail(mob/living/body, mob/living/tail) + SIGNAL_HANDLER + back = tail + update_mob_appearance() + +/// Called when our tail loses its chain component +/datum/component/mob_chain/proc/on_lost_tail() + SIGNAL_HANDLER + back = null + update_mob_appearance() + +/// Called when our tail gets pulled up to our body +/datum/component/mob_chain/proc/on_contracted(mob/living/shrinking) + SIGNAL_HANDLER + if (isnull(back)) + return + back.forceMove(shrinking.loc) + var/datum/action/cooldown/worm_contract/shrink = locate() in back.actions + if (isnull(shrink)) + return + INVOKE_ASYNC(shrink, TYPE_PROC_REF(/datum/action, Trigger)) + +/// If we die so does the guy behind us, then stop following the leader +/datum/component/mob_chain/proc/on_death() + SIGNAL_HANDLER + back?.death() + qdel(src) + +/// If we get deleted so does the guy behind us +/datum/component/mob_chain/proc/on_deletion() + SIGNAL_HANDLER + QDEL_NULL(back) + front?.update_appearance(UPDATE_ICON) + +/// Pull our tail behind us when we move +/datum/component/mob_chain/proc/on_moved(mob/living/mover, turf/old_loc) + SIGNAL_HANDLER + if(isnull(back) || back.loc == old_loc) + return + back.Move(old_loc) + +/// Update our visuals based on if we have someone in front and behind +/datum/component/mob_chain/proc/on_update_icon_state(mob/living/our_mob) + SIGNAL_HANDLER + var/current_icon_state = our_mob.base_icon_state + if(isnull(front)) + current_icon_state = "[current_icon_state]_start" + else if(isnull(back)) + current_icon_state = "[current_icon_state]_end" + else + current_icon_state = "[current_icon_state]_mid" + + our_mob.icon_state = current_icon_state + if (isanimal_or_basicmob(our_mob)) + var/mob/living/basic/basic_parent = our_mob + basic_parent.icon_living = current_icon_state + +/// Do not allow someone to be pulled out of the chain +/datum/component/mob_chain/proc/on_pulled(mob/living/our_mob) + SIGNAL_HANDLER + if (!isnull(front)) + return COMSIG_ATOM_CANT_PULL + +/// Tell our tail to attack too +/datum/component/mob_chain/proc/on_attack(mob/living/our_mob, atom/target) + SIGNAL_HANDLER + if (target == back || target == front) + return COMPONENT_CANCEL_ATTACK_CHAIN + if (isnull(back) || QDELETED(target)) + return + INVOKE_ASYNC(back, TYPE_PROC_REF(/mob, ClickOn), target) + +/// Maintain glide size backwards +/datum/component/mob_chain/proc/on_glide_size_changed(mob/living/our_mob, new_size) + SIGNAL_HANDLER + back?.set_glide_size(new_size) + +/// On gain or lose stamina, adjust our tail too +/datum/component/mob_chain/proc/on_adjust_stamina(mob/living/our_mob, type, amount, forced) + SIGNAL_HANDLER + if (forced) + return + back?.adjustStaminaLoss(amount, forced = forced) + +/// On damage or heal, affect our furthest segment +/datum/component/mob_chain/proc/on_adjust_damage(mob/living/our_mob, type, amount, forced) + SIGNAL_HANDLER + if (isnull(back) || forced) + return + switch (type) + if(BRUTE) + back.adjustBruteLoss(amount, forced = forced) + if(BURN) + back.adjustFireLoss(amount, forced = forced) + if(TOX) + back.adjustToxLoss(amount, forced = forced) + if(OXY) // If all segments are suffocating we pile damage backwards until our ass starts dying forwards + back.adjustOxyLoss(amount, forced = forced) + if(CLONE) + back.adjustCloneLoss(amount, forced = forced) + return COMPONENT_IGNORE_CHANGE + +/// Special handling for if damage is delegated to a mob's limbs instead of its overall damage +/datum/component/mob_chain/proc/on_limb_damage(mob/living/our_mob, limb, brute, burn) + SIGNAL_HANDLER + if (isnull(back)) + return + if (brute != 0) + back.adjustBruteLoss(brute, updating_health = FALSE) + if (burn != 0) + back.adjustFireLoss(burn, updating_health = FALSE) + if (brute != 0 || burn != 0) + back.updatehealth() + return COMPONENT_PREVENT_LIMB_DAMAGE + +/** + * Shrink the chain of mobs into one tile. + */ +/datum/action/cooldown/worm_contract + name = "Force Contract" + desc = "Forces your body to contract onto a single tile." + background_icon_state = "bg_heretic" + overlay_icon_state = "bg_heretic_border" + button_icon = 'icons/mob/actions/actions_ecult.dmi' + button_icon_state = "worm_contract" + cooldown_time = 30 SECONDS + melee_cooldown_time = 0 SECONDS + +/datum/action/cooldown/worm_contract/Activate(atom/target) + SEND_SIGNAL(owner, COMSIG_MOB_CHAIN_CONTRACT) + StartCooldown() diff --git a/code/datums/components/omen.dm b/code/datums/components/omen.dm index 4f3b17a7473528..f499d22968dbb5 100644 --- a/code/datums/components/omen.dm +++ b/code/datums/components/omen.dm @@ -238,7 +238,7 @@ return ..() death_explode(our_guy) - our_guy.gib() + our_guy.gib(DROP_ALL_REMAINS) /** * The quirk omen. Permanent. @@ -259,7 +259,7 @@ /datum/component/omen/quirk/check_death(mob/living/our_guy) if(!iscarbon(our_guy)) - our_guy.gib() + our_guy.gib(DROP_ALL_REMAINS) return // Don't explode if buckled to a stasis bed @@ -270,7 +270,7 @@ death_explode(our_guy) var/mob/living/carbon/player = our_guy - player.spread_bodyparts(skip_head = TRUE) + player.spread_bodyparts() player.spawn_gibs() return diff --git a/code/datums/components/pet_commands/fetch.dm b/code/datums/components/pet_commands/fetch.dm index a8723f8bd4bd1a..ae33983e1d00d3 100644 --- a/code/datums/components/pet_commands/fetch.dm +++ b/code/datums/components/pet_commands/fetch.dm @@ -18,6 +18,8 @@ /datum/pet_command/point_targetting/fetch/New(mob/living/parent) . = ..() + if(isnull(parent)) + return parent.AddElement(/datum/element/ai_held_item) // We don't remove this on destroy because they might still be holding something /datum/pet_command/point_targetting/fetch/add_new_friend(mob/living/tamer) diff --git a/code/datums/components/plumbing/_plumbing.dm b/code/datums/components/plumbing/_plumbing.dm index b140b003e6c9a9..af27b4bbb4611b 100644 --- a/code/datums/components/plumbing/_plumbing.dm +++ b/code/datums/components/plumbing/_plumbing.dm @@ -73,8 +73,8 @@ /datum/component/plumbing/process() if(!demand_connects || !reagents) - STOP_PROCESSING(SSplumbing, src) - return + return PROCESS_KILL + if(reagents.total_volume < reagents.maximum_volume) for(var/D in GLOB.cardinals) if(D & demand_connects) @@ -93,23 +93,29 @@ ///called from in process(). only calls process_request(), but can be overwritten for children with special behaviour /datum/component/plumbing/proc/send_request(dir) - process_request(amount = MACHINE_REAGENT_TRANSFER, reagent = null, dir = dir) + process_request(dir = dir) ///check who can give us what we want, and how many each of them will give us -/datum/component/plumbing/proc/process_request(amount, reagent, dir) - var/list/valid_suppliers = list() +/datum/component/plumbing/proc/process_request(amount = MACHINE_REAGENT_TRANSFER, reagent, dir) + //find the duct to take from var/datum/ductnet/net if(!ducts.Find(num2text(dir))) return net = ducts[num2text(dir)] + + //find all valid suppliers in the duct + var/list/valid_suppliers = list() for(var/datum/component/plumbing/supplier as anything in net.suppliers) if(supplier.can_give(amount, reagent, net)) valid_suppliers += supplier - // Need to ask for each in turn very carefully, making sure we get the total volume. This is to avoid a division that would always round down and become 0 - var/targetVolume = reagents.total_volume + amount var/suppliersLeft = valid_suppliers.len + if(!suppliersLeft) + return + + //take an equal amount from each supplier + var/currentRequest for(var/datum/component/plumbing/give as anything in valid_suppliers) - var/currentRequest = (targetVolume - reagents.total_volume) / suppliersLeft + currentRequest = amount / suppliersLeft give.transfer_to(src, currentRequest, reagent, net) suppliersLeft-- @@ -122,7 +128,7 @@ for(var/datum/reagent/contained_reagent as anything in reagents.reagent_list) if(contained_reagent.type == reagent) return TRUE - else if(reagents.total_volume > 0) //take whatever + else if(reagents.total_volume) //take whatever return TRUE ///this is where the reagent is actually transferred and is thus the finish point of our process() @@ -132,7 +138,7 @@ if(reagent) reagents.trans_id_to(target.recipient_reagents_holder, reagent, amount) else - reagents.trans_to(target.recipient_reagents_holder, amount, round_robin = TRUE, methods = methods)//we deal with alot of precise calculations so we round_robin=TRUE. Otherwise we get floating point errors, 1 != 1 and 2.5 + 2.5 = 6 + reagents.trans_to(target.recipient_reagents_holder, amount, methods = methods) ///We create our luxurious piping overlays/underlays, to indicate where we do what. only called once if use_overlays = TRUE in Initialize() /datum/component/plumbing/proc/create_overlays(atom/movable/parent_movable, list/overlays) diff --git a/code/datums/components/plumbing/reaction_chamber.dm b/code/datums/components/plumbing/reaction_chamber.dm index c750fda714255f..f728ce315e6ee1 100644 --- a/code/datums/components/plumbing/reaction_chamber.dm +++ b/code/datums/components/plumbing/reaction_chamber.dm @@ -18,16 +18,20 @@ if(chamber.emptying) return + var/present_amount + var/diff for(var/required_reagent in chamber.required_reagents) - var/has_reagent = FALSE + //find how much amount is already present if at all + present_amount = 0 for(var/datum/reagent/containg_reagent as anything in reagents.reagent_list) if(required_reagent == containg_reagent.type) - has_reagent = TRUE - if(containg_reagent.volume + CHEMICAL_QUANTISATION_LEVEL < chamber.required_reagents[required_reagent]) - process_request(min(chamber.required_reagents[required_reagent] - containg_reagent.volume, MACHINE_REAGENT_TRANSFER) , required_reagent, dir) - return - if(!has_reagent) - process_request(min(chamber.required_reagents[required_reagent], MACHINE_REAGENT_TRANSFER), required_reagent, dir) + present_amount = containg_reagent.volume + break + + //compute how much more is needed and round it + diff = chamber.required_reagents[required_reagent] - present_amount + if(diff > CHEMICAL_QUANTISATION_LEVEL) + process_request(min(diff, MACHINE_REAGENT_TRANSFER), required_reagent, dir) return reagents.flags &= ~NO_REACT @@ -45,16 +49,15 @@ ducting_layer = SECOND_DUCT_LAYER /datum/component/plumbing/acidic_input/send_request(dir) - process_request(amount = MACHINE_REAGENT_TRANSFER, reagent = /datum/reagent/reaction_agent/acidic_buffer, dir = dir) + process_request(reagent = /datum/reagent/reaction_agent/acidic_buffer, dir = dir) ///Special connect that we currently use for reaction chambers. Being used so we can keep certain inputs separate, like into a special internal base container /datum/component/plumbing/alkaline_input demand_connects = EAST demand_color = COLOR_VIBRANT_LIME - ducting_layer = FOURTH_DUCT_LAYER /datum/component/plumbing/alkaline_input/send_request(dir) - process_request(amount = MACHINE_REAGENT_TRANSFER, reagent = /datum/reagent/reaction_agent/basic_buffer, dir = dir) + process_request(reagent = /datum/reagent/reaction_agent/basic_buffer, dir = dir) diff --git a/code/datums/components/rot.dm b/code/datums/components/rot.dm index 11c4f2cb617490..64ddde2b2db9b2 100644 --- a/code/datums/components/rot.dm +++ b/code/datums/components/rot.dm @@ -114,7 +114,7 @@ /datum/component/rot/proc/rot_react_touch(datum/source, mob/living/react_to) SIGNAL_HANDLER - rot_react(source, react_to, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + rot_react(source, react_to, pick(GLOB.arm_zones)) /// Triggered when something enters the component's parent. /datum/component/rot/proc/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) diff --git a/code/datums/components/squashable.dm b/code/datums/components/squashable.dm index 5fc489873bf2da..8174127aeb39cd 100644 --- a/code/datums/components/squashable.dm +++ b/code/datums/components/squashable.dm @@ -72,7 +72,7 @@ /datum/component/squashable/proc/Squish(mob/living/target) if(squash_flags & SQUASHED_SHOULD_BE_GIBBED) - target.gib() + target.gib(DROP_ALL_REMAINS) else target.adjustBruteLoss(squash_damage) diff --git a/code/datums/components/stationstuck.dm b/code/datums/components/stationstuck.dm index 63a1dcabbbd19e..5634186f04e02c 100644 --- a/code/datums/components/stationstuck.dm +++ b/code/datums/components/stationstuck.dm @@ -49,7 +49,7 @@ It has a punishment variable that is what happens to the parent when they leave escapee.death() if(PUNISHMENT_GIB) escapee.investigate_log("has been gibbed by stationstuck component.", INVESTIGATE_DEATHS) - escapee.gib() + escapee.gib(DROP_ALL_REMAINS) if(PUNISHMENT_TELEPORT) var/targetturf = find_safe_turf(stuck_zlevel) if(!targetturf) diff --git a/code/datums/components/supermatter_crystal.dm b/code/datums/components/supermatter_crystal.dm index a9bdfc5b1549ed..38968d1e3d1f5d 100644 --- a/code/datums/components/supermatter_crystal.dm +++ b/code/datums/components/supermatter_crystal.dm @@ -4,6 +4,11 @@ var/datum/callback/tool_act_callback ///Callback used by the SM to get the damage and matter power increase/decrease var/datum/callback/consume_callback + // A whitelist of items that can interact with the SM without dusting the user + var/static/list/sm_item_whitelist = typecacheof(list( + /obj/item/melee/roastingstick, + /obj/item/toy/crayon/spraycan + )) /datum/component/supermatter_crystal/Initialize(datum/callback/tool_act_callback, datum/callback/consume_callback) @@ -15,8 +20,10 @@ RegisterSignal(parent, COMSIG_ATOM_ATTACK_HAND, PROC_REF(hand_hit)) RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(attackby_hit)) RegisterSignal(parent, COMSIG_ATOM_TOOL_ACT(TOOL_WRENCH), PROC_REF(tool_hit)) + RegisterSignal(parent, COMSIG_ATOM_SECONDARY_TOOL_ACT(TOOL_WRENCH), PROC_REF(tool_hit)) RegisterSignal(parent, COMSIG_ATOM_BUMPED, PROC_REF(bumped_hit)) RegisterSignal(parent, COMSIG_ATOM_INTERCEPT_Z_FALL, PROC_REF(intercept_z_fall)) + RegisterSignal(parent, COMSIG_ATOM_ON_Z_IMPACT, PROC_REF(on_z_impact)) src.tool_act_callback = tool_act_callback src.consume_callback = consume_callback @@ -36,8 +43,10 @@ COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACKBY, COMSIG_ATOM_TOOL_ACT(TOOL_WRENCH), + COMSIG_ATOM_SECONDARY_TOOL_ACT(TOOL_WRENCH), COMSIG_ATOM_BUMPED, COMSIG_ATOM_INTERCEPT_Z_FALL, + COMSIG_ATOM_ON_Z_IMPACT, ) UnregisterSignal(parent, signals_to_remove) @@ -150,7 +159,7 @@ var/atom/atom_source = source if(!istype(item) || (item.item_flags & ABSTRACT) || !istype(user)) return - if(istype(item, /obj/item/melee/roastingstick)) + if(is_type_in_typecache(item, sm_item_whitelist)) return FALSE if(istype(item, /obj/item/clothing/mask/cigarette)) var/obj/item/clothing/mask/cigarette/cig = item @@ -232,11 +241,36 @@ /datum/component/supermatter_crystal/proc/intercept_z_fall(datum/source, list/falling_movables, levels) SIGNAL_HANDLER for(var/atom/movable/hit_object as anything in falling_movables) - if(hit_object == source) - continue + if(parent == hit_object) + return + bumped_hit(parent, hit_object) return FALL_INTERCEPTED | FALL_NO_MESSAGE +/datum/component/supermatter_crystal/proc/on_z_impact(datum/source, turf/impacted_turf, levels) + SIGNAL_HANDLER + + var/atom/atom_source = source + + for(var/mob/living/poor_target in impacted_turf) + consume(atom_source, poor_target) + playsound(get_turf(atom_source), 'sound/effects/supermatter.ogg', 50, TRUE) + poor_target.visible_message(span_danger("\The [atom_source] slams into \the [poor_target] out of nowhere inducing a resonance... [poor_target.p_their()] body starts to glow and burst into flames before flashing into dust!"), + span_userdanger("\The [atom_source] slams into you out of nowhere as your ears are filled with unearthly ringing. Your last thought is \"The fuck.\""), + span_hear("You hear an unearthly noise as a wave of heat washes over you.")) + + for(var/atom/movable/hit_object as anything in impacted_turf) + if(parent == hit_object) + return + + if(iseffect(hit_object)) + continue + + consume(atom_source, hit_object) + playsound(get_turf(atom_source), 'sound/effects/supermatter.ogg', 50, TRUE) + atom_source.visible_message(span_danger("\The [atom_source], smacks into the plating out of nowhere, reducing everything below to ash."), null, + span_hear("You hear a loud crack as you are washed with a wave of heat.")) + /datum/component/supermatter_crystal/proc/dust_mob(datum/source, mob/living/nom, vis_msg, mob_msg, cause) if(nom.incorporeal_move || nom.status_flags & GODMODE) //try to keep supermatter sliver's + hemostat's dust conditions in sync with this too return diff --git a/code/datums/components/tackle.dm b/code/datums/components/tackle.dm index 4ae3a973d7ee18..a5b5606bf724cb 100644 --- a/code/datums/components/tackle.dm +++ b/code/datums/components/tackle.dm @@ -445,7 +445,7 @@ if(86 to 92) user.visible_message(span_danger("[user] slams head-first into [hit], suffering major cranial trauma!"), span_userdanger("You slam head-first into [hit], and the world explodes around you!")) - user.adjustStaminaLoss(30, updating_stamina=FALSE) + user.adjustStaminaLoss(30, updating_stamina = FALSE) user.adjustBruteLoss(30) user.adjust_confusion(15 SECONDS) if(prob(80)) @@ -457,7 +457,7 @@ if(68 to 85) user.visible_message(span_danger("[user] slams hard into [hit], knocking [user.p_them()] senseless!"), span_userdanger("You slam hard into [hit], knocking yourself senseless!")) - user.adjustStaminaLoss(30, updating_stamina=FALSE) + user.adjustStaminaLoss(30, updating_stamina = FALSE) user.adjustBruteLoss(10) user.adjust_confusion(10 SECONDS) user.Knockdown(3 SECONDS) @@ -465,7 +465,7 @@ if(1 to 67) user.visible_message(span_danger("[user] slams into [hit]!"), span_userdanger("You slam into [hit]!")) - user.adjustStaminaLoss(20, updating_stamina=FALSE) + user.adjustStaminaLoss(20, updating_stamina = FALSE) user.adjustBruteLoss(10) user.Knockdown(2 SECONDS) shake_camera(user, 2, 2) @@ -545,10 +545,11 @@ HOW_big_of_a_miss_did_we_just_make = ", making a ginormous mess!" // an extra exclamation point!! for emphasis!!! owner.visible_message(span_danger("[owner] trips over [kevved] and slams into it face-first[HOW_big_of_a_miss_did_we_just_make]!"), span_userdanger("You trip over [kevved] and slam into it face-first[HOW_big_of_a_miss_did_we_just_make]!")) - owner.adjustStaminaLoss(15 + messes.len * 2, FALSE) - owner.adjustBruteLoss(8 + messes.len) + owner.adjustStaminaLoss(15 + messes.len * 2, updating_stamina = FALSE) + owner.adjustBruteLoss(8 + messes.len, updating_health = FALSE) owner.Paralyze(0.4 SECONDS * messes.len) // .4 seconds of paralyze for each thing you knock around owner.Knockdown(2 SECONDS + 0.4 SECONDS * messes.len) // 2 seconds of knockdown after the paralyze + owner.updatehealth() for(var/obj/item/I in messes) var/dist = rand(1, 3) diff --git a/code/datums/components/temporary_description.dm b/code/datums/components/temporary_description.dm new file mode 100644 index 00000000000000..1ff5e6dccdba3d --- /dev/null +++ b/code/datums/components/temporary_description.dm @@ -0,0 +1,44 @@ +/** + * Adds examine text to something which is removed when receiving specified signals, by default the revive signal. + * The default settings are set up to be applied to a corpse to add some kind of immersive storytelling text which goes away upon revival. + */ +/datum/component/temporary_description + /// What do we display on examine? + var/description_text = "" + /// What do we display if examined by a clown? Usually only applied if this is put on a corpse, but go nuts. + var/naive_description = "" + /// When are we removed? + var/list/removal_signals + +/datum/component/temporary_description/Initialize( + description_text = "There's something unusual about them.", + naive_description = "", + list/removal_signals = list(COMSIG_LIVING_REVIVE), +) + . = ..() + if (!isatom(parent)) + return COMPONENT_INCOMPATIBLE + if (!description_text) + stack_trace("[type] applied to [parent] with empty description, which is pointless.") + src.description_text = description_text + src.naive_description = naive_description + if (length(removal_signals)) + src.removal_signals = removal_signals + +/datum/component/temporary_description/RegisterWithParent() + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examined)) + RegisterSignals(parent, removal_signals, PROC_REF(remove_component)) + +/datum/component/temporary_description/UnregisterFromParent() + UnregisterSignal(parent, removal_signals + COMSIG_ATOM_EXAMINE) + +/datum/component/temporary_description/proc/on_examined(atom/corpse, mob/thing_inspector, list/examine_list) + SIGNAL_HANDLER + if (naive_description && HAS_MIND_TRAIT(thing_inspector, TRAIT_NAIVE)) + examine_list += span_notice(naive_description) + return + examine_list += span_notice(description_text) + +/datum/component/temporary_description/proc/remove_component() + SIGNAL_HANDLER + qdel(src) // It wouldn't be immersive if the circumstances of my grisly death remained after I was revived diff --git a/code/datums/components/tippable.dm b/code/datums/components/tippable.dm index eafb234581812f..ee1f2c40547399 100644 --- a/code/datums/components/tippable.dm +++ b/code/datums/components/tippable.dm @@ -133,6 +133,8 @@ /datum/component/tippable/proc/do_tip(mob/living/tipped_mob, mob/tipper) if(QDELETED(tipped_mob)) CRASH("Tippable component: do_tip() called with QDELETED tipped_mob!") + if (is_tipped) // sanity check in case multiple people try to tip at the same time + return to_chat(tipper, span_warning("You tip over [tipped_mob].")) if (!isnull(tipped_mob.client)) @@ -185,6 +187,8 @@ /datum/component/tippable/proc/do_untip(mob/living/tipped_mob, mob/untipper) if(QDELETED(tipped_mob)) return + if (!is_tipped) // sanity check in case multiple people try to untip at the same time + return to_chat(untipper, span_notice("You right [tipped_mob].")) tipped_mob.visible_message( diff --git a/code/datums/components/tree_climber.dm b/code/datums/components/tree_climber.dm index b3c70153c719cd..9f506ae516f8ac 100644 --- a/code/datums/components/tree_climber.dm +++ b/code/datums/components/tree_climber.dm @@ -12,6 +12,8 @@ return COMPONENT_INCOMPATIBLE src.climbing_distance = climbing_distance + ADD_TRAIT(parent, TRAIT_SUBTREE_REQUIRED_OPERATIONAL_DATUM, type) + /datum/component/tree_climber/RegisterWithParent() RegisterSignals(parent, list(COMSIG_HOSTILE_PRE_ATTACKINGTARGET, COMSIG_LIVING_CLIMB_TREE), PROC_REF(climb_tree)) RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) diff --git a/code/datums/components/wall_mounted.dm b/code/datums/components/wall_mounted.dm index 6164d39b001663..8d1722f89feb80 100644 --- a/code/datums/components/wall_mounted.dm +++ b/code/datums/components/wall_mounted.dm @@ -17,7 +17,7 @@ /datum/component/wall_mounted/RegisterWithParent() RegisterSignal(hanging_wall_turf, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) - RegisterSignal(hanging_wall_turf, COMSIG_TURF_CHANGE, PROC_REF(drop_wallmount)) + RegisterSignal(hanging_wall_turf, COMSIG_TURF_CHANGE, PROC_REF(on_turf_changing)) RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(drop_wallmount)) RegisterSignal(parent, COMSIG_QDELETING, PROC_REF(on_linked_destroyed)) @@ -41,6 +41,14 @@ SIGNAL_HANDLER examine_list += span_notice("\The [hanging_wall_turf] is currently supporting [span_bold("[parent]")]. Deconstruction or excessive damage would cause it to [span_bold("fall to the ground")].") +/** + * When the type of turf changes, if it is changing into a floor we should drop our contents + */ +/datum/component/wall_mounted/proc/on_turf_changing(datum/source, path, new_baseturfs, flags, post_change_callbacks) + SIGNAL_HANDLER + if (ispath(path, /turf/open)) + drop_wallmount() + /** * Handles the dropping of the linked object. This is done via deconstruction, as that should be the most sane way to handle it for most objects. * Except for intercoms, which are handled by creating a new wallframe intercom, as they're apparently items. diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index b8f26a89b3cb43..aeea8b22cbaabb 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -4,7 +4,8 @@ /datum/proc/can_vv_get(var_name) return TRUE -/datum/proc/vv_edit_var(var_name, var_value) //called whenever a var is edited +/// Called when a var is edited with the new value to change to +/datum/proc/vv_edit_var(var_name, var_value) if(var_name == NAMEOF(src, vars)) return FALSE vars[var_name] = var_value @@ -20,9 +21,14 @@ /datum/proc/can_vv_mark() return TRUE -//please call . = ..() first and append to the result, that way parent items are always at the top and child items are further down -//add separaters by doing . += "---" +/** + * Gets all the dropdown options in the vv menu. + * When overriding, make sure to call . = ..() first and appent to the result, that way parent items are always at the top and child items are further down. + * Add seperators by doing VV_DROPDOWN_OPTION("", "---") + */ /datum/proc/vv_get_dropdown() + SHOULD_CALL_PARENT(TRUE) + . = list() VV_DROPDOWN_OPTION("", "---") VV_DROPDOWN_OPTION(VV_HK_CALLPROC, "Call Proc") @@ -35,9 +41,11 @@ VV_DROPDOWN_OPTION(VV_HK_MASS_REMOVECOMPONENT, "Mass Remove Component/Element") VV_DROPDOWN_OPTION(VV_HK_MODIFY_TRAITS, "Modify Traits") -//This proc is only called if everything topic-wise is verified. The only verifications that should happen here is things like permission checks! -//href_list is a reference, modifying it in these procs WILL change the rest of the proc in topic.dm of admin/view_variables! -//This proc is for "high level" actions like admin heal/set species/etc/etc. The low level debugging things should go in admin/view_variables/topic_basic.dm incase this runtimes. +/** + * This proc is only called if everything topic-wise is verified. The only verifications that should happen here is things like permission checks! + * href_list is a reference, modifying it in these procs WILL change the rest of the proc in topic.dm of admin/view_variables! + * This proc is for "high level" actions like admin heal/set species/etc/etc. The low level debugging things should go in admin/view_variables/topic_basic.dm incase this runtimes. + */ /datum/proc/vv_do_topic(list/href_list) if(!usr || !usr.client || !usr.client.holder || !check_rights(NONE)) return FALSE //This is VV, not to be called by anything else. diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm index 8754eb3b71d43b..55e2cdd6c656b9 100644 --- a/code/datums/diseases/advance/symptoms/heal.dm +++ b/code/datums/diseases/advance/symptoms/heal.dm @@ -161,8 +161,8 @@ if(!parts.len) return - for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len, BODYTYPE_ORGANIC)) + for(var/obj/item/bodypart/bodypart in parts) + if(bodypart.heal_damage(heal_amt/parts.len, heal_amt/parts.len, required_bodytype = BODYTYPE_ORGANIC)) M.update_damage_overlays() return 1 @@ -303,8 +303,8 @@ if(prob(5)) to_chat(M, span_notice("The darkness soothes and mends your wounds.")) - for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len * 0.5, BODYTYPE_ORGANIC)) //more effective on brute + for(var/obj/item/bodypart/bodypart in parts) + if(bodypart.heal_damage(heal_amt/parts.len, heal_amt/parts.len * 0.5, required_bodytype = BODYTYPE_ORGANIC)) //more effective on brute M.update_damage_overlays() return 1 @@ -405,8 +405,8 @@ if(!parts.len) return - for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len, BODYTYPE_ORGANIC)) + for(var/obj/item/bodypart/bodypart in parts) + if(bodypart.heal_damage(heal_amt/parts.len, heal_amt/parts.len, required_bodytype = BODYTYPE_ORGANIC)) M.update_damage_overlays() if(active_coma && M.getBruteLoss() + M.getFireLoss() == 0) @@ -469,8 +469,8 @@ if(prob(5)) to_chat(M, span_notice("You feel yourself absorbing the water around you to soothe your damaged skin.")) - for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len * 0.5, heal_amt/parts.len, BODYTYPE_ORGANIC)) + for(var/obj/item/bodypart/bodypart in parts) + if(bodypart.heal_damage(heal_amt/parts.len * 0.5, heal_amt/parts.len, required_bodytype = BODYTYPE_ORGANIC)) M.update_damage_overlays() return 1 @@ -592,8 +592,8 @@ return if(prob(5)) to_chat(M, span_notice("The pain from your wounds fades rapidly.")) - for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len, BODYTYPE_ORGANIC)) + for(var/obj/item/bodypart/bodypart in parts) + if(bodypart.heal_damage(heal_amt/parts.len, heal_amt/parts.len, required_bodytype = BODYTYPE_ORGANIC)) M.update_damage_overlays() return 1 @@ -637,10 +637,13 @@ /datum/symptom/heal/radiation/Heal(mob/living/carbon/M, datum/disease/advance/A, actual_power) var/heal_amt = actual_power + var/need_mob_update = FALSE if(cellular_damage) - M.adjustCloneLoss(-heal_amt * 0.5) + need_mob_update += M.adjustCloneLoss(-heal_amt * 0.5, updating_health = FALSE) - M.adjustToxLoss(-(2 * heal_amt)) + need_mob_update += M.adjustToxLoss(-(2 * heal_amt), updating_health = FALSE) + if(need_mob_update) + M.updatehealth() var/list/parts = M.get_damaged_bodyparts(1,1, BODYTYPE_ORGANIC) @@ -650,8 +653,8 @@ if(prob(4)) to_chat(M, span_notice("Your skin glows faintly, and you feel your wounds mending themselves.")) - for(var/obj/item/bodypart/L in parts) - if(L.heal_damage(heal_amt/parts.len, heal_amt/parts.len, BODYTYPE_ORGANIC)) + for(var/obj/item/bodypart/bodypart in parts) + if(bodypart.heal_damage(heal_amt/parts.len, heal_amt/parts.len, required_bodytype = BODYTYPE_ORGANIC)) M.update_damage_overlays() return 1 diff --git a/code/datums/diseases/advance/symptoms/oxygen.dm b/code/datums/diseases/advance/symptoms/oxygen.dm index 89da211b06b99a..fad70aff23f72e 100644 --- a/code/datums/diseases/advance/symptoms/oxygen.dm +++ b/code/datums/diseases/advance/symptoms/oxygen.dm @@ -38,8 +38,8 @@ var/mob/living/carbon/infected_mob = advanced_disease.affected_mob switch(advanced_disease.stage) if(4, 5) - infected_mob.adjustOxyLoss(-7, 0) infected_mob.losebreath = max(0, infected_mob.losebreath - 4) + infected_mob.adjustOxyLoss(-7) if(regenerate_blood && infected_mob.blood_volume < BLOOD_VOLUME_NORMAL) infected_mob.blood_volume += 1 else diff --git a/code/datums/diseases/chronic_illness.dm b/code/datums/diseases/chronic_illness.dm index 77c162d6d85c30..129883c17b5f0f 100644 --- a/code/datums/diseases/chronic_illness.dm +++ b/code/datums/diseases/chronic_illness.dm @@ -31,19 +31,23 @@ to_chat(affected_mob, span_notice("You look at your hand. Your vision blurs.")) affected_mob.set_eye_blur_if_lower(10 SECONDS) if(3) + var/need_mob_update = FALSE if(SPT_PROB(0.5, seconds_per_tick)) to_chat(affected_mob, span_danger("You feel a very sharp pain in your chest!")) if(prob(45)) affected_mob.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 20) if(SPT_PROB(0.5, seconds_per_tick)) to_chat(affected_mob, span_userdanger("[pick("You feel your heart slowing...", "You relax and slow your heartbeat.")]")) - affected_mob.adjustStaminaLoss(70, FALSE) + need_mob_update += affected_mob.adjustStaminaLoss(70, updating_stamina = FALSE) if(SPT_PROB(1, seconds_per_tick)) to_chat(affected_mob, span_danger("You feel a buzzing in your brain.")) SEND_SOUND(affected_mob, sound('sound/weapons/flash_ring.ogg')) if(SPT_PROB(0.5, seconds_per_tick)) - affected_mob.adjustBruteLoss(1) + need_mob_update += affected_mob.adjustBruteLoss(1, updating_health = FALSE) + if(need_mob_update) + affected_mob.updatehealth() if(4) + var/need_mob_update = FALSE if(prob(30)) affected_mob.playsound_local(affected_mob, 'sound/effects/singlebeat.ogg', 100, FALSE, use_reverb = FALSE) if(SPT_PROB(1, seconds_per_tick)) @@ -51,7 +55,7 @@ if(prob(75)) affected_mob.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 45) if(SPT_PROB(1, seconds_per_tick)) - affected_mob.adjustStaminaLoss(100, FALSE) + need_mob_update += affected_mob.adjustStaminaLoss(100, updating_stamina = FALSE) affected_mob.visible_message(span_warning("[affected_mob] collapses!")) if(prob(30)) to_chat(affected_mob, span_danger("Your vision blurs as you faint!")) @@ -59,7 +63,9 @@ if(SPT_PROB(0.5, seconds_per_tick)) to_chat(affected_mob, span_danger("[pick("You feel as though your atoms are accelerating in place.", "You feel like you're being torn apart!")]")) affected_mob.emote("scream") - affected_mob.adjustBruteLoss(10) + need_mob_update += affected_mob.adjustBruteLoss(10, updating_health = FALSE) + if(need_mob_update) + affected_mob.updatehealth() if(5) switch(rand(1,2)) if(1) diff --git a/code/datums/diseases/gbs.dm b/code/datums/diseases/gbs.dm index 22f84cf73a1f40..abf2116a92f062 100644 --- a/code/datums/diseases/gbs.dm +++ b/code/datums/diseases/gbs.dm @@ -30,5 +30,5 @@ to_chat(affected_mob, span_userdanger("Your body feels as if it's trying to rip itself apart!")) if(SPT_PROB(30, seconds_per_tick)) affected_mob.investigate_log("has been gibbed by GBS.", INVESTIGATE_DEATHS) - affected_mob.gib() + affected_mob.gib(DROP_ALL_REMAINS) return FALSE diff --git a/code/datums/diseases/rhumba_beat.dm b/code/datums/diseases/rhumba_beat.dm index 01188137915fbf..e64002ab528f7c 100644 --- a/code/datums/diseases/rhumba_beat.dm +++ b/code/datums/diseases/rhumba_beat.dm @@ -18,7 +18,7 @@ switch(stage) if(2) if(SPT_PROB(26, seconds_per_tick)) - affected_mob.adjustFireLoss(5, FALSE) + affected_mob.adjustFireLoss(5) if(SPT_PROB(0.5, seconds_per_tick)) to_chat(affected_mob, span_danger("You feel strange...")) if(3) diff --git a/code/datums/diseases/tuberculosis.dm b/code/datums/diseases/tuberculosis.dm index dd75ea7cc62c7b..de87cab6f3f673 100644 --- a/code/datums/diseases/tuberculosis.dm +++ b/code/datums/diseases/tuberculosis.dm @@ -28,23 +28,27 @@ if(SPT_PROB(2.5, seconds_per_tick)) to_chat(affected_mob, span_danger("You feel a cold sweat form.")) if(4) + var/need_mob_update = FALSE if(SPT_PROB(1, seconds_per_tick)) to_chat(affected_mob, span_userdanger("You see four of everything!")) affected_mob.set_dizzy_if_lower(10 SECONDS) if(SPT_PROB(1, seconds_per_tick)) to_chat(affected_mob, span_danger("You feel a sharp pain from your lower chest!")) - affected_mob.adjustOxyLoss(5, FALSE) + need_mob_update += affected_mob.adjustOxyLoss(5, updating_health = FALSE) affected_mob.emote("gasp") if(SPT_PROB(5, seconds_per_tick)) to_chat(affected_mob, span_danger("You feel air escape from your lungs painfully.")) - affected_mob.adjustOxyLoss(25, FALSE) + need_mob_update += affected_mob.adjustOxyLoss(25, updating_health = FALSE) affected_mob.emote("gasp") + if(need_mob_update) + affected_mob.updatehealth() if(5) + var/need_mob_update = FALSE if(SPT_PROB(1, seconds_per_tick)) to_chat(affected_mob, span_userdanger("[pick("You feel your heart slowing...", "You relax and slow your heartbeat.")]")) - affected_mob.adjustStaminaLoss(70, FALSE) + need_mob_update += affected_mob.adjustStaminaLoss(70, updating_stamina = FALSE) if(SPT_PROB(5, seconds_per_tick)) - affected_mob.adjustStaminaLoss(100, FALSE) + need_mob_update += affected_mob.adjustStaminaLoss(100, updating_stamina = FALSE) affected_mob.visible_message(span_warning("[affected_mob] faints!"), span_userdanger("You surrender yourself and feel at peace...")) affected_mob.AdjustSleeping(100) if(SPT_PROB(1, seconds_per_tick)) @@ -59,3 +63,5 @@ if(SPT_PROB(7.5, seconds_per_tick)) to_chat(affected_mob, span_danger("[pick("You feel uncomfortably hot...", "You feel like unzipping your jumpsuit...", "You feel like taking off some clothes...")]")) affected_mob.adjust_bodytemperature(40) + if(need_mob_update) + affected_mob.updatehealth() diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 5034a863f5619c..785b70eb4759ab 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -927,7 +927,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) switch(rand(0,6)) if(0) investigate_log("has been gibbed by DNA instability.", INVESTIGATE_DEATHS) - gib() + gib(DROP_ALL_REMAINS) if(1) investigate_log("has been dusted by DNA instability.", INVESTIGATE_DEATHS) dust() @@ -943,7 +943,7 @@ GLOBAL_LIST_INIT(total_uf_len_by_block, populate_total_uf_len_by_block()) BP.dismember() else investigate_log("has been gibbed by DNA instability.", INVESTIGATE_DEATHS) - gib() + gib(DROP_ALL_REMAINS) else set_species(/datum/species/dullahan) if(4) diff --git a/code/datums/elements/ai_flee_while_injured.dm b/code/datums/elements/ai_flee_while_injured.dm index fc1a2e33281684..0bbc08eb88bffd 100644 --- a/code/datums/elements/ai_flee_while_injured.dm +++ b/code/datums/elements/ai_flee_while_injured.dm @@ -32,14 +32,14 @@ return var/current_health_percentage = source.health / source.maxHealth - if (source.ai_controller.blackboard[BB_BASIC_MOB_FLEEING]) - if (current_health_percentage < stop_fleeing_at) + if (source.ai_controller.blackboard[BB_BASIC_MOB_STOP_FLEEING]) + if (current_health_percentage > start_fleeing_below) return - source.ai_controller.CancelActions() // Stop fleeing go back to whatever you were doing - source.ai_controller.set_blackboard_key(BB_BASIC_MOB_FLEEING, FALSE) + source.ai_controller.CancelActions() + source.ai_controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, FALSE) return - if (current_health_percentage > start_fleeing_below) + if (current_health_percentage < stop_fleeing_at) return - source.ai_controller.CancelActions() - source.ai_controller.set_blackboard_key(BB_BASIC_MOB_FLEEING, TRUE) + source.ai_controller.CancelActions() // Stop fleeing go back to whatever you were doing + source.ai_controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, TRUE) diff --git a/code/datums/elements/amputating_limbs.dm b/code/datums/elements/amputating_limbs.dm index c2fe7c454a96e0..16a99e96f6c197 100644 --- a/code/datums/elements/amputating_limbs.dm +++ b/code/datums/elements/amputating_limbs.dm @@ -1,4 +1,4 @@ -/// This component will intercept bare-handed attacks by the owner on critically injured carbons and amputate random limbs instead +/// This component will intercept bare-handed attacks by the owner on sufficiently injured carbons and amputate random limbs instead /datum/element/amputating_limbs element_flags = ELEMENT_BESPOKE argument_hash_start_idx = 2 @@ -6,6 +6,10 @@ var/surgery_time /// What is the means by which we describe the act of amputation? var/surgery_verb + /// How awake must our target be? + var/minimum_stat + /// How likely are we to perform this action? + var/snip_chance /// The types of limb we can remove var/list/target_zones @@ -13,6 +17,8 @@ datum/target, surgery_time = 5 SECONDS, surgery_verb = "prying", + minimum_stat = SOFT_CRIT, + snip_chance = 100, list/target_zones = list(BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_ARM, BODY_ZONE_R_LEG), ) . = ..() @@ -23,6 +29,8 @@ src.surgery_time = surgery_time src.surgery_verb = surgery_verb + src.minimum_stat = minimum_stat + src.snip_chance = snip_chance src.target_zones = target_zones RegisterSignals(target, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET), PROC_REF(try_amputate)) @@ -33,11 +41,11 @@ /// Called when you click on literally anything with your hands, see if it is an injured carbon and then try to cut it up /datum/element/amputating_limbs/proc/try_amputate(mob/living/surgeon, atom/victim) SIGNAL_HANDLER - if (!iscarbon(victim) || HAS_TRAIT(victim, TRAIT_NODISMEMBER)) + if (!iscarbon(victim) || HAS_TRAIT(victim, TRAIT_NODISMEMBER) || !prob(snip_chance)) return var/mob/living/carbon/limbed_victim = victim - if (limbed_victim.stat == CONSCIOUS) + if (limbed_victim.stat < minimum_stat) return if (DOING_INTERACTION_WITH_TARGET(surgeon, victim)) @@ -60,7 +68,7 @@ /// Chop one off /datum/element/amputating_limbs/proc/amputate(mob/living/surgeon, mob/living/carbon/victim, obj/item/bodypart/to_remove) - surgeon.visible_message(span_warning("[surgeon] begins [surgery_verb] [to_remove] off of [victim]!")) - if (!do_after(surgeon, delay = surgery_time, target = victim)) + surgeon.visible_message(span_warning("[surgeon] [surgery_verb] [to_remove] off of [victim]!")) + if (surgery_time > 0 && !do_after(surgeon, delay = surgery_time, target = victim)) return to_remove.dismember() diff --git a/code/datums/elements/climbable.dm b/code/datums/elements/climbable.dm index e953766571c2e5..b26990c59119bd 100644 --- a/code/datums/elements/climbable.dm +++ b/code/datums/elements/climbable.dm @@ -114,15 +114,13 @@ ///Handles climbing onto the atom when you click-drag /datum/element/climbable/proc/mousedrop_receive(atom/climbed_thing, atom/movable/dropped_atom, mob/user, params) SIGNAL_HANDLER - if(user == dropped_atom && isliving(dropped_atom)) - var/mob/living/living_target = dropped_atom - if(isanimal(living_target)) - var/mob/living/simple_animal/animal = dropped_atom - if (!animal.dextrous) - return - if(living_target.mobility_flags & MOBILITY_MOVE) - INVOKE_ASYNC(src, PROC_REF(climb_structure), climbed_thing, living_target, params) - return + if(user != dropped_atom || !isliving(dropped_atom)) + return + if(!HAS_TRAIT(dropped_atom, TRAIT_FENCE_CLIMBER) && !HAS_TRAIT(dropped_atom, TRAIT_CAN_HOLD_ITEMS)) // If you can hold items you can probably climb a fence + return + var/mob/living/living_target = dropped_atom + if(living_target.mobility_flags & MOBILITY_MOVE) + INVOKE_ASYNC(src, PROC_REF(climb_structure), climbed_thing, living_target, params) ///Tries to climb onto the target if the forced movement of the mob allows it /datum/element/climbable/proc/try_speedrun(datum/source, mob/bumpee) diff --git a/code/datums/elements/death_linked.dm b/code/datums/elements/death_linked.dm deleted file mode 100644 index c5d2c6c422c6ae..00000000000000 --- a/code/datums/elements/death_linked.dm +++ /dev/null @@ -1,29 +0,0 @@ -/** - * ## death linkage element! - * - * Bespoke element that when the owner dies, the linked mob dies too. - */ -/datum/element/death_linked - element_flags = ELEMENT_BESPOKE - argument_hash_start_idx = 3 - ///The mob that also dies when the user dies - var/datum/weakref/linked_mob - -/datum/element/death_linked/Attach(datum/target, mob/living/target_mob) - . = ..() - if(!isliving(target)) - return ELEMENT_INCOMPATIBLE - if(!target_mob) - stack_trace("[type] added to [target] with NO MOB.") - src.linked_mob = WEAKREF(target_mob) - RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_death)) - -/datum/element/death_linked/Detach(datum/target) - . = ..() - UnregisterSignal(target, COMSIG_LIVING_DEATH) - -///signal called by the stat of the target changing -/datum/element/death_linked/proc/on_death(mob/living/target, gibbed) - SIGNAL_HANDLER - var/mob/living/linked_mob_resolved = linked_mob?.resolve() - linked_mob_resolved?.death(TRUE) diff --git a/code/datums/elements/dextrous.dm b/code/datums/elements/dextrous.dm new file mode 100644 index 00000000000000..335c7c196d1cea --- /dev/null +++ b/code/datums/elements/dextrous.dm @@ -0,0 +1,69 @@ +/** + * Sets up the attachee to have hands and manages things like dropping items on death and displaying them on examine + * Actual hand performance is managed by code on /living/ and not encapsulated here, we just enable it + */ +/datum/element/dextrous + +/datum/element/dextrous/Attach(datum/target, hands_count = 2, hud_type = /datum/hud/dextrous) + . = ..() + if (!isliving(target) || iscarbon(target)) + return ELEMENT_INCOMPATIBLE // Incompatible with the carbon typepath because that already has its own hand handling and doesn't need hand holding + + var/mob/living/mob_parent = target + set_available_hands(mob_parent, hands_count) + mob_parent.set_hud_used(new hud_type(target)) + mob_parent.hud_used.show_hud(mob_parent.hud_used.hud_version) + ADD_TRAIT(target, TRAIT_CAN_HOLD_ITEMS, REF(src)) + RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_death)) + RegisterSignal(target, COMSIG_LIVING_UNARMED_ATTACK, PROC_REF(on_hand_clicked)) + RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(on_examined)) + +/datum/element/dextrous/Detach(datum/source) + . = ..() + var/mob/living/mob_parent = source + set_available_hands(mob_parent, initial(mob_parent.default_num_hands)) + var/initial_hud = initial(mob_parent.hud_type) + mob_parent.set_hud_used(new initial_hud(source)) + mob_parent.hud_used.show_hud(mob_parent.hud_used.hud_version) + REMOVE_TRAIT(source, TRAIT_CAN_HOLD_ITEMS, REF(src)) + UnregisterSignal(source, list( + COMSIG_ATOM_EXAMINE, + COMSIG_LIVING_DEATH, + COMSIG_LIVING_UNARMED_ATTACK, + )) + +/// Set up how many hands we should have +/datum/element/dextrous/proc/set_available_hands(mob/living/hand_owner, hands_count) + hand_owner.drop_all_held_items() + var/held_items = list() + for (var/i in 1 to hands_count) + held_items += null + hand_owner.held_items = held_items + hand_owner.set_num_hands(hands_count) + hand_owner.set_usable_hands(hands_count) + +/// Drop our shit when we die +/datum/element/dextrous/proc/on_death(mob/living/died, gibbed) + SIGNAL_HANDLER + died.drop_all_held_items() + +/// Try picking up items +/datum/element/dextrous/proc/on_hand_clicked(mob/living/hand_haver, atom/target, proximity, modifiers) + SIGNAL_HANDLER + if (!isitem(target) && hand_haver.combat_mode) + return + if (LAZYACCESS(modifiers, RIGHT_CLICK)) + INVOKE_ASYNC(target, TYPE_PROC_REF(/atom, attack_hand_secondary), hand_haver, modifiers) + else + INVOKE_ASYNC(target, TYPE_PROC_REF(/atom, attack_hand), hand_haver, modifiers) + INVOKE_ASYNC(hand_haver, TYPE_PROC_REF(/mob, update_held_items)) + return COMPONENT_CANCEL_ATTACK_CHAIN + +/// Tell people what we are holding +/datum/element/dextrous/proc/on_examined(mob/living/examined, mob/user, list/examine_list) + SIGNAL_HANDLER + for(var/obj/item/held_item in examined.held_items) + if(held_item.item_flags & (ABSTRACT|EXAMINE_SKIP|HAND_ITEM)) + continue + examine_list += span_info("[examined.p_They()] [examined.p_have()] [held_item.get_examine_string(user)] in [examined.p_their()] \ + [examined.get_held_index_name(examined.get_held_index_of_item(held_item))].") diff --git a/code/datums/elements/food/microwavable.dm b/code/datums/elements/food/microwavable.dm index 3ad3e272d345dd..8e7305545c0b0d 100644 --- a/code/datums/elements/food/microwavable.dm +++ b/code/datums/elements/food/microwavable.dm @@ -6,14 +6,18 @@ var/atom/default_typepath = /obj/item/food/badrecipe /// Resulting atom typepath on a completed microwave. var/atom/result_typepath + /// Reagents that should be added to the result + var/list/added_reagents -/datum/element/microwavable/Attach(datum/target, microwave_type) +/datum/element/microwavable/Attach(datum/target, microwave_type, list/reagents) . = ..() if(!isitem(target)) return ELEMENT_INCOMPATIBLE result_typepath = microwave_type || default_typepath + added_reagents = reagents + RegisterSignal(target, COMSIG_ITEM_MICROWAVE_ACT, PROC_REF(on_microwaved)) if(!ispath(result_typepath, default_typepath)) @@ -41,13 +45,15 @@ var/efficiency = istype(used_microwave) ? used_microwave.efficiency : 1 SEND_SIGNAL(result, COMSIG_ITEM_MICROWAVE_COOKED, source, efficiency) - if(IS_EDIBLE(result)) - if(microwaver && microwaver.mind) - ADD_TRAIT(result, TRAIT_FOOD_CHEF_MADE, REF(microwaver.mind)) + if(IS_EDIBLE(result) && (result_typepath != default_typepath)) + BLACKBOX_LOG_FOOD_MADE(result.type) result.reagents.clear_reagents() source.reagents?.trans_to(result, source.reagents.total_volume) + if(added_reagents) // Add any new reagents that should be added + result.reagents.add_reagent_list(added_reagents) - BLACKBOX_LOG_FOOD_MADE(result.type) + if(microwaver && microwaver.mind) + ADD_TRAIT(result, TRAIT_FOOD_CHEF_MADE, REF(microwaver.mind)) qdel(source) diff --git a/code/datums/elements/footstep.dm b/code/datums/elements/footstep.dm index 6c55b595563820..3a0a9961843c45 100644 --- a/code/datums/elements/footstep.dm +++ b/code/datums/elements/footstep.dm @@ -40,6 +40,8 @@ footstep_sounds = GLOB.heavyfootstep if(FOOTSTEP_MOB_SHOE) footstep_sounds = GLOB.footstep + if(FOOTSTEP_MOB_RUST) + footstep_sounds = 'sound/effects/footstep/rustystep1.ogg' if(FOOTSTEP_MOB_SLIME) footstep_sounds = 'sound/effects/footstep/slime1.ogg' if(FOOTSTEP_OBJ_MACHINE) @@ -64,11 +66,12 @@ if(!istype(turf)) return - if(!turf.footstep || source.buckled || source.throwing || source.movement_type & (VENTCRAWLING | FLYING) || HAS_TRAIT(source, TRAIT_IMMOBILIZED) || CHECK_MOVE_LOOP_FLAGS(source, MOVEMENT_LOOP_OUTSIDE_CONTROL)) + if(source.buckled || source.throwing || source.movement_type & (VENTCRAWLING | FLYING) || HAS_TRAIT(source, TRAIT_IMMOBILIZED) || CHECK_MOVE_LOOP_FLAGS(source, MOVEMENT_LOOP_OUTSIDE_CONTROL)) return if(source.body_position == LYING_DOWN) //play crawling sound if we're lying - playsound(turf, 'sound/effects/footstep/crawl1.ogg', 15 * volume, falloff_distance = 1, vary = sound_vary) + if(turf.footstep) + playsound(turf, 'sound/effects/footstep/crawl1.ogg', 15 * volume, falloff_distance = 1, vary = sound_vary) return if(iscarbon(source)) @@ -92,6 +95,9 @@ . = list(FOOTSTEP_MOB_SHOE = turf.footstep, FOOTSTEP_MOB_BAREFOOT = turf.barefootstep, FOOTSTEP_MOB_HEAVY = turf.heavyfootstep, FOOTSTEP_MOB_CLAW = turf.clawfootstep, STEP_SOUND_PRIORITY = STEP_SOUND_NO_PRIORITY) SEND_SIGNAL(turf, COMSIG_TURF_PREPARE_STEP_SOUND, .) + //The turf has no footstep sound (e.g. open space) and none of the objects on that turf (e.g. catwalks) overrides it + if(isnull(turf.footstep)) + return null return . /datum/element/footstep/proc/play_simplestep(mob/living/source, atom/oldloc, direction, forced, list/old_locs, momentum_change) diff --git a/code/datums/elements/sideway_movement.dm b/code/datums/elements/sideway_movement.dm index dfe23187807f54..e6d94745e6cdb0 100644 --- a/code/datums/elements/sideway_movement.dm +++ b/code/datums/elements/sideway_movement.dm @@ -23,5 +23,5 @@ return var/new_dir = old_dir if(direction == old_dir || direction == REVERSE_DIR(old_dir)) - new_dir = angle2dir(dir2angle(direction) + pick(90, -90)) + new_dir = turn(source.dir, pick(90, -90)) source.setDir(new_dir) diff --git a/code/datums/elements/structure_repair.dm b/code/datums/elements/structure_repair.dm new file mode 100644 index 00000000000000..d3b26eed815be9 --- /dev/null +++ b/code/datums/elements/structure_repair.dm @@ -0,0 +1,45 @@ +/// Intercepts attacks from mobs with this component to instead repair specified structures. +/datum/element/structure_repair + element_flags = ELEMENT_BESPOKE + argument_hash_start_idx = 2 + /// How much to heal structures by + var/heal_amount + /// Typecache of types of structures to repair + var/list/structure_types_typecache + +/datum/element/structure_repair/Attach( + datum/target, + heal_amount = 5, + structure_types_typecache = typecacheof(list(/obj/structure)), +) + . = ..() + if (!isliving(target)) + return ELEMENT_INCOMPATIBLE + + src.heal_amount = heal_amount + src.structure_types_typecache = structure_types_typecache + RegisterSignals(target, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET), PROC_REF(try_repair)) + +/datum/element/structure_repair/Detach(datum/source) + UnregisterSignal(source, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_HOSTILE_PRE_ATTACKINGTARGET)) + return ..() + +/// If the target is of a valid type, interrupt the attack chain to repair it instead +/datum/element/structure_repair/proc/try_repair(mob/living/fixer, atom/target) + SIGNAL_HANDLER + + if (!is_type_in_typecache(target, structure_types_typecache)) + return + + if (target.get_integrity() >= target.max_integrity) + target.balloon_alert(fixer, "not damaged!") + return COMPONENT_CANCEL_ATTACK_CHAIN + + target.repair_damage(heal_amount) + fixer.Beam(target, icon_state = "sendbeam", time = 0.4 SECONDS) + fixer.visible_message( + span_danger("[fixer] repairs [target]."), + span_danger("You repair [target], leaving it at [round(target.get_integrity() * 100 / target.max_integrity)]% stability."), + ) + + return COMPONENT_CANCEL_ATTACK_CHAIN diff --git a/code/datums/elements/waddling.dm b/code/datums/elements/waddling.dm index 9d9aede83edf44..825b0c4e4cb829 100644 --- a/code/datums/elements/waddling.dm +++ b/code/datums/elements/waddling.dm @@ -4,30 +4,21 @@ . = ..() if(!ismovable(target)) return ELEMENT_INCOMPATIBLE - if(isliving(target)) - RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(LivingWaddle)) - else - RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(Waddle)) + RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(Waddle)) /datum/element/waddling/Detach(datum/source) . = ..() UnregisterSignal(source, COMSIG_MOVABLE_MOVED) - -/datum/element/waddling/proc/LivingWaddle(mob/living/target, atom/oldloc, direction, forced) +/datum/element/waddling/proc/Waddle(atom/movable/moved, atom/oldloc, direction, forced) SIGNAL_HANDLER - - if(forced || target.incapacitated() || target.body_position == LYING_DOWN || CHECK_MOVE_LOOP_FLAGS(target, MOVEMENT_LOOP_OUTSIDE_CONTROL)) - return - waddling_animation(target) - - -/datum/element/waddling/proc/Waddle(atom/movable/target, atom/oldloc, direction, forced) - SIGNAL_HANDLER - - if(forced || CHECK_MOVE_LOOP_FLAGS(target, MOVEMENT_LOOP_OUTSIDE_CONTROL)) + if(forced || CHECK_MOVE_LOOP_FLAGS(moved, MOVEMENT_LOOP_OUTSIDE_CONTROL)) return - waddling_animation(target) + if(isliving(moved)) + var/mob/living/living_moved = moved + if (living_moved.incapacitated() || living_moved.body_position == LYING_DOWN) + return + waddling_animation(moved) /datum/element/waddling/proc/waddling_animation(atom/movable/target) animate(target, pixel_z = 4, time = 0) diff --git a/code/datums/elements/wall_walker.dm b/code/datums/elements/wall_walker.dm new file mode 100644 index 00000000000000..92ac3318c12879 --- /dev/null +++ b/code/datums/elements/wall_walker.dm @@ -0,0 +1,49 @@ +/// This element will allow the mob it's attached to to pass through a specified type of wall, and drag anything through it. +/datum/element/wall_walker + element_flags = ELEMENT_BESPOKE + argument_hash_start_idx = 2 + /// What kind of walls can we pass through? + var/wall_type + +/datum/element/wall_walker/Attach( + datum/target, + wall_type = /turf/closed/wall, +) + . = ..() + if (!isliving(target)) + return ELEMENT_INCOMPATIBLE + + src.wall_type = wall_type + RegisterSignal(target, COMSIG_LIVING_WALL_BUMP, PROC_REF(try_pass_wall)) + RegisterSignal(target, COMSIG_LIVING_WALL_EXITED, PROC_REF(exit_wall)) + +/datum/element/wall_walker/Detach(datum/source) + UnregisterSignal(source, list(COMSIG_LIVING_WALL_BUMP, COMSIG_LIVING_WALL_EXITED)) + return ..() + +/// If the wall is of the proper type, pass into it and keep hold on whatever you're pulling +/datum/element/wall_walker/proc/try_pass_wall(mob/living/passing_mob, turf/closed/bumped_wall) + if(!istype(bumped_wall, wall_type)) + return + + var/atom/movable/stored_pulling = passing_mob.pulling + if(stored_pulling) //force whatever you're pulling to come with you + stored_pulling.setDir(get_dir(stored_pulling.loc, passing_mob.loc)) + stored_pulling.forceMove(passing_mob.loc) + passing_mob.forceMove(bumped_wall) + + if(stored_pulling) //don't drop them because we went into a wall + passing_mob.start_pulling(stored_pulling, supress_message = TRUE) + +/// If the wall is of the proper type, pull whatever you're pulling into it +/datum/element/wall_walker/proc/exit_wall(mob/living/passing_mob, turf/closed/exited_wall) + if(!istype(exited_wall, wall_type)) + return + + var/atom/movable/stored_pulling = passing_mob.pulling + if(isnull(stored_pulling)) + return + + stored_pulling.setDir(get_dir(stored_pulling.loc, passing_mob.loc)) + stored_pulling.forceMove(exited_wall) + passing_mob.start_pulling(stored_pulling, supress_message = TRUE) diff --git a/code/datums/elements/wheel.dm b/code/datums/elements/wheel.dm new file mode 100644 index 00000000000000..2bb8977ca5cae9 --- /dev/null +++ b/code/datums/elements/wheel.dm @@ -0,0 +1,28 @@ +/// Element which spins you as you move +/datum/element/wheel + +/datum/element/wheel/Attach(datum/target) + . = ..() + if(!ismovable(target)) + return ELEMENT_INCOMPATIBLE + RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved)) + +/datum/element/wheel/Detach(datum/source) + . = ..() + UnregisterSignal(source, COMSIG_MOVABLE_MOVED) + +/datum/element/wheel/proc/on_moved(atom/movable/moved, atom/oldloc, direction, forced) + SIGNAL_HANDLER + if(forced || CHECK_MOVE_LOOP_FLAGS(moved, MOVEMENT_LOOP_OUTSIDE_CONTROL)) + return + if(isliving(moved)) + var/mob/living/living_moved = moved + if (living_moved.incapacitated() || living_moved.body_position == LYING_DOWN) + return + var/rotation_degree = (360 / 3) + if(direction & SOUTHWEST) + rotation_degree *= -1 + + var/matrix/to_turn = matrix(moved.transform) + to_turn = turn(moved.transform, rotation_degree) + animate(moved, transform = to_turn, time = 0.1 SECONDS, flags = ANIMATION_PARALLEL) diff --git a/code/datums/greyscale/config_types/greyscale_configs/greyscale_mobs.dm b/code/datums/greyscale/config_types/greyscale_configs/greyscale_mobs.dm index d247117f3a176e..a4c7c372525bf4 100644 --- a/code/datums/greyscale/config_types/greyscale_configs/greyscale_mobs.dm +++ b/code/datums/greyscale/config_types/greyscale_configs/greyscale_mobs.dm @@ -34,3 +34,8 @@ name = "Garden Gnome" icon_file = 'icons/mob/simple/garden_gnome.dmi' json_config = 'code/datums/greyscale/json_configs/garden_gnome.json' + +/datum/greyscale_config/pony + name = "Pony" + icon_file = 'icons/mob/simple/animal.dmi' + json_config = 'code/datums/greyscale/json_configs/pony.json' diff --git a/code/datums/greyscale/json_configs/pony.json b/code/datums/greyscale/json_configs/pony.json new file mode 100644 index 00000000000000..a08437c7cb6647 --- /dev/null +++ b/code/datums/greyscale/json_configs/pony.json @@ -0,0 +1,30 @@ +{ + "pony": [ + { + "type": "icon_state", + "icon_state": "pony", + "blend_mode": "overlay", + "color_ids": [ 1 ] + }, + { + "type": "icon_state", + "icon_state": "pony_hair", + "blend_mode": "overlay", + "color_ids": [ 2 ] + } + ], + "pony_dead": [ + { + "type": "icon_state", + "icon_state": "pony_dead", + "blend_mode": "overlay", + "color_ids": [ 1 ] + }, + { + "type": "icon_state", + "icon_state": "pony_hair_dead", + "blend_mode": "overlay", + "color_ids": [ 2 ] + } + ] +} diff --git a/code/datums/hud.dm b/code/datums/hud.dm index 1d112acf3237ae..604dea3ff712e0 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -18,7 +18,8 @@ GLOBAL_LIST_INIT(huds, list( DATA_HUD_SENTIENT_DISEASE = new/datum/atom_hud/sentient_disease(), DATA_HUD_AI_DETECT = new/datum/atom_hud/ai_detector(), DATA_HUD_FAN = new/datum/atom_hud/data/human/fan_hud(), - DATA_HUD_PERMIT = new/datum/atom_hud/data/human/permit(), // SKYRAT EDIT + DATA_HUD_PERMIT = new/datum/atom_hud/data/human/permit(), // SKYRAT EDIT ADDITION + DATA_HUD_DNR = new/datum/atom_hud/data/human/dnr(), // SKYRAT EDIT ADDITION )) /datum/atom_hud diff --git a/code/datums/id_trim/jobs.dm b/code/datums/id_trim/jobs.dm index 2a62d19452ddd2..6d50347aa3d78b 100644 --- a/code/datums/id_trim/jobs.dm +++ b/code/datums/id_trim/jobs.dm @@ -155,6 +155,30 @@ ) job = /datum/job/bartender +/datum/id_trim/job/bitrunner + assignment = "Bitrunner" + trim_state = "trim_bitrunner" + department_color = COLOR_CARGO_BROWN + subdepartment_color = COLOR_CARGO_BROWN + sechud_icon_state = SECHUD_BITRUNNER + minimal_access = list( + ACCESS_BIT_DEN, + ACCESS_CARGO, + ACCESS_MAINT_TUNNELS, + ACCESS_MECH_MINING, + ACCESS_MINERAL_STOREROOM, + ) + extra_access = list( + ACCESS_MINING, + ACCESS_MINING_STATION, + ) + template_access = list( + ACCESS_CAPTAIN, + ACCESS_CHANGE_IDS, + ACCESS_QM, + ) + job = /datum/job/bitrunner + /datum/id_trim/job/botanist assignment = "Botanist" trim_state = "trim_botanist" @@ -215,6 +239,7 @@ ACCESS_SHIPPING, ) extra_access = list( + ACCESS_BIT_DEN, ACCESS_MINING, ACCESS_MINING_STATION, ) @@ -576,6 +601,7 @@ ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_ARMORY, ACCESS_AUX_BASE, + ACCESS_BIT_DEN, ACCESS_BRIG, ACCESS_BRIG_ENTRANCE, ACCESS_CARGO, @@ -712,6 +738,7 @@ subdepartment_color = COLOR_MEDICAL_BLUE sechud_icon_state = SECHUD_PARAMEDIC minimal_access = list( + ACCESS_BIT_DEN, ACCESS_CARGO, ACCESS_CONSTRUCTION, ACCESS_HYDROPONICS, @@ -739,7 +766,7 @@ assignment = "Prisoner" trim_state = "trim_warden" department_color = COLOR_PRISONER_BLACK - subdepartment_color = COLOR_PRISONER_ORANGE + subdepartment_color = COLOR_PRISONER_BLACK sechud_icon_state = SECHUD_PRISONER template_access = list( ACCESS_CAPTAIN, @@ -810,6 +837,7 @@ sechud_icon_state = SECHUD_QUARTERMASTER minimal_access = list( ACCESS_AUX_BASE, + ACCESS_BIT_DEN, ACCESS_CARGO, ACCESS_MAINT_TUNNELS, ACCESS_MECH_MINING, @@ -1008,6 +1036,7 @@ assignment = "Security Officer (Cargo)" subdepartment_color = COLOR_CARGO_BROWN department_access = list( + ACCESS_BIT_DEN, ACCESS_CARGO, ACCESS_MINING, ACCESS_SHIPPING, @@ -1076,6 +1105,7 @@ ACCESS_MINING_STATION, ) extra_access = list( + ACCESS_BIT_DEN, ACCESS_MAINT_TUNNELS, ) template_access = list( diff --git a/code/datums/id_trim/outfits.dm b/code/datums/id_trim/outfits.dm index f62e451340f98c..2a06434ecdb869 100644 --- a/code/datums/id_trim/outfits.dm +++ b/code/datums/id_trim/outfits.dm @@ -55,3 +55,22 @@ subdepartment_color = COLOR_PRISONER_BLACK access = list(ACCESS_HUNTER) + +/// Trim for player controlled avatars in the Virtual Domain. +/datum/id_trim/bit_avatar + assignment = "Bit Avatar" + trim_state = "trim_bitavatar" + department_color = COLOR_BLACK + subdepartment_color = COLOR_GREEN + +/// Trim for cyber police in the Virtual Domain. +/datum/id_trim/cyber_police + assignment = "Cyber Police" + trim_state = "trim_deathcommando" + department_color = COLOR_BLACK + subdepartment_color = COLOR_GREEN + +/datum/id_trim/cyber_police/New() + . = ..() + + access |= SSid_access.get_region_access_list(list(REGION_ALL_GLOBAL)) diff --git a/code/datums/lazy_template.dm b/code/datums/lazy_template.dm index 0b8b2999f69938..e3006e13056df5 100644 --- a/code/datums/lazy_template.dm +++ b/code/datums/lazy_template.dm @@ -7,8 +7,11 @@ /// If this is true each load will increment an index keyed to the type and it will load [map_name]_[index] var/list/datum/turf_reservation/reservations = list() var/uses_multiple_allocations = FALSE + /// Key to identify this template - used in caching var/key + /// Directory of maps to prefix to the filename var/map_dir = "_maps/templates/lazy_templates" + /// The filename (without extension) of the map to load var/map_name /datum/lazy_template/New() @@ -61,12 +64,18 @@ if(!reservation) CRASH("Failed to reserve a block for lazy template: '[key]'") + // lists kept for overall loading var/list/loaded_atom_movables = list() var/list/loaded_turfs = list() var/list/loaded_areas = list() + + var/list/obj/structure/cable/loaded_cables = list() + var/list/obj/machinery/atmospherics/loaded_atmospherics = list() + for(var/z_idx in parsed_template.parsed_bounds[MAP_MAXZ] to 1 step -1) var/turf/bottom_left = reservation.bottom_left_turfs[z_idx] var/turf/top_right = reservation.top_right_turfs[z_idx] + load_map( file(load_path), bottom_left.x, @@ -78,12 +87,20 @@ for(var/turf/turf as anything in block(bottom_left, top_right)) loaded_turfs += turf loaded_areas |= get_area(turf) - for(var/thing in turf.get_all_contents()) - // atoms can actually be in the contents of two or more turfs based on its icon/bound size - // see https://www.byond.com/docs/ref/index.html#/atom/var/contents + + // atoms can actually be in the contents of two or more turfs based on its icon/bound size + // see https://www.byond.com/docs/ref/index.html#/atom/var/contents + for(var/thing in (turf.get_all_contents() - turf)) + if(istype(thing, /obj/structure/cable)) + loaded_cables += thing + else if(istype(thing, /obj/machinery/atmospherics)) + loaded_atmospherics += thing loaded_atom_movables |= thing - SSatoms.InitializeAtoms(loaded_atom_movables + loaded_turfs + loaded_areas) + SSatoms.InitializeAtoms(loaded_areas + loaded_atom_movables + loaded_turfs) + SSmachines.setup_template_powernets(loaded_cables) + SSair.setup_template_machinery(loaded_atmospherics) + SEND_SIGNAL(src, COMSIG_LAZY_TEMPLATE_LOADED, loaded_atom_movables, loaded_turfs, loaded_areas) reservations += reservation return reservation diff --git a/code/datums/looping_sounds/burning.dm b/code/datums/looping_sounds/burning.dm new file mode 100644 index 00000000000000..191ae88db8924b --- /dev/null +++ b/code/datums/looping_sounds/burning.dm @@ -0,0 +1,9 @@ +/// Soundloop for the fire (bonfires, fireplaces, etc.) +/datum/looping_sound/burning + start_sound = 'sound/items/match_strike.ogg' + start_length = 3 SECONDS + mid_sounds = 'sound/effects/comfyfire.ogg' + mid_length = 5 SECONDS + volume = 50 + vary = TRUE + extra_range = MEDIUM_RANGE_SOUND_EXTRARANGE diff --git a/code/datums/mapgen/Cavegens/IcemoonCaves.dm b/code/datums/mapgen/Cavegens/IcemoonCaves.dm index 7d7437ccda6c80..b0fcd471db2fff 100644 --- a/code/datums/mapgen/Cavegens/IcemoonCaves.dm +++ b/code/datums/mapgen/Cavegens/IcemoonCaves.dm @@ -62,12 +62,12 @@ weighted_closed_turf_types = list(/turf/closed/mineral/random/snow/underground = 1) weighted_mob_spawn_list = list( SPAWN_MEGAFAUNA = 1, + /mob/living/basic/mining/ice_demon = 100, /mob/living/basic/mining/ice_whelp = 60, /mob/living/basic/mining/legion/snow = 100, - /mob/living/simple_animal/hostile/asteroid/ice_demon = 100, /obj/structure/spawner/ice_moon/demonic_portal = 6, - /obj/structure/spawner/ice_moon/demonic_portal/snowlegion = 6, /obj/structure/spawner/ice_moon/demonic_portal/ice_whelp = 6, + /obj/structure/spawner/ice_moon/demonic_portal/snowlegion = 6, ) weighted_megafauna_spawn_list = list(/mob/living/simple_animal/hostile/megafauna/colossus = 1) weighted_flora_spawn_list = list( diff --git a/code/datums/martial/cqc.dm b/code/datums/martial/cqc.dm index c982f0e086c374..e5b959b340f509 100644 --- a/code/datums/martial/cqc.dm +++ b/code/datums/martial/cqc.dm @@ -80,9 +80,21 @@ return TRUE /datum/martial_art/cqc/proc/Kick(mob/living/attacker, mob/living/defender) - if(!can_use(attacker)) + if(!can_use(attacker) || defender.stat != CONSCIOUS) return FALSE - if(!defender.stat || !defender.IsParalyzed()) + + if(defender.body_position == LYING_DOWN && !defender.IsUnconscious() && defender.getStaminaLoss() >= 100) + log_combat(attacker, defender, "knocked out (Head kick)(CQC)") + defender.visible_message(span_danger("[attacker] kicks [defender]'s head, knocking [defender.p_them()] out!"), \ + span_userdanger("You're knocked unconscious by [attacker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), null, attacker) + to_chat(attacker, span_danger("You kick [defender]'s head, knocking [defender.p_them()] out!")) + playsound(get_turf(attacker), 'sound/weapons/genhit1.ogg', 50, TRUE, -1) + + var/helmet_protection = defender.run_armor_check(BODY_ZONE_HEAD, MELEE) + defender.apply_effect(20 SECONDS, EFFECT_KNOCKDOWN, helmet_protection) + defender.apply_effect(10 SECONDS, EFFECT_UNCONSCIOUS, helmet_protection) + defender.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 150) + else defender.visible_message(span_danger("[attacker] kicks [defender] back!"), \ span_userdanger("You're kicked back by [attacker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), COMBAT_MESSAGE_RANGE, attacker) to_chat(attacker, span_danger("You kick [defender] back!")) @@ -90,17 +102,9 @@ var/atom/throw_target = get_edge_target_turf(defender, attacker.dir) defender.throw_at(throw_target, 1, 14, attacker) defender.apply_damage(10, attacker.get_attack_type()) + defender.adjustStaminaLoss(45) log_combat(attacker, defender, "kicked (CQC)") - . = TRUE - if(defender.IsParalyzed() && !defender.stat) - log_combat(attacker, defender, "knocked out (Head kick)(CQC)") - defender.visible_message(span_danger("[attacker] kicks [defender]'s head, knocking [defender.p_them()] out!"), \ - span_userdanger("You're knocked unconscious by [attacker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), null, attacker) - to_chat(attacker, span_danger("You kick [defender]'s head, knocking [defender.p_them()] out!")) - playsound(get_turf(attacker), 'sound/weapons/genhit1.ogg', 50, TRUE, -1) - defender.SetSleeping(30 SECONDS) - defender.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 150) - . = TRUE + . = TRUE /datum/martial_art/cqc/proc/Pressure(mob/living/attacker, mob/living/defender) if(!can_use(attacker)) @@ -166,6 +170,19 @@ /datum/martial_art/cqc/harm_act(mob/living/attacker, mob/living/defender) if(!can_use(attacker)) return FALSE + + if(attacker.resting && defender.stat != DEAD && defender.body_position == STANDING_UP) + defender.visible_message(span_danger("[attacker] leg sweeps [defender]!"), \ + span_userdanger("Your legs are sweeped by [attacker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), null, attacker) + to_chat(attacker, span_danger("You leg sweep [defender]!")) + playsound(get_turf(attacker), 'sound/effects/hit_kick.ogg', 50, TRUE, -1) + attacker.do_attack_animation(defender) + defender.apply_damage(10, BRUTE) + defender.Knockdown(5 SECONDS) + log_combat(attacker, defender, "sweeped (CQC)") + reset_streak() + return TRUE + add_to_streak("H", defender) if(check_streak(attacker, defender)) return TRUE @@ -185,14 +202,7 @@ span_userdanger("You're [picked_hit_type]ed by [attacker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), COMBAT_MESSAGE_RANGE, attacker) to_chat(attacker, span_danger("You [picked_hit_type] [defender]!")) log_combat(attacker, defender, "[picked_hit_type]s (CQC)") - if(attacker.resting && !defender.stat && !defender.IsParalyzed()) - defender.visible_message(span_danger("[attacker] leg sweeps [defender]!"), \ - span_userdanger("Your legs are sweeped by [attacker]!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), null, attacker) - to_chat(attacker, span_danger("You leg sweep [defender]!")) - playsound(get_turf(attacker), 'sound/effects/hit_kick.ogg', 50, TRUE, -1) - defender.apply_damage(10, BRUTE) - defender.Paralyze(6 SECONDS) - log_combat(attacker, defender, "sweeped (CQC)") + return TRUE /datum/martial_art/cqc/disarm_act(mob/living/attacker, mob/living/defender) @@ -239,7 +249,7 @@ to_chat(usr, "You try to remember some of the basics of CQC.") to_chat(usr, "[span_notice("Slam")]: Grab Punch. Slam opponent into the ground, knocking them down.") - to_chat(usr, "[span_notice("CQC Kick")]: Punch Punch. Knocks opponent away. Knocks out stunned or knocked down opponents.") + to_chat(usr, "[span_notice("CQC Kick")]: Punch Punch. Knocks opponent away. Knocks out stunned opponents and does stamina damage.") to_chat(usr, "[span_notice("Restrain")]: Grab Grab. Locks opponents into a restraining position, disarm to knock them out with a chokehold.") to_chat(usr, "[span_notice("Pressure")]: Shove Grab. Decent stamina damage.") to_chat(usr, "[span_notice("Consecutive CQC")]: Shove Shove Punch. Mainly offensive move, huge damage and decent stamina damage.") diff --git a/code/datums/martial/plasma_fist.dm b/code/datums/martial/plasma_fist.dm index 1bc353cc6982fb..f4c89177ac363f 100644 --- a/code/datums/martial/plasma_fist.dm +++ b/code/datums/martial/plasma_fist.dm @@ -68,7 +68,7 @@ log_combat(attacker, defender, "gibbed (Plasma Fist)") var/turf/Dturf = get_turf(defender) defender.investigate_log("has been gibbed by plasma fist.", INVESTIGATE_DEATHS) - defender.gib() + defender.gib(DROP_ALL_REMAINS) if(nobomb) return if(!hasclient) diff --git a/code/datums/materials/_material.dm b/code/datums/materials/_material.dm index d91884d972e961..06d26f31ea3081 100644 --- a/code/datums/materials/_material.dm +++ b/code/datums/materials/_material.dm @@ -33,8 +33,16 @@ Simple datum which is instanced once per type and is used for every object of sa var/strength_modifier = 1 ///This is a modifier for integrity, and resembles the strength of the material var/integrity_modifier = 1 + ///This is the amount of value per 1 unit of the material var/value_per_unit = 0 + ///This is the minimum value of the material, used in the stock market for any mat that isn't set to null + var/minimum_value_override = null + ///Is this material traded on the stock market? + var/tradable = FALSE + ///If this material is tradable, what is the base quantity of the material on the stock market? + var/tradable_base_quantity = 0 + ///Armor modifiers, multiplies an items normal armor vars by these amounts. var/armor_modifiers = list(MELEE = 1, BULLET = 1, LASER = 1, ENERGY = 1, BOMB = 1, BIO = 1, FIRE = 1, ACID = 1) ///How beautiful is this material per unit. diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index fcef1b5d3d8a00..f79b9f7e4224f5 100644 --- a/code/datums/materials/basemats.dm +++ b/code/datums/materials/basemats.dm @@ -7,6 +7,9 @@ categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) sheet_type = /obj/item/stack/sheet/iron value_per_unit = 5 / SHEET_MATERIAL_AMOUNT + minimum_value_override = 0 + tradable = TRUE + tradable_base_quantity = MATERIAL_QUANTITY_COMMON /datum/material/iron/on_accidental_mat_consumption(mob/living/carbon/victim, obj/item/source_item) victim.apply_damage(10, BRUTE, BODY_ZONE_HEAD, wound_bonus = 5) @@ -25,6 +28,9 @@ shard_type = /obj/item/shard debris_type = /obj/effect/decal/cleanable/glass value_per_unit = 5 / SHEET_MATERIAL_AMOUNT + minimum_value_override = 0 + tradable = TRUE + tradable_base_quantity = MATERIAL_QUANTITY_COMMON beauty_modifier = 0.05 armor_modifiers = list(MELEE = 0.2, BULLET = 0.2, ENERGY = 1, BIO = 0.2, FIRE = 1, ACID = 0.2) @@ -56,6 +62,8 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) sheet_type = /obj/item/stack/sheet/mineral/silver value_per_unit = 50 / SHEET_MATERIAL_AMOUNT + tradable = TRUE + tradable_base_quantity = MATERIAL_QUANTITY_UNCOMMON beauty_modifier = 0.075 /datum/material/silver/on_accidental_mat_consumption(mob/living/carbon/victim, obj/item/source_item) @@ -72,6 +80,8 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) sheet_type = /obj/item/stack/sheet/mineral/gold value_per_unit = 125 / SHEET_MATERIAL_AMOUNT + tradable = TRUE + tradable_base_quantity = MATERIAL_QUANTITY_RARE beauty_modifier = 0.15 armor_modifiers = list(MELEE = 1.1, BULLET = 1.1, LASER = 1.15, ENERGY = 1.15, BOMB = 1, BIO = 1, FIRE = 0.7, ACID = 1.1) @@ -90,6 +100,8 @@ Unless you know what you're doing, only use the first three numbers. They're in alpha = 132 starlight_color = COLOR_BLUE_LIGHT value_per_unit = 500 / SHEET_MATERIAL_AMOUNT + tradable = TRUE + tradable_base_quantity = MATERIAL_QUANTITY_EXOTIC beauty_modifier = 0.3 armor_modifiers = list(MELEE = 1.3, BULLET = 1.3, LASER = 0.6, ENERGY = 1, BOMB = 1.2, BIO = 1, FIRE = 1, ACID = 1) @@ -106,6 +118,8 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) sheet_type = /obj/item/stack/sheet/mineral/uranium value_per_unit = 100 / SHEET_MATERIAL_AMOUNT + tradable = TRUE + tradable_base_quantity = MATERIAL_QUANTITY_RARE beauty_modifier = 0.3 //It shines so beautiful armor_modifiers = list(MELEE = 1.5, BULLET = 1.4, LASER = 0.5, ENERGY = 0.5, FIRE = 1, ACID = 1) @@ -173,6 +187,8 @@ Unless you know what you're doing, only use the first three numbers. They're in beauty_modifier = 0.5 sheet_type = /obj/item/stack/sheet/bluespace_crystal value_per_unit = 300 / SHEET_MATERIAL_AMOUNT + tradable = TRUE + tradable_base_quantity = MATERIAL_QUANTITY_EXOTIC /datum/material/bluespace/on_accidental_mat_consumption(mob/living/carbon/victim, obj/item/source_item) victim.reagents.add_reagent(/datum/reagent/bluespace, rand(5, 8)) @@ -216,6 +232,8 @@ Unless you know what you're doing, only use the first three numbers. They're in categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE, MAT_CATEGORY_ITEM_MATERIAL=TRUE) sheet_type = /obj/item/stack/sheet/mineral/titanium value_per_unit = 125 / SHEET_MATERIAL_AMOUNT + tradable = TRUE + tradable_base_quantity = MATERIAL_QUANTITY_UNCOMMON beauty_modifier = 0.05 armor_modifiers = list(MELEE = 1.35, BULLET = 1.3, LASER = 1.3, ENERGY = 1.25, BOMB = 1.25, BIO = 1, FIRE = 0.7, ACID = 1) diff --git a/code/datums/memory/_memory.dm b/code/datums/memory/_memory.dm index 35d1a6683f38ae..2b3e250a3fbf28 100644 --- a/code/datums/memory/_memory.dm +++ b/code/datums/memory/_memory.dm @@ -246,6 +246,7 @@ var/static/list/something_pool = list( /mob/living/basic/bat, /mob/living/basic/bear, + /mob/living/basic/blob_minion/blobbernaut, /mob/living/basic/butterfly, /mob/living/basic/carp, /mob/living/basic/carp/magic, @@ -255,6 +256,8 @@ /mob/living/basic/cow, /mob/living/basic/cow/wisdom, /mob/living/basic/crab, + /mob/living/basic/goat, + /mob/living/basic/gorilla, /mob/living/basic/headslug, /mob/living/basic/killer_tomato, /mob/living/basic/lizard, @@ -272,10 +275,7 @@ /mob/living/basic/statue, /mob/living/basic/stickman, /mob/living/basic/stickman/dog, - /mob/living/simple_animal/hostile/blob/blobbernaut/independent, - /mob/living/simple_animal/hostile/gorilla, /mob/living/simple_animal/hostile/megafauna/dragon/lesser, - /mob/living/simple_animal/hostile/retaliate/goat, /mob/living/simple_animal/parrot, /mob/living/simple_animal/pet/cat, /mob/living/simple_animal/pet/cat/cak, diff --git a/code/datums/mind/_mind.dm b/code/datums/mind/_mind.dm index fa9114a5284782..deb55e92ecb40d 100644 --- a/code/datums/mind/_mind.dm +++ b/code/datums/mind/_mind.dm @@ -569,16 +569,14 @@ /// Sets us to the passed job datum, then greets them to their new job. /// Use this one for when you're assigning this mind to a new job for the first time, /// or for when someone's recieving a job they'd really want to be greeted to. -/datum/mind/proc/set_assigned_role_with_greeting(datum/job/new_role, client/incoming_client) +/datum/mind/proc/set_assigned_role_with_greeting(datum/job/new_role, client/incoming_client, alt_title) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: /datum/mind/proc/set_assigned_role_with_greeting(datum/job/new_role, client/incoming_client) . = set_assigned_role(new_role) if(assigned_role != new_role) return - to_chat(incoming_client || src, span_infoplain("You are the [new_role.title].")) - - var/related_policy = get_policy(new_role.title) - if(related_policy) - to_chat(incoming_client || src, related_policy) + var/intro_message = new_role.get_spawn_message(alt_title) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: var/intro_message = new_role.get_spawn_message() + if(incoming_client && intro_message) + to_chat(incoming_client, intro_message) /mob/proc/sync_mind() mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist) diff --git a/code/datums/mind/initialization.dm b/code/datums/mind/initialization.dm index 12a5dddb229cb7..eb622cc5af5494 100644 --- a/code/datums/mind/initialization.dm +++ b/code/datums/mind/initialization.dm @@ -11,6 +11,7 @@ mind.set_current(src) // There's nowhere else to set this up, mind code makes me depressed mind.antag_hud = add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/antagonist_hud, "combo_hud", mind) + SEND_SIGNAL(src, COMSIG_MOB_MIND_INITIALIZED, mind) /mob/living/carbon/mind_initialize() ..() diff --git a/code/datums/mind/skills.dm b/code/datums/mind/skills.dm index 5847236435b934..474291d5ae0d4a 100644 --- a/code/datums/mind/skills.dm +++ b/code/datums/mind/skills.dm @@ -18,12 +18,10 @@ experience_multiplier += experience_multiplier_reasons[key] known_skills[skill][SKILL_EXP] = max(0, known_skills[skill][SKILL_EXP] + amt*experience_multiplier) //Update exp. Prevent going below 0 known_skills[skill][SKILL_LVL] = update_skill_level(skill)//Check what the current skill level is based on that skill's exp - if(silent) - return if(known_skills[skill][SKILL_LVL] > old_level) - S.level_gained(src, known_skills[skill][SKILL_LVL], old_level) + S.level_gained(src, known_skills[skill][SKILL_LVL], old_level, silent) else if(known_skills[skill][SKILL_LVL] < old_level) - S.level_lost(src, known_skills[skill][SKILL_LVL], old_level) + S.level_lost(src, known_skills[skill][SKILL_LVL], old_level, silent) ///Set experience of a specific skill to a number /datum/mind/proc/set_experience(skill, amt, silent = FALSE) diff --git a/code/datums/mood_events/drug_events.dm b/code/datums/mood_events/drug_events.dm index c734f2797b48cb..8ac323dda7a769 100644 --- a/code/datums/mood_events/drug_events.dm +++ b/code/datums/mood_events/drug_events.dm @@ -19,6 +19,10 @@ else description = initial(description) +/datum/mood_event/hang_over + mood_change = -4 + description = "I have a killer hang over!" + timeout = 1 MINUTES /datum/mood_event/smoked description = "I have had a smoke recently." diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index 53bcce6c6ff0e0..23a3364adc318c 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -316,6 +316,11 @@ description = "I need something to cover my head..." mood_change = -3 +/datum/mood_event/bald_reminder + description = "I was reminded that I can't grow my hair back at all! This is awful!" + mood_change = -5 + timeout = 4 MINUTES + /datum/mood_event/bad_touch description = "I don't like when people touch me." mood_change = -3 diff --git a/code/datums/mutations/body.dm b/code/datums/mutations/body.dm index 094e650fe33f00..24aa41321f3690 100644 --- a/code/datums/mutations/body.dm +++ b/code/datums/mutations/body.dm @@ -266,9 +266,9 @@ name = "Anti-Glow" desc = "Your skin seems to attract and absorb nearby light creating 'darkness' around you." text_gain_indication = "The light around you seems to disappear." - glow = -1.5 conflicts = list(/datum/mutation/human/glow) locked = TRUE + glow_power = -1.5 /datum/mutation/human/glow/anti/get_glow_color() return COLOR_BLACK @@ -508,7 +508,7 @@ to_chat(borgo, span_userdanger("Your sensors are disabled by a shower of blood!")) borgo.Paralyze(6 SECONDS) owner.investigate_log("has been gibbed by the martyrdom mutation.", INVESTIGATE_DEATHS) - owner.gib() + owner.gib(DROP_ALL_REMAINS) /datum/mutation/human/headless name = "H.A.R.S." diff --git a/code/datums/quirks/positive_quirks/drunk_healing.dm b/code/datums/quirks/positive_quirks/drunk_healing.dm index fbab2503b4e9c4..e1c4ba911255ef 100644 --- a/code/datums/quirks/positive_quirks/drunk_healing.dm +++ b/code/datums/quirks/positive_quirks/drunk_healing.dm @@ -10,13 +10,16 @@ mail_goodies = list(/obj/effect/spawner/random/food_or_drink/booze) /datum/quirk/drunkhealing/process(seconds_per_tick) + var/need_mob_update = FALSE switch(quirk_holder.get_drunk_amount()) if (6 to 40) - quirk_holder.adjustBruteLoss(-0.1 * seconds_per_tick, FALSE, required_bodytype = BODYTYPE_ORGANIC) - quirk_holder.adjustFireLoss(-0.05 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC) + need_mob_update += quirk_holder.adjustBruteLoss(-0.1 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) + need_mob_update += quirk_holder.adjustFireLoss(-0.05 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) if (41 to 60) - quirk_holder.adjustBruteLoss(-0.4 * seconds_per_tick, FALSE, required_bodytype = BODYTYPE_ORGANIC) - quirk_holder.adjustFireLoss(-0.2 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC) + need_mob_update += quirk_holder.adjustBruteLoss(-0.4 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) + need_mob_update += quirk_holder.adjustFireLoss(-0.2 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) if (61 to INFINITY) - quirk_holder.adjustBruteLoss(-0.8 * seconds_per_tick, FALSE, required_bodytype = BODYTYPE_ORGANIC) - quirk_holder.adjustFireLoss(-0.4 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC) + need_mob_update += quirk_holder.adjustBruteLoss(-0.8 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) + need_mob_update += quirk_holder.adjustFireLoss(-0.4 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) + if(need_mob_update) + quirk_holder.updatehealth() diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index 968e6df544e828..b3bc5a4dc18dd8 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -53,7 +53,7 @@ Probably best to stay clear." prefix = "_maps/RandomRuins/LavaRuins/skyrat/" // SKYRAT ADDITION suffix = "lavaland_surface_ash_walker1_skyrat.dmm" // SKYRAT EDIT - ORIGINAL: lavaland_surface_ash_walker1.dmm - always_place = TRUE //SKYRAT EDIT CHANGE + cost = 1000 //SKYRAT EDIT: Original: 20 allow_duplicates = FALSE //SKYRAT EDIT REMOVAL BEGIN - MAPPING /* @@ -286,3 +286,19 @@ suffix = "lavaland_battle_site.dmm" allow_duplicates = TRUE cost = 3 + +/datum/map_template/ruin/lavaland/watcher_grave + name = "Watchers' Grave" + id = "watcher-grave" + description = "A lonely cave where an orphaned child awaits a new parent." + suffix = "lavaland_surface_watcher_grave.dmm" + cost = 5 + allow_duplicates = FALSE + +/datum/map_template/ruin/lavaland/mook_village + name = "Mook Village" + id = "mook_village" + description = "A village hosting a community of friendly mooks!" + suffix = "lavaland_surface_mookvillage.dmm" + allow_duplicates = FALSE + cost = 5 diff --git a/code/datums/skills/_skill.dm b/code/datums/skills/_skill.dm index ec52ebd9e96688..b8438c67927ca8 100644 --- a/code/datums/skills/_skill.dm +++ b/code/datums/skills/_skill.dm @@ -27,8 +27,7 @@ GLOBAL_LIST_INIT(skill_types, subtypesof(/datum/skill)) span_nicegreen("I'm getting a little better at [name]!"), span_nicegreen("I'm getting much better at [name]!"), span_nicegreen("I feel like I've become quite proficient at [name]!"), - "After lots of practice, I've begun to truly understand the intricacies \ - and surprising depth behind [name]. I now consider myself a master [title].", + span_nicegreen("After lots of practice, I've begun to truly understand the intricacies and surprising depth behind [name]. I now consider myself a master [title]."), span_nicegreen("Through incredible determination and effort, I've reached the peak of my [name] abiltities. I'm finally able to consider myself a legendary [title]!") ) levelDownMessages = list(span_nicegreen("I have somehow completely lost all understanding of [name]. Please tell an admin if you see this."), span_nicegreen("I'm starting to forget what [name] really even is. I need more practice..."), @@ -46,13 +45,18 @@ GLOBAL_LIST_INIT(skill_types, subtypesof(/datum/skill)) * * mind - The mind that you'll want to send messages * * new_level - The newly gained level. Can check the actual level to give different messages at different levels, see defines in skills.dm * * old_level - Similar to the above, but the level you had before levelling up. + * * silent - Silences the announcement if TRUE */ -/datum/skill/proc/level_gained(datum/mind/mind, new_level, old_level)//just for announcements (doesn't go off if the xp gain is silent) +/datum/skill/proc/level_gained(datum/mind/mind, new_level, old_level, silent) + if(silent) + return to_chat(mind.current, levelUpMessages[new_level]) //new_level will be a value from 1 to 6, so we get appropriate message from the 6-element levelUpMessages list /** * level_lost: See level_gained, same idea but fires on skill level-down */ -/datum/skill/proc/level_lost(datum/mind/mind, new_level, old_level) +/datum/skill/proc/level_lost(datum/mind/mind, new_level, old_level, silent) + if(silent) + return to_chat(mind.current, levelDownMessages[old_level]) //old_level will be a value from 1 to 6, so we get appropriate message from the 6-element levelUpMessages list /** diff --git a/code/datums/skills/fishing.dm b/code/datums/skills/fishing.dm index d5ecff3c8f5769..ddf90e1a0a3ac5 100644 --- a/code/datums/skills/fishing.dm +++ b/code/datums/skills/fishing.dm @@ -8,3 +8,17 @@ desc = "How empty and alone you are on this barren Earth." modifiers = list(SKILL_VALUE_MODIFIER = list(1, 1, 0, -1, -2, -4, -6)) skill_item_path = /obj/item/clothing/head/soft/fishing_hat + +/datum/skill/fishing/New() + . = ..() + levelUpMessages[SKILL_LEVEL_MASTER] = span_nicegreen("After lots of practice, I've begun to truly understand the surprising depth behind [name]. As a master [title], I can take an easier guess of what I'm trying to catch now.") + +/datum/skill/fishing/level_gained(datum/mind/mind, new_level, old_level, silent) + . = ..() + if(new_level >= SKILL_LEVEL_MASTER && old_level < SKILL_LEVEL_MASTER) + ADD_TRAIT(mind, TRAIT_REVEAL_FISH, SKILL_TRAIT) + +/datum/skill/fishing/level_lost(datum/mind/mind, new_level, old_level, silent) + . = ..() + if(old_level >= SKILL_LEVEL_MASTER && new_level < SKILL_LEVEL_MASTER) + REMOVE_TRAIT(mind, TRAIT_REVEAL_FISH, SKILL_TRAIT) diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm index f57f6c2e9dd64d..8402c70236baae 100644 --- a/code/datums/station_traits/neutral_traits.dm +++ b/code/datums/station_traits/neutral_traits.dm @@ -148,7 +148,7 @@ show_in_report = FALSE // Selective attention test. Did you spot the gorilla? /// The gorilla we created, we only hold this ref until the round starts. - var/mob/living/simple_animal/hostile/gorilla/cargo_domestic/cargorilla + var/mob/living/basic/gorilla/cargorilla/cargorilla /datum/station_trait/cargorilla/New() . = ..() @@ -158,8 +158,8 @@ /datum/station_trait/cargorilla/proc/replace_cargo(datum/source) SIGNAL_HANDLER - var/mob/living/simple_animal/sloth/cargo_sloth = GLOB.cargo_sloth - if(!cargo_sloth) + var/mob/living/basic/sloth/cargo_sloth = GLOB.cargo_sloth + if(isnull(cargo_sloth)) return cargorilla = new(cargo_sloth.loc) @@ -189,7 +189,7 @@ cargorilla = null /// Get us a ghost for the gorilla. -/datum/station_trait/cargorilla/proc/get_ghost_for_gorilla(mob/living/simple_animal/hostile/gorilla/cargo_domestic/gorilla) +/datum/station_trait/cargorilla/proc/get_ghost_for_gorilla(mob/living/basic/gorilla/cargorilla/gorilla) if(QDELETED(gorilla)) return diff --git a/code/datums/station_traits/positive_traits.dm b/code/datums/station_traits/positive_traits.dm index 165cc4c2ad4834..7c36ed24db9e1a 100644 --- a/code/datums/station_traits/positive_traits.dm +++ b/code/datums/station_traits/positive_traits.dm @@ -283,6 +283,7 @@ /datum/job/assistant = /obj/item/organ/internal/heart/cybernetic, //real cardiac /datum/job/atmospheric_technician = /obj/item/organ/internal/cyberimp/mouth/breathing_tube, /datum/job/bartender = /obj/item/organ/internal/liver/cybernetic/tier3, + /datum/job/bitrunner = /obj/item/organ/internal/eyes/robotic/thermals, /datum/job/botanist = /obj/item/organ/internal/cyberimp/chest/nutriment, /datum/job/captain = /obj/item/organ/internal/heart/cybernetic/tier3, /datum/job/cargo_technician = /obj/item/organ/internal/stomach/cybernetic/tier2, diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index cb0b55be059afb..fd9e3d9aee5695 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -44,13 +44,15 @@ owner.apply_status_effect(/datum/status_effect/his_wrath) qdel(src) return - var/grace_heal = bloodlust * 0.05 - owner.adjustBruteLoss(-grace_heal) - owner.adjustFireLoss(-grace_heal) - owner.adjustToxLoss(-grace_heal, TRUE, TRUE) - owner.adjustOxyLoss(-(grace_heal * 2)) - owner.adjustCloneLoss(-grace_heal) - + var/grace_heal = bloodlust * 0.02 + var/need_mob_update = FALSE + need_mob_update += owner.adjustBruteLoss(-grace_heal * seconds_between_ticks, updating_health = FALSE, forced = TRUE) + need_mob_update += owner.adjustFireLoss(-grace_heal * seconds_between_ticks, updating_health = FALSE, forced = TRUE) + need_mob_update += owner.adjustToxLoss(-grace_heal * seconds_between_ticks, forced = TRUE) + need_mob_update += owner.adjustOxyLoss(-(grace_heal * 2) * seconds_between_ticks, updating_health = FALSE, forced = TRUE) + need_mob_update += owner.adjustCloneLoss(-grace_heal * seconds_between_ticks, updating_health = FALSE, forced = TRUE) + if(need_mob_update) + owner.updatehealth() /datum/status_effect/wish_granters_gift //Fully revives after ten seconds. id = "wish_granters_gift" @@ -61,7 +63,6 @@ to_chat(owner, span_notice("Death is not your end! The Wish Granter's energy suffuses you, and you begin to rise...")) return ..() - /datum/status_effect/wish_granters_gift/on_remove() owner.revive(ADMIN_HEAL_ALL) owner.visible_message(span_warning("[owner] appears to wake from the dead, having healed all wounds!"), span_notice("You have regenerated.")) @@ -140,9 +141,12 @@ if(owner.on_fire) return - owner.adjustBruteLoss(-10, FALSE) - owner.adjustFireLoss(-5, FALSE) - owner.adjustOxyLoss(-10) + var/need_mob_update = FALSE + need_mob_update += owner.adjustBruteLoss(-4 * seconds_between_ticks, updating_health = FALSE) + need_mob_update += owner.adjustFireLoss(-2 * seconds_between_ticks, updating_health = FALSE) + need_mob_update += owner.adjustOxyLoss(-4 * seconds_between_ticks, updating_health = FALSE) + if(need_mob_update) + owner.updatehealth() /datum/status_effect/fleshmend/proc/on_ignited(datum/source) SIGNAL_HANDLER @@ -254,13 +258,16 @@ //Because a servant of medicines stops at nothing to help others, lets keep them on their toes and give them an additional boost. if(itemUser.health < itemUser.maxHealth) new /obj/effect/temp_visual/heal(get_turf(itemUser), "#375637") - itemUser.adjustBruteLoss(-1.5) - itemUser.adjustFireLoss(-1.5) - itemUser.adjustToxLoss(-1.5, forced = TRUE) //Because Slime People are people too - itemUser.adjustOxyLoss(-1.5, forced = TRUE) - itemUser.adjustStaminaLoss(-1.5) - itemUser.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1.5) - itemUser.adjustCloneLoss(-0.5) //Becasue apparently clone damage is the bastion of all health + var/need_mob_update = FALSE + need_mob_update += itemUser.adjustBruteLoss(-0.6 * seconds_between_ticks, updating_health = FALSE, forced = TRUE) + need_mob_update += itemUser.adjustFireLoss(-0.6 * seconds_between_ticks, updating_health = FALSE, forced = TRUE) + need_mob_update += itemUser.adjustToxLoss(-0.6 * seconds_between_ticks, updating_health = FALSE, forced = TRUE) //Because Slime People are people too + need_mob_update += itemUser.adjustOxyLoss(-0.6 * seconds_between_ticks, updating_health = FALSE, forced = TRUE) + need_mob_update += itemUser.adjustStaminaLoss(-0.6 * seconds_between_ticks, updating_stamina = FALSE, forced = TRUE) + need_mob_update += itemUser.adjustOrganLoss(ORGAN_SLOT_BRAIN, -0.6 * seconds_between_ticks) + need_mob_update += itemUser.adjustCloneLoss(-0.2 * seconds_between_ticks, updating_health = FALSE, forced = TRUE) //Because apparently clone damage is the bastion of all health + if(need_mob_update) + itemUser.updatehealth() /datum/status_effect/hippocratic_oath/proc/consume_owner() owner.visible_message(span_notice("[owner]'s soul is absorbed into the rod, relieving the previous snake of its duty.")) @@ -274,7 +281,6 @@ owner.investigate_log("has been consumed by the Rod of Asclepius.", INVESTIGATE_DEATHS) qdel(owner) - /datum/status_effect/good_music id = "Good Music" alert_type = null @@ -444,10 +450,13 @@ qdel(src) return - owner.adjustBruteLoss(-2 * seconds_between_ticks, updating_health = FALSE) - owner.adjustFireLoss(-2 * seconds_between_ticks, updating_health = FALSE) - owner.adjustOxyLoss(-4 * seconds_between_ticks, updating_health = FALSE) - owner.adjustStaminaLoss(-4 * seconds_between_ticks, updating_stamina = FALSE) + var/need_mob_update = FALSE + need_mob_update += owner.adjustBruteLoss(-2 * seconds_between_ticks, updating_health = FALSE) + need_mob_update += owner.adjustFireLoss(-2 * seconds_between_ticks, updating_health = FALSE) + need_mob_update += owner.adjustOxyLoss(-4 * seconds_between_ticks, updating_health = FALSE) + need_mob_update += owner.adjustStaminaLoss(-4 * seconds_between_ticks, updating_stamina = FALSE) + if(need_mob_update) + owner.updatehealth() owner.adjust_bodytemperature(BODYTEMP_NORMAL, 0, BODYTEMP_NORMAL) //Won't save you from the void of space, but it will stop you from freezing or suffocating in low pressure diff --git a/code/datums/status_effects/debuffs/cursed.dm b/code/datums/status_effects/debuffs/cursed.dm index 285fb86348e0d0..8d331bbe90add7 100644 --- a/code/datums/status_effects/debuffs/cursed.dm +++ b/code/datums/status_effects/debuffs/cursed.dm @@ -102,7 +102,7 @@ to_chat(owner, span_userdanger("Why couldn't I get one more try?!")) owner.investigate_log("has been gibbed by the cursed status effect after accumulating [curse_count] curses.", INVESTIGATE_DEATHS) - owner.gib() + owner.gib(DROP_ALL_REMAINS) qdel(src) return diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index 8c8f910fd572e6..f4c78b69101f1c 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -206,6 +206,7 @@ if(locate(/obj/item/pillow) in owner.loc) healing += 0.1 + var/need_mob_update = FALSE if(healing > 0) if(iscarbon(owner)) var/mob/living/carbon/carbon_owner = owner @@ -219,10 +220,12 @@ target_organ.apply_organ_damage(-healing_bonus * target_organ.maxHealth) if(health_ratio > 0.8) // only heals minor physical damage - owner.adjustBruteLoss(-1 * healing, required_bodytype = BODYTYPE_ORGANIC) - owner.adjustFireLoss(-1 * healing, required_bodytype = BODYTYPE_ORGANIC) - owner.adjustToxLoss(-1 * healing * 0.5, TRUE, TRUE, required_biotype = MOB_ORGANIC) - owner.adjustStaminaLoss(min(-1 * healing, -1 * HEALING_SLEEP_DEFAULT)) + need_mob_update += owner.adjustBruteLoss(-0.4 * healing * seconds_between_ticks, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) + need_mob_update += owner.adjustFireLoss(-0.4 * healing * seconds_between_ticks, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) + need_mob_update += owner.adjustToxLoss(-0.2 * healing * seconds_between_ticks, updating_health = FALSE, forced = TRUE, required_biotype = MOB_ORGANIC) + need_mob_update += owner.adjustStaminaLoss(min(-0.4 * healing * seconds_between_ticks, -0.4 * HEALING_SLEEP_DEFAULT * seconds_between_ticks), updating_stamina = FALSE) + if(need_mob_update) + owner.updatehealth() // Drunkenness gets reduced by 0.3% per tick (6% per 2 seconds) owner.set_drunk_effect(owner.get_drunk_amount() * 0.997) @@ -311,9 +314,12 @@ for(var/obj/item/his_grace/HG in owner.held_items) qdel(src) return - owner.adjustBruteLoss(0.1) - owner.adjustFireLoss(0.1) - owner.adjustToxLoss(0.2, TRUE, TRUE) + var/need_mob_update + need_mob_update = owner.adjustBruteLoss(0.04 * seconds_between_ticks, updating_health = FALSE) + need_mob_update += owner.adjustFireLoss(0.04 * seconds_between_ticks, updating_health = FALSE) + need_mob_update += owner.adjustToxLoss(0.08 * seconds_between_ticks, updating_health = FALSE, forced = TRUE) + if(need_mob_update) + owner.updatehealth() /datum/status_effect/cultghost //is a cult ghost and can't use manifest runes id = "cult_ghost" @@ -688,7 +694,7 @@ /datum/status_effect/dna_melt/on_remove() if(!ishuman(owner)) - owner.gib() //fuck you in particular + owner.gib(DROP_ALL_REMAINS) //fuck you in particular return var/mob/living/carbon/human/H = owner INVOKE_ASYNC(H, TYPE_PROC_REF(/mob/living/carbon/human, something_horrible), kill_either_way) @@ -821,7 +827,8 @@ /datum/status_effect/ants/tick(seconds_between_ticks) var/mob/living/carbon/human/victim = owner - victim.adjustBruteLoss(max(0.1, round((ants_remaining * 0.004),0.1))) //Scales with # of ants (lowers with time). Roughly 10 brute over 50 seconds. + var/need_mob_update + need_mob_update = victim.adjustBruteLoss(max(0.1, round((ants_remaining * 0.0016) * seconds_between_ticks,0.1)), updating_health = FALSE) //Scales with # of ants (lowers with time). Roughly 10 brute over 50 seconds. if(victim.stat <= SOFT_CRIT) //Makes sure people don't scratch at themselves while they're in a critical condition if(prob(15)) switch(rand(1,2)) @@ -834,20 +841,22 @@ if (1 to 8) //16% Chance var/obj/item/bodypart/head/hed = victim.get_bodypart(BODY_ZONE_HEAD) to_chat(victim, span_danger("You scratch at the ants on your scalp!.")) - hed.receive_damage(1,0) + need_mob_update += hed.receive_damage(brute = 0.4 * seconds_between_ticks, burn = 0, updating_health = FALSE) if (9 to 29) //40% chance var/obj/item/bodypart/arm = victim.get_bodypart(pick(BODY_ZONE_L_ARM,BODY_ZONE_R_ARM)) to_chat(victim, span_danger("You scratch at the ants on your arms!")) - arm.receive_damage(3,0) + need_mob_update += arm.receive_damage(brute = 1.2 * seconds_between_ticks, burn = 0, updating_health = FALSE) if (30 to 49) //38% chance var/obj/item/bodypart/leg = victim.get_bodypart(pick(BODY_ZONE_L_LEG,BODY_ZONE_R_LEG)) to_chat(victim, span_danger("You scratch at the ants on your leg!")) - leg.receive_damage(3,0) + need_mob_update += leg.receive_damage(brute = 1.2 * seconds_between_ticks, burn = 0, updating_health = FALSE) if(50) // 2% chance to_chat(victim, span_danger("You rub some ants away from your eyes!")) victim.set_eye_blur_if_lower(6 SECONDS) ants_remaining -= 5 // To balance out the blindness, it'll be a little shorter. ants_remaining-- + if(need_mob_update) + victim.updatehealth() if(ants_remaining <= 0 || victim.stat >= HARD_CRIT) victim.remove_status_effect(/datum/status_effect/ants) //If this person has no more ants on them or are dead, they are no longer affected. @@ -961,5 +970,71 @@ /datum/movespeed_modifier/careful_driving multiplicative_slowdown = 3 +/datum/status_effect/midas_blight + id = "midas_blight" + alert_type = /atom/movable/screen/alert/status_effect/midas_blight + status_type = STATUS_EFFECT_REPLACE + tick_interval = 0.2 SECONDS + remove_on_fullheal = TRUE + + /// The visual overlay state, helps tell both you and enemies how much gold is in your system + var/midas_state = "midas_1" + /// How fast the gold in a person's system scales. + var/goldscale = 30 // x2.8 - Gives ~ 15u for 1 second + +/datum/status_effect/midas_blight/on_creation(mob/living/new_owner, duration = 1) + // Duration is already input in SECONDS + src.duration = duration + RegisterSignal(new_owner, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(on_update_overlays)) + return ..() + +/atom/movable/screen/alert/status_effect/midas_blight + name = "Midas Blight" + desc = "Your blood is being turned to gold, slowing your movements!" + icon_state = "midas_blight" + +/datum/status_effect/midas_blight/tick(seconds_between_ticks) + var/mob/living/carbon/human/victim = owner + // We're transmuting blood, time to lose some. + if(victim.blood_volume > BLOOD_VOLUME_SURVIVE + 50 && !HAS_TRAIT(victim, TRAIT_NOBLOOD)) + victim.blood_volume -= 5 * seconds_between_ticks + // This has been hell to try and balance so that you'll actually get anything out of it + victim.reagents.add_reagent(/datum/reagent/gold/cursed, amount = seconds_between_ticks * goldscale, no_react = TRUE) + var/current_gold_amount = victim.reagents.get_reagent_amount(/datum/reagent/gold, include_subtypes = TRUE) + switch(current_gold_amount) + if(-INFINITY to 50) + victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/soft, update = TRUE) + victim.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/midas_blight/soft, update = TRUE) + midas_state = "midas_1" + if(50 to 100) + victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/medium, update = TRUE) + victim.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/midas_blight/medium, update = TRUE) + midas_state = "midas_2" + if(100 to 200) + victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/hard, update = TRUE) + victim.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/midas_blight/hard, update = TRUE) + midas_state = "midas_3" + if(200 to INFINITY) + victim.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/midas_blight/gold, update = TRUE) + victim.add_actionspeed_modifier(/datum/actionspeed_modifier/status_effect/midas_blight/gold, update = TRUE) + midas_state = "midas_4" + victim.update_icon() + if(victim.stat == DEAD) + qdel(src) // Dead people stop being turned to gold. Don't want people sitting on dead bodies. + +/datum/status_effect/midas_blight/proc/on_update_overlays(atom/parent_atom, list/overlays) + SIGNAL_HANDLER + + if(midas_state) + var/mutable_appearance/midas_overlay = mutable_appearance('icons/mob/effects/debuff_overlays.dmi', midas_state) + midas_overlay.blend_mode = BLEND_MULTIPLY + overlays += midas_overlay + +/datum/status_effect/midas_blight/on_remove() + owner.remove_movespeed_modifier(MOVESPEED_ID_MIDAS_BLIGHT, update = TRUE) + owner.remove_actionspeed_modifier(ACTIONSPEED_ID_MIDAS_BLIGHT, update = TRUE) + UnregisterSignal(owner, COMSIG_ATOM_UPDATE_OVERLAYS) + owner.update_icon() + #undef HEALING_SLEEP_DEFAULT #undef HEALING_SLEEP_ORGAN_MULTIPLIER diff --git a/code/datums/status_effects/debuffs/drunk.dm b/code/datums/status_effects/debuffs/drunk.dm index 705fcc60eeb97b..cdac6b59225005 100644 --- a/code/datums/status_effects/debuffs/drunk.dm +++ b/code/datums/status_effects/debuffs/drunk.dm @@ -213,19 +213,28 @@ if(drunk_value >= 91) owner.adjustToxLoss(1) owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.4) - if(owner.stat == CONSCIOUS && prob(20)) - // Don't put us in a deep sleep if the shuttle's here. QoL, mainly. - if(SSshuttle.emergency.mode == SHUTTLE_DOCKED && is_station_level(owner.z)) - to_chat(owner, span_warning("You're so tired... but you can't miss that shuttle...")) - - else - to_chat(owner, span_warning("Just a quick nap...")) - owner.Sleeping(90 SECONDS) + if(owner.stat == CONSCIOUS) + attempt_to_blackout() // And finally, over 100 - let's be honest, you shouldn't be alive by now. if(drunk_value >= 101) owner.adjustToxLoss(2) +/datum/status_effect/inebriated/drunk/proc/attempt_to_blackout() + /* SKYRAT EDIT REMOVAL - Blackout drunk begone + var/mob/living/carbon/drunkard = owner + if(drunkard.gain_trauma(/datum/brain_trauma/severe/split_personality/blackout, TRAUMA_LIMIT_ABSOLUTE)) + drunk_value -= 50 //So that the drunk personality can spice things up without being killed by liver failure + return + else if(drunkard.has_trauma_type(/datum/brain_trauma/severe/split_personality/blackout) && prob(10)) + to_chat(owner, span_warning("You stumbled and fall over!")) + owner.slip(1 SECONDS) + */ // SKYRAT EDIT REMOVAL END (also removed the else on the line after) + if(SSshuttle.emergency.mode == SHUTTLE_DOCKED && is_station_level(owner.z))// Don't put us in a deep sleep if the shuttle's here. QoL, mainly. + to_chat(owner, span_warning("You're so tired... but you can't miss that shuttle...")) + else + owner.Sleeping(90 SECONDS) + /// Status effect for being fully drunk (not tipsy). /atom/movable/screen/alert/status_effect/drunk name = "Drunk" diff --git a/code/datums/status_effects/debuffs/fire_stacks.dm b/code/datums/status_effects/debuffs/fire_stacks.dm index 112e8bd861409e..6f31faaefaae6b 100644 --- a/code/datums/status_effects/debuffs/fire_stacks.dm +++ b/code/datums/status_effects/debuffs/fire_stacks.dm @@ -147,7 +147,10 @@ if(!on_fire) return TRUE - adjust_stacks(owner.fire_stack_decay_rate * seconds_between_ticks) + if(HAS_TRAIT(owner, TRAIT_HUSK)) + adjust_stacks(-2 * seconds_between_ticks) + else + adjust_stacks(owner.fire_stack_decay_rate * seconds_between_ticks) if(stacks <= 0) qdel(src) diff --git a/code/datums/status_effects/debuffs/static_vision.dm b/code/datums/status_effects/debuffs/static_vision.dm new file mode 100644 index 00000000000000..7132c189b9d449 --- /dev/null +++ b/code/datums/status_effects/debuffs/static_vision.dm @@ -0,0 +1,29 @@ +/datum/status_effect/static_vision + id = "static_vision" + status_type = STATUS_EFFECT_REPLACE + alert_type = null + +/datum/status_effect/static_vision/on_creation(mob/living/new_owner, duration = 3 SECONDS) + src.duration = duration + return ..() + +/datum/status_effect/static_vision/on_apply() + RegisterSignal(owner, COMSIG_LIVING_DEATH, PROC_REF(remove_static_vision)) + + owner.overlay_fullscreen(id, /atom/movable/screen/fullscreen/static_vision) + owner.sound_environment_override = SOUND_ENVIRONMENT_UNDERWATER + + return TRUE + +/datum/status_effect/static_vision/on_remove() + UnregisterSignal(owner, COMSIG_LIVING_DEATH) + + owner.clear_fullscreen(id) + if(owner.sound_environment_override == SOUND_ENVIRONMENT_UNDERWATER) + owner.sound_environment_override = SOUND_ENVIRONMENT_NONE + +/// Handles clearing on death +/datum/status_effect/static_vision/proc/remove_static_vision(datum/source, admin_revive) + SIGNAL_HANDLER + + qdel(src) diff --git a/code/datums/status_effects/drug_effects.dm b/code/datums/status_effects/drug_effects.dm index d01a92743b5890..1d37c8f0e43eba 100644 --- a/code/datums/status_effects/drug_effects.dm +++ b/code/datums/status_effects/drug_effects.dm @@ -70,7 +70,7 @@ /datum/status_effect/stoned/on_apply() if(!ishuman(owner)) - CRASH("[type] status effect added to non-human owner: [owner ? owner.type : "null owner"]") + return FALSE var/mob/living/carbon/human/human_owner = owner original_eye_color_left = human_owner.eye_color_left original_eye_color_right = human_owner.eye_color_right @@ -85,7 +85,7 @@ /datum/status_effect/stoned/on_remove() if(!ishuman(owner)) - stack_trace("[type] status effect being removed from non-human owner: [owner ? owner.type : "null owner"]") + return var/mob/living/carbon/human/human_owner = owner human_owner.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/cannabis) human_owner.eye_color_left = original_eye_color_left diff --git a/code/datums/status_effects/neutral.dm b/code/datums/status_effects/neutral.dm index 7161946c9ff9f5..a2aa81ebb698a0 100644 --- a/code/datums/status_effects/neutral.dm +++ b/code/datums/status_effects/neutral.dm @@ -109,11 +109,14 @@ for(var/datum/action/cooldown/spell/spell in rewarded.actions) spell.reset_spell_cooldown() - rewarded.adjustBruteLoss(-25) - rewarded.adjustFireLoss(-25) - rewarded.adjustToxLoss(-25) - rewarded.adjustOxyLoss(-25) - rewarded.adjustCloneLoss(-25) + var/need_mob_update = FALSE + need_mob_update += rewarded.adjustBruteLoss(-25, updating_health = FALSE) + need_mob_update += rewarded.adjustFireLoss(-25, updating_health = FALSE) + need_mob_update += rewarded.adjustToxLoss(-25, updating_health = FALSE) + need_mob_update += rewarded.adjustOxyLoss(-25, updating_health = FALSE) + need_mob_update += rewarded.adjustCloneLoss(-25, updating_health = FALSE) + if(need_mob_update) + rewarded.updatehealth() // heldup is for the person being aimed at /datum/status_effect/grouped/heldup diff --git a/code/datums/storage/subtypes/bag_of_holding.dm b/code/datums/storage/subtypes/bag_of_holding.dm index 9176588b5fca7f..9e3a486cdcd4ae 100644 --- a/code/datums/storage/subtypes/bag_of_holding.dm +++ b/code/datums/storage/subtypes/bag_of_holding.dm @@ -32,6 +32,6 @@ user.log_message("detonated a bag of holding at [loc_name(loccheck)].", LOG_ATTACK, color="red") user.investigate_log("has been gibbed by a bag of holding recursive insertion.", INVESTIGATE_DEATHS) - user.gib(TRUE, TRUE, TRUE) + user.gib() new/obj/boh_tear(loccheck) qdel(resolve_parent) diff --git a/code/datums/storage/subtypes/surgery_tray.dm b/code/datums/storage/subtypes/surgery_tray.dm index 358865813188b0..42b369b4ce9221 100644 --- a/code/datums/storage/subtypes/surgery_tray.dm +++ b/code/datums/storage/subtypes/surgery_tray.dm @@ -6,6 +6,7 @@ /datum/storage/surgery_tray/New() . = ..() set_holdable(list( + /obj/item/autopsy_scanner, /obj/item/blood_filter, /obj/item/bonesetter, /obj/item/cautery, diff --git a/code/datums/weather/weather_types/void_storm.dm b/code/datums/weather/weather_types/void_storm.dm index becfa9859a81a8..4d3638c5827116 100644 --- a/code/datums/weather/weather_types/void_storm.dm +++ b/code/datums/weather/weather_types/void_storm.dm @@ -33,8 +33,11 @@ return FALSE /datum/weather/void_storm/weather_act(mob/living/victim) - victim.adjustFireLoss(1) - victim.adjustOxyLoss(rand(1, 3)) + var/need_mob_update = FALSE + victim.adjustFireLoss(1, updating_health = FALSE) + victim.adjustOxyLoss(rand(1, 3), updating_health = FALSE) + if(need_mob_update) + victim.updatehealth() victim.adjust_eye_blur(rand(0 SECONDS, 2 SECONDS)) victim.adjust_bodytemperature(-30 * TEMPERATURE_DAMAGE_COEFFICIENT) diff --git a/code/datums/wires/explosive.dm b/code/datums/wires/explosive.dm index 925c948183124e..800b5b884449f5 100644 --- a/code/datums/wires/explosive.dm +++ b/code/datums/wires/explosive.dm @@ -151,4 +151,4 @@ /datum/wires/explosive/gibtonite/explode() var/obj/item/gibtonite/P = holder - P.GibtoniteReaction(null, 2) + P.GibtoniteReaction(null, "A wire signal has primed a") diff --git a/code/datums/wires/microwave.dm b/code/datums/wires/microwave.dm index abce90e8de5e24..e3efabac08c4d6 100644 --- a/code/datums/wires/microwave.dm +++ b/code/datums/wires/microwave.dm @@ -4,7 +4,8 @@ /datum/wires/microwave/New(atom/holder) wires = list( - WIRE_ACTIVATE + WIRE_ACTIVATE, + WIRE_MODE_SELECT ) ..() @@ -12,18 +13,23 @@ if(!..()) return FALSE . = FALSE - var/obj/machinery/microwave/M = holder - if(M.panel_open) + var/obj/machinery/microwave/mw = holder + if(mw.panel_open) . = TRUE /datum/wires/microwave/on_pulse(wire) - var/obj/machinery/microwave/M = holder + var/obj/machinery/microwave/mw = holder switch(wire) if(WIRE_ACTIVATE) - M.cook() + mw.cook() + if(WIRE_MODE_SELECT) + if(mw.vampire_charging_capable) + mw.vampire_charging_enabled = !mw.vampire_charging_enabled /datum/wires/microwave/on_cut(wire, mend, source) - var/obj/machinery/microwave/M = holder + var/obj/machinery/microwave/mw = holder switch(wire) if(WIRE_ACTIVATE) - M.wire_disabled = !mend + mw.wire_disabled = !mend + if(WIRE_MODE_SELECT) + mw.wire_mode_swap = !mend diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm index 265b9d49815920..d930c496de6ce9 100644 --- a/code/datums/world_topic.dm +++ b/code/datums/world_topic.dm @@ -195,7 +195,7 @@ /datum/world_topic/status/Run(list/input) . = list() .["version"] = GLOB.game_version - .["respawn"] = config ? !CONFIG_GET(flag/norespawn) : FALSE + .["respawn"] = config ? !!CONFIG_GET(flag/allow_respawn) : FALSE // show respawn as true regardless of "respawn as char" or "free respawn" .["enter"] = !LAZYACCESS(SSlag_switch.measures, DISABLE_NON_OBSJOBS) .["ai"] = CONFIG_GET(flag/allow_ai) .["host"] = world.host ? world.host : null @@ -240,4 +240,3 @@ // Shuttle status, see /__DEFINES/stat.dm .["shuttle_timer"] = SSshuttle.emergency.timeLeft() // Shuttle timer, in seconds - diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm index faf1ef87057221..7d211b9ae29247 100644 --- a/code/datums/wounds/_wounds.dm +++ b/code/datums/wounds/_wounds.dm @@ -185,7 +185,7 @@ * * attack_direction: For bloodsplatters, if relevant * * wound_source: The source of the wound, such as a weapon. */ -/datum/wound/proc/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE, attack_direction = null, wound_source = "Unknown") +/datum/wound/proc/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE, attack_direction = null, wound_source = "Unknown", replacing = FALSE) if (!can_be_applied_to(L, old_wound)) qdel(src) @@ -198,7 +198,7 @@ src.wound_source = wound_source set_victim(L.owner) - set_limb(L) + set_limb(L, replacing) LAZYADD(victim.all_wounds, src) LAZYADD(limb.wounds, src) update_descriptions() @@ -290,7 +290,7 @@ . = limb if(limb) // if we're nulling limb, we're basically detaching from it, so we should remove ourselves in that case UnregisterSignal(limb, COMSIG_QDELETING) - UnregisterSignal(limb, list(COMSIG_BODYPART_GAUZED, COMSIG_BODYPART_GAUZE_DESTROYED)) + UnregisterSignal(limb, list(COMSIG_BODYPART_GAUZED, COMSIG_BODYPART_UNGAUZED)) LAZYREMOVE(limb.wounds, src) limb.update_wounds(replaced) if (disabling) @@ -302,7 +302,7 @@ if (limb) RegisterSignal(limb, COMSIG_QDELETING, PROC_REF(source_died)) - RegisterSignals(limb, list(COMSIG_BODYPART_GAUZED, COMSIG_BODYPART_GAUZE_DESTROYED), PROC_REF(gauze_state_changed)) + RegisterSignals(limb, list(COMSIG_BODYPART_GAUZED, COMSIG_BODYPART_UNGAUZED), PROC_REF(gauze_state_changed)) if (disabling) limb.add_traits(list(TRAIT_PARALYSIS, TRAIT_DISABLED_BY_WOUND), REF(src)) @@ -371,7 +371,7 @@ already_scarred = TRUE var/obj/item/bodypart/cached_limb = limb // remove_wound() nulls limb so we have to track it locally remove_wound(replaced=TRUE) - new_wound.apply_wound(cached_limb, old_wound = src, smited = smited, attack_direction = attack_direction, wound_source = wound_source) + new_wound.apply_wound(cached_limb, old_wound = src, smited = smited, attack_direction = attack_direction, wound_source = wound_source, replacing = TRUE) . = new_wound qdel(src) @@ -435,14 +435,14 @@ else limp_slowdown = initial(limp_slowdown) limp_chance = initial(limp_chance) - else if(limb.body_zone in list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + else if(limb.body_zone in GLOB.arm_zones) if(limb.current_gauze?.splint_factor) set_interaction_efficiency_penalty(1 + ((get_effective_actionspeed_modifier()) * limb.current_gauze.splint_factor)) else set_interaction_efficiency_penalty(initial(interaction_efficiency_penalty)) if(initial(disabling)) - set_disabling(!limb.current_gauze) + set_disabling(isnull(limb.current_gauze)) limb.update_wounds(replaced_or_replacing) diff --git a/code/datums/wounds/bones.dm b/code/datums/wounds/bones.dm index 59e64db1ccf3d6..270d2a23f42868 100644 --- a/code/datums/wounds/bones.dm +++ b/code/datums/wounds/bones.dm @@ -384,7 +384,7 @@ threshold_minimum = 115 // doesn't make much sense for "a" bone to stick out of your head -/datum/wound/blunt/bone/critical/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE, attack_direction = null, wound_source = "Unknown") +/datum/wound/blunt/bone/critical/apply_wound(obj/item/bodypart/L, silent = FALSE, datum/wound/old_wound = null, smited = FALSE, attack_direction = null, wound_source = "Unknown", replacing = FALSE) if(L.body_zone == BODY_ZONE_HEAD) occur_text = "splits open, exposing a bare, cracked skull through the flesh and blood" examine_desc = "has an unsettling indent, with bits of skull poking out" diff --git a/code/datums/wounds/burns.dm b/code/datums/wounds/burns.dm index a97706c8e16d8d..39e91d06fb65f4 100644 --- a/code/datums/wounds/burns.dm +++ b/code/datums/wounds/burns.dm @@ -48,7 +48,7 @@ for(var/datum/reagent/reagent as anything in victim.reagents.reagent_list) if(reagent.chemical_flags & REAGENT_AFFECTS_WOUNDS) - reagent.on_burn_wound_processing() + reagent.on_burn_wound_processing(src) if(HAS_TRAIT(victim, TRAIT_VIRUS_RESISTANCE)) sanitization += 0.9 diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 4912a69f7b8e6b..add1cdf887c19b 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -129,6 +129,11 @@ var/base_pixel_x = 0 ///Default pixel y shifting for the atom's icon. var/base_pixel_y = 0 + // Use SET_BASE_VISUAL_PIXEL(x, y) to set these in typepath definitions, it'll handle pixel_w and z for you + ///Default pixel w shifting for the atom's icon. + var/base_pixel_w = 0 + ///Default pixel z shifting for the atom's icon. + var/base_pixel_z = 0 ///Used for changing icon states for different base sprites. var/base_icon_state @@ -318,6 +323,8 @@ /atom/proc/CanPass(atom/movable/mover, border_dir) SHOULD_CALL_PARENT(TRUE) SHOULD_BE_PURE(TRUE) + if(SEND_SIGNAL(src, COMSIG_ATOM_TRIED_PASS, mover, border_dir) & COMSIG_COMPONENT_PERMIT_PASSAGE) + return TRUE if(mover.movement_type & PHASING) return TRUE . = CanAllowThrough(mover, border_dir) @@ -672,11 +679,11 @@ var/reagent_sigreturn = SEND_SIGNAL(src, COMSIG_ATOM_REAGENT_EXAMINE, user, ., user_sees_reagents) if(!(reagent_sigreturn & STOP_GENERIC_REAGENT_EXAMINE)) if(reagents.flags & TRANSPARENT) - if(reagents.total_volume > 0) + if(reagents.total_volume) . += "It contains [round(reagents.total_volume, 0.01)] units of various reagents[user_sees_reagents ? ":" : "."]" - if(user_sees_reagents) //Show each individual reagent + if(user_sees_reagents) //Show each individual reagent for detailed examination for(var/datum/reagent/current_reagent as anything in reagents.reagent_list) - . += "• [round(current_reagent.volume, 0.01)] units of [current_reagent.name]" + . += "• [FLOOR(current_reagent.volume, CHEMICAL_QUANTISATION_LEVEL)] units of [current_reagent.name]" if(reagents.is_reacting) . += span_warning("It is currently reacting!") . += span_notice("The solution's pH is [round(reagents.ph, 0.01)] and has a temperature of [reagents.chem_temp]K.") diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm index 0be75a321ef88a..dbc9a19a6c5152 100644 --- a/code/game/data_huds.dm +++ b/code/game/data_huds.dm @@ -18,7 +18,7 @@ /datum/atom_hud/data /datum/atom_hud/data/human/medical - hud_icons = list(STATUS_HUD, HEALTH_HUD) + hud_icons = list(STATUS_HUD, HEALTH_HUD, DNR_HUD) // SKYRAT EDIT ADDITION - DNR_HUD /datum/atom_hud/data/human/medical/basic @@ -47,7 +47,7 @@ hud_icons = list(ID_HUD) /datum/atom_hud/data/human/security/advanced - hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD, WANTED_HUD, PERMIT_HUD) //SKYRAT EDIT: ADD PERMIT_HUD + hud_icons = list(ID_HUD, IMPTRACK_HUD, IMPLOYAL_HUD, IMPCHEM_HUD, WANTED_HUD, PERMIT_HUD, DNR_HUD) //SKYRAT EDIT ADDITION - PERMIT_HUD, DNR_HUD /datum/atom_hud/data/human/fan_hud hud_icons = list(FAN_HUD) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 6208df36de1b67..ce64f2004587af 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -17,6 +17,8 @@ GLOBAL_LIST_EMPTY(dynamic_forced_roundstart_ruleset) GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1) /// Modify the threat level for station traits before dynamic can be Initialized. List(instance = threat_reduction) GLOBAL_LIST_EMPTY(dynamic_station_traits) +/// Rulesets which have been forcibly enabled or disabled +GLOBAL_LIST_EMPTY(dynamic_forced_rulesets) /datum/game_mode/dynamic // Threat logging vars diff --git a/code/game/gamemodes/dynamic/dynamic_midround_rolling.dm b/code/game/gamemodes/dynamic/dynamic_midround_rolling.dm index 5079035834be55..c3e295ae875fee 100644 --- a/code/game/gamemodes/dynamic/dynamic_midround_rolling.dm +++ b/code/game/gamemodes/dynamic/dynamic_midround_rolling.dm @@ -45,7 +45,11 @@ continue if (!ruleset.acceptable(GLOB.alive_player_list.len, threat_level)) - log_dynamic("FAIL: [ruleset] is not acceptable with the current parameters. Alive players: [GLOB.alive_player_list.len], threat level: [threat_level]") + var/ruleset_forced = GLOB.dynamic_forced_rulesets[type] || RULESET_NOT_FORCED + if (ruleset_forced == RULESET_NOT_FORCED) + log_dynamic("FAIL: [ruleset] is not acceptable with the current parameters. Alive players: [GLOB.alive_player_list.len], threat level: [threat_level]") + else + log_dynamic("FAIL: [ruleset] was disabled.") continue if (mid_round_budget < ruleset.cost) diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets.dm b/code/game/gamemodes/dynamic/dynamic_rulesets.dm index a1c4c9232e2bf4..0af18e0b0aa81f 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets.dm @@ -33,6 +33,7 @@ JOB_DETECTIVE, JOB_HEAD_OF_SECURITY, JOB_SECURITY_OFFICER, + JOB_WARDEN, ) /// If enemy_roles was set, this is the amount of enemy job workers needed per threat_level range (0-10,10-20,etc) IMPORTANT: DOES NOT WORK ON ROUNDSTART RULESETS. var/required_enemies = list(1,1,0,0,0,0,0,0,0,0) @@ -105,23 +106,39 @@ /// By default, a rule is acceptable if it satisfies the threat level/population requirements. /// If your rule has extra checks, such as counting security officers, do that in ready() instead /datum/dynamic_ruleset/proc/acceptable(population = 0, threat_level = 0) - pop_per_requirement = pop_per_requirement > 0 ? pop_per_requirement : mode.pop_per_requirement - indice_pop = min(requirements.len,round(population/pop_per_requirement)+1) - - if(minimum_players > population) - log_dynamic("FAIL: [src] failed acceptable: minimum_players ([minimum_players]) > population ([population])") + var/ruleset_forced = GLOB.dynamic_forced_rulesets[type] || RULESET_NOT_FORCED + if (ruleset_forced != RULESET_NOT_FORCED) + if (ruleset_forced == RULESET_FORCE_ENABLED) + return TRUE + else + log_dynamic("FAIL: [src] was disabled in admin panel.") + return FALSE + + if(!is_valid_population(population)) + var/range = maximum_players > 0 ? "([minimum_players] - [maximum_players])" : "(minimum: [minimum_players])" + log_dynamic("FAIL: [src] failed acceptable: min/max players out of range [range] vs population ([population])") return FALSE - if(maximum_players > 0 && population > maximum_players) - log_dynamic("FAIL: [src] failed acceptable: maximum_players ([maximum_players]) < population ([population])") - return FALSE - - if (threat_level < requirements[indice_pop]) + if (!is_valid_threat(population, threat_level)) log_dynamic("FAIL: [src] failed acceptable: threat_level ([threat_level]) < requirement ([requirements[indice_pop]])") return FALSE return TRUE +/// Returns true if we have enough players to run +/datum/dynamic_ruleset/proc/is_valid_population(population) + if(minimum_players > population) + return FALSE + if(maximum_players > 0 && population > maximum_players) + return FALSE + return TRUE + +/// Sets the current threat indices and returns true if we're inside of them +/datum/dynamic_ruleset/proc/is_valid_threat(population, threat_level) + pop_per_requirement = pop_per_requirement > 0 ? pop_per_requirement : mode.pop_per_requirement + indice_pop = min(requirements.len,round(population/pop_per_requirement)+1) + return threat_level >= requirements[indice_pop] + /// When picking rulesets, if dynamic picks the same one multiple times, it will "scale up". /// However, doing this blindly would result in lowpop rounds (think under 10 people) where over 80% of the crew is antags! /// This function is here to ensure the antag ratio is kept under control while scaling up. @@ -174,7 +191,7 @@ candidates = list() assigned = list() antag_datum = null - + /// Here you can perform any additional checks you want. (such as checking the map etc) /// Remember that on roundstart no one knows what their job is at this point. /// IMPORTANT: If ready() returns TRUE, that means pre_execute() or execute() should never fail! diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm index 3610d8aad91086..7b125439d53d50 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm @@ -38,8 +38,8 @@ job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it var/threat = round(mode.threat_level/10) - - if (job_check < required_enemies[threat]) + var/ruleset_forced = (GLOB.dynamic_forced_rulesets[type] || RULESET_NOT_FORCED) == RULESET_FORCE_ENABLED + if (!ruleset_forced && job_check < required_enemies[threat]) log_dynamic("FAIL: [src] is not ready, because there are not enough enemies: [required_enemies[threat]] needed, [job_check] found") return FALSE diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm index 91f82f29f1ca43..80fcbc54db88ce 100644 --- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm +++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm @@ -52,42 +52,50 @@ dead_players = trim_list(GLOB.dead_player_list) list_observers = trim_list(GLOB.current_observers_list) -/datum/dynamic_ruleset/midround/proc/trim_list(list/L = list()) - var/list/trimmed_list = L.Copy() - for(var/mob/M in trimmed_list) - if (!istype(M, required_type)) - trimmed_list.Remove(M) +/datum/dynamic_ruleset/midround/proc/trim_list(list/to_trim = list()) + var/list/trimmed_list = to_trim.Copy() + for(var/mob/creature in trimmed_list) + if (!istype(creature, required_type)) + trimmed_list.Remove(creature) continue - if (!M.client) // Are they connected? - trimmed_list.Remove(M) + if (isnull(creature.client)) // Are they connected? + trimmed_list.Remove(creature) + continue + if (isnull(creature.mind)) + trimmed_list.Remove(creature) continue //SKYRAT EDIT ADDITION - if(is_banned_from(M.client.ckey, BAN_ANTAGONIST)) - trimmed_list.Remove(M) + if(is_banned_from(creature.client.ckey, BAN_ANTAGONIST)) + trimmed_list.Remove(creature) continue - if(!M.client?.prefs?.read_preference(/datum/preference/toggle/be_antag)) - trimmed_list.Remove(M) + if(!creature.client?.prefs?.read_preference(/datum/preference/toggle/be_antag)) + trimmed_list.Remove(creature) continue //SKYRAT EDIT END - if(M.client.get_remaining_days(minimum_required_age) > 0) - trimmed_list.Remove(M) + if(creature.client.get_remaining_days(minimum_required_age) > 0) + trimmed_list.Remove(creature) continue - if (!((antag_preference || antag_flag) in M.client.prefs.be_special)) - trimmed_list.Remove(M) + if (!((antag_preference || antag_flag) in creature.client.prefs.be_special)) + trimmed_list.Remove(creature) continue - if (is_banned_from(M.ckey, list(antag_flag_override || antag_flag, ROLE_SYNDICATE))) - trimmed_list.Remove(M) + if (is_banned_from(creature.ckey, list(antag_flag_override || antag_flag, ROLE_SYNDICATE))) + trimmed_list.Remove(creature) + continue + if (restrict_ghost_roles && (creature.mind.assigned_role.title in GLOB.exp_specialmap[EXP_TYPE_SPECIAL])) // Are they playing a ghost role? + trimmed_list.Remove(creature) + continue + if (creature.mind.assigned_role.title in restricted_roles) // Does their job allow it? + trimmed_list.Remove(creature) + continue + if (length(exclusive_roles) && !(creature.mind.assigned_role.title in exclusive_roles)) // Is the rule exclusive to their job? + trimmed_list.Remove(creature) + continue + if(HAS_TRAIT(creature, TRAIT_MIND_TEMPORARILY_GONE)) // are they out of body? + trimmed_list.Remove(creature) + continue + if(HAS_TRAIT(creature, TRAIT_TEMPORARY_BODY)) // are they an avatar? + trimmed_list.Remove(creature) continue - if (M.mind) - if (restrict_ghost_roles && (M.mind.assigned_role.title in GLOB.exp_specialmap[EXP_TYPE_SPECIAL])) // Are they playing a ghost role? - trimmed_list.Remove(M) - continue - if (M.mind.assigned_role.title in restricted_roles) // Does their job allow it? - trimmed_list.Remove(M) - continue - if ((exclusive_roles.len > 0) && !(M.mind.assigned_role.title in exclusive_roles)) // Is the rule exclusive to their job? - trimmed_list.Remove(M) - continue return trimmed_list // You can then for example prompt dead players in execute() to join as strike teams or whatever @@ -108,8 +116,8 @@ job_check++ // Checking for "enemies" (such as sec officers). To be counters, they must either not be candidates to that rule, or have a job that restricts them from it var/threat = round(mode.threat_level/10) - - if (job_check < required_enemies[threat]) + var/ruleset_forced = (GLOB.dynamic_forced_rulesets[type] || RULESET_NOT_FORCED) == RULESET_FORCE_ENABLED + if (!ruleset_forced && job_check < required_enemies[threat]) log_dynamic("FAIL: [src] is not ready, because there are not enough enemies: [required_enemies[threat]] needed, [job_check] found") return FALSE @@ -366,6 +374,7 @@ JOB_DETECTIVE, JOB_HEAD_OF_SECURITY, JOB_SECURITY_OFFICER, + JOB_WARDEN, ) required_enemies = list(3,3,3,3,3,2,1,1,0,0) required_candidates = 5 @@ -378,7 +387,7 @@ var/list/operative_cap = list(2,2,3,3,4,5,5,5,5,5) -/datum/dynamic_ruleset/midround/from_ghosts/nuclear/acceptable(population=0, threat=0) +/datum/dynamic_ruleset/midround/from_ghosts/nuclear/acceptable(population=0, threat_level=0) if (locate(/datum/dynamic_ruleset/roundstart/nuclear) in mode.executed_rules) return FALSE // Unavailable if nuke ops were already sent at roundstart indice_pop = min(operative_cap.len, round(living_players.len/5)+1) @@ -533,7 +542,7 @@ minimum_players = 15 repeatable = TRUE -/datum/dynamic_ruleset/midround/from_ghosts/nightmare/acceptable(population = 0, threat = 0) +/datum/dynamic_ruleset/midround/from_ghosts/nightmare/acceptable(population = 0, threat_level = 0) var/turf/spawn_loc = find_maintenance_spawn(atmos_sensitive = TRUE, require_darkness = TRUE) //Checks if there's a single safe, dark tile on station. if(!spawn_loc) return FALSE @@ -710,7 +719,7 @@ spawn_locs = list() return ..() -/datum/dynamic_ruleset/midround/from_ghosts/revenant/acceptable(population=0, threat=0) +/datum/dynamic_ruleset/midround/from_ghosts/revenant/acceptable(population=0, threat_level=0) if(GLOB.dead_mob_list.len < dead_mobs_required) return FALSE return ..() @@ -734,7 +743,7 @@ . = ..() /datum/dynamic_ruleset/midround/from_ghosts/revenant/generate_ruleset_body(mob/applicant) - var/mob/living/simple_animal/revenant/revenant = new(pick(spawn_locs)) + var/mob/living/basic/revenant/revenant = new(pick(spawn_locs)) revenant.key = applicant.key message_admins("[ADMIN_LOOKUPFLW(revenant)] has been made into a revenant by the midround ruleset.") log_game("[key_name(revenant)] was spawned as a revenant by the midround ruleset.") @@ -773,7 +782,7 @@ minimum_players = 20 repeatable = TRUE -/datum/dynamic_ruleset/midround/pirates/acceptable(population=0, threat=0) +/datum/dynamic_ruleset/midround/pirates/acceptable(population=0, threat_level=0) if (SSmapping.is_planetary() || GLOB.light_pirate_gangs.len == 0) return FALSE return ..() @@ -795,7 +804,7 @@ minimum_players = 25 repeatable = TRUE -/datum/dynamic_ruleset/midround/dangerous_pirates/acceptable(population=0, threat=0) +/datum/dynamic_ruleset/midround/dangerous_pirates/acceptable(population=0, threat_level=0) if (SSmapping.is_planetary() || GLOB.heavy_pirate_gangs.len == 0) return FALSE return ..() @@ -873,6 +882,7 @@ JOB_DETECTIVE, JOB_HEAD_OF_SECURITY, JOB_SECURITY_OFFICER, + JOB_WARDEN, ) required_enemies = list(2, 2, 1, 1, 1, 1, 1, 0, 0, 0) required_candidates = 1 diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index fde5c89b88de94..494f1cca77ef79 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -591,13 +591,7 @@ if(!isliving(user)) return FALSE //no ghosts allowed, sorry - var/is_dextrous = FALSE - if(isanimal(user)) - var/mob/living/simple_animal/user_as_animal = user - if (user_as_animal.dextrous) - is_dextrous = TRUE - - if(!issilicon(user) && !is_dextrous && !user.can_hold_items()) + if(!issilicon(user) && !user.can_hold_items()) return FALSE //spiders gtfo if(issilicon(user)) // If we are a silicon, make sure the machine allows silicons to interact with it diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm index 4c3532e3616b0a..f4d1b29da186f6 100644 --- a/code/game/machinery/airlock_control.dm +++ b/code/game/machinery/airlock_control.dm @@ -6,10 +6,6 @@ var/airlock_state var/frequency -/obj/machinery/door/airlock/Initialize(mapload) - . = ..() - RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide)) - /// Forces the airlock to unbolt and open /obj/machinery/door/airlock/proc/secure_open() locked = FALSE @@ -35,17 +31,6 @@ locked = FALSE return ..() -/obj/machinery/door/airlock/proc/grey_tide(datum/source, list/grey_tide_areas) - SIGNAL_HANDLER - - if(!is_station_level(z) || critical_machine) - return //Skip doors in critical positions, such as the SM chamber. - - for(var/area_type in grey_tide_areas) - if(!istype(get_area(src), area_type)) - continue - INVOKE_ASYNC(src, PROC_REF(prison_open)) //Sleep gets called further down in open(), so we have to invoke async - /obj/machinery/airlock_sensor icon = 'icons/obj/machines/wallmounts.dmi' icon_state = "airlock_sensor_off" diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 87e53ebb368de1..2bc13e156d441d 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -65,10 +65,12 @@ /obj/machinery/computer/aifixer/proc/Fix() use_power(1000) - occupier.adjustOxyLoss(-5, FALSE) - occupier.adjustFireLoss(-5, FALSE) - occupier.adjustBruteLoss(-5, FALSE) - occupier.updatehealth() + var/need_mob_update = FALSE + need_mob_update += occupier.adjustOxyLoss(-5, updating_health = FALSE) + need_mob_update += occupier.adjustFireLoss(-5, updating_health = FALSE) + need_mob_update += occupier.adjustBruteLoss(-5, updating_health = FALSE) + if(need_mob_update) + occupier.updatehealth() if(occupier.health >= 0 && occupier.stat == DEAD) occupier.revive() if(!occupier.radio_enabled) diff --git a/code/game/machinery/computer/arcade/arcade.dm b/code/game/machinery/computer/arcade/arcade.dm index 28034872289e3a..58a7280e8643e9 100644 --- a/code/game/machinery/computer/arcade/arcade.dm +++ b/code/game/machinery/computer/arcade/arcade.dm @@ -582,7 +582,7 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( var/mob/living/living_user = user if (istype(living_user)) living_user.investigate_log("has been gibbed by an emagged Orion Trail game.", INVESTIGATE_DEATHS) - living_user.gib() + living_user.gib(DROP_ALL_REMAINS) SSblackbox.record_feedback("nested tally", "arcade_results", 1, list("loss", "hp", (obj_flags & EMAGGED ? "emagged":"normal"))) user.lost_game() diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 5a604cd969b7d4..54e622fb12d384 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -82,17 +82,18 @@ /obj/machinery/computer/security/ui_data() var/list/data = list() - data["network"] = network data["activeCamera"] = null if(active_camera) data["activeCamera"] = list( name = active_camera.c_tag, + ref = REF(active_camera), status = active_camera.status, ) return data /obj/machinery/computer/security/ui_static_data() var/list/data = list() + data["network"] = network data["mapRef"] = cam_screen.assigned_map var/list/cameras = get_camera_list(network) data["cameras"] = list() @@ -100,6 +101,7 @@ var/obj/machinery/camera/C = cameras[i] data["cameras"] += list(list( name = C.c_tag, + ref = REF(C), )) return data @@ -110,13 +112,11 @@ return if(action == "switch_camera") - var/c_tag = params["name"] - var/list/cameras = get_camera_list(network) - var/obj/machinery/camera/selected_camera = cameras[c_tag] + var/obj/machinery/camera/selected_camera = locate(params["camera"]) in GLOB.cameranet.cameras active_camera = selected_camera playsound(src, get_sfx(SFX_TERMINAL_TYPE), 25, FALSE) - if(!selected_camera) + if(isnull(active_camera)) return TRUE update_active_camera_screen() diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index c433565dbf8b3d..bc4a4ecabed14e 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -134,7 +134,8 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) JOB_QUARTERMASTER = 50, JOB_SHAFT_MINER = 51, JOB_CARGO_TECHNICIAN = 52, - JOB_CUSTOMS_AGENT = 53, // SKYRAT EDIT ADDITION + JOB_BITRUNNER = 53, + JOB_CUSTOMS_AGENT = 54, // SKYRAT EDIT ADDITION // 60+: Civilian/other JOB_HEAD_OF_PERSONNEL = 60, JOB_BARTENDER = 61, diff --git a/code/game/machinery/computer/operating_computer.dm b/code/game/machinery/computer/operating_computer.dm index f7b0ef24ffdc9d..3b639a9ce573f0 100644 --- a/code/game/machinery/computer/operating_computer.dm +++ b/code/game/machinery/computer/operating_computer.dm @@ -25,11 +25,15 @@ if(!CONFIG_GET(flag/no_default_techweb_link) && !linked_techweb) CONNECT_TO_RND_SERVER_ROUNDSTART(linked_techweb, src) - experiment_handler = AddComponent( \ + var/list/operating_signals = list( + COMSIG_OPERATING_COMPUTER_AUTOPSY_COMPLETE = TYPE_PROC_REF(/datum/component/experiment_handler, try_run_autopsy_experiment), + ) + experiment_handler = AddComponent( /datum/component/experiment_handler, \ allowed_experiments = list(/datum/experiment/autopsy), \ config_flags = EXPERIMENT_CONFIG_ALWAYS_ACTIVE, \ config_mode = EXPERIMENT_CONFIG_ALTCLICK, \ + experiment_signals = operating_signals, \ ) /obj/machinery/computer/operating/Destroy() diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 2786ed0f7691db..9d18b7ecb8501b 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -191,12 +191,23 @@ diag_hud_set_electrified() - RegisterSignal(src, COMSIG_MACHINERY_BROKEN, PROC_REF(on_break)) - // Click on the floor to close airlocks AddComponent(/datum/component/redirect_attack_hand_from_turf) - return INITIALIZE_HINT_LATELOAD + RegisterSignal(src, COMSIG_MACHINERY_BROKEN, PROC_REF(on_break)) + + RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide)) + +/obj/machinery/door/airlock/proc/grey_tide(datum/source, list/grey_tide_areas) + SIGNAL_HANDLER + + if(!is_station_level(z) || critical_machine) + return //Skip doors in critical positions, such as the SM chamber. + + for(var/area_type in grey_tide_areas) + if(!istype(get_area(src), area_type)) + continue + INVOKE_ASYNC(src, PROC_REF(prison_open)) //Sleep gets called further down in open(), so we have to invoke async /obj/machinery/door/airlock/connect_to_shuttle(mapload, obj/docking_port/mobile/port, obj/docking_port/stationary/dock) if(id_tag) diff --git a/code/game/machinery/doors/poddoor.dm b/code/game/machinery/doors/poddoor.dm index 4b49e7ee963e46..7eb1163871e459 100644 --- a/code/game/machinery/doors/poddoor.dm +++ b/code/game/machinery/doors/poddoor.dm @@ -49,7 +49,7 @@ return if (deconstruction != BLASTDOOR_FINISHED) return - var/change_id = tgui_input_number(user, "Set the door controllers ID", "Door Controller ID", id, 100) + var/change_id = tgui_input_text(user, "Set the door controllers ID", "Door Controller ID", id, 100) if(!change_id || QDELETED(usr) || QDELETED(src) || !usr.can_perform_action(src, FORBID_TELEKINESIS_REACH)) return id = change_id diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm index 63a48dcd976351..1a16c00e42da86 100644 --- a/code/game/machinery/harvester.dm +++ b/code/game/machinery/harvester.dm @@ -75,21 +75,18 @@ /obj/machinery/harvester/proc/can_harvest() if(!powered() || state_open || !occupant || !iscarbon(occupant)) return - var/mob/living/carbon/C = occupant + var/mob/living/carbon/carbon_occupant = occupant if(!allow_clothing) - for(var/A in C.held_items + C.get_equipped_items()) - if(!isitem(A)) - continue - var/obj/item/I = A - if(!(HAS_TRAIT(I, TRAIT_NODROP))) + for(var/obj/item/abiotic_item in carbon_occupant.held_items + carbon_occupant.get_equipped_items()) + if(!(HAS_TRAIT(abiotic_item, TRAIT_NODROP))) say("Subject may not have abiotic items on.") playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE) return - if(!(C.mob_biotypes & MOB_ORGANIC)) + if(!(carbon_occupant.mob_biotypes & MOB_ORGANIC)) say("Subject is not organic.") playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE) return - if(!allow_living && !(C.stat == DEAD || HAS_TRAIT(C, TRAIT_FAKEDEATH))) //I mean, the machines scanners arent advanced enough to tell you're alive + if(!allow_living && !(carbon_occupant.stat == DEAD || HAS_TRAIT(carbon_occupant, TRAIT_FAKEDEATH))) //I mean, the machines scanners arent advanced enough to tell you're alive say("Subject is still alive.") playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE) return @@ -124,21 +121,21 @@ end_harvesting(success = FALSE) return playsound(src, 'sound/machines/juicer.ogg', 20, TRUE) - var/mob/living/carbon/C = occupant + var/mob/living/carbon/carbon_occupant = occupant if(!LAZYLEN(operation_order)) //The list is empty, so we're done here end_harvesting(success = TRUE) return var/turf/target = get_step(src, output_dir) - for(var/obj/item/bodypart/BP in operation_order) //first we do non-essential limbs - BP.drop_limb() - C.emote("scream") - if(BP.body_zone != "chest") - BP.forceMove(target) //Move the limbs right next to it, except chest, that's a weird one - BP.drop_organs() + for(var/obj/item/bodypart/limb_to_remove as anything in operation_order) //first we do non-essential limbs + limb_to_remove.drop_limb() + carbon_occupant.emote("scream") + if(limb_to_remove.body_zone != "chest") + limb_to_remove.forceMove(target) //Move the limbs right next to it, except chest, that's a weird one + limb_to_remove.drop_organs() else - for(var/obj/item/organ/O in BP.dismember()) - O.forceMove(target) //Some organs, like chest ones, are different so we need to manually move them - operation_order.Remove(BP) + for(var/obj/item/organ/organ_to_remove in limb_to_remove.dismember()) + organ_to_remove.forceMove(target) //Some organs, like chest ones, are different so we need to manually move them + operation_order.Remove(limb_to_remove) break use_power(active_power_usage) addtimer(CALLBACK(src, PROC_REF(harvest)), interval) @@ -154,7 +151,7 @@ say("Subject has been successfully harvested.") playsound(src, 'sound/machines/microwave/microwave-end.ogg', 100, FALSE) -/obj/machinery/harvester/screwdriver_act(mob/living/user, obj/item/I) +/obj/machinery/harvester/screwdriver_act(mob/living/user, obj/item/tool) . = TRUE if(..()) return @@ -164,20 +161,20 @@ if(state_open) to_chat(user, span_warning("[src] must be closed to [panel_open ? "close" : "open"] its maintenance hatch!")) return - if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I)) + if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), tool)) return return FALSE -/obj/machinery/harvester/crowbar_act(mob/living/user, obj/item/I) - if(default_pry_open(I)) +/obj/machinery/harvester/crowbar_act(mob/living/user, obj/item/tool) + if(default_pry_open(tool)) return TRUE - if(default_deconstruction_crowbar(I)) + if(default_deconstruction_crowbar(tool)) return TRUE -/obj/machinery/harvester/default_pry_open(obj/item/I) //wew - . = !(state_open || panel_open || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR //We removed is_operational here +/obj/machinery/harvester/default_pry_open(obj/item/tool) //wew + . = !(state_open || panel_open || (flags_1 & NODECONSTRUCT_1)) && tool.tool_behaviour == TOOL_CROWBAR //We removed is_operational here if(.) - I.play_tool_sound(src, 50) + tool.play_tool_sound(src, 50) visible_message(span_notice("[usr] pries open \the [src]."), span_notice("You pry open [src].")) open_machine() diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index 0e53fa8e36caca..f1cbc110a3e50f 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -504,7 +504,7 @@ for(var/mob/living/L in get_turf(src)) visible_message(span_danger("\The [src] is suddenly occupying the same space as \the [L]!")) L.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) - L.gib() + L.gib(DROP_ALL_REMAINS) RegisterSignal(src, COMSIG_ATOM_SINGULARITY_TRY_MOVE, PROC_REF(block_singularity)) /obj/machinery/shieldwall/Destroy() diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index d5d0e9c732e13b..15c740a31e4bdb 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -138,6 +138,9 @@ storage_type = /obj/item/tank/jetpack/oxygen/harness mod_type = /obj/item/mod/control/pre_equipped/nuclear +/obj/machinery/suit_storage_unit/syndicate/lavaland + mod_type = /obj/item/mod/control/pre_equipped/nuclear/no_jetpack + /obj/machinery/suit_storage_unit/interdyne mask_type = /obj/item/clothing/mask/gas/syndicate storage_type = /obj/item/tank/jetpack/oxygen/harness diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm index 188f3b4f52ee9e..9015eaacedc697 100644 --- a/code/game/machinery/syndicatebeacon.dm +++ b/code/game/machinery/syndicatebeacon.dm @@ -146,3 +146,7 @@ /obj/item/sbeacondrop/clownbomb desc = "A label on it reads: Warning: Activating this device will send a silly explosive to your location." droptype = /obj/machinery/syndicatebomb/badmin/clown + +/obj/item/sbeacondrop/horse + desc = "A label on it reads: Warning: Activating this device will send a live horse to your location." + droptype = /mob/living/basic/pony/syndicate diff --git a/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm b/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm index dae527c3e6b7ec..2d524e190429a0 100644 --- a/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/fluid_spread/effects_smoke.dm @@ -394,6 +394,15 @@ reagents.expose(smoker, INGEST, fraction) return TRUE +/// Helper to quickly create a cloud of reagent smoke +/proc/do_chem_smoke(range = 0, amount = DIAMOND_AREA(range), atom/holder = null, location = null, reagent_type = /datum/reagent/water, reagent_volume = 10, log = FALSE) + var/datum/reagents/smoke_reagents = new/datum/reagents(reagent_volume) + smoke_reagents.add_reagent(reagent_type, reagent_volume) + + var/datum/effect_system/fluid_spread/smoke/chem/smoke = new + smoke.attach(location) + smoke.set_up(amount = amount, holder = holder, location = location, carry = smoke_reagents, silent = TRUE) + smoke.start(log = log) /// A factory which produces clouds of chemical bearing smoke. /datum/effect_system/fluid_spread/smoke/chem diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 2c4a594b806035..4e5b36bf5e8d7b 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -84,6 +84,10 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark) name = "Cargo Technician" icon_state = "Cargo Technician" +/obj/effect/landmark/start/bitrunner + name = "Bitrunner" + icon_state = "x3" + /obj/effect/landmark/start/bartender name = "Bartender" icon_state = "Bartender" diff --git a/code/game/objects/effects/spawners/random/decoration.dm b/code/game/objects/effects/spawners/random/decoration.dm index 1beafc37df563f..6116d228733174 100644 --- a/code/game/objects/effects/spawners/random/decoration.dm +++ b/code/game/objects/effects/spawners/random/decoration.dm @@ -93,6 +93,14 @@ loot_type_path = /obj/structure/showcase loot = list() +/obj/effect/spawner/random/decoration/microwave + name = "microwave showcase spawner" + icon_state = "showcase" + loot = list( + /obj/structure/showcase/machinery/microwave, + /obj/structure/showcase/machinery/microwave_engineering, + ) + /obj/effect/spawner/random/decoration/glowstick name = "random colored glowstick" icon_state = "glowstick" diff --git a/code/game/objects/effects/spawners/random/entertainment.dm b/code/game/objects/effects/spawners/random/entertainment.dm index 18876dfc927fee..1c635f07a5aaeb 100644 --- a/code/game/objects/effects/spawners/random/entertainment.dm +++ b/code/game/objects/effects/spawners/random/entertainment.dm @@ -271,7 +271,6 @@ /obj/item/toy/plush/carpplushie = 3, /obj/item/toy/plush/lizard_plushie/green = 3, /obj/item/toy/plush/lizard_plushie/space/green = 3, - /obj/item/toy/plush/awakenedplushie = 3, /obj/item/toy/plush/goatplushie = 3, /obj/item/toy/plush/rouny = 3, /obj/item/toy/plush/abductor = 3, diff --git a/code/game/objects/effects/spawners/random/techstorage.dm b/code/game/objects/effects/spawners/random/techstorage.dm index c1f9304039654e..4bfdeec27d1803 100644 --- a/code/game/objects/effects/spawners/random/techstorage.dm +++ b/code/game/objects/effects/spawners/random/techstorage.dm @@ -34,6 +34,7 @@ /obj/item/circuitboard/machine/ore_redemption, /obj/item/circuitboard/computer/order_console/mining, /obj/item/circuitboard/machine/microwave, + /obj/item/circuitboard/machine/microwave/engineering, /obj/item/circuitboard/machine/deep_fryer, /obj/item/circuitboard/machine/griddle, /obj/item/circuitboard/machine/reagentgrinder, diff --git a/code/game/objects/effects/spiderwebs.dm b/code/game/objects/effects/spiderwebs.dm index 3bdac03396fa1d..9b44d3507db2e1 100644 --- a/code/game/objects/effects/spiderwebs.dm +++ b/code/game/objects/effects/spiderwebs.dm @@ -174,11 +174,11 @@ /obj/structure/spider/sticky/CanAllowThrough(atom/movable/mover, border_dir) . = ..() - if(isspider(mover)) + if(HAS_TRAIT(mover, TRAIT_WEB_SURFER)) return TRUE if(!isliving(mover)) return - if(isspider(mover.pulledby)) + if(!isnull(mover.pulledby) && HAS_TRAIT(mover.pulledby, TRAIT_WEB_SURFER)) return TRUE loc.balloon_alert(mover, "stuck in web!") return FALSE diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm index e88753d25c1f86..c736aac35d8fda 100644 --- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm +++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm @@ -594,11 +594,22 @@ var/datum/weakref/pinged_person /// The icon state applied to the image created for this ping. var/real_icon_state = "sonar_ping" + /// Does the visual follow the creature? + var/follow_creature = TRUE + /// Creature's X & Y coords, which can either be overridden or kept the same depending on follow_creature. + var/creature_x + var/creature_y -/obj/effect/temp_visual/sonar_ping/Initialize(mapload, mob/living/looker, mob/living/creature) +/obj/effect/temp_visual/sonar_ping/Initialize(mapload, mob/living/looker, mob/living/creature, ping_state, follow_creatures = TRUE) . = ..() if(!looker || !creature) return INITIALIZE_HINT_QDEL + if(ping_state) + real_icon_state = ping_state + follow_creature = follow_creatures + creature_x = creature.x + creature_y = creature.y + modsuit_image = image(icon = icon, loc = looker.loc, icon_state = real_icon_state, layer = ABOVE_ALL_MOB_LAYER, pixel_x = ((creature.x - looker.x) * 32), pixel_y = ((creature.y - looker.y) * 32)) modsuit_image.plane = ABOVE_LIGHTING_PLANE SET_PLANE_EXPLICIT(modsuit_image, ABOVE_LIGHTING_PLANE, creature) @@ -631,8 +642,12 @@ if(isnull(looker) || isnull(creature)) return PROCESS_KILL modsuit_image.loc = looker.loc - modsuit_image.pixel_x = ((creature.x - looker.x) * 32) - modsuit_image.pixel_y = ((creature.y - looker.y) * 32) + // Long pings follow, short pings stay put. We still need to update for looker.x&y though + if(follow_creature) + creature_y = creature.y + creature_x = creature.x + modsuit_image.pixel_x = ((creature_x - looker.x) * 32) + modsuit_image.pixel_y = ((creature_y - looker.y) * 32) /obj/effect/temp_visual/block //color is white by default, set to whatever is needed name = "blocking glow" diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm index eabf86811042f9..9dd7e125055f18 100644 --- a/code/game/objects/items/cards_ids.dm +++ b/code/game/objects/items/cards_ids.dm @@ -32,6 +32,7 @@ lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi' w_class = WEIGHT_CLASS_TINY + /// Cached icon that has been built for this card. Intended to be displayed in chat. Cardboards IDs and actual IDs use it. var/icon/cached_flat_icon @@ -757,10 +758,10 @@ break /obj/item/card/id/examine_more(mob/user) + . = ..() if(!user.can_read(src)) return - . = ..() . += span_notice("You examine [src] closer, and note the following...") if(registered_age) diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm index f04c6e0058fa6b..79efe62a2250d0 100644 --- a/code/game/objects/items/circuitboards/computer_circuitboards.dm +++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm @@ -540,6 +540,10 @@ name = "Golem Ship Equipment Vendor Console" build_path = /obj/machinery/computer/order_console/mining/golem +/obj/item/circuitboard/computer/order_console/bitrunning + name = "Bitrunning Vendor Console" + build_path = /obj/machinery/computer/order_console/bitrunning + /obj/item/circuitboard/computer/ferry name = "Transport Ferry" greyscale_colors = CIRCUIT_COLOR_SUPPLY diff --git a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm index dae27c175b4e83..f41cb62c9deee5 100644 --- a/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machines/machine_circuitboards.dm @@ -1251,10 +1251,22 @@ req_components = list( /datum/stock_part/micro_laser = 1, /datum/stock_part/matter_bin = 1, + /datum/stock_part/capacitor = 1, /obj/item/stack/cable_coil = 2, /obj/item/stack/sheet/glass = 2) needs_anchored = FALSE +/obj/item/circuitboard/machine/microwave/engineering + name = "Wireless Microwave Oven" + greyscale_colors = CIRCUIT_COLOR_SERVICE + build_path = /obj/machinery/microwave/engineering + req_components = list( + /datum/stock_part/micro_laser = 1, + /datum/stock_part/matter_bin = 1, + /datum/stock_part/capacitor/tier2 = 1, + /obj/item/stack/cable_coil = 4, + /obj/item/stack/sheet/glass = 2) + /obj/item/circuitboard/machine/processor name = "Food Processor" greyscale_colors = CIRCUIT_COLOR_SERVICE @@ -1309,6 +1321,15 @@ req_components = list( /datum/stock_part/card_reader = 1) +/obj/item/circuitboard/machine/fishing_portal_generator + name = "Fishing Portal Generator" + greyscale_colors = CIRCUIT_COLOR_SERVICE + build_path = /obj/machinery/fishing_portal_generator + req_components = list( + /datum/stock_part/matter_bin = 2, + /datum/stock_part/capacitor = 1) + needs_anchored = FALSE + //Supply /obj/item/circuitboard/machine/ore_redemption name = "Ore Redemption" @@ -1357,16 +1378,14 @@ greyscale_colors = CIRCUIT_COLOR_SUPPLY build_path = /obj/machinery/rnd/production/techfab/department/cargo -/obj/item/circuitboard/machine/bepis - name = "BEPIS Chamber" +/obj/item/circuitboard/machine/materials_market + name = "Galactic Materials Market" greyscale_colors = CIRCUIT_COLOR_SUPPLY - build_path = /obj/machinery/rnd/bepis + build_path = /obj/machinery/materials_market req_components = list( /obj/item/stack/cable_coil = 5, - /datum/stock_part/capacitor = 1, - /datum/stock_part/servo = 1, - /datum/stock_part/micro_laser = 1, - /datum/stock_part/scanning_module = 1) + /datum/stock_part/scanning_module = 1, + /datum/stock_part/card_reader = 1) //Misc /obj/item/circuitboard/machine/sheetifier @@ -1527,3 +1546,4 @@ /obj/item/mod/module/rad_protection = 1, /obj/item/stack/sheet/plasteel = 2, ) + diff --git a/code/game/objects/items/cosmetics.dm b/code/game/objects/items/cosmetics.dm index 686bd40c698442..9e49a99d73b89e 100644 --- a/code/game/objects/items/cosmetics.dm +++ b/code/game/objects/items/cosmetics.dm @@ -1,3 +1,7 @@ +#define UPPER_LIP "Upper" +#define MIDDLE_LIP "Middle" +#define LOWER_LIP "Lower" + /obj/item/lipstick gender = PLURAL name = "red lipstick" @@ -9,6 +13,8 @@ var/open = FALSE /// Actual color of the lipstick, also gets applied to the human var/lipstick_color = COLOR_RED + /// The style of lipstick. Upper, middle, or lower lip. Default is middle. + var/style = "lipstick" /// A trait that's applied while someone has this lipstick applied, and is removed when the lipstick is removed var/lipstick_trait @@ -22,6 +28,10 @@ if(vname == NAMEOF(src, open)) update_appearance(UPDATE_ICON) +/obj/item/lipstick/examine(mob/user) + . = ..() + . += "Alt-click to change the style." + /obj/item/lipstick/update_icon_state() icon_state = "lipstick[open ? "_uncap" : null]" inhand_icon_state = "lipstick[open ? "open" : null]" @@ -35,6 +45,42 @@ colored_overlay.color = lipstick_color . += colored_overlay +/obj/item/lipstick/AltClick(mob/user) + . = ..() + if(.) + return TRUE + + if(!user.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS|ALLOW_RESTING)) + return FALSE + + return display_radial_menu(user) + +/obj/item/lipstick/proc/display_radial_menu(mob/living/carbon/human/user) + var/style_options = list( + UPPER_LIP = icon('icons/hud/radial.dmi', UPPER_LIP), + MIDDLE_LIP = icon('icons/hud/radial.dmi', MIDDLE_LIP), + LOWER_LIP = icon('icons/hud/radial.dmi', LOWER_LIP), + ) + var/pick = show_radial_menu(user, src, style_options, custom_check = CALLBACK(src, PROC_REF(check_menu), user), radius = 36, require_near = TRUE) + if(!pick) + return TRUE + + switch(pick) + if(MIDDLE_LIP) + style = "lipstick" + if(LOWER_LIP) + style = "lipstick_lower" + if(UPPER_LIP) + style = "lipstick_upper" + return TRUE + +/obj/item/lipstick/proc/check_menu(mob/living/user) + if(!istype(user)) + return FALSE + if(user.incapacitated() || !user.is_holding(src)) + return FALSE + return TRUE + /obj/item/lipstick/purple name = "purple lipstick" lipstick_color = COLOR_PURPLE @@ -106,7 +152,7 @@ if(target == user) user.visible_message(span_notice("[user] does [user.p_their()] lips with \the [src]."), \ span_notice("You take a moment to apply \the [src]. Perfect!")) - target.update_lips("lipstick", lipstick_color, lipstick_trait) + target.update_lips(style, lipstick_color, lipstick_trait) return user.visible_message(span_warning("[user] begins to do [target]'s lips with \the [src]."), \ @@ -115,7 +161,7 @@ return user.visible_message(span_notice("[user] does [target]'s lips with \the [src]."), \ span_notice("You apply \the [src] on [target]'s lips.")) - target.update_lips("lipstick", lipstick_color, lipstick_trait) + target.update_lips(style, lipstick_color, lipstick_trait) //you can wipe off lipstick with paper! /obj/item/paper/attack(mob/M, mob/user) @@ -285,3 +331,7 @@ /obj/item/razor/surgery/get_surgery_tool_overlay(tray_extended) return "razor" + +#undef UPPER_LIP +#undef MIDDLE_LIP +#undef LOWER_LIP diff --git a/code/game/objects/items/debug_items.dm b/code/game/objects/items/debug_items.dm index 68ae291e73645b..e2febe30fcfd06 100644 --- a/code/game/objects/items/debug_items.dm +++ b/code/game/objects/items/debug_items.dm @@ -163,7 +163,7 @@ playsound(src, 'sound/voice/borg_deathsound.ogg') sleep(3 SECONDS) living_user.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) - living_user.gib() + living_user.gib(DROP_ALL_REMAINS) return var/turf/loc_turf = get_turf(src) for(var/spawn_atom in (choice == "No" ? typesof(path) : subtypesof(path))) diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 279f81010079a2..8e4a3a41171a92 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -578,6 +578,12 @@ do_cancel() /obj/item/shockpaddles/proc/do_help(mob/living/carbon/H, mob/living/user) + var/target_synthetic = (H.mob_biotypes & MOB_ROBOTIC) // SKYRAT EDIT ADDITION BEGIN - SYNTH REVIVAL + if (target_synthetic) + to_chat(user, span_boldwarning("[H] is a synthetic lifeform! This defibrillator probably isn't calibrated to revive [H.p_them()] properly and could have some serious consequences! \ + [span_warning("You might want to [span_blue("surgically revive [H.p_them()]")]...")]")) + balloon_alert(user, "target is synthetic!") // immediately grabs their attention even if they dont see chat + // SKYRAT EDIT ADDITION END - SYNTH REVIVAL user.visible_message(span_warning("[user] begins to place [src] on [H]'s chest."), span_warning("You begin to place [src] on [H]'s chest...")) busy = TRUE update_appearance() @@ -636,17 +642,19 @@ var/total_brute = H.getBruteLoss() var/total_burn = H.getFireLoss() + var/need_mob_update = FALSE //If the body has been fixed so that they would not be in crit when defibbed, give them oxyloss to put them back into crit if (H.health > HALFWAYCRITDEATH) - H.adjustOxyLoss(H.health - HALFWAYCRITDEATH, 0) + need_mob_update += H.adjustOxyLoss(H.health - HALFWAYCRITDEATH, updating_health = FALSE) else var/overall_damage = total_brute + total_burn + H.getToxLoss() + H.getOxyLoss() var/mobhealth = H.health - H.adjustOxyLoss((mobhealth - HALFWAYCRITDEATH) * (H.getOxyLoss() / overall_damage), 0) - H.adjustToxLoss((mobhealth - HALFWAYCRITDEATH) * (H.getToxLoss() / overall_damage), 0, TRUE) // force tox heal for toxin lovers too - H.adjustFireLoss((mobhealth - HALFWAYCRITDEATH) * (total_burn / overall_damage), 0) - H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), 0) - H.updatehealth() // Previous "adjust" procs don't update health, so we do it manually. + need_mob_update += H.adjustOxyLoss((mobhealth - HALFWAYCRITDEATH) * (H.getOxyLoss() / overall_damage), updating_health = FALSE) + need_mob_update += H.adjustToxLoss((mobhealth - HALFWAYCRITDEATH) * (H.getToxLoss() / overall_damage), updating_health = FALSE, forced = TRUE) // force tox heal for toxin lovers too + need_mob_update += H.adjustFireLoss((mobhealth - HALFWAYCRITDEATH) * (total_burn / overall_damage), updating_health = FALSE) + need_mob_update += H.adjustBruteLoss((mobhealth - HALFWAYCRITDEATH) * (total_brute / overall_damage), updating_health = FALSE) + if(need_mob_update) + H.updatehealth() // Previous "adjust" procs don't update health, so we do it manually. user.visible_message(span_notice("[req_defib ? "[defib]" : "[src]"] pings: Resuscitation successful.")) playsound(src, 'sound/machines/defib_success.ogg', 50, FALSE) H.set_heartattack(FALSE) @@ -662,6 +670,23 @@ else user.add_mood_event("saved_life", /datum/mood_event/saved_life) log_combat(user, H, "revived", defib) + // SKYRAT EDIT ADDITION BEGIN - SYNTH REVIVAL + if (target_synthetic) + user.visible_message(span_boldwarning("[src] fire a powerful jolt of electricity into [H]'s vulnerable circuitry!")) + to_chat(H, span_userdanger("[user]'s defibrillator fires a powerful jolt of electricity into your vulnerable circuitry, overloading it!")) + // You may ask, why not just call H.emp_act()? + // well my dear reader, that EMPs contents. I only want to EMP bodyparts and organs specifically + for (var/obj/item/bodypart/iterated_part as anything in H.bodyparts) + iterated_part.emp_act(EMP_LIGHT) + for (var/obj/item/organ/iterated_organ as anything in H.organs) + iterated_organ.emp_act(EMP_LIGHT) + var/obj/item/organ/internal/brain/brain_organ = H.get_organ_slot(ORGAN_SLOT_BRAIN) + if (istype(brain_organ)) + var/datum/brain_trauma/trauma = brain_organ.gain_trauma_type(SYNTH_DEFIBBED_TRAUMA_SEVERITY, TRAUMA_LIMIT_BASIC) + if (!QDELETED(trauma)) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(remove_synth_defib_trauma), brain_organ, trauma), SYNTH_DEFIBBED_TRAUMA_DURATION) + // SKYRAT EDIT ADDITION END - SYNTH REVIVAL + do_success() return else if (!H.get_organ_by_type(/obj/item/organ/internal/heart)) diff --git a/code/game/objects/items/devices/polycircuit.dm b/code/game/objects/items/devices/polycircuit.dm index 9dbdbff993d742..5b7fd42d6f6bd3 100644 --- a/code/game/objects/items/devices/polycircuit.dm +++ b/code/game/objects/items/devices/polycircuit.dm @@ -51,7 +51,7 @@ else to_chat(user, span_notice("You navigate the sharp edges of circuitry and remove a single board from [src]")) else - H.apply_damage(15, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + H.apply_damage(15, BRUTE, pick(GLOB.arm_zones)) to_chat(user, span_warning("You give yourself a wicked cut on [src]'s many sharp corners and edges!")) /obj/item/stack/circuit_stack/full diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index dcb7ddc1936ca4..5fe777f20dcce9 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -20,7 +20,7 @@ unscrewed = TRUE /obj/item/radio/intercom/prison - name = "prison intercom" + name = "receive-only intercom" desc = "A station intercom. It looks like it has been modified to not broadcast." /obj/item/radio/intercom/prison/Initialize(mapload, ndir, building) diff --git a/code/game/objects/items/food/_food.dm b/code/game/objects/items/food/_food.dm index 69cfdde4668bc9..0fb85e67589e40 100644 --- a/code/game/objects/items/food/_food.dm +++ b/code/game/objects/items/food/_food.dm @@ -115,7 +115,7 @@ ///Set decomp_req_handle to TRUE to only make it decompose when someone picks it up. ///Requires /datum/component/germ_sensitive to detect exposure /obj/item/food/proc/make_germ_sensitive(mapload) - if(istype(src, /obj/item/food/bowled) || istype(src, /obj/item/food/canned) || !isnull(trash_type)) + if(!isnull(trash_type)) return // You don't eat the package and it protects from decomposing AddComponent(/datum/component/germ_sensitive, mapload) if(!preserved_food) diff --git a/code/game/objects/items/food/donkpocket.dm b/code/game/objects/items/food/donkpocket.dm index f2495e0ee52ff0..d4b4636f15c9b3 100644 --- a/code/game/objects/items/food/donkpocket.dm +++ b/code/game/objects/items/food/donkpocket.dm @@ -20,12 +20,16 @@ var/baking_time_short = 25 SECONDS /// The upper end for how long it takes to bake var/baking_time_long = 30 SECONDS + /// The reagents added when microwaved. Needed since microwaving ignores food_reagents + var/static/list/added_reagents = list(/datum/reagent/medicine/omnizine = 6) + /// The reagents that most child types add when microwaved. Needed because you can't override static lists. + var/static/list/child_added_reagents = list(/datum/reagent/medicine/omnizine = 2) /obj/item/food/donkpocket/make_bakeable() - AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE) + AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, added_reagents) /obj/item/food/donkpocket/make_microwaveable() - AddElement(/datum/element/microwavable, warm_type) + AddElement(/datum/element/microwavable, warm_type, added_reagents) /obj/item/food/donkpocket/warm name = "warm Donk-pocket" @@ -69,6 +73,12 @@ foodtypes = GRAIN warm_type = /obj/item/food/donkpocket/warm/spicy +/obj/item/food/donkpocket/spicy/make_bakeable() + AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, child_added_reagents) + +/obj/item/food/donkpocket/spicy/make_microwaveable() + AddElement(/datum/element/microwavable, warm_type, child_added_reagents) + /obj/item/food/donkpocket/warm/spicy name = "warm Spicy-pocket" desc = "The classic snack food, now maybe a bit too spicy." @@ -95,6 +105,12 @@ foodtypes = GRAIN warm_type = /obj/item/food/donkpocket/warm/teriyaki +/obj/item/food/donkpocket/teriyaki/make_bakeable() + AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, child_added_reagents) + +/obj/item/food/donkpocket/teriyaki/make_microwaveable() + AddElement(/datum/element/microwavable, warm_type, child_added_reagents) + /obj/item/food/donkpocket/warm/teriyaki name = "warm Teriyaki-pocket" desc = "An east-asian take on the classic stationside snack, now steamy and warm." @@ -121,6 +137,12 @@ foodtypes = GRAIN warm_type = /obj/item/food/donkpocket/warm/pizza +/obj/item/food/donkpocket/pizza/make_bakeable() + AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, child_added_reagents) + +/obj/item/food/donkpocket/pizza/make_microwaveable() + AddElement(/datum/element/microwavable, warm_type, child_added_reagents) + /obj/item/food/donkpocket/warm/pizza name = "warm Pizza-pocket" desc = "Delicious, cheesy, and even better when hot." @@ -146,6 +168,16 @@ foodtypes = GRAIN warm_type = /obj/item/food/donkpocket/warm/honk crafting_complexity = FOOD_COMPLEXITY_3 + var/static/list/honk_added_reagents = list( + /datum/reagent/medicine/omnizine = 2, + /datum/reagent/consumable/laughter = 6, + ) + +/obj/item/food/donkpocket/honk/make_bakeable() + AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, honk_added_reagents) + +/obj/item/food/donkpocket/honk/make_microwaveable() + AddElement(/datum/element/microwavable, warm_type, honk_added_reagents) /obj/item/food/donkpocket/warm/honk name = "warm Honk-pocket" @@ -173,6 +205,12 @@ foodtypes = GRAIN warm_type = /obj/item/food/donkpocket/warm/berry +/obj/item/food/donkpocket/berry/make_bakeable() + AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, child_added_reagents) + +/obj/item/food/donkpocket/berry/make_microwaveable() + AddElement(/datum/element/microwavable, warm_type, child_added_reagents) + /obj/item/food/donkpocket/warm/berry name = "warm Berry-pocket" desc = "A relentlessly sweet donk-pocket, now warm and delicious." @@ -198,6 +236,16 @@ foodtypes = GRAIN warm_type = /obj/item/food/donkpocket/warm/gondola + var/static/list/gondola_added_reagents = list( + /datum/reagent/medicine/omnizine = 2, + /datum/reagent/gondola_mutation_toxin = 5, + ) + +/obj/item/food/donkpocket/gondola/make_bakeable() + AddComponent(/datum/component/bakeable, warm_type, rand(baking_time_short, baking_time_long), TRUE, TRUE, gondola_added_reagents) + +/obj/item/food/donkpocket/gondola/make_microwaveable() + AddElement(/datum/element/microwavable, warm_type, gondola_added_reagents) /obj/item/food/donkpocket/warm/gondola name = "warm Gondola-pocket" diff --git a/code/game/objects/items/food/egg.dm b/code/game/objects/items/food/egg.dm index 555b16e24b69e5..60bbb58e3ac873 100644 --- a/code/game/objects/items/food/egg.dm +++ b/code/game/objects/items/food/egg.dm @@ -28,6 +28,7 @@ GLOBAL_VAR_INIT(chicks_from_eggs, 0) ant_attracting = FALSE decomp_type = /obj/item/food/egg/rotten decomp_req_handle = TRUE //so laid eggs can actually become chickens + /// How likely is it that a chicken will come out of here if we throw it? var/chick_throw_prob = 13 /obj/item/food/egg/make_bakeable() @@ -68,24 +69,25 @@ GLOBAL_VAR_INIT(chicks_from_eggs, 0) var/turf/hit_turf = get_turf(hit_atom) new /obj/effect/decal/cleanable/food/egg_smudge(hit_turf) - //Chicken code uses this MAX_CHICKENS variable, so I figured that I'd use it again here. Even this check and the check in chicken code both use the MAX_CHICKENS variable, they use independent counter variables and thus are independent of each other. - if(GLOB.chicks_from_eggs < MAX_CHICKENS) //Roughly a 1/8 (12.5%) chance to make a chick, as in Minecraft, with a 1/256 (~0.39%) chance to make four chicks instead. - var/chance = rand(0, 255) - switch(chance) - if(0 to 30) - new /mob/living/basic/chick(hit_turf) - GLOB.chicks_from_eggs++ - visible_message(span_notice("A chick comes out of the cracked egg!")) - if(31) - var/spawned_chickens = min(4, MAX_CHICKENS - GLOB.chicks_from_eggs) // We don't want to go over the limit - visible_message(span_notice("[spawned_chickens] chicks come out of the egg! Jackpot!")) - for(var/i in 1 to spawned_chickens) - new /mob/living/basic/chick(hit_turf) - GLOB.chicks_from_eggs++ - + if (prob(chick_throw_prob)) + spawn_impact_chick(hit_turf) reagents.expose(hit_atom, TOUCH) qdel(src) +/// Spawn a baby chicken from throwing an egg +/obj/item/food/egg/proc/spawn_impact_chick(turf/spawn_turf) + var/chickens_remaining = MAX_CHICKENS - GLOB.chicks_from_eggs + if (chickens_remaining < 1) + return + var/spawned_chickens = prob(97) ? 1 : min(4, chickens_remaining) // We don't want to go over the limit + if (spawned_chickens > 1) // Chicken jackpot! + visible_message(span_notice("[spawned_chickens] chicks come out of the egg! Jackpot!")) + else + visible_message(span_notice("A chick comes out of the cracked egg!")) + for(var/i in 1 to spawned_chickens) + new /mob/living/basic/chick(spawn_turf) + GLOB.chicks_from_eggs++ + /obj/item/food/egg/attackby(obj/item/item, mob/user, params) if(istype(item, /obj/item/toy/crayon)) var/obj/item/toy/crayon/crayon = item diff --git a/code/game/objects/items/food/monkeycube.dm b/code/game/objects/items/food/monkeycube.dm index 5cf9db79fd01ec..ffc9b63c62f09f 100644 --- a/code/game/objects/items/food/monkeycube.dm +++ b/code/game/objects/items/food/monkeycube.dm @@ -48,7 +48,7 @@ return Expand() user.visible_message(span_danger("[user]'s torso bursts open as a primate emerges!")) - user.gib(null, TRUE, null, TRUE) + user.gib(DROP_BRAIN|DROP_BODYPARTS|DROP_ITEMS) // just remove the organs /obj/item/food/monkeycube/syndicate faction = list(FACTION_NEUTRAL, ROLE_SYNDICATE) @@ -62,7 +62,7 @@ /datum/reagent/medicine/strange_reagent = 5, ) tastes = list("the jungle" = 1, "bananas" = 1, "jimmies" = 1) - spawned_mob = /mob/living/simple_animal/hostile/gorilla + spawned_mob = /mob/living/basic/gorilla /obj/item/food/monkeycube/chicken name = "chicken cube" diff --git a/code/game/objects/items/food/moth.dm b/code/game/objects/items/food/moth.dm index 3bb3c8738d41f0..41c2d8ec3a1662 100644 --- a/code/game/objects/items/food/moth.dm +++ b/code/game/objects/items/food/moth.dm @@ -522,7 +522,7 @@ desc = "A salad with added cotton and a basic dressing. Presumably either moths are around, or the South's risen again." icon = 'icons/obj/food/moth.dmi' icon_state = "cotton_salad" - food_reagents = list(, + food_reagents = list( /datum/reagent/consumable/nutriment = 8, /datum/reagent/consumable/nutriment/vitamin = 14, ) diff --git a/code/game/objects/items/food/packaged.dm b/code/game/objects/items/food/packaged.dm index edcc0bd09ed611..1dabec57cdd1a2 100644 --- a/code/game/objects/items/food/packaged.dm +++ b/code/game/objects/items/food/packaged.dm @@ -16,6 +16,9 @@ w_class = WEIGHT_CLASS_SMALL preserved_food = TRUE +/obj/item/food/canned/make_germ_sensitive(mapload) + return // It's in a can + /obj/item/food/canned/proc/open_can(mob/user) to_chat(user, span_notice("You pull back the tab of \the [src].")) playsound(user.loc, 'sound/items/foodcanopen.ogg', 50) @@ -209,11 +212,14 @@ /// What type of ready-donk are we warmed into? var/warm_type = /obj/item/food/ready_donk/warm + /// What reagents should be added when this item is warmed? + var/static/list/added_reagents = list(/datum/reagent/medicine/omnizine = 3) + /obj/item/food/ready_donk/make_bakeable() - AddComponent(/datum/component/bakeable, warm_type, rand(15 SECONDS, 20 SECONDS), TRUE, TRUE) + AddComponent(/datum/component/bakeable, warm_type, rand(15 SECONDS, 20 SECONDS), TRUE, TRUE, added_reagents) /obj/item/food/ready_donk/make_microwaveable() - AddElement(/datum/element/microwavable, warm_type) + AddElement(/datum/element/microwavable, warm_type, added_reagents) /obj/item/food/ready_donk/examine_more(mob/user) . = ..() diff --git a/code/game/objects/items/food/pizza.dm b/code/game/objects/items/food/pizza.dm index fdbb1e33c870e7..b93cd7ed7219c5 100644 --- a/code/game/objects/items/food/pizza.dm +++ b/code/game/objects/items/food/pizza.dm @@ -389,7 +389,7 @@ if(istype(item, /obj/item/food/pineappleslice)) to_chat(user, "If you want something crazy like pineapple, I'll kill you.") //this is in bigger text because it's hard to spam something that gibs you, and so that you're perfectly aware of the reason why you died user.investigate_log("has been gibbed by putting pineapple on an arnold pizza.", INVESTIGATE_DEATHS) - user.gib() //if you want something crazy like pineapple, i'll kill you + user.gib(DROP_ALL_REMAINS) //if you want something crazy like pineapple, i'll kill you else if(istype(item, /obj/item/food/grown/mushroom) && iscarbon(user)) to_chat(user, span_userdanger("So, if you want mushroom, shut up.")) //not as large as the pineapple text, because you could in theory spam it var/mob/living/carbon/shutup = user diff --git a/code/game/objects/items/food/sandwichtoast.dm b/code/game/objects/items/food/sandwichtoast.dm index fec714ad8503d8..8b91b04621e00b 100644 --- a/code/game/objects/items/food/sandwichtoast.dm +++ b/code/game/objects/items/food/sandwichtoast.dm @@ -302,5 +302,5 @@ /obj/item/food/sandwich/death/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] starts to shove [src] down [user.p_their()] throat the wrong way. It looks like [user.p_theyre()] trying to commit suicide!")) qdel(src) - user.gib(TRUE, TRUE, TRUE) + user.gib() return MANUAL_SUICIDE diff --git a/code/game/objects/items/food/soup.dm b/code/game/objects/items/food/soup.dm index 08eb86ebaa0fe3..e1482b17a817b1 100644 --- a/code/game/objects/items/food/soup.dm +++ b/code/game/objects/items/food/soup.dm @@ -7,6 +7,9 @@ eatverbs = list("slurp", "sip", "inhale", "drink") venue_value = FOOD_PRICE_CHEAP +/obj/item/food/bowled/make_germ_sensitive(mapload) + return // It's in a bowl + /obj/item/food/bowled/wish name = "wish soup" desc = "I wish this was soup." diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm index 5902298032c3ab..d5f3b0dec9d431 100644 --- a/code/game/objects/items/grenades/plastic.dm +++ b/code/game/objects/items/grenades/plastic.dm @@ -161,7 +161,7 @@ user.visible_message(span_suicide("[user] activates [src] and holds it above [user.p_their()] head! It looks like [user.p_theyre()] going out with a bang!")) shout_syndicate_crap(user) explosion(user, heavy_impact_range = 2, explosion_cause = src) //Cheap explosion imitation because putting detonate() here causes runtimes - user.gib(1, 1) + user.gib(DROP_BODYPARTS) qdel(src) // X4 is an upgraded directional variant of c4 which is relatively safe to be standing next to. And much less safe to be standing on the other side of. diff --git a/code/game/objects/items/implants/implant_explosive.dm b/code/game/objects/items/implants/implant_explosive.dm index 70471a8e99a183..c9f961b594e26e 100644 --- a/code/game/objects/items/implants/implant_explosive.dm +++ b/code/game/objects/items/implants/implant_explosive.dm @@ -166,7 +166,7 @@ explosion(src, devastation_range = explosion_devastate, heavy_impact_range = explosion_heavy, light_impact_range = explosion_light, flame_range = explosion_light, flash_range = explosion_light, explosion_cause = src) if(imp_in) imp_in.investigate_log("has been gibbed by an explosive implant.", INVESTIGATE_DEATHS) - imp_in.gib(TRUE) + imp_in.gib(DROP_ORGANS|DROP_BODYPARTS) qdel(src) ///Macrobomb has the strength and delay of 10 microbombs diff --git a/code/game/objects/items/implants/implant_freedom.dm b/code/game/objects/items/implants/implant_freedom.dm index d010b57e506774..1fa61c27510fa1 100644 --- a/code/game/objects/items/implants/implant_freedom.dm +++ b/code/game/objects/items/implants/implant_freedom.dm @@ -3,37 +3,45 @@ desc = "Use this to escape from those evil Red Shirts." icon_state = "freedom" implant_color = "r" - uses = 4 + uses = FREEDOM_IMPLANT_CHARGES +/obj/item/implant/freedom/implant(mob/living/target, mob/user, silent, force) + . = ..() + if(!.) + return FALSE + if(!iscarbon(target)) //This is pretty much useless for anyone else since they can't be cuffed + balloon_alert(user, "that would be a waste!") + return FALSE + return TRUE /obj/item/implant/freedom/activate() . = ..() + var/mob/living/carbon/carbon_imp_in = imp_in + if(!carbon_imp_in.handcuffed && !carbon_imp_in.legcuffed) + balloon_alert(carbon_imp_in, "no restraints!") + return + uses-- - to_chat(imp_in, span_hear("You feel a faint click.")) - if(iscarbon(imp_in)) - var/mob/living/carbon/C_imp_in = imp_in - C_imp_in.uncuff() + + carbon_imp_in.uncuff() if(!uses) + addtimer(CALLBACK(carbon_imp_in, TYPE_PROC_REF(/atom, balloon_alert), carbon_imp_in, "implant degraded!"), 1 SECONDS) qdel(src) - /obj/item/implant/freedom/get_data() var/dat = {" -Implant Specifications:
-Name: Freedom Beacon
-Life: optimum 5 uses
-Important Notes: Illegal
-
-Implant Details:
-Function: Transmits a specialized cluster of signals to override handcuff locking -mechanisms
-Special Features:
-Neuro-Scan- Analyzes certain shadow signals in the nervous system
-
-No Implant Specifics"} + Implant Specifications:
+ Name: Freedom Beacon
+ Life: Optimum [initial(uses)] uses
+ Important Notes: Illegal
+
+ Implant Details:
+ Function: Transmits a specialized cluster of signals to override handcuff locking + mechanisms. These signals will release any bindings on both the arms and legs.
+ Disclaimer: Heavy-duty restraints such as straightjackets are deemed "too complex" to release from. + "} return dat - /obj/item/implanter/freedom name = "implanter" // Skyrat edit , was implanter (freedom) imp_type = /obj/item/implant/freedom diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm index bcae55357e46b6..9d8cd8e9426e9d 100644 --- a/code/game/objects/items/manuals.dm +++ b/code/game/objects/items/manuals.dm @@ -431,9 +431,10 @@ H.gib_animation() sleep(0.3 SECONDS) H.adjustBruteLoss(1000) //to make the body super-bloody + // if we use gib() then the body gets deleted H.spawn_gibs() - H.spill_organs() - H.spread_bodyparts() + H.spill_organs(DROP_ALL_REMAINS) + H.spread_bodyparts(DROP_BRAIN) return BRUTELOSS /obj/item/book/manual/wiki/plumbing diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm index 77b76d852240d3..eab3f34d343fe1 100644 --- a/code/game/objects/items/plushes.dm +++ b/code/game/objects/items/plushes.dm @@ -584,6 +584,7 @@ squeak_override = list('sound/effects/blobattack.ogg' = 1) gender = FEMALE //given all the jokes and drawings, I'm not sure the xenobiologists would make a slimeboy +// This is supposed to be only in the bus ruin, don't spawn it elsewhere /obj/item/toy/plush/awakenedplushie name = "awakened plushie" desc = "An ancient plushie that has grown enlightened to the true nature of reality." diff --git a/code/game/objects/items/puzzle_pieces.dm b/code/game/objects/items/puzzle_pieces.dm index fc80355a7cc59b..9bf33e36f2fe9e 100644 --- a/code/game/objects/items/puzzle_pieces.dm +++ b/code/game/objects/items/puzzle_pieces.dm @@ -61,6 +61,19 @@ fire = 100 acid = 100 +/obj/machinery/door/puzzle/Initialize(mapload) + . = ..() + RegisterSignal(SSdcs, COMSIG_GLOB_PUZZLE_COMPLETED, PROC_REF(try_signal)) + +/obj/machinery/door/puzzle/Destroy(force) + . = ..() + UnregisterSignal(SSdcs, COMSIG_GLOB_PUZZLE_COMPLETED) + +/obj/machinery/door/puzzle/proc/try_signal(datum/source, try_id) + SIGNAL_HANDLER + + INVOKE_ASYNC(src, PROC_REF(try_puzzle_open), try_id) + /obj/machinery/door/puzzle/Bumped(atom/movable/AM) return !density && ..() @@ -111,15 +124,6 @@ /obj/machinery/door/puzzle/light desc = "This door only opens when a linked mechanism is powered. It looks virtually indestructible." -/obj/machinery/door/puzzle/light/Initialize(mapload) - . = ..() - RegisterSignal(SSdcs, COMSIG_GLOB_LIGHT_MECHANISM_COMPLETED, PROC_REF(check_mechanism)) - -/obj/machinery/door/puzzle/light/proc/check_mechanism(datum/source, try_id) - SIGNAL_HANDLER - - INVOKE_ASYNC(src, PROC_REF(try_puzzle_open), try_id) - //************************* //***Box Pushing Puzzles*** //************************* @@ -268,5 +272,5 @@ return visible_message(span_boldnotice("[src] becomes fully charged!")) powered = TRUE - SEND_GLOBAL_SIGNAL(COMSIG_GLOB_LIGHT_MECHANISM_COMPLETED, puzzle_id) + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_PUZZLE_COMPLETED, puzzle_id) playsound(src, 'sound/machines/synth_yes.ogg', 100, TRUE) diff --git a/code/game/objects/items/rcd/RCD.dm b/code/game/objects/items/rcd/RCD.dm index bf6f5c2ab1f0a4..33994c91774405 100644 --- a/code/game/objects/items/rcd/RCD.dm +++ b/code/game/objects/items/rcd/RCD.dm @@ -76,6 +76,7 @@ list(FURNISH_TYPE = /obj/structure/table/glass, ICON = "glass_table", TITLE = "Glass Table"), list(FURNISH_TYPE = /obj/structure/rack, ICON = "rack", TITLE = "Rack"), list(FURNISH_TYPE = /obj/structure/bed, ICON = "bed", TITLE = "Bed"), + list(FURNISH_TYPE = /obj/machinery/microwave/engineering, ICON = "engi_mw_complete", TITLE = "Wireless Microwave"), ), ), @@ -259,7 +260,7 @@ GLOBAL_VAR_INIT(icon_holographic_window, init_holographic_window()) useResource(16, user) activate() playsound(loc, 'sound/machines/click.ogg', 50, 1) - user.gib() + user.gib(DROP_ALL_REMAINS) return MANUAL_SUICIDE user.visible_message(span_suicide("[user] pulls the trigger... But there is not enough ammo!")) diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm index f58d3ad93cf636..e68a1b8c88324d 100644 --- a/code/game/objects/items/religion.dm +++ b/code/game/objects/items/religion.dm @@ -64,15 +64,18 @@ /obj/item/banner/proc/check_inspiration(mob/living/carbon/human/H) //Banner-specific conditions for being eligible return -/obj/item/banner/proc/inspiration(mob/living/carbon/human/H) - H.adjustBruteLoss(-15) - H.adjustFireLoss(-15) - H.AdjustStun(-40) - H.AdjustKnockdown(-40) - H.AdjustImmobilized(-40) - H.AdjustParalyzed(-40) - H.AdjustUnconscious(-40) - playsound(H, 'sound/magic/staff_healing.ogg', 25, FALSE) +/obj/item/banner/proc/inspiration(mob/living/carbon/human/inspired_human) + var/need_mob_update = FALSE + need_mob_update += inspired_human.adjustBruteLoss(-15, updating_health = FALSE) + need_mob_update += inspired_human.adjustFireLoss(-15, updating_health = FALSE) + if(need_mob_update) + inspired_human.updatehealth() + inspired_human.AdjustStun(-40) + inspired_human.AdjustKnockdown(-40) + inspired_human.AdjustImmobilized(-40) + inspired_human.AdjustParalyzed(-40) + inspired_human.AdjustUnconscious(-40) + playsound(inspired_human, 'sound/magic/staff_healing.ogg', 25, FALSE) /obj/item/banner/proc/special_inspiration(mob/living/carbon/human/H) //Any banner-specific inspiration effects go here return @@ -128,10 +131,13 @@ /obj/item/clothing/under/rank/medical/doctor = 1) category = CAT_MISC -/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/H) - H.adjustToxLoss(-15) - H.setOxyLoss(0) - H.reagents.add_reagent(/datum/reagent/medicine/inaprovaline, 5) +/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/inspired_human) + var/need_mob_update = FALSE + need_mob_update += inspired_human.adjustToxLoss(-15, updating_health = FALSE) + need_mob_update += inspired_human.setOxyLoss(0, updating_health = FALSE) + if(need_mob_update) + inspired_human.updatehealth() + inspired_human.reagents.add_reagent(/datum/reagent/medicine/inaprovaline, 5) /obj/item/banner/science name = "sciencia banner" diff --git a/code/game/objects/items/robot/items/storage.dm b/code/game/objects/items/robot/items/storage.dm index 6570e159b6a094..4995c7d9df6066 100644 --- a/code/game/objects/items/robot/items/storage.dm +++ b/code/game/objects/items/robot/items/storage.dm @@ -57,18 +57,20 @@ /obj/item/borg/apparatus/pre_attack(atom/atom, mob/living/user, params) if(!stored) - var/itemcheck = FALSE - for(var/storable_type in storable) - if(istype(atom, storable_type)) - itemcheck = TRUE - break - if(itemcheck) - var/obj/item/item = atom - item.forceMove(src) - stored = item - RegisterSignal(stored, COMSIG_ATOM_UPDATED_ICON, PROC_REF(on_stored_updated_icon)) - update_appearance() - return TRUE + // Borgs should not be grabbing their own modules + if(!istype(atom.loc, /mob/living/silicon/robot)) + var/itemcheck = FALSE + for(var/storable_type in storable) + if(istype(atom, storable_type)) + itemcheck = TRUE + break + if(itemcheck) + var/obj/item/item = atom + item.forceMove(src) + stored = item + RegisterSignal(stored, COMSIG_ATOM_UPDATED_ICON, PROC_REF(on_stored_updated_icon)) + update_appearance() + return TRUE else stored.melee_attack_chain(user, atom, params) return TRUE diff --git a/code/game/objects/items/skub.dm b/code/game/objects/items/skub.dm index 7e9cd381e336b9..12e6da344d0b85 100644 --- a/code/game/objects/items/skub.dm +++ b/code/game/objects/items/skub.dm @@ -13,6 +13,6 @@ /obj/item/skub/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] has declared themself as anti-skub! The skub tears them apart!")) - user.gib() + user.gib(DROP_ALL_REMAINS) playsound(src, 'sound/items/eatfood.ogg', 50, TRUE, -1) return MANUAL_SUICIDE diff --git a/code/game/objects/items/spear.dm b/code/game/objects/items/spear.dm index d9f13911731db4..410cddd1fc079d 100644 --- a/code/game/objects/items/spear.dm +++ b/code/game/objects/items/spear.dm @@ -152,7 +152,7 @@ user.say("[war_cry]", forced="spear warcry") explosive.forceMove(user) explosive.detonate() - user.gib() + user.gib(DROP_ALL_REMAINS) qdel(src) return BRUTELOSS diff --git a/code/game/objects/items/stacks/golem_food/golem_hand_actions.dm b/code/game/objects/items/stacks/golem_food/golem_hand_actions.dm index fc87d09447744d..39c17d2346c6a5 100644 --- a/code/game/objects/items/stacks/golem_food/golem_hand_actions.dm +++ b/code/game/objects/items/stacks/golem_food/golem_hand_actions.dm @@ -35,7 +35,7 @@ playsound(src, 'sound/weapons/sonic_jackhammer.ogg', 50, TRUE) held_gibtonite.forceMove(get_turf(src)) held_gibtonite.det_time = 2 SECONDS - held_gibtonite.GibtoniteReaction(user) + held_gibtonite.GibtoniteReaction(user, "A [src] has targeted [target] with a thrown and primed") held_gibtonite.throw_at(target, range = 10, speed = 3, thrower = user) held_gibtonite = null qdel(src) @@ -44,7 +44,7 @@ /// Called when you can't hold it in any longer and just drop it on the ground /obj/item/gibtonite_hand/proc/release_gibtonite() held_gibtonite.forceMove(get_turf(src)) - held_gibtonite.GibtoniteReaction(isliving(loc) ? loc : null) + held_gibtonite.GibtoniteReaction(isliving(loc) ? loc : null, "A [src] has dropped and primed a") held_gibtonite = null qdel(src) diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index 081ab5d78e015e..f4a61f2d7ca4d2 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -159,6 +159,15 @@ splint_factor = 0.7 burn_cleanliness_bonus = 0.35 merge_type = /obj/item/stack/medical/gauze + var/obj/item/bodypart/gauzed_bodypart + +/obj/item/stack/medical/gauze/Destroy(force) + . = ..() + + if (gauzed_bodypart) + gauzed_bodypart.current_gauze = null + SEND_SIGNAL(gauzed_bodypart, COMSIG_BODYPART_UNGAUZED, src) + gauzed_bodypart = null // gauze is only relevant for wounds, which are handled in the wounds themselves /obj/item/stack/medical/gauze/try_heal(mob/living/patient, mob/user, silent) @@ -474,3 +483,27 @@ /obj/item/stack/medical/poultice/post_heal_effects(amount_healed, mob/living/carbon/healed_mob, mob/user) . = ..() healed_mob.adjustOxyLoss(amount_healed) + +/obj/item/stack/medical/bandage + name = "first aid bandage" + desc = "A DeForest brand bandage designed for basic first aid on blunt-force trauma." + icon_state = "bandage" + inhand_icon_state = "bandage" + novariants = TRUE + amount = 1 + max_amount = 1 + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + heal_brute = 25 + stop_bleeding = 0.2 + self_delay = 3 SECONDS + other_delay = 1 SECONDS + grind_results = list(/datum/reagent/medicine/c2/libital = 2) + +/obj/item/stack/medical/bandage/makeshift + name = "makeshift bandage" + desc = "A hastily constructed bandage designed for basic first aid on blunt-force trauma." + icon_state = "bandage_makeshift" + icon_state_preview = "bandage_makeshift" + inhand_icon_state = "bandage" + novariants = TRUE diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 381cdd7a2962d8..1ad86868212f5c 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -609,7 +609,8 @@ GLOBAL_LIST_INIT(cardboard_recipes, list ( \ new /datum/stack_recipe("light bulbs box", /obj/item/storage/box/lights/bulbs, check_density = FALSE, category = CAT_CONTAINERS), \ new /datum/stack_recipe("mixed lights box", /obj/item/storage/box/lights/mixed, check_density = FALSE, category = CAT_CONTAINERS), \ new /datum/stack_recipe("mouse traps box", /obj/item/storage/box/mousetraps, check_density = FALSE, category = CAT_CONTAINERS), \ - new /datum/stack_recipe("candle box", /obj/item/storage/fancy/candle_box, check_density = FALSE, category = CAT_CONTAINERS) + new /datum/stack_recipe("candle box", /obj/item/storage/fancy/candle_box, check_density = FALSE, category = CAT_CONTAINERS), \ + new /datum/stack_recipe("bandage box", /obj/item/storage/box/bandages, check_density = FALSE, category = CAT_CONTAINERS) )), null, \ diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index a67d85979f1040..abd9f8efb2f93c 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -235,7 +235,7 @@ /obj/item/healthanalyzer, /obj/item/hemostat, /obj/item/holosign_creator/medical, - /obj/item/hypospray/mkii, //SKYRAT EDIT HYPOSPRAYS + /obj/item/hypospray/mkii, //SKYRAT EDIT ADDITION - HYPOSPRAYS /obj/item/implant, /obj/item/implantcase, /obj/item/implanter, @@ -248,7 +248,7 @@ /obj/item/reagent_containers/dropper, /obj/item/reagent_containers/cup/beaker, /obj/item/reagent_containers/cup/bottle, - /obj/item/reagent_containers/cup/vial, //SKYRAT EDIT HYPOSPRAYS + /obj/item/reagent_containers/cup/vial, //SKYRAT EDIT ADDITION - HYPOSPRAYS /obj/item/reagent_containers/cup/tube, /obj/item/reagent_containers/hypospray, /obj/item/reagent_containers/medigel, @@ -694,6 +694,7 @@ atom_storage.max_slots = 6 atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL // Set to this so the light replacer can fit. atom_storage.set_holdable(list( + /obj/item/access_key, /obj/item/assembly/mousetrap, /obj/item/clothing/gloves, /obj/item/flashlight, diff --git a/code/game/objects/items/storage/boxes/medical_boxes.dm b/code/game/objects/items/storage/boxes/medical_boxes.dm index ad0fd9b37f54b1..ff4b232454c771 100644 --- a/code/game/objects/items/storage/boxes/medical_boxes.dm +++ b/code/game/objects/items/storage/boxes/medical_boxes.dm @@ -129,3 +129,43 @@ /obj/item/reagent_containers/cup/beaker/meta/rezadone = 1, ) generate_items_inside(items_inside, src) + +/obj/item/storage/box/bandages + name = "box of bandages" + desc = "A box of DeForest brand gel bandages designed to treat blunt-force trauma." + icon = 'icons/obj/storage/box.dmi' // SKYRAT EDIT CHANGE + icon_state = "brutebox" + base_icon_state = "brutebox" + inhand_icon_state = "brutebox" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + drop_sound = 'sound/items/handling/matchbox_drop.ogg' + pickup_sound = 'sound/items/handling/matchbox_pickup.ogg' + illustration = null + w_class = WEIGHT_CLASS_SMALL + custom_price = PAYCHECK_CREW * 1.75 + +/obj/item/storage/box/bandages/Initialize(mapload) + . = ..() + atom_storage.max_slots = 6 + atom_storage.set_holdable(list( + /obj/item/stack/medical/bandage, + /obj/item/reagent_containers/pill, + /obj/item/reagent_containers/pill/patch, + )) + +/obj/item/storage/box/bandages/PopulateContents() + for(var/i in 1 to 5) + new /obj/item/stack/medical/bandage(src) + +/obj/item/storage/box/bandages/update_icon_state() + . = ..() + switch(length(contents)) + if(5) + icon_state = "[base_icon_state]_f" + if(3 to 4) + icon_state = "[base_icon_state]_almostfull" + if(1 to 2) + icon_state = "[base_icon_state]_almostempty" + if(0) + icon_state = base_icon_state diff --git a/code/game/objects/items/storage/holsters.dm b/code/game/objects/items/storage/holsters.dm index 7b8bc6a6716f48..cb722469a2c033 100644 --- a/code/game/objects/items/storage/holsters.dm +++ b/code/game/objects/items/storage/holsters.dm @@ -30,6 +30,8 @@ /obj/item/food/grown/banana, /obj/item/gun/energy/laser/thermal, /obj/item/gun/ballistic/rifle/boltaction, //fits if you make it an obrez + /obj/item/gun/energy/laser/captain, + /obj/item/gun/energy/e_gun/hos, )) /obj/item/storage/belt/holster/energy @@ -47,6 +49,8 @@ /obj/item/food/grown/banana, /obj/item/gun/energy/laser/thermal, /obj/item/gun/energy/recharge/ebow, + /obj/item/gun/energy/laser/captain, + /obj/item/gun/energy/e_gun/hos, )) /obj/item/storage/belt/holster/energy/thermal @@ -100,6 +104,8 @@ /obj/item/gun/energy/disabler, /obj/item/gun/energy/dueling, /obj/item/gun/energy/laser/thermal, + /obj/item/gun/energy/laser/captain, + /obj/item/gun/energy/e_gun/hos, /obj/item/gun/ballistic/rifle/boltaction, //fits if you make it an obrez )) @@ -150,7 +156,9 @@ /obj/item/gun/energy/recharge/ebow, /obj/item/gun/energy/e_gun/mini, /obj/item/gun/energy/disabler, - /obj/item/gun/energy/dueling + /obj/item/gun/energy/dueling, + /obj/item/gun/energy/laser/captain, + /obj/item/gun/energy/e_gun/hos, )) atom_storage.silent = TRUE @@ -176,3 +184,18 @@ /obj/item/ammo_casing, // For shotgun shells, rockets, launcher grenades, and a few other things. /obj/item/grenade, // All regular grenades, the big grenade launcher fires these. )) + +/obj/item/storage/belt/holster/nukie/cowboy + desc = "A deep shoulder holster capable of holding almost any form of small firearm and its ammo. This one's specialized for handguns." + +/obj/item/storage/belt/holster/nukie/cowboy/Initialize(mapload) + . = ..() + atom_storage.max_slots = 3 + atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL + +/obj/item/storage/belt/holster/nukie/cowboy/full/PopulateContents() + generate_items_inside(list( + /obj/item/gun/ballistic/revolver/syndicate/cowboy = 1, + /obj/item/ammo_box/a357 = 2, + ), src) + diff --git a/code/game/objects/items/storage/medkit.dm b/code/game/objects/items/storage/medkit.dm index 6ca84e415e01b0..4b08d1551a34e3 100644 --- a/code/game/objects/items/storage/medkit.dm +++ b/code/game/objects/items/storage/medkit.dm @@ -34,6 +34,7 @@ /obj/item/reagent_containers/medigel, /obj/item/reagent_containers/spray, /obj/item/lighter, + /obj/item/storage/box/bandages, /obj/item/storage/fancy/cigarettes, /obj/item/storage/pill_bottle, /obj/item/stack/medical, @@ -288,18 +289,19 @@ if(empty) return var/static/list/items_inside = list( + /obj/item/cautery = 1, + /obj/item/scalpel = 1, + /obj/item/healthanalyzer/advanced = 1, + /obj/item/hemostat = 1, + /obj/item/reagent_containers/medigel/sterilizine = 1, + /obj/item/storage/box/bandages = 1, + /obj/item/surgical_drapes = 1, + /obj/item/reagent_containers/hypospray/medipen/atropine = 2, + /obj/item/stack/medical/gauze = 2, /obj/item/stack/medical/suture/medicated = 2, /obj/item/stack/medical/mesh/advanced = 2, /obj/item/reagent_containers/pill/patch/libital = 4, /obj/item/reagent_containers/pill/patch/aiuri = 4, - /obj/item/healthanalyzer/advanced = 1, - /obj/item/stack/medical/gauze = 2, - /obj/item/reagent_containers/hypospray/medipen/atropine = 2, - /obj/item/reagent_containers/medigel/sterilizine = 1, - /obj/item/surgical_drapes = 1, - /obj/item/scalpel = 1, - /obj/item/hemostat = 1, - /obj/item/cautery = 1, ) generate_items_inside(items_inside,src) @@ -332,6 +334,7 @@ /obj/item/mod/module/health_analyzer = 1, /obj/item/autosurgeon/syndicate/emaggedsurgerytoolset = 1, /obj/item/reagent_containers/hypospray/combat/empty = 1, + /obj/item/storage/box/bandages = 1, /obj/item/storage/box/evilmeds = 1, /obj/item/reagent_containers/medigel/sterilizine = 1, /obj/item/clothing/glasses/hud/health/night/science = 1, diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index 9fa66404aeda3a..fc1b264b811805 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -789,6 +789,21 @@ for(var/i in 1 to poster_count) new /obj/item/poster/traitor(src) +/obj/item/storage/box/syndie_kit/cowboy + name = "western outlaw pack" + desc = "Contains everything you'll need to be the rootin' tootin' cowboy you always wanted. Either play the Lone Ranger or go in with your posse of outlaws." + +/obj/item/storage/box/syndie_kit/cowboy/PopulateContents() + generate_items_inside(list( + /obj/item/clothing/shoes/cowboy/black/syndicate= 1, + /obj/item/clothing/head/cowboy/black/syndicate = 1, + /obj/item/storage/belt/holster/nukie/cowboy/full = 1, + /obj/item/clothing/under/costume/dutch/syndicate = 1, + /obj/item/lighter/skull = 1, + /obj/item/sbeacondrop/horse = 1, + /obj/item/food/grown/apple = 1, + ), src) + #undef KIT_RECON #undef KIT_BLOODY_SPAI #undef KIT_STEALTHY diff --git a/code/game/objects/items/surgery_tray.dm b/code/game/objects/items/surgery_tray.dm index 37494a39b555e0..edd92522446d1f 100644 --- a/code/game/objects/items/surgery_tray.dm +++ b/code/game/objects/items/surgery_tray.dm @@ -6,6 +6,7 @@ /datum/storage/surgery_tray/New() . = ..() set_holdable(list( + /obj/item/autopsy_scanner, /obj/item/blood_filter, /obj/item/bonesetter, /obj/item/cautery, diff --git a/code/game/objects/items/tail_pin.dm b/code/game/objects/items/tail_pin.dm index 3052075c94d145..de3148dd06dea3 100644 --- a/code/game/objects/items/tail_pin.dm +++ b/code/game/objects/items/tail_pin.dm @@ -2,7 +2,7 @@ icon = 'icons/obj/poster.dmi' icon_state = "tailpin" name = "tail pin" - desc = "Offically branded 'pin the tail on the corgi' style party implement. Not intended to be used on people." + desc = "Officially branded 'pin the tail on the corgi' style party implement. Not intended to be used on people." force = 0 w_class = WEIGHT_CLASS_SMALL throwforce = 0 diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm index 533fc755fa1881..07e178acba5f9c 100644 --- a/code/game/objects/items/teleportation.dm +++ b/code/game/objects/items/teleportation.dm @@ -489,7 +489,7 @@ destination.ex_act(EXPLODE_HEAVY) victim.unequip_everything() victim.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) - victim.gib() + victim.gib(DROP_ALL_REMAINS) ///Damage and stun all mobs in fragging_location turf, called after a teleport /obj/item/syndicate_teleporter/proc/telefrag(turf/fragging_location, mob/user) // Don't let this gib. Never let this gib. diff --git a/code/game/objects/items/tongs.dm b/code/game/objects/items/tongs.dm new file mode 100644 index 00000000000000..8e7753bf488493 --- /dev/null +++ b/code/game/objects/items/tongs.dm @@ -0,0 +1,100 @@ +/// Tongs, let you pick up and feed people food from further away. +/obj/item/kitchen/tongs + name = "tongs" + desc = "So you never have to touch anything with your dirty, unwashed hands." + reach = 2 + icon_state = "tongs" + base_icon_state = "tongs" + inhand_icon_state = "fork" // close enough + attack_verb_continuous = list("pinches", "tongs", "nips") + attack_verb_simple = list("pinch", "tong", "nip") + /// What are we holding in our tongs? + var/obj/item/tonged + /// Sound to play when we click our tongs together + var/clack_sound = 'sound/items/handling/component_drop.ogg' + /// Time to wait between clacking sounds + var/clack_delay = 2 SECONDS + /// Have we clacked recently? + COOLDOWN_DECLARE(clack_cooldown) + +/obj/item/kitchen/tongs/Destroy(force) + QDEL_NULL(tonged) + return ..() + +/obj/item/kitchen/tongs/examine(mob/user) + . = ..() + if (!isnull(tonged)) + . += span_notice("It is holding [tonged].") + +/obj/item/kitchen/tongs/dropped(mob/user, silent) + . = ..() + drop_tonged() + +/obj/item/kitchen/tongs/attack_self(mob/user, modifiers) + . = ..() + if(.) + return TRUE + if (!isnull(tonged)) + drop_tonged() + return TRUE + if (!COOLDOWN_FINISHED(src, clack_cooldown)) + return TRUE + user.visible_message(span_notice("[user] clacks [user.p_their()] [src] together like a crab. Click clack!")) + click_clack() + return TRUE + +/// Release the food we are holding +/obj/item/kitchen/tongs/proc/drop_tonged() + if (isnull(tonged)) + return + visible_message(span_notice("[tonged] falls to the ground!")) + var/turf/location = drop_location() + tonged.forceMove(location) + tonged.do_drop_animation(location) + +/// Play a clacking sound and appear closed, then open again +/obj/item/kitchen/tongs/proc/click_clack() + COOLDOWN_START(src, clack_cooldown, clack_delay) + playsound(src, clack_sound, vol = 100, vary = FALSE) + icon_state = "[base_icon_state]_closed" + var/delay = min(0.5 SECONDS, clack_delay / 2) // Just in case someone's been fucking with the cooldown + addtimer(CALLBACK(src, PROC_REF(clack)), delay, TIMER_DELETE_ME) + +/// Plays a clacking sound and appear open +/obj/item/kitchen/tongs/proc/clack() + playsound(src, clack_sound, vol = 100, vary = FALSE) + icon_state = base_icon_state + +/obj/item/kitchen/tongs/Exited(atom/movable/leaving, direction) + . = ..() + if (leaving != tonged) + return + tonged = null + update_appearance(UPDATE_ICON) + +/obj/item/kitchen/tongs/pre_attack(obj/item/attacked, mob/living/user, params) + if (!isnull(tonged)) + attacked.attackby(tonged, user) + return TRUE + if (isliving(attacked)) + if (COOLDOWN_FINISHED(src, clack_cooldown)) + click_clack() + return ..() + if (!IsEdible(attacked) || attacked.w_class > WEIGHT_CLASS_NORMAL || !isnull(tonged)) + return ..() + tonged = attacked + attacked.do_pickup_animation(src) + attacked.forceMove(src) + update_appearance(UPDATE_ICON) + +/obj/item/kitchen/tongs/update_overlays() + . = ..() + if (isnull(tonged)) + return + var/mutable_appearance/held_food = new /mutable_appearance(tonged.appearance) + held_food.layer = layer + held_food.plane = plane + held_food.transform = held_food.transform.Scale(0.7, 0.7) + held_food.pixel_x = 6 + held_food.pixel_y = 6 + . += held_food diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 21fc15572bfc25..8c949b36a79e49 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -922,7 +922,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 if(isliving(target)) var/mob/living/bug = target bug.investigate_log("has been splatted by a flyswatter.", INVESTIGATE_DEATHS) - bug.gib() + bug.gib(DROP_ALL_REMAINS) else qdel(target) return @@ -1099,7 +1099,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 if(living_target.stat == DEAD && prob(force*damage_mod*0.5)) living_target.visible_message(span_danger("[living_target] explodes in a shower of gore!"), blind_message = span_hear("You hear organic matter ripping and tearing!")) living_target.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) - living_target.gib() + living_target.gib(DROP_ALL_REMAINS) log_combat(user, living_target, "gibbed", src) else if(target.uses_integrity) target.take_damage(force*damage_mod*3, BRUTE, MELEE, FALSE, null, 50) diff --git a/code/game/objects/structures/bonfire.dm b/code/game/objects/structures/bonfire.dm index 3ca135a5786003..a6cbbf8b0099ac 100644 --- a/code/game/objects/structures/bonfire.dm +++ b/code/game/objects/structures/bonfire.dm @@ -17,19 +17,14 @@ anchored = TRUE buckle_lying = 0 pass_flags_self = PASSTABLE | LETPASSTHROW - ///is the bonfire lit? + /// is the bonfire lit? var/burning = FALSE - ///icon for the bonfire while on. for a softer more burning embers icon, use "bonfire_warm" + /// icon for the bonfire while on. for a softer more burning embers icon, use "bonfire_warm" var/burn_icon = "bonfire_on_fire" - ///if the bonfire has a grill attached + /// if the bonfire has a grill attached var/grill = FALSE - -/obj/structure/bonfire/dense - density = TRUE - -/obj/structure/bonfire/prelit/Initialize(mapload) - . = ..() - start_burning() + /// the looping sound effect that is played while burning + var/datum/looping_sound/burning/burning_loop /obj/structure/bonfire/Initialize(mapload) . = ..() @@ -37,6 +32,12 @@ COMSIG_ATOM_ENTERED = PROC_REF(on_entered), ) AddElement(/datum/element/connect_loc, loc_connections) + burning_loop = new(src) + +/obj/structure/bonfire/Destroy() + STOP_PROCESSING(SSobj, src) + QDEL_NULL(burning_loop) + . = ..() /obj/structure/bonfire/attackby(obj/item/used_item, mob/living/user, params) if(istype(used_item, /obj/item/stack/rods) && !can_buckle && !grill) @@ -77,7 +78,6 @@ else return ..() - /obj/structure/bonfire/attack_hand(mob/user, list/modifiers) . = ..() if(.) @@ -107,6 +107,8 @@ /obj/structure/bonfire/proc/start_burning() if(burning || !check_oxygen()) return + + burning_loop.start() icon_state = burn_icon burning = TRUE set_light(6) @@ -169,6 +171,8 @@ . = ..() if(!burning) return + + burning_loop.stop() icon_state = "bonfire" burning = FALSE set_light(0) @@ -183,4 +187,11 @@ if(..()) buckled_mob.pixel_y -= 13 +/obj/structure/bonfire/dense + density = TRUE + +/obj/structure/bonfire/prelit/Initialize(mapload) + . = ..() + start_burning() + #undef BONFIRE_FIRE_STACK_STRENGTH 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 9700a3e80fa98f..ec46756140ca25 100755 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -17,7 +17,7 @@ new /obj/item/radio/headset/heads/captain/alt(src) new /obj/item/radio/headset/heads/captain(src) new /obj/item/storage/belt/sabre(src) - new /obj/item/storage/box/gunset/pdh(src) // SKYRAT EDIT CHANGE - ORIGINAL: new /obj/item/gun/energy/e_gun(src) + new /obj/item/gun/energy/e_gun(src) new /obj/item/door_remote/captain(src) new /obj/item/storage/photo_album/captain(src) @@ -25,7 +25,6 @@ name = "head of personnel's locker" icon_state = "hop" req_access = list(ACCESS_HOP) - storage_capacity = 40 //SKYRAT EDIT ADDITION /obj/structure/closet/secure_closet/hop/PopulateContents() ..() diff --git a/code/game/objects/structures/divine.dm b/code/game/objects/structures/divine.dm index cda00d98d0b37f..ef9f650e42a562 100644 --- a/code/game/objects/structures/divine.dm +++ b/code/game/objects/structures/divine.dm @@ -18,7 +18,7 @@ return to_chat(user, span_notice("Invoking the sacred ritual, you sacrifice [L].")) L.investigate_log("has been sacrificially gibbed on an altar.", INVESTIGATE_DEATHS) - L.gib() + L.gib(DROP_ALL_REMAINS) message_admins("[ADMIN_LOOKUPFLW(user)] has sacrificed [key_name_admin(L)] on the sacrificial altar at [AREACOORD(src)].") /obj/structure/healingfountain diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm index 59a00618b0e915..31ba1cd47aa59f 100644 --- a/code/game/objects/structures/fireaxe.dm +++ b/code/game/objects/structures/fireaxe.dm @@ -211,6 +211,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/fireaxecabinet, 32) /obj/structure/fireaxecabinet/empty populate_contents = FALSE +MAPPING_DIRECTIONAL_HELPERS(/obj/structure/fireaxecabinet/empty, 32) + /obj/item/wallframe/fireaxecabinet name = "fire axe cabinet" desc = "Home to a window's greatest nightmare. Apply to wall to use." @@ -238,6 +240,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/fireaxecabinet/mechremoval, 32) /obj/structure/fireaxecabinet/mechremoval/empty populate_contents = FALSE +MAPPING_DIRECTIONAL_HELPERS(/obj/structure/fireaxecabinet/mechremoval/empty, 32) + /obj/item/wallframe/fireaxecabinet/mechremoval name = "mech removal tool cabinet" desc = "Home to a very special crowbar. Apply to wall to use." diff --git a/code/game/objects/structures/fireplace.dm b/code/game/objects/structures/fireplace.dm index afd4d27efe6c63..8c9d09585c998a 100644 --- a/code/game/objects/structures/fireplace.dm +++ b/code/game/objects/structures/fireplace.dm @@ -14,17 +14,22 @@ light_color = LIGHT_COLOR_FIRE light_angle = 170 light_flags = LIGHT_IGNORE_OFFSET + /// is the fireplace lit? var/lit = FALSE - + /// the amount of fuel for the fire var/fuel_added = 0 + /// how much time is left before fire runs out of fuel var/flame_expiry_timer + /// the looping sound effect that is played while burning + var/datum/looping_sound/burning/burning_loop /obj/structure/fireplace/Initialize(mapload) . = ..() - START_PROCESSING(SSobj, src) + burning_loop = new(src) /obj/structure/fireplace/Destroy() STOP_PROCESSING(SSobj, src) + QDEL_NULL(burning_loop) . = ..() /obj/structure/fireplace/setDir(newdir) @@ -126,7 +131,6 @@ put_out() return - playsound(src, 'sound/effects/comfyfire.ogg',50,FALSE, FALSE, TRUE) var/turf/T = get_turf(src) T.hotspot_expose(700, 2.5 * seconds_per_tick) update_appearance() @@ -155,6 +159,8 @@ return max(0, fuel_added) /obj/structure/fireplace/proc/ignite() + START_PROCESSING(SSobj, src) + burning_loop.start() lit = TRUE desc = "A large stone brick fireplace, warm and cozy." flame_expiry_timer = world.time + fuel_added @@ -163,6 +169,8 @@ adjust_light() /obj/structure/fireplace/proc/put_out() + STOP_PROCESSING(SSobj, src) + burning_loop.stop() lit = FALSE update_appearance() adjust_light() diff --git a/code/game/objects/structures/icemoon/cave_entrance.dm b/code/game/objects/structures/icemoon/cave_entrance.dm index 7393c20758e245..add1f278569fc0 100644 --- a/code/game/objects/structures/icemoon/cave_entrance.dm +++ b/code/game/objects/structures/icemoon/cave_entrance.dm @@ -20,6 +20,9 @@ GLOBAL_LIST_INIT(ore_probability, list( mob_types = list(/mob/living/simple_animal/hostile/asteroid/wolf) move_resist = INFINITY anchored = TRUE + scanner_taggable = TRUE + mob_gps_id = "WF" // wolf + spawner_gps_id = "Animal Den" /obj/structure/spawner/ice_moon/Initialize(mapload) . = ..() @@ -65,6 +68,7 @@ GLOBAL_LIST_INIT(ore_probability, list( max_mobs = 1 spawn_time = 60 SECONDS mob_types = list(/mob/living/simple_animal/hostile/asteroid/polarbear) + mob_gps_id = "BR" // bear /obj/structure/spawner/ice_moon/polarbear/clear_rock() for(var/turf/potential in RANGE_TURFS(1, src)) @@ -76,9 +80,11 @@ GLOBAL_LIST_INIT(ore_probability, list( name = "demonic portal" desc = "A portal that goes to another world, normal creatures couldn't survive there." icon_state = "nether" - mob_types = list(/mob/living/simple_animal/hostile/asteroid/ice_demon) + mob_types = list(/mob/living/basic/mining/ice_demon) light_range = 1 light_color = COLOR_SOFT_RED + mob_gps_id = "WT|B" // watcher | bluespace + spawner_gps_id = "Netheric Distortion" /obj/structure/spawner/ice_moon/demonic_portal/Initialize(mapload) . = ..() @@ -100,9 +106,11 @@ GLOBAL_LIST_INIT(ore_probability, list( /obj/structure/spawner/ice_moon/demonic_portal/ice_whelp mob_types = list(/mob/living/basic/mining/ice_whelp) + mob_gps_id = "ID|W" // ice drake | whelp /obj/structure/spawner/ice_moon/demonic_portal/snowlegion mob_types = list(/mob/living/basic/mining/legion/snow/spawner_made) + mob_gps_id = "LG|S" // legion | snow /obj/effect/collapsing_demonic_portal name = "collapsing demonic portal" diff --git a/code/game/objects/structures/lavaland/necropolis_tendril.dm b/code/game/objects/structures/lavaland/necropolis_tendril.dm index 22f7f0422cd191..6d6b2e6af37af9 100644 --- a/code/game/objects/structures/lavaland/necropolis_tendril.dm +++ b/code/game/objects/structures/lavaland/necropolis_tendril.dm @@ -14,19 +14,22 @@ move_resist=INFINITY // just killing it tears a massive hole in the ground, let's not move it anchored = TRUE resistance_flags = FIRE_PROOF | LAVA_PROOF - - var/gps = null var/obj/effect/light_emitter/tendril/emitted_light - + scanner_taggable = TRUE + mob_gps_id = "WT" + spawner_gps_id = "Necropolis Tendril" /obj/structure/spawner/lavaland/goliath mob_types = list(/mob/living/basic/mining/goliath) + mob_gps_id = "GL" /obj/structure/spawner/lavaland/legion mob_types = list(/mob/living/basic/mining/legion/spawner_made) + mob_gps_id = "LG" /obj/structure/spawner/lavaland/icewatcher mob_types = list(/mob/living/basic/mining/watcher/icewing) + mob_gps_id = "WT|I" // icewing GLOBAL_LIST_INIT(tendrils, list()) /obj/structure/spawner/lavaland/Initialize(mapload) @@ -63,7 +66,6 @@ GLOBAL_LIST_INIT(tendrils, list()) L.client.give_award(/datum/award/score/tendril_score, L) //Progresses score by one GLOB.tendrils -= src QDEL_NULL(emitted_light) - QDEL_NULL(gps) return ..() /obj/effect/light_emitter/tendril diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm index 3c99aee7233d30..6072d905781d6b 100644 --- a/code/game/objects/structures/mirror.dm +++ b/code/game/objects/structures/mirror.dm @@ -1,3 +1,20 @@ + +// Normal Mirrors + +#define CHANGE_HAIR "Change Hair" +#define CHANGE_BEARD "Change Beard" + +// Magic Mirrors! + +#define CHANGE_RACE "Change Race" +#define CHANGE_SEX "Change Sex" +#define CHANGE_NAME "Change Name" +#define CHANGE_EYES "Change Eyes" + +#define INERT_MIRROR_OPTIONS list(CHANGE_HAIR, CHANGE_BEARD) +#define PRIDE_MIRROR_OPTIONS list(CHANGE_HAIR, CHANGE_BEARD, CHANGE_RACE, CHANGE_SEX, CHANGE_EYES) +#define MAGIC_MIRROR_OPTIONS list(CHANGE_HAIR, CHANGE_BEARD, CHANGE_RACE, CHANGE_SEX, CHANGE_EYES, CHANGE_NAME) + /obj/structure/mirror name = "mirror" desc = "Mirror mirror on the wall, who's the most robust of them all?" @@ -6,8 +23,28 @@ movement_type = FLOATING density = FALSE anchored = TRUE - max_integrity = 200 integrity_failure = 0.5 + max_integrity = 200 + var/list/mirror_options = INERT_MIRROR_OPTIONS + var/magical_mirror = FALSE + + ///Flags this race must have to be selectable with this type of mirror. + var/race_flags = MIRROR_MAGIC + ///List of all Races that can be chosen, decided by its Initialize. + var/list/selectable_races = list() + +/obj/structure/mirror/Initialize(mapload) + . = ..() + update_choices() + +/obj/structure/mirror/Destroy() + mirror_options = null + selectable_races = null + return ..() + +/obj/structure/mirror/proc/update_choices() + for(var/i in mirror_options) + mirror_options[i] = icon('icons/hud/radial.dmi', i) /obj/structure/mirror/Initialize(mapload) . = ..() @@ -40,46 +77,160 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror, 28) MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) -/* SKYRAT EDIT REMOVAL -/obj/structure/mirror/attack_hand(mob/user, list/modifiers) +/obj/structure/mirror/attack_hand(mob/living/carbon/human/user) . = ..() - if(.) - return TRUE - if(broken || !Adjacent(user)) - return TRUE - if(!ishuman(user)) + if(. || !ishuman(user) || broken || !magical_mirror) // SKYRAT EDIT CHANGE - MUNDANE MIRRORS DON'T LET YOU CHANGE - ORIGINAL: if(. || !ishuman(user) || broken) return TRUE - var/mob/living/carbon/human/hairdresser = user - //handle facial hair (if necessary) - if(hairdresser.gender != FEMALE) - var/new_style = tgui_input_list(user, "Select a facial hairstyle", "Grooming", GLOB.facial_hairstyles_list) + if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH) && !magical_mirror) + return TRUE //no tele-grooming (if nonmagical) + + return display_radial_menu(user) + +/obj/structure/mirror/proc/display_radial_menu(mob/living/carbon/human/user) + var/pick = show_radial_menu(user, src, mirror_options, user, radius = 36, require_near = TRUE) + if(!pick) + return TRUE //get out + + switch(pick) + if(CHANGE_HAIR) + change_hair(user) + if(CHANGE_BEARD) + change_beard(user) + if(CHANGE_RACE) + change_race(user) + if(CHANGE_SEX) // sex: yes + change_sex(user) + if(CHANGE_NAME) + change_name(user) + if(CHANGE_EYES) + change_eyes(user) + + return display_radial_menu(user) + +/obj/structure/mirror/proc/change_beard(mob/living/carbon/human/beard_dresser) + if(beard_dresser.physique != FEMALE && !magical_mirror) + var/new_style = tgui_input_list(beard_dresser, "Select a facial hairstyle", "Grooming", GLOB.facial_hairstyles_list) if(isnull(new_style)) return TRUE - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return TRUE //no tele-grooming - if(HAS_TRAIT(hairdresser, TRAIT_SHAVED)) - to_chat(hairdresser, span_notice("If only growing back facial hair were that easy for you...")) + if(HAS_TRAIT(beard_dresser, TRAIT_SHAVED)) + to_chat(beard_dresser, span_notice("If only growing back facial hair were that easy for you... The reminder makes you feel terrible.")) + beard_dresser.add_mood_event("bald_hair_day", /datum/mood_event/bald_reminder) return TRUE - hairdresser.set_facial_hairstyle(new_style, update = TRUE) + beard_dresser.set_facial_hairstyle(new_style, update = TRUE) else - hairdresser.set_facial_hairstyle("Shaved", update = TRUE) + if(beard_dresser.facial_hairstyle == "Shaved") + to_chat(beard_dresser, span_notice("You realize you don't have any facial hair.")) + return + beard_dresser.set_facial_hairstyle("Shaved", update = TRUE) - //handle normal hair - var/new_style = tgui_input_list(user, "Select a hairstyle", "Grooming", GLOB.hairstyles_list) +/obj/structure/mirror/proc/change_hair(mob/living/carbon/human/hairdresser) + var/new_style = tgui_input_list(hairdresser, "Select a hairstyle", "Grooming", GLOB.hairstyles_list) if(isnull(new_style)) return TRUE - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return TRUE //no tele-grooming if(HAS_TRAIT(hairdresser, TRAIT_BALD)) - to_chat(hairdresser, span_notice("If only growing back hair were that easy for you...")) + to_chat(hairdresser, span_notice("If only growing back hair were that easy for you... The reminder makes you feel terrible.")) + hairdresser.add_mood_event("bald_hair_day", /datum/mood_event/bald_reminder) return TRUE hairdresser.set_hairstyle(new_style, update = TRUE) -*/ -/obj/structure/mirror/examine_status(mob/user) +/obj/structure/mirror/proc/change_name(mob/living/carbon/human/user) + var/newname = sanitize_name(tgui_input_text(user, "Who are we again?", "Name change", user.name, MAX_NAME_LEN), allow_numbers = TRUE) //It's magic so whatever. + if(!newname) + return TRUE + user.real_name = newname + user.name = newname + if(user.dna) + user.dna.real_name = newname + if(user.mind) + user.mind.name = newname + +// Erm ackshually the proper term is species. Get it right?? +/obj/structure/mirror/proc/change_race(mob/living/carbon/human/race_changer) + var/racechoice = tgui_input_list(race_changer, "What are we again?", "Race change", selectable_races) + if(isnull(racechoice)) + return TRUE + if(!selectable_races[racechoice]) + return TRUE + + + var/datum/species/newrace = new selectable_races[racechoice] + + var/attributes_desc = newrace.get_physical_attributes() + qdel(newrace) + + var/answer = tgui_alert(race_changer, attributes_desc, "Become a [newrace]?", list("Yes", "No")) + if(answer != "Yes") + change_race(race_changer) // try again + return + + race_changer.set_species(newrace, icon_update = FALSE) + if(HAS_TRAIT(race_changer, TRAIT_USES_SKINTONES)) + var/new_s_tone = tgui_input_list(race_changer, "Choose your skin tone", "Race change", GLOB.skin_tones) + if(new_s_tone) + race_changer.skin_tone = new_s_tone + race_changer.dna.update_ui_block(DNA_SKIN_TONE_BLOCK) + else if(HAS_TRAIT(race_changer, TRAIT_MUTANT_COLORS) && !HAS_TRAIT(race_changer, TRAIT_FIXED_MUTANT_COLORS)) + var/new_mutantcolor = input(race_changer, "Choose your skin color:", "Race change", race_changer.dna.features["mcolor"]) as color|null + if(new_mutantcolor) + var/temp_hsv = RGBtoHSV(new_mutantcolor) + + if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright + race_changer.dna.features["mcolor"] = sanitize_hexcolor(new_mutantcolor) + race_changer.dna.update_uf_block(DNA_MUTANT_COLOR_BLOCK) + + else + to_chat(race_changer, span_notice("Invalid color. Your color is not bright enough.")) + return TRUE + + race_changer.update_body(is_creating = TRUE) + race_changer.update_mutations_overlay() // no hulk lizard + +// possible Genders: MALE, FEMALE, PLURAL, NEUTER +// possible Physique: MALE, FEMALE +// saved you a click (many) +/obj/structure/mirror/proc/change_sex(mob/living/carbon/human/sexy) + + var/chosen_sex = tgui_input_list(sexy, "Become a..", "Confirmation", list("Warlock", "Witch", "Wizard", "Itzard")) // YOU try coming up with the 'it' version of wizard + + switch(chosen_sex) + if("Warlock") + sexy.gender = MALE + to_chat(sexy, span_notice("Man, you feel like a man!")) + if("Witch") + sexy.gender = FEMALE + to_chat(sexy, span_notice("Man, you feel like a woman!")) + if("Wizard") + sexy.gender = PLURAL + to_chat(sexy, span_notice("Woah dude, you feel like a dude!")) + if("Itzard") + sexy.gender = NEUTER + to_chat(sexy, span_notice("Woah dude, you feel like something else!")) + + var/chosen_physique = tgui_input_list(sexy, "Alter your physique as well?", "Confirmation", list("Warlock Physique", "Witch Physique", "Wizards Don't Need Gender")) + + if(chosen_physique && chosen_physique != "Wizards Don't Need Gender") + sexy.physique = (chosen_physique == "Warlock Physique") ? MALE : FEMALE + + sexy.dna.update_ui_block(DNA_GENDER_BLOCK) + sexy.update_body(is_creating = TRUE) // or else physique won't change properly + sexy.update_mutations_overlay() //(hulk male/female) + sexy.update_clothing(ITEM_SLOT_ICLOTHING) // update gender shaped clothing + +/obj/structure/mirror/proc/change_eyes(mob/living/carbon/human/user) + var/new_eye_color = input(user, "Choose your eye color", "Eye Color", user.eye_color_left) as color|null + if(isnull(new_eye_color)) + return TRUE + user.eye_color_left = sanitize_hexcolor(new_eye_color) + user.eye_color_right = sanitize_hexcolor(new_eye_color) + user.dna.update_ui_block(DNA_EYE_COLOR_LEFT_BLOCK) + user.dna.update_ui_block(DNA_EYE_COLOR_RIGHT_BLOCK) + user.update_body() + to_chat(user, span_notice("You gaze at your new eyes with your new eyes. Perfect!")) + +/obj/structure/mirror/examine_status(mob/living/carbon/human/user) if(broken) return list()// no message spam return ..() @@ -165,11 +316,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) name = "magic mirror" desc = "Turn and face the strange... face." icon_state = "magic_mirror" - - ///Flags this race must have to be selectable with this type of mirror. - var/race_flags = MIRROR_MAGIC - ///List of all Races that can be chosen, decided by its Initialize. - var/list/selectable_races = list() + mirror_options = MAGIC_MIRROR_OPTIONS + magical_mirror = TRUE /obj/structure/mirror/magic/Initialize(mapload) . = ..() @@ -181,133 +329,38 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) selectable_races[initial(species_type.name)] = species_type selectable_races = sort_list(selectable_races) -/obj/structure/mirror/magic/attack_hand(mob/user, list/modifiers) - . = ..() - if(.) - return TRUE - if(!ishuman(user)) - return TRUE +//Magic mirrors can change hair color as well +/obj/structure/mirror/magic/change_hair(mob/living/carbon/human/user) + var/hairchoice = tgui_alert(user, "Hairstyle or hair color?", "Change Hair", list("Style", "Color")) + if(hairchoice == "Style") //So you just want to use a mirror then? + return ..() - var/mob/living/carbon/human/amazed_human = user -// SKYRAT EDIT BEGIN - Magic Mirror Character Application - var/choice - var/ask = tgui_alert(user, "Would you like to apply your loaded character?","Confirm", list("Yes!", "No, I want to manually edit my character here.")) + var/new_hair_color = input(user, "Choose your hair color", "Hair Color", user.hair_color) as color|null - if(ask == "Yes!") - user?.client?.prefs?.safe_transfer_prefs_to(amazed_human) - else - choice = tgui_input_list(user, "Something to change?", "Magical Grooming", list("name", "race", "gender", "hair", "eyes")) -// SKYRAT EDIT END - if(isnull(choice)) - return TRUE + if(new_hair_color) + user.set_haircolor(sanitize_hexcolor(new_hair_color), update = FALSE) + user.dna.update_ui_block(DNA_HAIR_COLOR_BLOCK) + if(user.physique == MALE) + var/new_face_color = input(user, "Choose your facial hair color", "Hair Color", user.facial_hair_color) as color|null + if(new_face_color) + user.set_facial_haircolor(sanitize_hexcolor(new_face_color), update = FALSE) + user.dna.update_ui_block(DNA_FACIAL_HAIR_COLOR_BLOCK) + user.update_body_parts() + user.update_mutant_bodyparts(force_update = TRUE) /// SKYRAT EDIT ADDITION - Mirrors are no longer scared of colored ears - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) +/obj/structure/mirror/magic/attack_hand(mob/living/carbon/human/user) + . = ..() + if(!.) return TRUE - switch(choice) - if("name") - var/newname = sanitize_name(tgui_input_text(amazed_human, "Who are we again?", "Name change", amazed_human.name, MAX_NAME_LEN), allow_numbers = TRUE) //It's magic so whatever. - if(!newname) - return TRUE - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return TRUE - amazed_human.real_name = newname - amazed_human.name = newname - if(amazed_human.dna) - amazed_human.dna.real_name = newname - if(amazed_human.mind) - amazed_human.mind.name = newname - - if("race") - var/racechoice = tgui_input_list(amazed_human, "What are we again?", "Race change", selectable_races) - if(isnull(racechoice)) - return TRUE - if(!selectable_races[racechoice]) - return TRUE - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return TRUE + if(HAS_TRAIT(user, TRAIT_ADVANCEDTOOLUSER) && HAS_TRAIT(user, TRAIT_LITERATE)) + return TRUE - var/datum/species/newrace = selectable_races[racechoice] - amazed_human.set_species(newrace, icon_update = FALSE) - if(HAS_TRAIT(amazed_human, TRAIT_USES_SKINTONES)) - var/new_s_tone = tgui_input_list(user, "Choose your skin tone", "Race change", GLOB.skin_tones) - if(new_s_tone) - amazed_human.skin_tone = new_s_tone - amazed_human.dna.update_ui_block(DNA_SKIN_TONE_BLOCK) - else if(HAS_TRAIT(amazed_human, TRAIT_MUTANT_COLORS) && !HAS_TRAIT(amazed_human, TRAIT_FIXED_MUTANT_COLORS)) - var/new_mutantcolor = input(user, "Choose your skin color:", "Race change", amazed_human.dna.features["mcolor"]) as color|null - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return TRUE - if(new_mutantcolor) - var/temp_hsv = RGBtoHSV(new_mutantcolor) - - if(ReadHSV(temp_hsv)[3] >= ReadHSV("#7F7F7F")[3]) // mutantcolors must be bright - amazed_human.dna.features["mcolor"] = sanitize_hexcolor(new_mutantcolor) - amazed_human.dna.update_uf_block(DNA_MUTANT_COLOR_BLOCK) - - else - to_chat(amazed_human, span_notice("Invalid color. Your color is not bright enough.")) - return TRUE - - amazed_human.update_body(is_creating = TRUE) - amazed_human.update_mutations_overlay() // no hulk lizard - - if("gender") - if(!(amazed_human.gender in list(MALE, FEMALE))) //blame the patriarchy - return TRUE - if(amazed_human.gender == MALE) - if(tgui_alert(amazed_human, "Become a Witch?", "Confirmation", list("Yes", "No")) == "Yes") - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return TRUE - amazed_human.gender = FEMALE - amazed_human.physique = FEMALE - to_chat(amazed_human, span_notice("Man, you feel like a woman!")) - else - return TRUE - else - if(tgui_alert(amazed_human, "Become a Warlock?", "Confirmation", list("Yes", "No")) == "Yes") - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return TRUE - amazed_human.gender = MALE - amazed_human.physique = MALE - to_chat(amazed_human, span_notice("Whoa man, you feel like a man!")) - else - return TRUE - amazed_human.dna.update_ui_block(DNA_GENDER_BLOCK) - amazed_human.update_body() - amazed_human.update_mutations_overlay() //(hulk male/female) - - if("hair") - var/hairchoice = tgui_alert(amazed_human, "Hairstyle or hair color?", "Change Hair", list("Style", "Color")) - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return TRUE - if(hairchoice == "Style") //So you just want to use a mirror then? - return ..() - else - var/new_hair_color = input(amazed_human, "Choose your hair color", "Hair Color",amazed_human.hair_color) as color|null - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return TRUE - if(new_hair_color) - amazed_human.set_haircolor(sanitize_hexcolor(new_hair_color), update = FALSE) - amazed_human.dna.update_ui_block(DNA_HAIR_COLOR_BLOCK) - if(amazed_human.gender == MALE) - var/new_face_color = input(amazed_human, "Choose your facial hair color", "Hair Color", amazed_human.facial_hair_color) as color|null - if(new_face_color) - amazed_human.set_facial_haircolor(sanitize_hexcolor(new_face_color), update = FALSE) - amazed_human.dna.update_ui_block(DNA_FACIAL_HAIR_COLOR_BLOCK) - amazed_human.update_body_parts() - amazed_human.update_mutant_bodyparts(force_update = TRUE) /// SKYRAT EDIT - Mirrors are no longer scared of colored ears - - if(BODY_ZONE_PRECISE_EYES) - var/new_eye_color = input(amazed_human, "Choose your eye color", "Eye Color", amazed_human.eye_color_left) as color|null - if(!user.can_perform_action(src, FORBID_TELEKINESIS_REACH)) - return TRUE - if(new_eye_color) - amazed_human.eye_color_left = sanitize_hexcolor(new_eye_color) - amazed_human.eye_color_right = sanitize_hexcolor(new_eye_color) - amazed_human.dna.update_ui_block(DNA_EYE_COLOR_LEFT_BLOCK) - amazed_human.dna.update_ui_block(DNA_EYE_COLOR_RIGHT_BLOCK) - amazed_human.update_body() + to_chat(user, span_alert("You feel quite intelligent.")) + // Prevents wizards from being soft locked out of everything + // If this stays after the species was changed once more, well, the magic mirror did it. It's magic i aint gotta explain shit + ADD_TRAIT(user, list(TRAIT_LITERATE, TRAIT_ADVANCEDTOOLUSER), SPECIES_TRAIT) + return TRUE /obj/structure/mirror/magic/lesser/Initialize(mapload) // Roundstart species don't have a flag, so it has to be set on Initialize. @@ -321,10 +374,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) name = "pride's mirror" desc = "Pride cometh before the..." race_flags = MIRROR_PRIDE + mirror_options = PRIDE_MIRROR_OPTIONS -/obj/structure/mirror/magic/pride/attack_hand(mob/user, list/modifiers) +/obj/structure/mirror/magic/pride/attack_hand(mob/living/carbon/human/user) . = ..() - if(.) + if(!.) return TRUE user.visible_message(span_danger("The ground splits beneath [user] as [user.p_their()] hand leaves the mirror!"), \ @@ -340,3 +394,15 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28) var/turf/open/chasm/new_chasm = user_turf new_chasm.set_target(dest) new_chasm.drop(user) + +#undef CHANGE_HAIR +#undef CHANGE_BEARD + +#undef CHANGE_RACE +#undef CHANGE_SEX +#undef CHANGE_NAME +#undef CHANGE_EYES + +#undef INERT_MIRROR_OPTIONS +#undef PRIDE_MIRROR_OPTIONS +#undef MAGIC_MIRROR_OPTIONS diff --git a/code/game/objects/structures/petrified_statue.dm b/code/game/objects/structures/petrified_statue.dm index 78bd478d52347a..54896c2e414055 100644 --- a/code/game/objects/structures/petrified_statue.dm +++ b/code/game/objects/structures/petrified_statue.dm @@ -94,7 +94,7 @@ /mob/proc/petrify(statue_timer) -/mob/living/carbon/human/petrify(statue_timer, save_brain) +/mob/living/carbon/human/petrify(statue_timer, save_brain, colorlist) if(!isturf(loc)) return FALSE var/obj/structure/statue/petrified/S = new(loc, src, statue_timer, save_brain) @@ -102,6 +102,8 @@ ADD_TRAIT(src, TRAIT_NOBLOOD, MAGIC_TRAIT) S.copy_overlays(src) var/newcolor = list(rgb(77,77,77), rgb(150,150,150), rgb(28,28,28), rgb(0,0,0)) + if(colorlist) + newcolor = colorlist S.add_atom_colour(newcolor, FIXED_COLOUR_PRIORITY) return TRUE diff --git a/code/game/objects/structures/railings.dm b/code/game/objects/structures/railings.dm index 7f9dab59a466af..f88ba15ecc52cf 100644 --- a/code/game/objects/structures/railings.dm +++ b/code/game/objects/structures/railings.dm @@ -8,6 +8,8 @@ density = TRUE anchored = TRUE pass_flags_self = LETPASSTHROW|PASSSTRUCTURE + layer = ABOVE_MOB_LAYER + plane = GAME_PLANE_UPPER /// armor is a little bit less than a grille. max_integrity about half that of a grille. armor_type = /datum/armor/structure_railing max_integrity = 25 diff --git a/code/game/objects/structures/showcase.dm b/code/game/objects/structures/showcase.dm index 91ccdaef80a2a0..2349d9b0f4913a 100644 --- a/code/game/objects/structures/showcase.dm +++ b/code/game/objects/structures/showcase.dm @@ -84,7 +84,13 @@ name = "\improper Nanotrasen-brand microwave" desc = "The famous Nanotrasen-brand microwave, the multi-purpose cooking appliance every station needs! This one appears to be drawn onto a cardboard box." icon = 'icons/obj/machines/microwave.dmi' - icon_state = "map_icon" + icon_state = "mw_complete" + +/obj/structure/showcase/machinery/microwave_engineering + name = "\improper Nanotrasen Wave(tm) microwave" + desc = "Just when everyone thought Nanotrasen couldn't improve on their famous microwave, this 2563 model features Waveâ„¢! A Nanotrasen exclusive, Waveâ„¢ allows your PDA to be charged wirelessly through microwave frequencies. Because nothing says 'future' like charging your PDA while overcooking your leftovers. Nanotrasen Waveâ„¢ - Multitasking, redefined." + icon = 'icons/obj/machines/microwave.dmi' + icon_state = "engi_mw_complete" /obj/structure/showcase/machinery/cloning_pod name = "cloning pod exhibit" diff --git a/code/game/objects/structures/spawner.dm b/code/game/objects/structures/spawner.dm index 340bcf212ded6e..2ad70bdbc84203 100644 --- a/code/game/objects/structures/spawner.dm +++ b/code/game/objects/structures/spawner.dm @@ -14,6 +14,52 @@ var/spawn_text = "emerges from" var/faction = list(FACTION_HOSTILE) var/spawner_type = /datum/component/spawner + /// Is this spawner taggable with something? + var/scanner_taggable = FALSE + /// If this spawner's taggable, what can we tag it with? + var/static/list/scanner_types = list(/obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner) + /// If this spawner's taggable, what's the text we use to describe what we can tag it with? + var/scanner_descriptor = "mining analyzer" + /// Has this spawner been tagged/analyzed by a mining scanner? + var/gps_tagged = FALSE + /// A short identifier for the mob it spawns. Keep around 3 characters or less? + var/mob_gps_id = "???" + /// A short identifier for what kind of spawner it is, for use in putting together its GPS tag. + var/spawner_gps_id = "Creature Nest" + /// A complete identifier. Generated on tag (if tagged), used for its examine. + var/assigned_tag + +/obj/structure/spawner/examine(mob/user) + . = ..() + if(!scanner_taggable) + return + if(gps_tagged) + . += span_notice("A holotag's been attached, projecting \"[assigned_tag]\".") + else + . += span_notice("It looks like you could probably scan and tag it with a [scanner_descriptor].") + +/obj/structure/spawner/attackby(obj/item/item, mob/user, params) + . = ..() + if(.) + return TRUE + if(scanner_taggable && is_type_in_list(item, scanner_types)) + gps_tag(user) + return TRUE + +/// Tag the spawner, prefixing its GPS entry with an identifier - or giving it one, if nonexistent. +/obj/structure/spawner/proc/gps_tag(mob/user) + if(gps_tagged) + to_chat(user, span_warning("[src] already has a holotag attached!")) + return + to_chat(user, span_notice("You affix a holotag to [src].")) + playsound(src, 'sound/machines/twobeep.ogg', 100) + gps_tagged = TRUE + assigned_tag = "\[[mob_gps_id]-[rand(100,999)]\] " + spawner_gps_id + var/datum/component/gps/our_gps = GetComponent(/datum/component/gps) + if(our_gps) + our_gps.gpstag = assigned_tag + return + AddComponent(/datum/component/gps, assigned_tag) /obj/structure/spawner/Initialize(mapload) . = ..() @@ -32,6 +78,8 @@ spawn_text = "warps in from" mob_types = list(/mob/living/basic/syndicate/ranged) faction = list(ROLE_SYNDICATE) + mob_gps_id = "SYN" // syndicate + spawner_gps_id = "Hostile Warp Beacon" /obj/structure/spawner/skeleton name = "bone pit" @@ -44,6 +92,8 @@ mob_types = list(/mob/living/simple_animal/hostile/skeleton) spawn_text = "climbs out of" faction = list(FACTION_SKELETON) + mob_gps_id = "SKL" // skeletons + spawner_gps_id = "Bone Pit" /obj/structure/spawner/clown name = "Laughing Larry" @@ -67,6 +117,8 @@ ) spawn_text = "climbs out of" faction = list(FACTION_CLOWN) + mob_gps_id = "???" // clowns + spawner_gps_id = "Clown Planet Distortion" /obj/structure/spawner/mining name = "monster den" @@ -80,7 +132,7 @@ /mob/living/basic/mining/basilisk, /mob/living/basic/mining/goldgrub, /mob/living/basic/mining/goliath/ancient, - /mob/living/basic/mining/legion, + /mob/living/basic/mining/hivelord, /mob/living/basic/wumborian_fugu, ) faction = list(FACTION_MINING) @@ -89,26 +141,31 @@ name = "goldgrub den" desc = "A den housing a nest of goldgrubs, annoying but arguably much better than anything else you'll find in a nest." mob_types = list(/mob/living/basic/mining/goldgrub) + mob_gps_id = "GG" /obj/structure/spawner/mining/goliath name = "goliath den" desc = "A den housing a nest of goliaths, oh god why?" mob_types = list(/mob/living/basic/mining/goliath/ancient) + mob_gps_id = "GL|A" /obj/structure/spawner/mining/hivelord name = "hivelord den" desc = "A den housing a nest of hivelords." mob_types = list(/mob/living/basic/mining/hivelord) + mob_gps_id = "HL" /obj/structure/spawner/mining/basilisk name = "basilisk den" desc = "A den housing a nest of basilisks, bring a coat." mob_types = list(/mob/living/basic/mining/basilisk) + mob_gps_id = "BK" /obj/structure/spawner/mining/wumborian name = "wumborian fugu den" desc = "A den housing a nest of wumborian fugus, how do they all even fit in there?" mob_types = list(/mob/living/basic/wumborian_fugu) + mob_gps_id = "WF" /obj/structure/spawner/nether name = "netherworld link" @@ -125,6 +182,9 @@ /mob/living/basic/migo, ) faction = list(FACTION_NETHER) + scanner_taggable = TRUE + mob_gps_id = "?!?" + spawner_gps_id = "Netheric Distortion" /obj/structure/spawner/nether/Initialize(mapload) . = ..() diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm index f5b40238ed60c7..1253d156a2c20c 100644 --- a/code/game/turfs/change_turf.dm +++ b/code/game/turfs/change_turf.dm @@ -252,7 +252,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list( //SKYRAT EDIT END if(excited || excited_group) SSair.remove_from_active(src) //Clean up wall excitement, and refresh excited groups - if(ispath(path,/turf/closed) || ispath(path,/turf/cordon)) + if(ispath(path, /turf/closed) || ispath(path, /turf/cordon)) flags |= CHANGETURF_RECALC_ADJACENT return ..() diff --git a/code/game/turfs/closed/indestructible.dm b/code/game/turfs/closed/indestructible.dm index b364ad428d0359..a569f7c58944ca 100644 --- a/code/game/turfs/closed/indestructible.dm +++ b/code/game/turfs/closed/indestructible.dm @@ -313,6 +313,9 @@ SKYRAT EDIT REMOVAL END */ explosive_resistance = 50 baseturfs = /turf/closed/indestructible/riveted/boss +/turf/closed/indestructible/riveted/boss/wasteland + baseturfs = /turf/open/misc/asteroid/basalt/wasteland + /turf/closed/indestructible/riveted/boss/see_through opacity = FALSE diff --git a/code/game/turfs/closed/wall/misc_walls.dm b/code/game/turfs/closed/wall/misc_walls.dm index a26e456971d881..9fbce09ace274c 100644 --- a/code/game/turfs/closed/wall/misc_walls.dm +++ b/code/game/turfs/closed/wall/misc_walls.dm @@ -18,16 +18,6 @@ /turf/closed/wall/mineral/cult/devastate_wall() new sheet_type(get_turf(src), sheet_amount) -/turf/closed/wall/mineral/cult/Exited(atom/movable/gone, direction) - . = ..() - if(istype(gone, /mob/living/simple_animal/hostile/construct/harvester)) //harvesters can go through cult walls, dragging something with - var/mob/living/simple_animal/hostile/construct/harvester/H = gone - var/atom/movable/stored_pulling = H.pulling - if(stored_pulling) - stored_pulling.setDir(direction) - stored_pulling.forceMove(src) - H.start_pulling(stored_pulling, supress_message = TRUE) - /turf/closed/wall/mineral/cult/artificer name = "runed stone wall" desc = "A cold stone wall engraved with indecipherable symbols. Studying them causes your head to pound." diff --git a/code/game/turfs/closed/walls.dm b/code/game/turfs/closed/walls.dm index 7b601fb82ac5c4..06a063f16eac6d 100644 --- a/code/game/turfs/closed/walls.dm +++ b/code/game/turfs/closed/walls.dm @@ -363,5 +363,13 @@ /turf/closed/wall/metal_foam_base girder_type = /obj/structure/foamedmetal +/turf/closed/wall/Bumped(atom/movable/bumped_atom) + . = ..() + SEND_SIGNAL(bumped_atom, COMSIG_LIVING_WALL_BUMP, src) + +/turf/closed/wall/Exited(atom/movable/gone, direction) + . = ..() + SEND_SIGNAL(gone, COMSIG_LIVING_WALL_EXITED, src) + #undef MAX_DENT_DECALS #undef LEANING_OFFSET diff --git a/code/game/turfs/open/chasm.dm b/code/game/turfs/open/chasm.dm index 4c8ac12202d093..49f6663d097203 100644 --- a/code/game/turfs/open/chasm.dm +++ b/code/game/turfs/open/chasm.dm @@ -105,7 +105,6 @@ icon = 'icons/turf/floors/junglechasm.dmi' icon_state = "junglechasm-255" base_icon_state = "junglechasm" - initial_gas_mix = OPENTURF_LOW_PRESSURE planetary_atmos = TRUE baseturfs = /turf/open/chasm/jungle diff --git a/code/game/turfs/open/floor.dm b/code/game/turfs/open/floor.dm index a0d1a191bc6294..8c80b35bb3da17 100644 --- a/code/game/turfs/open/floor.dm +++ b/code/game/turfs/open/floor.dm @@ -264,6 +264,9 @@ else if(the_rcd.furnish_type == /obj/structure/bed) cost = 8 delay = 1.5 SECONDS + else if(the_rcd.furnish_type == /obj/machinery/microwave/engineering) + cost = 48 + delay = 4 SECONDS if(cost == 0) return FALSE return list("mode" = RCD_FURNISHING, "delay" = cost, "cost" = delay) @@ -380,6 +383,11 @@ return FALSE var/atom/new_furnish = new the_rcd.furnish_type(src) new_furnish.setDir(user.dir) + if(istype(new_furnish, /obj/machinery/microwave/engineering)) + var/obj/machinery/microwave/engineering/new_mw = new_furnish + var/obj/item/stock_parts/cell/new_cell = new() + new_mw.cell = new_cell + new_mw.update_appearance() return TRUE return FALSE diff --git a/code/game/turfs/open/lava.dm b/code/game/turfs/open/lava.dm index 24c690498a6c35..b8e04949662046 100644 --- a/code/game/turfs/open/lava.dm +++ b/code/game/turfs/open/lava.dm @@ -392,8 +392,11 @@ if(IS_ROBOTIC_LIMB(burn_limb)) robo_parts += burn_limb - burn_human.adjustToxLoss(15, required_biotype = MOB_ORGANIC) // This is from plasma, so it should obey plasma biotype requirements - burn_human.adjustFireLoss(25) + var/need_mob_update + need_mob_update += burn_human.adjustToxLoss(15, updating_health = FALSE, required_biotype = MOB_ORGANIC) // This is from plasma, so it should obey plasma biotype requirements + need_mob_update += burn_human.adjustFireLoss(25, updating_health = FALSE) + if(need_mob_update) + burn_human.updatehealth() if(plasma_parts.len) var/obj/item/bodypart/burn_limb = pick(plasma_parts) //using the above-mentioned list to get a choice of limbs burn_human.emote("scream") diff --git a/code/game/turfs/open/planet.dm b/code/game/turfs/open/planet.dm index e5ab02c0924608..65c76cef957a70 100644 --- a/code/game/turfs/open/planet.dm +++ b/code/game/turfs/open/planet.dm @@ -18,14 +18,27 @@ name = "dirt flooring" //FOR THE LOVE OF GOD USE THIS INSTEAD OF DIRT FOR STATION MAPS desc = "You heard this place was dirty, but this is just absurd." baseturfs = /turf/open/floor/plating - initial_gas_mix = OPENTURF_LOW_PRESSURE + initial_gas_mix = OPENTURF_DEFAULT_ATMOS planetary_atmos = FALSE +/turf/open/misc/dirt/jungle + slowdown = 0.5 + initial_gas_mix = OPENTURF_DEFAULT_ATMOS + /turf/open/misc/dirt/dark icon_state = "greenerdirt" base_icon_state = "greenerdirt" -/turf/open/misc/dirt/jungle +/turf/open/misc/dirt/dark/station + baseturfs = /turf/open/floor/plating + initial_gas_mix = OPENTURF_DEFAULT_ATMOS + planetary_atmos = FALSE + +/turf/open/misc/dirt/dark/station/airless + initial_gas_mix = AIRLESS_ATMOS + temperature = TCMB + +/turf/open/misc/dirt/dark/jungle slowdown = 0.5 initial_gas_mix = OPENTURF_DEFAULT_ATMOS @@ -68,7 +81,7 @@ return list("jungle_damaged") /turf/closed/mineral/random/jungle - baseturfs = /turf/open/misc/dirt/dark + baseturfs = /turf/open/misc/dirt/dark/jungle /turf/closed/mineral/random/jungle/mineral_chances() return list( @@ -81,3 +94,6 @@ /obj/item/stack/ore/titanium = 11, /obj/item/stack/ore/uranium = 5, ) + +/turf/closed/mineral/random/jungle/space_safe + baseturfs = /turf/open/misc/dirt/dark/station/airless diff --git a/code/game/world.dm b/code/game/world.dm index e851bb992d4e32..de6386243193ac 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -361,8 +361,8 @@ GLOBAL_VAR(restart_counter) var/server_name = CONFIG_GET(string/servername) if (server_name) new_status += "[server_name] " - if(!CONFIG_GET(flag/norespawn)) - features += "respawn" + if(CONFIG_GET(flag/allow_respawn)) + features += "respawn" // show "respawn" regardless of "respawn as char" or "free respawn" if(!CONFIG_GET(flag/allow_ai)) features += "AI disabled" hostedby = CONFIG_GET(string/hostedby) diff --git a/code/modules/actionspeed/modifiers/status_effects.dm b/code/modules/actionspeed/modifiers/status_effects.dm index fa080edb8d009d..ec7b0dba22e0f3 100644 --- a/code/modules/actionspeed/modifiers/status_effects.dm +++ b/code/modules/actionspeed/modifiers/status_effects.dm @@ -12,3 +12,19 @@ /datum/actionspeed_modifier/status_effect/hazard_area multiplicative_slowdown = 4 + +/// Get slower the more gold is in your system. +/datum/actionspeed_modifier/status_effect/midas_blight + id = ACTIONSPEED_ID_MIDAS_BLIGHT + +/datum/actionspeed_modifier/status_effect/midas_blight/soft + multiplicative_slowdown = 0.25 + +/datum/actionspeed_modifier/status_effect/midas_blight/medium + multiplicative_slowdown = 0.75 + +/datum/actionspeed_modifier/status_effect/midas_blight/hard + multiplicative_slowdown = 1.5 + +/datum/actionspeed_modifier/status_effect/midas_blight/gold + multiplicative_slowdown = 2 diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index bc6942a9a110c5..2d2c692ed5fcad 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -21,6 +21,7 @@ var/dat = "
Game Panel

" if(SSticker.current_state <= GAME_STATE_PREGAME) + dat += "(Manage Dynamic Rulesets)
" dat += "(Force Roundstart Rulesets)
" if (GLOB.dynamic_forced_roundstart_ruleset.len > 0) for(var/datum/dynamic_ruleset/roundstart/rule in GLOB.dynamic_forced_roundstart_ruleset) @@ -30,6 +31,8 @@ dat += "
" if(SSticker.IsRoundInProgress()) dat += "(Game Mode Panel)
" + if(istype(SSticker.mode, /datum/game_mode/dynamic)) + dat += "(Manage Dynamic Rulesets)
" dat += {"
Create Object
@@ -143,6 +146,111 @@ user << browse(dat, "window=dyn_mode_options;size=900x650") +/datum/admins/proc/dynamic_ruleset_manager(mob/user) + if (SSticker.current_state > GAME_STATE_PREGAME && !istype(SSticker.mode, /datum/game_mode/dynamic)) + return // Not running dynamic + + var/dat = "

Dynamic Ruleset Management


\ + Change these options to forcibly enable or disable dynamic rulesets.
\ + Disabled rulesets will never run, even if they would otherwise be valid.
\ + Enabled rulesets will run even if the qualifying minimum of threat or player count is not present, this does not guarantee that they will necessarily be chosen (for example their weight may be set to 0 in config).
\ + \[force enable all / \ + force disable all / \ + reset all\]" + + if (SSticker.current_state <= GAME_STATE_PREGAME) // Don't bother displaying after the round has started + var/static/list/rulesets_by_context = list() + if (!length(rulesets_by_context)) + for (var/datum/dynamic_ruleset/rule as anything in subtypesof(/datum/dynamic_ruleset)) + if (initial(rule.name) == "") + continue + LAZYADD(rulesets_by_context[initial(rule.ruletype)], rule) + + dat += dynamic_ruleset_category_pre_start_display("Roundstart", rulesets_by_context[ROUNDSTART_RULESET]) + dat += dynamic_ruleset_category_pre_start_display("Latejoin", rulesets_by_context[LATEJOIN_RULESET]) + dat += dynamic_ruleset_category_pre_start_display("Midround", rulesets_by_context[MIDROUND_RULESET]) + user << browse(dat, "window=dyn_mode_options;size=900x650") + return + + var/datum/game_mode/dynamic/current_mode = SSticker.mode + var/pop_count = length(GLOB.alive_player_list) + var/threat_level = current_mode.threat_level + dat += dynamic_ruleset_category_during_round_display("Latejoin", current_mode.latejoin_rules, pop_count, threat_level) + dat += dynamic_ruleset_category_during_round_display("Midround", current_mode.midround_rules, pop_count, threat_level) + user << browse(dat, "window=dyn_mode_options;size=900x650") + +/datum/admins/proc/dynamic_ruleset_category_pre_start_display(title, list/rules) + var/dat = "

[title]

" + for (var/datum/dynamic_ruleset/rule as anything in rules) + var/forced = GLOB.dynamic_forced_rulesets[rule] || RULESET_NOT_FORCED + var/color = COLOR_BLACK + switch (forced) + if (RULESET_FORCE_ENABLED) + color = COLOR_GREEN + if (RULESET_FORCE_DISABLED) + color = COLOR_RED + dat += "" + dat += "
[initial(rule.name)]\[[forced]\]\[\ + force enabled /\ + force disabled /\ + reset\]
" + return dat + +/datum/admins/proc/dynamic_ruleset_category_during_round_display(title, list/rules, pop_count, threat_level) + var/dat = "

[title]

" + for (var/datum/dynamic_ruleset/rule as anything in rules) + var/active = rule.acceptable(population = pop_count, threat_level = threat_level) && rule.weight > 0 + var/forced = GLOB.dynamic_forced_rulesets[rule.type] || RULESET_NOT_FORCED + var/color = (active) ? COLOR_GREEN : COLOR_RED + var/explanation = "" + if (!active) + if (rule.weight <= 0) + explanation = " - Weight is zero" + else if (forced == RULESET_FORCE_DISABLED) + explanation = " - Forcibly disabled" + else if (forced == RULESET_FORCE_ENABLED) + explanation = " - Failed spawn conditions" + else if (!rule.is_valid_population(pop_count)) + explanation = " - Invalid player count" + else if (!rule.is_valid_threat(pop_count, threat_level)) + explanation = " - Insufficient threat" + else + explanation = " - Failed spawn conditions" + else if (forced == RULESET_FORCE_ENABLED) + explanation = " - Forcibly enabled" + active = active ? "Active" : "Inactive" + + dat += "\ + \ + " + dat += "
[rule.name]\[Weight : [rule.weight]\]\ + \[[active][explanation]\]\[\ + force enabled /\ + force disabled /\ + reset\]\[VV\]
" + return dat + + +/datum/admins/proc/force_all_rulesets(mob/user, force_value) + if (force_value == RULESET_NOT_FORCED) + GLOB.dynamic_forced_rulesets = list() + else + for (var/datum/dynamic_ruleset/rule as anything in subtypesof(/datum/dynamic_ruleset)) + GLOB.dynamic_forced_rulesets[rule] = force_value + var/logged_message = "[key_name(user)] set all dynamic rulesets to [force_value]." + log_admin(logged_message) + message_admins(logged_message) + dynamic_ruleset_manager(user) + +/datum/admins/proc/set_dynamic_ruleset_forced(mob/user, datum/dynamic_ruleset/type, force_value) + if (isnull(type)) + return + GLOB.dynamic_forced_rulesets[type] = force_value + dynamic_ruleset_manager(user) + var/logged_message = "[key_name(user)] set '[initial(type.name)] ([initial(type.ruletype)])' to [GLOB.dynamic_forced_rulesets[type]]." + log_admin(logged_message) + message_admins(logged_message) + /datum/admins/proc/create_or_modify_area() set category = "Debug" set name = "Create or modify area" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 0b731c613737ab..243ff3d07d16ad 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -58,6 +58,9 @@ GLOBAL_PROTECT(admin_verbs_admin) /client/proc/admin_enable_shuttle, /*undoes the above*/ /client/proc/admin_ghost, /*allows us to ghost/reenter body at will*/ /client/proc/admin_hostile_environment, /*Allows admins to prevent the emergency shuttle from leaving, also lets admins clear hostile environments if theres one stuck*/ + /client/proc/centcom_podlauncher,/*Open a window to launch a Supplypod and configure it or it's contents*/ + /client/proc/check_ai_laws, /*shows AI and borg laws*/ + /client/proc/check_antagonists, /*shows all antags*/ /client/proc/cmd_admin_check_contents, /*displays the contents of an instance*/ /client/proc/cmd_admin_check_player_exp, /* shows players by playtime */ /client/proc/cmd_admin_create_centcom_report, @@ -68,9 +71,7 @@ GLOBAL_PROTECT(admin_verbs_admin) /client/proc/cmd_admin_subtle_message, /*send a message to somebody as a 'voice in their head'*/ /client/proc/cmd_admin_world_narrate, /*sends text to all players with no padding*/ /client/proc/cmd_change_command_name, - /client/proc/centcom_podlauncher,/*Open a window to launch a Supplypod and configure it or it's contents*/ - /client/proc/check_ai_laws, /*shows AI and borg laws*/ - /client/proc/check_antagonists, /*shows all antags*/ + /client/proc/create_mob_worm, /client/proc/fax_panel, /*send a paper to fax*/ /client/proc/force_load_lazy_template, /client/proc/game_panel, /*game panel, allows to change game-mode etc*/ @@ -117,7 +118,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list( /datum/admins/proc/station_traits_panel, // Client procs /client/proc/admin_away, - /client/proc/add_mob_ability, + /client/proc/add_marked_mob_ability, /client/proc/admin_change_sec_level, /client/proc/cinematic, /client/proc/cmd_admin_add_freeform_ai_law, @@ -132,7 +133,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list( /client/proc/mass_zombie_infection, /client/proc/object_say, /client/proc/polymorph_all, - /client/proc/remove_mob_ability, + /client/proc/remove_marked_mob_ability, /client/proc/reset_ooc, /client/proc/run_weather, /client/proc/set_dynex_scale, @@ -255,6 +256,7 @@ GLOBAL_PROTECT(admin_verbs_debug) /client/proc/unload_ctf, /client/proc/validate_cards, /client/proc/validate_puzzgrids, + /client/proc/GeneratePipeSpritesheet, /client/proc/view_runtimes, /client/proc/reload_interactions, /*SKYRAT EDIT ADDITION*/ @@ -718,6 +720,80 @@ GLOBAL_PROTECT(admin_verbs_poll) set category = "Debug" SStrading_card_game.printAllCards() +/client/proc/give_mob_action(mob/ability_recipient in GLOB.mob_list) + set category = "Admin.Fun" + set name = "Give Mob Action" + set desc = "Gives a mob ability to a mob." + + var/static/list/all_mob_actions = sort_list(subtypesof(/datum/action/cooldown/mob_cooldown), GLOBAL_PROC_REF(cmp_typepaths_asc)) + var/static/list/actions_by_name = list() + if (!length(actions_by_name)) + for (var/datum/action/cooldown/mob_cooldown as anything in all_mob_actions) + actions_by_name["[initial(mob_cooldown.name)] ([mob_cooldown])"] = mob_cooldown + + var/ability = tgui_input_list(usr, "Choose an ability", "Ability", actions_by_name) + if(isnull(ability)) + return + + var/ability_type = actions_by_name[ability] + var/datum/action/cooldown/mob_cooldown/add_ability + + var/make_sequence = tgui_alert(usr, "Would you like this action to be a sequence of multiple abilities?", "Sequence Ability", list("Yes", "No")) + if(make_sequence == "Yes") + add_ability = new /datum/action/cooldown/mob_cooldown(ability_recipient) + add_ability.sequence_actions = list() + while(!isnull(ability_type)) + var/ability_delay = tgui_input_number(usr, "Enter the delay in seconds before the next ability in the sequence is used", "Ability Delay", 2) + if(isnull(ability_delay) || ability_delay < 0) + ability_delay = 0 + add_ability.sequence_actions[ability_type] = ability_delay * 1 SECONDS + ability = tgui_input_list(usr, "Choose a new sequence ability", "Sequence Ability", actions_by_name) + ability_type = actions_by_name[ability] + var/ability_cooldown = tgui_input_number(usr, "Enter the sequence abilities cooldown in seconds", "Ability Cooldown", 2) + if(isnull(ability_cooldown) || ability_cooldown < 0) + ability_cooldown = 2 + add_ability.cooldown_time = ability_cooldown * 1 SECONDS + var/ability_melee_cooldown = tgui_input_number(usr, "Enter the abilities melee cooldown in seconds", "Melee Cooldown", 2) + if(isnull(ability_melee_cooldown) || ability_melee_cooldown < 0) + ability_melee_cooldown = 2 + add_ability.melee_cooldown_time = ability_melee_cooldown * 1 SECONDS + add_ability.name = tgui_input_text(usr, "Choose ability name", "Ability name", "Generic Ability") + add_ability.create_sequence_actions() + else + add_ability = new ability_type(ability_recipient) + + if(isnull(ability_recipient)) + return + add_ability.Grant(ability_recipient) + + message_admins("[key_name_admin(usr)] added mob ability [ability_type] to mob [ability_recipient].") + log_admin("[key_name(usr)] added mob ability [ability_type] to mob [ability_recipient].") + SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Mob Ability") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! + +/client/proc/remove_mob_action(mob/removal_target in GLOB.mob_list) + set category = "Admin.Fun" + set name = "Remove Mob Action" + set desc = "Remove a special ability from the selected mob." + + var/list/target_abilities = list() + for(var/datum/action/cooldown/mob_cooldown/ability in removal_target.actions) + target_abilities[ability.name] = ability + + if(!length(target_abilities)) + return + + var/chosen_ability = tgui_input_list(usr, "Choose the spell to remove from [removal_target]", "Depower", sort_list(target_abilities)) + if(isnull(chosen_ability)) + return + var/datum/action/cooldown/mob_cooldown/to_remove = target_abilities[chosen_ability] + if(!istype(to_remove)) + return + + qdel(to_remove) + log_admin("[key_name(usr)] removed the ability [chosen_ability] from [key_name(removal_target)].") + message_admins("[key_name_admin(usr)] removed the ability [chosen_ability] from [key_name_admin(removal_target)].") + SSblackbox.record_feedback("tally", "admin_verb", 1, "Remove Mob Ability") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! + /client/proc/give_spell(mob/spell_recipient in GLOB.mob_list) set category = "Admin.Fun" set name = "Give Spell" @@ -1036,8 +1112,6 @@ GLOBAL_PROTECT(admin_verbs_poll) var/reqs = initial(spell.spell_requirements) if(reqs & SPELL_CASTABLE_AS_BRAIN) real_reqs += "Castable as brain" - if(reqs & SPELL_CASTABLE_WHILE_PHASED) - real_reqs += "Castable phased" if(reqs & SPELL_REQUIRES_HUMAN) real_reqs += "Must be human" if(reqs & SPELL_REQUIRES_MIME_VOW) @@ -1102,3 +1176,48 @@ GLOBAL_PROTECT(admin_verbs_poll) holder.library_manager = new() holder.library_manager.ui_interact(usr) SSblackbox.record_feedback("tally", "admin_verb", 1, "Library Management") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! + +/client/proc/create_mob_worm() + set category = "Admin.Fun" + set name = "Create Mob Worm" + set desc = "Attached a linked list of mobs to a marked mob" + if (!check_rights(R_FUN)) + return + if(isnull(holder)) + return + if(!isliving(holder.marked_datum)) + to_chat(usr, span_warning("Error: Please mark a mob to attach mobs to.")) + return + var/mob/living/head = holder.marked_datum + + var/attempted_target_path = tgui_input_text( + usr, + "Enter typepath of a mob you'd like to make your chain from.", + "Typepath", + "[/mob/living/basic/pet/dog/corgi/ian]", + ) + + if (isnull(attempted_target_path)) + return //The user pressed "Cancel" + + var/desired_mob = text2path(attempted_target_path) + if(!ispath(desired_mob)) + var/static/list/mob_paths = make_types_fancy(subtypesof(/mob/living)) + desired_mob = pick_closest_path(attempted_target_path, mob_paths) + if(isnull(desired_mob) || !ispath(desired_mob) || QDELETED(head)) + return //The user pressed "Cancel" + + var/amount = tgui_input_number(usr, "How long should our tail be?", "Worm Configurator", default = 3, min_value = 1) + if (isnull(amount) || amount < 1 || QDELETED(head)) + return + head.AddComponent(/datum/component/mob_chain) + var/mob/living/previous = head + for (var/i in 1 to amount) + var/mob/living/segment = new desired_mob(head.drop_location()) + if (QDELETED(segment)) // ffs mobs which replace themselves with other mobs + i-- + continue + ADD_TRAIT(segment, TRAIT_PERMANENTLY_MORTAL, INNATE_TRAIT) + QDEL_NULL(segment.ai_controller) + segment.AddComponent(/datum/component/mob_chain, front = previous) + previous = segment diff --git a/code/modules/admin/smites/bsa.dm b/code/modules/admin/smites/bsa.dm index cf0399acf2612d..bdf5f9e37b13ce 100644 --- a/code/modules/admin/smites/bsa.dm +++ b/code/modules/admin/smites/bsa.dm @@ -20,10 +20,7 @@ target_turf.break_tile() if (target.health <= 1) - target.gib( - /* no_brain = */ TRUE, - /* no_organs = */ TRUE, - ) + target.gib(DROP_BODYPARTS) else target.adjustBruteLoss(min(BSA_MAX_DAMAGE, target.health - 1)) target.Paralyze(BSA_PARALYZE_TIME) diff --git a/code/modules/admin/smites/gib.dm b/code/modules/admin/smites/gib.dm index 471479e7645c44..4c7c4324823cda 100644 --- a/code/modules/admin/smites/gib.dm +++ b/code/modules/admin/smites/gib.dm @@ -4,4 +4,4 @@ /datum/smite/gib/effect(client/user, mob/living/target) . = ..() - target.gib(/* no_brain = */ FALSE) + target.gib(DROP_ORGANS|DROP_BODYPARTS) diff --git a/code/modules/admin/smites/puzzgrid.dm b/code/modules/admin/smites/puzzgrid.dm index 481f85a191f672..fe5f88d6a5f3a0 100644 --- a/code/modules/admin/smites/puzzgrid.dm +++ b/code/modules/admin/smites/puzzgrid.dm @@ -91,7 +91,7 @@ span_bolddanger("You were unable to free [victim] from their fiendish prison, leaving them as nothing more than a smattering of mush!"), span_bolddanger("Your compatriates were unable to free you from your fiendish prison, leaving you as nothing more than a smattering of mush!"), ) - victim.gib() + victim.gib(DROP_ALL_REMAINS) victim = null qdel(src) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 7c2d34bd30fc39..c4c09b51adf2e5 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -465,6 +465,39 @@ log_admin("[key_name(usr)] removed [rule] from the forced roundstart rulesets.") message_admins("[key_name(usr)] removed [rule] from the forced roundstart rulesets.", 1) + else if (href_list["f_dynamic_ruleset_manage"]) + if(!check_rights(R_ADMIN)) + return + dynamic_ruleset_manager(usr) + else if (href_list["f_dynamic_ruleset_force_all_on"]) + if(!check_rights(R_ADMIN)) + return + force_all_rulesets(usr, RULESET_FORCE_ENABLED) + else if (href_list["f_dynamic_ruleset_force_all_off"]) + if(!check_rights(R_ADMIN)) + return + force_all_rulesets(usr, RULESET_FORCE_DISABLED) + else if (href_list["f_dynamic_ruleset_force_all_reset"]) + if(!check_rights(R_ADMIN)) + return + force_all_rulesets(usr, RULESET_NOT_FORCED) + else if (href_list["f_dynamic_ruleset_force_on"]) + if(!check_rights(R_ADMIN)) + return + set_dynamic_ruleset_forced(usr, locate(href_list["f_dynamic_ruleset_force_on"]), RULESET_FORCE_ENABLED) + else if (href_list["f_dynamic_ruleset_force_off"]) + if(!check_rights(R_ADMIN)) + return + set_dynamic_ruleset_forced(usr, locate(href_list["f_dynamic_ruleset_force_off"]), RULESET_FORCE_DISABLED) + else if (href_list["f_dynamic_ruleset_force_reset"]) + if(!check_rights(R_ADMIN)) + return + set_dynamic_ruleset_forced(usr, locate(href_list["f_dynamic_ruleset_force_reset"]), RULESET_NOT_FORCED) + else if (href_list["f_inspect_ruleset"]) + if(!check_rights(R_ADMIN)) + return + usr.client.debug_variables(locate(href_list["f_inspect_ruleset"])) + else if (href_list["f_dynamic_options"]) if(!check_rights(R_ADMIN)) return @@ -1309,16 +1342,16 @@ new /obj/effect/pod_landingzone(target, pod) if (number == 1) - log_admin("[key_name(usr)] created a [english_list(paths)]") + log_admin("[key_name(usr)] created an instance of [english_list(paths)]") for(var/path in paths) if(ispath(path, /mob)) - message_admins("[key_name_admin(usr)] created a [english_list(paths)]") + message_admins("[key_name_admin(usr)] created an instance of [english_list(paths)]") break else - log_admin("[key_name(usr)] created [number]ea [english_list(paths)]") + log_admin("[key_name(usr)] created [number] instances of [english_list(paths)]") for(var/path in paths) if(ispath(path, /mob)) - message_admins("[key_name_admin(usr)] created [number]ea [english_list(paths)]") + message_admins("[key_name_admin(usr)] created [number] instances of [english_list(paths)]") break return diff --git a/code/modules/admin/verbs/admin_newscaster.dm b/code/modules/admin/verbs/admin_newscaster.dm index e6616e2539b8c5..0a25ebaca65599 100644 --- a/code/modules/admin/verbs/admin_newscaster.dm +++ b/code/modules/admin/verbs/admin_newscaster.dm @@ -304,7 +304,7 @@ return TRUE var/choice = tgui_alert(usr, "Please confirm feed channel creation","Network Channel Handler", list("Confirm","Cancel")) if(choice == "Confirm") - GLOB.news_network.create_feed_channel(channel_name, "Centcom Offical", channel_desc, locked = channel_locked) + GLOB.news_network.create_feed_channel(channel_name, "Centcom Official", channel_desc, locked = channel_locked) SSblackbox.record_feedback("text", "newscaster_channels", 1, "[channel_name]") creating_channel = FALSE @@ -316,7 +316,7 @@ creating_comment = FALSE return TRUE var/datum/feed_comment/new_feed_comment = new /datum/feed_comment - new_feed_comment.author = "Centcom Offical" + new_feed_comment.author = "Centcom Official" new_feed_comment.body = comment_text new_feed_comment.time_stamp = station_time_timestamp() current_message.comments += new_feed_comment diff --git a/code/modules/admin/verbs/adminevents.dm b/code/modules/admin/verbs/adminevents.dm index ca5458bdb1ee59..dd8f1d96f60e94 100644 --- a/code/modules/admin/verbs/adminevents.dm +++ b/code/modules/admin/verbs/adminevents.dm @@ -338,9 +338,9 @@ log_admin("[key_name(usr)] started weather of type [weather_type] on the z-level [z_level].") SSblackbox.record_feedback("tally", "admin_verb", 1, "Run Weather") -/client/proc/add_mob_ability() +/client/proc/add_marked_mob_ability() set category = "Admin.Events" - set name = "Add Mob Ability" + set name = "Add Mob Ability (Marked Mob)" set desc = "Adds an ability to a marked mob." if(!holder) @@ -349,56 +349,11 @@ if(!isliving(holder.marked_datum)) to_chat(usr, span_warning("Error: Please mark a mob to add actions to it.")) return + give_mob_action(holder.marked_datum) - var/mob/living/marked_mob = holder.marked_datum - - var/static/list/all_mob_actions = sort_list(subtypesof(/datum/action/cooldown/mob_cooldown), GLOBAL_PROC_REF(cmp_typepaths_asc)) - var/static/list/actions_by_name = list() - if (!length(actions_by_name)) - for (var/datum/action/cooldown/mob_cooldown as anything in all_mob_actions) - actions_by_name["[initial(mob_cooldown.name)] ([mob_cooldown])"] = mob_cooldown - - var/ability = tgui_input_list(usr, "Choose an ability", "Ability", actions_by_name) - if(isnull(ability)) - return - - var/ability_type = actions_by_name[ability] - var/datum/action/cooldown/mob_cooldown/add_ability - - var/make_sequence = tgui_alert(usr, "Would you like this action to be a sequence of multiple abilities?", "Sequence Ability", list("Yes", "No")) - if(make_sequence == "Yes") - add_ability = new /datum/action/cooldown/mob_cooldown(marked_mob) - add_ability.sequence_actions = list() - while(!isnull(ability_type)) - var/ability_delay = tgui_input_number(usr, "Enter the delay in seconds before the next ability in the sequence is used", "Ability Delay", 2) - if(isnull(ability_delay) || ability_delay < 0) - ability_delay = 0 - add_ability.sequence_actions[ability_type] = ability_delay * 1 SECONDS - ability_type = tgui_input_list(usr, "Choose a new sequence ability", "Sequence Ability", all_mob_actions) - var/ability_cooldown = tgui_input_number(usr, "Enter the sequence abilities cooldown in seconds", "Ability Cooldown", 2) - if(isnull(ability_cooldown) || ability_cooldown < 0) - ability_cooldown = 2 - add_ability.cooldown_time = ability_cooldown * 1 SECONDS - var/ability_melee_cooldown = tgui_input_number(usr, "Enter the abilities melee cooldown in seconds", "Melee Cooldown", 2) - if(isnull(ability_melee_cooldown) || ability_melee_cooldown < 0) - ability_melee_cooldown = 2 - add_ability.melee_cooldown_time = ability_melee_cooldown * 1 SECONDS - add_ability.name = tgui_input_text(usr, "Choose ability name", "Ability name", "Generic Ability") - add_ability.create_sequence_actions() - else - add_ability = new ability_type(marked_mob) - - if(isnull(marked_mob)) - return - add_ability.Grant(marked_mob) - - message_admins("[key_name_admin(usr)] added mob ability [ability_type] to mob [marked_mob].") - log_admin("[key_name(usr)] added mob ability [ability_type] to mob [marked_mob].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Add Mob Ability") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! - -/client/proc/remove_mob_ability() +/client/proc/remove_marked_mob_ability() set category = "Admin.Events" - set name = "Remove Mob Ability" + set name = "Remove Mob Ability (Marked Mob)" set desc = "Removes an ability from marked mob." if(!holder) @@ -407,24 +362,7 @@ if(!isliving(holder.marked_datum)) to_chat(usr, span_warning("Error: Please mark a mob to remove actions from it.")) return - - var/mob/living/marked_mob = holder.marked_datum - - var/list/all_mob_actions = list() - for(var/datum/action/cooldown/mob_cooldown/ability in marked_mob.actions) - all_mob_actions.Add(ability) - - var/datum/action/cooldown/mob_cooldown/ability = tgui_input_list(usr, "Remove an ability", "Ability", all_mob_actions) - - if(!ability) - return - - var/ability_name = ability.name - QDEL_NULL(ability) - - message_admins("[key_name_admin(usr)] removed ability [ability_name] from mob [marked_mob].") - log_admin("[key_name(usr)] removed mob ability [ability_name] from mob [marked_mob].") - SSblackbox.record_feedback("tally", "admin_verb", 1, "Remove Mob Ability") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! + remove_mob_action(holder.marked_datum) /client/proc/command_report_footnote() diff --git a/code/modules/admin/verbs/adminfun.dm b/code/modules/admin/verbs/adminfun.dm index b1e0327510a5f1..f51a922e419287 100644 --- a/code/modules/admin/verbs/adminfun.dm +++ b/code/modules/admin/verbs/adminfun.dm @@ -78,9 +78,9 @@ if (istype(living_victim)) living_victim.investigate_log("has been gibbed by an admin.", INVESTIGATE_DEATHS) if(confirm == "Yes") - living_victim.gib() + living_victim.gib(DROP_ALL_REMAINS) else - living_victim.gib(TRUE) + living_victim.gib(DROP_ORGANS|DROP_BODYPARTS) SSblackbox.record_feedback("tally", "admin_verb", 1, "Gib") // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! @@ -97,7 +97,7 @@ var/mob/living/ourself = mob if (istype(ourself)) - ourself.gib(TRUE, TRUE, TRUE) + ourself.gib() /client/proc/everyone_random() set category = "Admin.Fun" diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index 64d2d5831a6dc5..5f61a508b3656c 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -422,7 +422,7 @@ GLOBAL_VAR_INIT(say_disabled, FALSE) var/list/foodcount = list() for(var/obj/item/food/fuck_me in world) var/turf/location = get_turf(fuck_me) - if(!location || SSmapping.level_trait(location.z, ZTRAIT_STATION)) + if(!location || !SSmapping.level_trait(location.z, ZTRAIT_STATION)) continue LAZYADDASSOC(foodcount, fuck_me.type, 1) @@ -445,7 +445,7 @@ GLOBAL_VAR_INIT(say_disabled, FALSE) var/list/stackcount = list() for(var/obj/item/stack/fuck_me in world) var/turf/location = get_turf(fuck_me) - if(!location || SSmapping.level_trait(location.z, ZTRAIT_STATION)) + if(!location || !SSmapping.level_trait(location.z, ZTRAIT_STATION)) continue LAZYADDASSOC(stackcount, fuck_me.type, fuck_me.amount) diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index a03d61d426e8d4..e29ed6404e4279 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -220,7 +220,7 @@ GLOBAL_DATUM(everyone_a_traitor, /datum/everyone_is_a_traitor_controller) var/result = input(holder, "Please choose a new species","Species") as null|anything in GLOB.species_list if(result) SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Mass Species Change", "[result]")) - log_admin("[key_name(holder)] turned all humans into [result]", 1) + log_admin("[key_name(holder)] turned all humans into [result]") message_admins("\blue [key_name_admin(holder)] turned all humans into [result]") var/newtype = GLOB.species_list[result] for(var/i in GLOB.human_list) @@ -230,21 +230,21 @@ GLOBAL_DATUM(everyone_a_traitor, /datum/everyone_is_a_traitor_controller) if(!is_funmin) return SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Power All APCs")) - log_admin("[key_name(holder)] made all areas powered", 1) + log_admin("[key_name(holder)] made all areas powered") message_admins(span_adminnotice("[key_name_admin(holder)] made all areas powered")) power_restore() if("unpower") if(!is_funmin) return SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Depower All APCs")) - log_admin("[key_name(holder)] made all areas unpowered", 1) + log_admin("[key_name(holder)] made all areas unpowered") message_admins(span_adminnotice("[key_name_admin(holder)] made all areas unpowered")) power_failure() if("quickpower") if(!is_funmin) return SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Power All SMESs")) - log_admin("[key_name(holder)] made all SMESs powered", 1) + log_admin("[key_name(holder)] made all SMESs powered") message_admins(span_adminnotice("[key_name_admin(holder)] made all SMESs powered")) power_restore_quick() if("anon_name") diff --git a/code/modules/admin/verbs/server.dm b/code/modules/admin/verbs/server.dm index 811b2a3506d66b..47fe392c973349 100644 --- a/code/modules/admin/verbs/server.dm +++ b/code/modules/admin/verbs/server.dm @@ -185,16 +185,42 @@ set category = "Server" set desc = "Respawn basically" set name = "Toggle Respawn" - var/new_nores = !CONFIG_GET(flag/norespawn) - CONFIG_SET(flag/norespawn, new_nores) - if (!new_nores) - to_chat(world, "You may now respawn.", confidential = TRUE) - else - to_chat(world, "You may no longer respawn :(", confidential = TRUE) - message_admins(span_adminnotice("[key_name_admin(usr)] toggled respawn to [!new_nores ? "On" : "Off"].")) - log_admin("[key_name(usr)] toggled respawn to [!new_nores ? "On" : "Off"].") + + var/respawn_state = CONFIG_GET(flag/allow_respawn) + var/new_state = -1 + var/new_state_text = "" + switch(respawn_state) + if(RESPAWN_FLAG_DISABLED) // respawn currently disabled + new_state = RESPAWN_FLAG_FREE + new_state_text = "Enabled" + to_chat(world, span_bold("You may now respawn."), confidential = TRUE) + + if(RESPAWN_FLAG_FREE) // respawn currently enabled + new_state = RESPAWN_FLAG_NEW_CHARACTER + new_state_text = "Enabled, Different Slot" + to_chat(world, span_bold("You may now respawn as a different character."), confidential = TRUE) + + if(RESPAWN_FLAG_NEW_CHARACTER) // respawn currently enabled for different slot characters only + new_state = RESPAWN_FLAG_DISABLED + new_state_text = "Disabled" + to_chat(world, span_bold("You may no longer respawn :("), confidential = TRUE) + + else + WARNING("Invalid respawn state in config: [respawn_state]") + + if(new_state == -1) + to_chat(usr, span_warning("The config for respawn is set incorrectly, please complain to your nearest server host (or fix it yourself). \ + In the meanwhile respawn has been set to \"Off\".")) + new_state = RESPAWN_FLAG_DISABLED + new_state_text = "Disabled" + + CONFIG_SET(flag/allow_respawn, new_state) + + message_admins(span_adminnotice("[key_name_admin(usr)] toggled respawn to \"[new_state_text]\".")) + log_admin("[key_name(usr)] toggled respawn to \"[new_state_text]\".") + world.update_status() - SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Respawn", "[!new_nores ? "Enabled" : "Disabled"]")) // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! + SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Respawn", "[new_state_text]")) // If you are copy-pasting this, ensure the 4th parameter is unique to the new proc! /datum/admins/proc/delay() set category = "Server" diff --git a/code/modules/admin/view_variables/debug_variables.dm b/code/modules/admin/view_variables/debug_variables.dm index 230a0e462844b0..5196d83b124f07 100644 --- a/code/modules/admin/view_variables/debug_variables.dm +++ b/code/modules/admin/view_variables/debug_variables.dm @@ -41,6 +41,10 @@ item = "[name_part] = /icon ([value])" #endif + else if(isappearance(value)) + var/image/actually_an_appearance = value + item = "[name_part] = /appearance ([actually_an_appearance.icon])" + else if (isfile(value)) item = "[name_part] = '[value]'" @@ -55,6 +59,7 @@ [M.c][M.f]1  "} //TODO link to modify_transform wrapper for all matrices + else if (isdatum(value)) var/datum/DV = value if ("[DV]" != "[DV.type]") //if the thing as a name var, lets use it. diff --git a/code/modules/antagonists/abductor/equipment/glands/chem.dm b/code/modules/antagonists/abductor/equipment/glands/chem.dm index 47868841c8504d..965d8f2fc201aa 100644 --- a/code/modules/antagonists/abductor/equipment/glands/chem.dm +++ b/code/modules/antagonists/abductor/equipment/glands/chem.dm @@ -16,5 +16,5 @@ /obj/item/organ/internal/heart/gland/chem/activate() var/chem_to_add = pick(possible_reagents) owner.reagents.add_reagent(chem_to_add, 2) - owner.adjustToxLoss(-5, TRUE, TRUE) + owner.adjustToxLoss(-5, forced = TRUE) ..() diff --git a/code/modules/antagonists/abductor/equipment/glands/heal.dm b/code/modules/antagonists/abductor/equipment/glands/heal.dm index 2fa677cba0ef00..683cb33fc9adb5 100644 --- a/code/modules/antagonists/abductor/equipment/glands/heal.dm +++ b/code/modules/antagonists/abductor/equipment/glands/heal.dm @@ -194,7 +194,7 @@ var/keep_going = FALSE owner.vomit(vomit_flags = (MOB_VOMIT_BLOOD | MOB_VOMIT_FORCE), lost_nutrition = 0, distance = 3) owner.Stun(15) - owner.adjustToxLoss(-15, TRUE, TRUE) + owner.adjustToxLoss(-15, forced = TRUE) owner.blood_volume = min(BLOOD_VOLUME_NORMAL, owner.blood_volume + 20) if(owner.blood_volume < BLOOD_VOLUME_NORMAL) diff --git a/code/modules/antagonists/blob/blob_minion.dm b/code/modules/antagonists/blob/blob_minion.dm index 9ba8e7089b9e86..9bf37e961d5ddf 100644 --- a/code/modules/antagonists/blob/blob_minion.dm +++ b/code/modules/antagonists/blob/blob_minion.dm @@ -34,9 +34,3 @@ objective.owner = owner objective.overmind = overmind objectives += objective - -/datum/antagonist/blob_minion/blobbernaut - name = "\improper Blobbernaut" - -/datum/antagonist/blob_minion/blob_zombie - name = "\improper Blob Zombie" diff --git a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm index 6225eec9da9364..6f01eb67aa72a9 100644 --- a/code/modules/antagonists/blob/blobstrains/_blobstrain.dm +++ b/code/modules/antagonists/blob/blobstrains/_blobstrain.dm @@ -96,12 +96,12 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/ B.modify_max_integrity(B.max_integrity * max_structure_health_multiplier) B.update_appearance() - for(var/mob/living/simple_animal/hostile/blob/BM as anything in overmind.blob_mobs) - BM.maxHealth *= max_mob_health_multiplier - BM.health *= max_mob_health_multiplier - BM.update_icons() //If it's getting a new strain, tell it what it does! - to_chat(BM, "Your overmind's blob strain is now: [name]!") - to_chat(BM, "The [name] strain [shortdesc ? "[shortdesc]" : "[description]"]") + for(var/mob/living/blob_mob as anything in overmind.blob_mobs) + blob_mob.maxHealth *= max_mob_health_multiplier + blob_mob.health *= max_mob_health_multiplier + blob_mob.update_icons() //If it's getting a new strain, tell it what it does! + to_chat(blob_mob, "Your overmind's blob strain is now: [name]!") + to_chat(blob_mob, "The [name] strain [shortdesc ? "[shortdesc]" : "[description]"]") /datum/blobstrain/proc/on_lose() if(overmind.blob_core) @@ -122,9 +122,9 @@ GLOBAL_LIST_INIT(valid_blobstrains, subtypesof(/datum/blobstrain) - list(/datum/ for(var/obj/structure/blob/B as anything in overmind.all_blobs) B.modify_max_integrity(B.max_integrity / max_structure_health_multiplier) - for(var/mob/living/simple_animal/hostile/blob/BM as anything in overmind.blob_mobs) - BM.maxHealth /= max_mob_health_multiplier - BM.health /= max_mob_health_multiplier + for(var/mob/living/blob_mob as anything in overmind.blob_mobs) + blob_mob.maxHealth /= max_mob_health_multiplier + blob_mob.health /= max_mob_health_multiplier /datum/blobstrain/proc/on_sporedeath(mob/living/spore) diff --git a/code/modules/antagonists/blob/blobstrains/_reagent.dm b/code/modules/antagonists/blob/blobstrains/_reagent.dm index aefd6c02f3c3e0..05bc73f95c8de6 100644 --- a/code/modules/antagonists/blob/blobstrains/_reagent.dm +++ b/code/modules/antagonists/blob/blobstrains/_reagent.dm @@ -15,8 +15,9 @@ var/mob_protection = L.getarmor(null, BIO) * 0.01 reagent.expose_mob(L, VAPOR, BLOBMOB_BLOBBERNAUT_REAGENTATK_VOL+blobbernaut_reagentatk_bonus, FALSE, mob_protection, overmind)//this will do between 10 and 20 damage(reduced by mob protection), depending on chemical, plus 4 from base brute damage. -/datum/blobstrain/reagent/on_sporedeath(mob/living/spore) - spore.reagents.add_reagent(reagent.type, 10) +/datum/blobstrain/reagent/on_sporedeath(mob/living/basic/spore) + var/burst_range = (spore.type == /mob/living/basic/blob_minion/spore) ? 1 : 0 + do_chem_smoke(range = burst_range, holder = spore, location = get_turf(spore), reagent_type = reagent.type) // These can only be applied by blobs. They are what (reagent) blobs are made out of. /datum/reagent/blob @@ -29,7 +30,7 @@ /// Used by blob reagents to calculate the reaction volume they should use when exposing mobs. /datum/reagent/blob/proc/return_mob_expose_reac_volume(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - if(exposed_mob.stat == DEAD || isblobmonster(exposed_mob)) + if(exposed_mob.stat == DEAD || HAS_TRAIT(exposed_mob, TRAIT_BLOB_ALLY)) return 0 //the dead, and blob mobs, don't cause reactions return round(reac_volume * min(1.5 - touch_protection, 1), 0.1) //full touch protection means 50% volume, any prot below 0.5 means 100% volume. diff --git a/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm b/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm index a20ddf89805cb0..a18d802ff7dd4f 100644 --- a/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm +++ b/code/modules/antagonists/blob/blobstrains/cryogenic_poison.dm @@ -26,8 +26,10 @@ exposed_mob.apply_damage(0.2*reac_volume, BRUTE, wound_bonus=CANT_WOUND) /datum/reagent/blob/cryogenic_poison/on_mob_life(mob/living/carbon/exposed_mob, seconds_per_tick, times_fired) - exposed_mob.adjustBruteLoss(0.5 * REM * seconds_per_tick, FALSE) - exposed_mob.adjustFireLoss(0.5 * REM * seconds_per_tick, FALSE) - exposed_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, FALSE) - . = 1 - ..() + . = ..() + var/need_mob_update + need_mob_update = exposed_mob.adjustBruteLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += exposed_mob.adjustFireLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += exposed_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE) + if(need_mob_update) + . = UPDATE_MOB_HEALTH diff --git a/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm b/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm index f97599948a13fb..ea2bf54d7692c3 100644 --- a/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm +++ b/code/modules/antagonists/blob/blobstrains/distributed_neurons.dm @@ -11,18 +11,16 @@ message_living = ", and you feel tired" reagent = /datum/reagent/blob/distributed_neurons -/datum/blobstrain/reagent/distributed_neurons/damage_reaction(obj/structure/blob/B, damage, damage_type, damage_flag) - if((damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) && damage <= 20 && B.get_integrity() - damage <= 0 && prob(15)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 15% chance of a shitty spore. - B.visible_message(span_warning("A spore floats free of the blob!")) - var/mob/living/simple_animal/hostile/blob/blobspore/weak/BS = new/mob/living/simple_animal/hostile/blob/blobspore/weak(B.loc) - BS.overmind = B.overmind - BS.update_icons() - B.overmind.blob_mobs.Add(BS) +/datum/blobstrain/reagent/distributed_neurons/damage_reaction(obj/structure/blob/blob_tile, damage, damage_type, damage_flag) + if((damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) && damage <= 20 && blob_tile.get_integrity() - damage <= 0 && prob(15)) //if the cause isn't fire or a bomb, the damage is less than 21, we're going to die from that damage, 15% chance of a shitty spore. + blob_tile.visible_message(span_boldwarning("A spore floats free of the blob!")) + blob_tile.overmind.create_spore(blob_tile.loc, /mob/living/basic/blob_minion/spore/minion/weak) return ..() /datum/reagent/blob/distributed_neurons name = "Distributed Neurons" color = "#E88D5D" + taste_description = "fizzing" /datum/reagent/blob/distributed_neurons/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) . = ..() @@ -33,10 +31,7 @@ exposed_mob.investigate_log("has been killed by distributed neurons (blob).", INVESTIGATE_DEATHS) exposed_mob.death() //sleeping in a fight? bad plan. if(exposed_mob.stat == DEAD && overmind.can_buy(5)) - var/mob/living/simple_animal/hostile/blob/blobspore/spore = new/mob/living/simple_animal/hostile/blob/blobspore(get_turf(exposed_mob)) - spore.overmind = overmind - spore.update_icons() - overmind.blob_mobs.Add(spore) + var/mob/living/basic/blob_minion/spore/minion/spore = overmind.create_spore(get_turf(exposed_mob)) spore.zombify(exposed_mob) overmind.add_points(-5) to_chat(overmind, span_notice("Spent 5 resources for the zombification of [exposed_mob].")) diff --git a/code/modules/antagonists/blob/blobstrains/reactive_spines.dm b/code/modules/antagonists/blob/blobstrains/reactive_spines.dm index 53f336ca419e29..1c8cb893df8395 100644 --- a/code/modules/antagonists/blob/blobstrains/reactive_spines.dm +++ b/code/modules/antagonists/blob/blobstrains/reactive_spines.dm @@ -16,15 +16,15 @@ if(damage && ((damage_type == BRUTE) || (damage_type == BURN)) && B.get_integrity() - damage > 0 && COOLDOWN_FINISHED(src, retaliate_cooldown)) // Is there any damage, is it burn or brute, will we be alive, and has the cooldown finished? COOLDOWN_START(src, retaliate_cooldown, 2.5 SECONDS) // 2.5 seconds before auto-retaliate can whack everything within 1 tile again B.visible_message(span_boldwarning("The blob retaliates, lashing out!")) - for(var/atom/A in range(1, B)) - if(!A.can_blob_attack()) + for(var/atom/thing in range(1, B)) + if(!thing.can_blob_attack()) continue - var/attacked_turf = get_turf(A) - if(isliving(A) && !isblobmonster(A)) // Make sure to inject strain-reagents with automatic attacks when needed. + var/attacked_turf = get_turf(thing) + if(isliving(thing) && !HAS_TRAIT(thing, TRAIT_BLOB_ALLY)) // Make sure to inject strain-reagents with automatic attacks when needed. B.blob_attack_animation(attacked_turf, overmind) - attack_living(A) + attack_living(thing) - else if(A.blob_act(B)) // After checking for mobs, whack everything else with the standard attack + else if(thing.blob_act(B)) // After checking for mobs, whack everything else with the standard attack B.blob_attack_animation(attacked_turf, overmind) // Only play the animation if the attack did something meaningful return ..() @@ -35,7 +35,7 @@ color = "#9ACD32" /datum/reagent/blob/reactive_spines/return_mob_expose_reac_volume(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message, touch_protection, mob/camera/blob/overmind) - if(exposed_mob.stat == DEAD || isblobmonster(exposed_mob)) + if(exposed_mob.stat == DEAD || HAS_TRAIT(exposed_mob, TRAIT_BLOB_ALLY)) return 0 //the dead, and blob mobs, don't cause reactions return reac_volume diff --git a/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm b/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm index 78b67dae6509a7..0b70cc9c741240 100644 --- a/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm +++ b/code/modules/antagonists/blob/blobstrains/regenerative_materia.dm @@ -25,9 +25,9 @@ exposed_mob.apply_damage(0.7*reac_volume, TOX) /datum/reagent/blob/regenerative_materia/on_mob_life(mob/living/carbon/metabolizer, seconds_per_tick, times_fired) - metabolizer.adjustToxLoss(1 * REM * seconds_per_tick) - ..() - return TRUE + . = ..() + if(metabolizer.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/blob/regenerative_materia/on_mob_metabolize(mob/living/metabolizer) . = ..() diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index 70a1e69e1e3e69..d87574c092dcf4 100644 --- a/code/modules/antagonists/blob/overmind.dm +++ b/code/modules/antagonists/blob/overmind.dm @@ -54,6 +54,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) var/list/strain_choices /mob/camera/blob/Initialize(mapload, starting_points = OVERMIND_STARTING_POINTS) + ADD_TRAIT(src, TRAIT_BLOB_ALLY, INNATE_TRAIT) validate_location() blob_points = starting_points manualplace_min_time += world.time @@ -71,6 +72,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) SSshuttle.registerHostileEnvironment(src) . = ..() START_PROCESSING(SSobj, src) + GLOB.blob_telepathy_mobs |= src /mob/camera/blob/proc/validate_location() var/turf/T = get_turf(src) @@ -112,6 +114,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) to_chat(src, span_notice("The [blobstrain.name] strain [blobstrain.description]")) if(blobstrain.effectdesc) to_chat(src, span_notice("The [blobstrain.name] strain [blobstrain.effectdesc]")) + SEND_SIGNAL(src, COMSIG_BLOB_SELECTED_STRAIN, blobstrain) /mob/camera/blob/can_z_move(direction, turf/start, turf/destination, z_move_flags = NONE, mob/living/rider) if(placed) // The blob can't expand vertically (yet) @@ -162,50 +165,70 @@ GLOBAL_LIST_EMPTY(blob_nodes) priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", ANNOUNCER_OUTBREAK5) has_announced = TRUE +/// Create a blob spore and link it to us +/mob/camera/blob/proc/create_spore(turf/spore_turf, spore_type = /mob/living/basic/blob_minion/spore/minion) + var/mob/living/basic/blob_minion/spore/spore = new spore_type(spore_turf) + assume_direct_control(spore) + return spore + +/// Give our new minion the properties of a minion +/mob/camera/blob/proc/assume_direct_control(mob/living/minion) + minion.AddComponent(/datum/component/blob_minion, src) + +/// Add something to our list of mobs and wait for it to die +/mob/camera/blob/proc/register_new_minion(mob/living/minion) + blob_mobs |= minion + if (!istype(minion, /mob/living/basic/blob_minion/blobbernaut)) + RegisterSignal(minion, COMSIG_LIVING_DEATH, PROC_REF(on_minion_death)) + +/// When a spore (or zombie) dies then we do this +/mob/camera/blob/proc/on_minion_death(mob/living/spore) + SIGNAL_HANDLER + blobstrain.on_sporedeath(spore) + /mob/camera/blob/proc/victory() sound_to_playing_players('sound/machines/alarm.ogg') sleep(10 SECONDS) - for(var/i in GLOB.mob_living_list) - var/mob/living/L = i - var/turf/T = get_turf(L) - if(!T || !is_station_level(T.z)) + for(var/mob/living/live_guy as anything in GLOB.mob_living_list) + var/turf/guy_turf = get_turf(live_guy) + if(isnull(guy_turf) || !is_station_level(guy_turf.z)) continue - if(L in GLOB.overminds || (L.pass_flags & PASSBLOB)) + if(live_guy in GLOB.overminds || (live_guy.pass_flags & PASSBLOB)) continue - var/area/Ablob = get_area(T) - - if(!(Ablob.area_flags & BLOBS_ALLOWED)) + var/area/blob_area = get_area(guy_turf) + if(!(blob_area.area_flags & BLOBS_ALLOWED)) continue - if(!(ROLE_BLOB in L.faction)) - playsound(L, 'sound/effects/splat.ogg', 50, TRUE) - if(L.stat != DEAD) - L.investigate_log("has died from blob takeover.", INVESTIGATE_DEATHS) - L.death() - new/mob/living/simple_animal/hostile/blob/blobspore(T) + if(!(ROLE_BLOB in live_guy.faction)) + playsound(live_guy, 'sound/effects/splat.ogg', 50, TRUE) + if(live_guy.stat != DEAD) + live_guy.investigate_log("has died from blob takeover.", INVESTIGATE_DEATHS) + live_guy.death() + create_spore(guy_turf) else - L.fully_heal() + live_guy.fully_heal() - for(var/area/A in GLOB.areas) - if(!(A.type in GLOB.the_station_areas)) + for(var/area/check_area in GLOB.areas) + if(!is_type_in_list(check_area, GLOB.the_station_areas)) continue - if(!(A.area_flags & BLOBS_ALLOWED)) + if(!(check_area.area_flags & BLOBS_ALLOWED)) continue - A.color = blobstrain.color - A.name = "blob" - A.icon = 'icons/mob/nonhuman-player/blob.dmi' - A.icon_state = "blob_shield" - A.layer = BELOW_MOB_LAYER - A.invisibility = 0 - A.blend_mode = 0 + check_area.color = blobstrain.color + check_area.name = "blob" + check_area.icon = 'icons/mob/nonhuman-player/blob.dmi' + check_area.icon_state = "blob_shield" + check_area.layer = BELOW_MOB_LAYER + check_area.invisibility = 0 + check_area.blend_mode = 0 + var/datum/antagonist/blob/B = mind.has_antag_datum(/datum/antagonist/blob) if(B) var/datum/objective/blob_takeover/main_objective = locate() in B.objectives if(main_objective) main_objective.completed = TRUE - to_chat(world, span_blob("[real_name] consumed the station in an unstoppable tide!")) + to_chat(world, span_blobannounce("[real_name] consumed the station in an unstoppable tide!")) SSticker.news_report = BLOB_WIN SSticker.force_ending = FORCE_END_ROUND @@ -216,11 +239,6 @@ GLOBAL_LIST_EMPTY(blob_nodes) if(B && B.overmind == src) B.overmind = null B.update_appearance() //reset anything that was ours - for(var/BLO in blob_mobs) - var/mob/living/simple_animal/hostile/blob/BM = BLO - if(BM) - BM.overmind = null - BM.update_icons() for(var/obj/structure/blob/blob_structure as anything in all_blobs) blob_structure.overmind = null all_blobs = null @@ -233,6 +251,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) SSshuttle.clearHostileEnvironment(src) STOP_PROCESSING(SSobj, src) + GLOB.blob_telepathy_mobs -= src return ..() @@ -240,7 +259,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) . = ..() if(!. || !client) return FALSE - to_chat(src, span_blob("You are the overmind!")) + to_chat(src, span_blobannounce("You are the overmind!")) if(!placed && autoplace_max_time <= world.time) to_chat(src, span_boldannounce("You will automatically place your blob core in [DisplayTimeText(autoplace_max_time - world.time)].")) to_chat(src, span_boldannounce("You [manualplace_min_time ? "will be able to":"can"] manually place your blob core by pressing the Place Blob Core button in the bottom right corner of the screen.")) @@ -257,9 +276,11 @@ GLOBAL_LIST_EMPTY(blob_nodes) return FALSE var/current_health = round((blob_core.get_integrity() / blob_core.max_integrity) * 100) hud_used.healths.maptext = MAPTEXT("
[current_health]%
") - for(var/mob/living/simple_animal/hostile/blob/blobbernaut/blobbernaut in blob_mobs) - if(blobbernaut.hud_used && blobbernaut.hud_used.blobpwrdisplay) - blobbernaut.hud_used.blobpwrdisplay.maptext = MAPTEXT("
[current_health]%
") + for(var/mob/living/basic/blob_minion/blobbernaut/blobbernaut in blob_mobs) + var/datum/hud/using_hud = blobbernaut.hud_used + if(!using_hud?.blobpwrdisplay) + continue + using_hud.blobpwrdisplay.maptext = MAPTEXT("
[current_health]%
") /mob/camera/blob/proc/add_points(points) blob_points = clamp(blob_points + points, 0, max_blob_points) @@ -273,7 +294,7 @@ GLOBAL_LIST_EMPTY(blob_nodes) if(client.prefs.muted & MUTE_IC) to_chat(src, span_boldwarning("You cannot send IC messages (muted).")) return - if (!(ignore_spam || forced) && src.client.handle_spam_prevention(message,MUTE_IC)) + if (!(ignore_spam || forced) && src.client.handle_spam_prevention(message, MUTE_IC)) return if (stat) @@ -291,14 +312,8 @@ GLOBAL_LIST_EMPTY(blob_nodes) src.log_talk(message, LOG_SAY) var/message_a = say_quote(message) - var/rendered = span_big("\[Blob Telepathy\] [name]([blobstrain.name]) [message_a]") - - for(var/mob/M in GLOB.mob_list) - if(isovermind(M) || isblobmonster(M)) - to_chat(M, rendered) - if(isobserver(M)) - var/link = FOLLOW_LINK(M, src) - to_chat(M, "[link] [rendered]") + var/rendered = span_big(span_blob("\[Blob Telepathy\] [name]([blobstrain.name]) [message_a]")) + relay_to_list_and_observers(rendered, GLOB.blob_telepathy_mobs, src) /mob/camera/blob/blob_act(obj/structure/blob/B) return @@ -324,8 +339,8 @@ GLOBAL_LIST_EMPTY(blob_nodes) else return FALSE else - var/area/A = get_area(NewLoc) - if(isgroundlessturf(NewLoc) || istype(A, /area/shuttle)) //if unplaced, can't go on shuttles or goundless tiles + var/area/check_area = get_area(NewLoc) + if(isgroundlessturf(NewLoc) || istype(check_area, /area/shuttle)) //if unplaced, can't go on shuttles or groundless tiles return FALSE forceMove(NewLoc) return TRUE diff --git a/code/modules/antagonists/blob/powers.dm b/code/modules/antagonists/blob/powers.dm index c75a41a48fff7e..04054f6df85a3d 100644 --- a/code/modules/antagonists/blob/powers.dm +++ b/code/modules/antagonists/blob/powers.dm @@ -196,38 +196,25 @@ var/list/mob/dead/observer/candidates = poll_ghost_candidates("Do you want to play as a [blobstrain.name] blobbernaut?", ROLE_BLOB, ROLE_BLOB, 50) - factory.is_creating_blobbernaut = FALSE - if(!length(candidates)) to_chat(src, span_warning("You could not conjure a sentience for your blobbernaut. Your points have been refunded. Try again later.")) add_points(BLOBMOB_BLOBBERNAUT_RESOURCE_COST) - factory.blobbernaut = null //players must answer rapidly + factory.assign_blobbernaut(null) return FALSE - factory.modify_max_integrity(initial(factory.max_integrity) * 0.25) //factories that produced a blobbernaut have much lower health - factory.update_appearance() - factory.visible_message(span_warning("The blobbernaut [pick("rips", "tears", "shreds")] its way out of the factory blob!")) - playsound(factory.loc, 'sound/effects/splat.ogg', 50, TRUE) - - var/mob/living/simple_animal/hostile/blob/blobbernaut/blobber = new /mob/living/simple_animal/hostile/blob/blobbernaut(get_turf(factory)) - flick("blobbernaut_produce", blobber) - - factory.blobbernaut = blobber - blobber.factory = factory - blobber.overmind = src - blobber.update_icons() - blobber.adjustHealth(blobber.maxHealth * 0.5) - blob_mobs += blobber - + var/mob/living/basic/blob_minion/blobbernaut/minion/blobber = new(get_turf(factory)) + assume_direct_control(blobber) + factory.assign_blobbernaut(blobber) var/mob/dead/observer/player = pick(candidates) - blobber.key = player.key + blobber.assign_key(player.key, blobstrain) + RegisterSignal(blobber, COMSIG_HOSTILE_POST_ATTACKINGTARGET, PROC_REF(on_blobbernaut_attacked)) - SEND_SOUND(blobber, sound('sound/effects/blobattack.ogg')) - SEND_SOUND(blobber, sound('sound/effects/attackblob.ogg')) - to_chat(blobber, span_infoplain("You are powerful, hard to kill, and slowly regenerate near nodes and cores, [span_cultlarge("but will slowly die if not near the blob")] or if the factory that made you is killed.")) - to_chat(blobber, span_infoplain("You can communicate with other blobbernauts and overminds telepathically by attempting to speak normally")) - to_chat(blobber, span_infoplain("Your overmind's blob reagent is: [blobstrain.name]!")) - to_chat(blobber, span_infoplain("The [blobstrain.name] reagent [blobstrain.shortdesc ? "[blobstrain.shortdesc]" : "[blobstrain.description]"]")) +/// When one of our boys attacked something, we sometimes want to perform extra effects +/mob/camera/blob/proc/on_blobbernaut_attacked(mob/living/basic/blobbynaut, atom/target, success) + SIGNAL_HANDLER + if (!success) + return + blobstrain.blobbernaut_attack(target, blobbynaut) /** Moves the core */ /mob/camera/blob/proc/relocate_core() @@ -358,10 +345,11 @@ var/list/surrounding_turfs = TURF_NEIGHBORS(tile) if(!length(surrounding_turfs)) return FALSE - for(var/mob/living/simple_animal/hostile/blob/blobspore/spore as anything in blob_mobs) - if(isturf(spore.loc) && get_dist(spore, tile) <= 35 && !spore.key) - spore.LoseTarget() - spore.Goto(pick(surrounding_turfs), spore.move_to_delay) + for(var/mob/living/basic/blob_mob as anything in blob_mobs) + if(!isturf(blob_mob.loc) || get_dist(blob_mob, tile) > 35 || blob_mob.key) + continue + blob_mob.ai_controller.clear_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET) + blob_mob.ai_controller.set_blackboard_key(BB_TRAVEL_DESTINATION, pick(surrounding_turfs)) /** Opens the reroll menu to change strains */ /mob/camera/blob/proc/strain_reroll() diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm index 543da00d2f5787..e206d97c26b12d 100644 --- a/code/modules/antagonists/blob/structures/_blob.dm +++ b/code/modules/antagonists/blob/structures/_blob.dm @@ -129,13 +129,13 @@ return FALSE //oh no we failed /obj/structure/blob/proc/ConsumeTile() - for(var/atom/A in loc) - if(!A.can_blob_attack()) + for(var/atom/thing in loc) + if(!thing.can_blob_attack()) continue - if(isliving(A) && overmind && !isblobmonster(A)) // Make sure to inject strain-reagents with automatic attacks when needed. - overmind.blobstrain.attack_living(A) + if(isliving(thing) && overmind && !HAS_TRAIT(thing, TRAIT_BLOB_ALLY)) // Make sure to inject strain-reagents with automatic attacks when needed. + overmind.blobstrain.attack_living(thing) continue // Don't smack them twice though - A.blob_act(src) + thing.blob_act(src) if(iswallturf(loc)) loc.blob_act(src) //don't ask how a wall got on top of the core, just eat it diff --git a/code/modules/antagonists/blob/structures/factory.dm b/code/modules/antagonists/blob/structures/factory.dm index 7f28dcce224360..cee7e9a0ac58d7 100644 --- a/code/modules/antagonists/blob/structures/factory.dm +++ b/code/modules/antagonists/blob/structures/factory.dm @@ -10,12 +10,12 @@ armor_type = /datum/armor/structure_blob/factory ///How many spores this factory can have. var/max_spores = BLOB_FACTORY_MAX_SPORES - ///The list of spores - var/list/spores = list() + ///The list of spores and zombies + var/list/spores_and_zombies = list() COOLDOWN_DECLARE(spore_delay) var/spore_cooldown = BLOBMOB_SPORE_SPAWN_COOLDOWN ///Its Blobbernaut, if it has spawned any. - var/mob/living/simple_animal/hostile/blob/blobbernaut/blobbernaut + var/mob/living/basic/blob_minion/blobbernaut/minion/blobbernaut ///Used in blob/powers.dm, checks if it's already trying to spawn a blobbernaut to prevent issues. var/is_creating_blobbernaut = FALSE @@ -32,15 +32,8 @@ overmind.factory_blobs += src /obj/structure/blob/special/factory/Destroy() - for(var/mob/living/simple_animal/hostile/blob/blobspore/spore in spores) - to_chat(spore, span_userdanger("Your factory was destroyed! You can no longer sustain yourself.")) - spore.death() - spores = null - if(blobbernaut) - blobbernaut.factory = null - to_chat(blobbernaut, span_userdanger("Your factory was destroyed! You feel yourself dying!")) - blobbernaut.throw_alert("nofactory", /atom/movable/screen/alert/nofactory) - blobbernaut = null + spores_and_zombies = null + blobbernaut = null if(overmind) overmind.factory_blobs -= src return ..() @@ -49,13 +42,57 @@ . = ..() if(blobbernaut) return - if(spores.len >= max_spores) + if(length(spores_and_zombies) >= max_spores) return if(!COOLDOWN_FINISHED(src, spore_delay)) return COOLDOWN_START(src, spore_delay, spore_cooldown) - var/mob/living/simple_animal/hostile/blob/blobspore/BS = new (loc, src) - if(overmind) //if we don't have an overmind, we don't need to do anything but make a spore - BS.overmind = overmind - BS.update_icons() - overmind.blob_mobs.Add(BS) + var/mob/living/basic/blob_minion/created_spore = (overmind) ? overmind.create_spore(loc) : new(loc) + register_mob(created_spore) + RegisterSignal(created_spore, COMSIG_BLOB_ZOMBIFIED, PROC_REF(on_zombie_created)) + +/// Tracks the existence of a mob in our mobs list +/obj/structure/blob/special/factory/proc/register_mob(mob/living/basic/blob_minion/blob_mob) + spores_and_zombies |= blob_mob + blob_mob.link_to_factory(src) + RegisterSignal(blob_mob, COMSIG_LIVING_DEATH, PROC_REF(on_spore_died)) + RegisterSignal(blob_mob, COMSIG_QDELETING, PROC_REF(on_spore_lost)) + +/// When a spore or zombie dies reset our spawn cooldown so we don't instantly replace it +/obj/structure/blob/special/factory/proc/on_spore_died(mob/living/dead_spore) + SIGNAL_HANDLER + COOLDOWN_START(src, spore_delay, spore_cooldown) + +/// When a spore is deleted remove it from our list +/obj/structure/blob/special/factory/proc/on_spore_lost(mob/living/dead_spore) + SIGNAL_HANDLER + spores_and_zombies -= dead_spore + +/// When a spore makes a zombie add it to our mobs list +/obj/structure/blob/special/factory/proc/on_zombie_created(mob/living/spore, mob/living/zombie) + SIGNAL_HANDLER + register_mob(zombie) + +/// Produce a blobbernaut +/obj/structure/blob/special/factory/proc/assign_blobbernaut(mob/living/new_naut) + is_creating_blobbernaut = FALSE + if (isnull(new_naut)) + return + + modify_max_integrity(initial(max_integrity) * 0.25) //factories that produced a blobbernaut have much lower health + visible_message(span_boldwarning("The blobbernaut [pick("rips", "tears", "shreds")] its way out of the factory blob!")) + playsound(loc, 'sound/effects/splat.ogg', 50, TRUE) + + blobbernaut = new_naut + blobbernaut.link_to_factory(src) + RegisterSignals(new_naut, list(COMSIG_QDELETING, COMSIG_LIVING_DEATH), PROC_REF(on_blobbernaut_death)) + update_appearance(UPDATE_ICON) + +/// When our brave soldier dies, reset our max integrity +/obj/structure/blob/special/factory/proc/on_blobbernaut_death(mob/living/death_naut) + SIGNAL_HANDLER + if (isnull(blobbernaut) || blobbernaut != death_naut) + return + blobbernaut = null + max_integrity = initial(max_integrity) + update_appearance(UPDATE_ICON) diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 23c828c97643dc..40c224a2a30d3f 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -372,12 +372,11 @@ /datum/antagonist/changeling/proc/regain_powers() emporium_action.Grant(owner.current) for(var/datum/action/changeling/power as anything in innate_powers) - if(power.needs_button) - power.Grant(owner.current) + power.Grant(owner.current) for(var/power_path in purchased_powers) var/datum/action/changeling/power = purchased_powers[power_path] - if(istype(power) && power.needs_button) + if(istype(power)) power.Grant(owner.current) /* @@ -1138,9 +1137,6 @@ /datum/outfit/changeling_space name = "Changeling (Space)" - - head = /obj/item/clothing/head/helmet/space/changeling - suit = /obj/item/clothing/suit/space/changeling l_hand = /obj/item/melee/arm_blade #undef FORMAT_CHEM_CHARGES_TEXT diff --git a/code/modules/antagonists/changeling/changeling_power.dm b/code/modules/antagonists/changeling/changeling_power.dm index ee2001bfe03fcc..a4d9044d977a18 100644 --- a/code/modules/antagonists/changeling/changeling_power.dm +++ b/code/modules/antagonists/changeling/changeling_power.dm @@ -7,8 +7,6 @@ background_icon_state = "bg_changeling" overlay_icon_state = "bg_changeling_border" button_icon = 'icons/mob/actions/actions_changeling.dmi' - /// For passive abilities like hivemind that dont need an action button - var/needs_button = TRUE /// Details displayed in fine print within the changling emporium var/helptext = "" /// How many changeling chems it costs to use @@ -44,8 +42,7 @@ the same goes for Remove(). if you override Remove(), call parent or else your p /datum/action/changeling/proc/on_purchase(mob/user, is_respec) if(!is_respec) SSblackbox.record_feedback("tally", "changeling_power_purchase", 1, name) - if(needs_button) - Grant(user)//how powers are added rather than the checks in mob.dm + Grant(user)//how powers are added rather than the checks in mob.dm /datum/action/changeling/Trigger(trigger_flags) var/mob/user = owner @@ -75,6 +72,7 @@ the same goes for Remove(). if you override Remove(), call parent or else your p return FALSE /datum/action/changeling/proc/sting_action(mob/living/user, mob/living/target) + SHOULD_CALL_PARENT(TRUE) SSblackbox.record_feedback("nested tally", "changeling_powers", 1, list("[name]")) return FALSE diff --git a/code/modules/antagonists/changeling/headslug_eggs.dm b/code/modules/antagonists/changeling/headslug_eggs.dm index 08733a7e6af0d2..e4327aa3ed1e48 100644 --- a/code/modules/antagonists/changeling/headslug_eggs.dm +++ b/code/modules/antagonists/changeling/headslug_eggs.dm @@ -37,7 +37,7 @@ changeling_datum.regain_powers() owner.investigate_log("has been gibbed by a changeling egg burst.", INVESTIGATE_DEATHS) - owner.gib() + owner.gib(DROP_ALL_REMAINS) qdel(src) #undef EGG_INCUBATION_TIME diff --git a/code/modules/antagonists/changeling/powers/absorb.dm b/code/modules/antagonists/changeling/powers/absorb.dm index cee0f0da5b99a7..1fdb50a7babf71 100644 --- a/code/modules/antagonists/changeling/powers/absorb.dm +++ b/code/modules/antagonists/changeling/powers/absorb.dm @@ -28,6 +28,8 @@ return changeling.can_absorb_dna(target) /datum/action/changeling/absorb_dna/sting_action(mob/owner) + SHOULD_CALL_PARENT(FALSE) // the only reason to call parent is for proper blackbox logging, and we do that ourselves in a snowflake way + var/datum/antagonist/changeling/changeling = owner.mind.has_antag_datum(/datum/antagonist/changeling) var/mob/living/carbon/human/target = owner.pulling is_absorbing = TRUE diff --git a/code/modules/antagonists/changeling/powers/biodegrade.dm b/code/modules/antagonists/changeling/powers/biodegrade.dm index 16bd707831b294..eba507ad5e0798 100644 --- a/code/modules/antagonists/changeling/powers/biodegrade.dm +++ b/code/modules/antagonists/changeling/powers/biodegrade.dm @@ -8,11 +8,6 @@ req_human = TRUE /datum/action/changeling/biodegrade/sting_action(mob/living/carbon/human/user) - var/used = FALSE // only one form of shackles removed per use - if(!HAS_TRAIT(user, TRAIT_RESTRAINED) && !user.legcuffed && isopenturf(user.loc)) - user.balloon_alert(user, "already free!") - return FALSE - if(user.handcuffed) var/obj/O = user.get_item_by_slot(ITEM_SLOT_HANDCUFFED) if(!istype(O)) @@ -21,7 +16,9 @@ span_warning("We vomit acidic ooze onto our restraints!")) addtimer(CALLBACK(src, PROC_REF(dissolve_handcuffs), user, O), 30) - used = TRUE + log_combat(user, user.handcuffed, "melted handcuffs", addition = "(biodegrade)") + ..() + return TRUE if(user.legcuffed) var/obj/O = user.get_item_by_slot(ITEM_SLOT_LEGCUFFED) @@ -31,37 +28,45 @@ span_warning("We vomit acidic ooze onto our restraints!")) addtimer(CALLBACK(src, PROC_REF(dissolve_legcuffs), user, O), 30) - used = TRUE + log_combat(user, user.legcuffed, "melted legcuffs", addition = "(biodegrade)") + ..() + return TRUE - if(user.wear_suit && user.wear_suit.breakouttime && !used) + if(user.wear_suit?.breakouttime) var/obj/item/clothing/suit/S = user.get_item_by_slot(ITEM_SLOT_OCLOTHING) if(!istype(S)) return FALSE user.visible_message(span_warning("[user] vomits a glob of acid across the front of [user.p_their()] [S]!"), \ - span_warning("We vomit acidic ooze onto our straight jacket!")) + span_warning("We vomit acidic ooze onto our [user.wear_suit.name]!")) addtimer(CALLBACK(src, PROC_REF(dissolve_straightjacket), user, S), 30) - used = TRUE - + log_combat(user, user.wear_suit, "melted [user.wear_suit]", addition = "(biodegrade)") + ..() + return TRUE - if(istype(user.loc, /obj/structure/closet) && !used) + if(istype(user.loc, /obj/structure/closet)) var/obj/structure/closet/C = user.loc if(!istype(C)) return FALSE C.visible_message(span_warning("[C]'s hinges suddenly begin to melt and run!")) to_chat(user, span_warning("We vomit acidic goop onto the interior of [C]!")) addtimer(CALLBACK(src, PROC_REF(open_closet), user, C), 70) - used = TRUE + log_combat(user, user.loc, "melted locker", addition = "(biodegrade)") + ..() + return TRUE - if(istype(user.loc, /obj/structure/spider/cocoon) && !used) + if(istype(user.loc, /obj/structure/spider/cocoon)) var/obj/structure/spider/cocoon/C = user.loc if(!istype(C)) return FALSE C.visible_message(span_warning("[src] shifts and starts to fall apart!")) to_chat(user, span_warning("We secrete acidic enzymes from our skin and begin melting our cocoon...")) addtimer(CALLBACK(src, PROC_REF(dissolve_cocoon), user, C), 25) //Very short because it's just webs - used = TRUE - ..() - return used + log_combat(user, user.loc, "melted cocoon", addition = "(biodegrade)") + ..() + return TRUE + + user.balloon_alert(user, "already free!") + return FALSE /datum/action/changeling/biodegrade/proc/dissolve_handcuffs(mob/living/carbon/human/user, obj/O) if(O && user.handcuffed == O) diff --git a/code/modules/antagonists/changeling/powers/defib_grasp.dm b/code/modules/antagonists/changeling/powers/defib_grasp.dm index 20ff3049c8fdd1..135b9b243f7217 100644 --- a/code/modules/antagonists/changeling/powers/defib_grasp.dm +++ b/code/modules/antagonists/changeling/powers/defib_grasp.dm @@ -4,7 +4,7 @@ we will snatch their arms off and instantly finalize our stasis." helptext = "This ability is passive, and will trigger when a defibrillator paddle is applied to our chest \ while we are dead or in stasis. Will also stun cyborgs momentarily." - needs_button = FALSE + owner_has_control = FALSE dna_cost = 0 /// Flags to pass to fully heal when we get zapped diff --git a/code/modules/antagonists/changeling/powers/headcrab.dm b/code/modules/antagonists/changeling/powers/headcrab.dm index 7daebc4cfb2b9d..f608d1620b86f1 100644 --- a/code/modules/antagonists/changeling/powers/headcrab.dm +++ b/code/modules/antagonists/changeling/powers/headcrab.dm @@ -35,7 +35,7 @@ user.transfer_observers_to(user_turf) // user is about to be deleted, store orbiters on the turf if(user.stat != DEAD) user.investigate_log("has been gibbed by headslug burst.", INVESTIGATE_DEATHS) - user.gib() + user.gib(DROP_ALL_REMAINS) . = TRUE addtimer(CALLBACK(src, PROC_REF(spawn_headcrab), stored_mind, user_turf, organs), 1 SECONDS) diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index bf4f8c2b3da3e4..54027b7d8a24f8 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -480,78 +480,6 @@ remaining_uses-- return ..() - -/***************************************\ -|*********SPACE SUIT + HELMET***********| -\***************************************/ -/datum/action/changeling/suit/organic_space_suit - name = "Organic Space Suit" - desc = "We grow an organic suit to protect ourselves from space exposure, including regulation of temperature and oxygen needs. Costs 20 chemicals." - helptext = "We must constantly repair our form to make it space-proof, reducing chemical production while we are protected. Cannot be used in lesser form." - button_icon_state = "organic_suit" - chemical_cost = 20 - dna_cost = 2 - req_human = TRUE - - suit_type = /obj/item/clothing/suit/space/changeling - helmet_type = /obj/item/clothing/head/helmet/space/changeling - suit_name_simple = "flesh shell" - helmet_name_simple = "space helmet" - recharge_slowdown = 0.25 - blood_on_castoff = 1 - -/obj/item/clothing/suit/space/changeling - name = "flesh mass" - icon_state = "lingspacesuit_t" - icon = 'icons/obj/clothing/suits/costume.dmi' - worn_icon = 'icons/mob/clothing/suits/costume.dmi' - desc = "A huge, bulky mass of pressure and temperature-resistant organic tissue, evolved to facilitate space travel." - 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_type = /datum/armor/space_changeling - actions_types = list() - cell = null - show_hud = FALSE - -/datum/armor/space_changeling - bio = 100 - fire = 90 - acid = 90 - -/obj/item/clothing/suit/space/changeling/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) - if(ismob(loc)) - loc.visible_message(span_warning("[loc.name]\'s flesh rapidly inflates, forming a bloated mass around [loc.p_their()] body!"), span_warning("We inflate our flesh, creating a spaceproof suit!"), span_hear("You hear organic matter ripping and tearing!")) - START_PROCESSING(SSobj, src) - -// seal the cell door -/obj/item/clothing/suit/space/changeling/toggle_spacesuit_cell(mob/user) - return - -/obj/item/clothing/suit/space/changeling/process(seconds_per_tick) - if(ishuman(loc)) - var/mob/living/carbon/human/H = loc - H.reagents.add_reagent(/datum/reagent/medicine/salbutamol, REAGENTS_METABOLISM * (seconds_per_tick / SSMOBS_DT)) - H.adjust_bodytemperature(temperature_setting - H.bodytemperature) // force changelings to normal temp step mode played badly - -/obj/item/clothing/head/helmet/space/changeling - name = "flesh mass" - icon = 'icons/obj/clothing/head/costume.dmi' - worn_icon = 'icons/mob/clothing/head/costume.dmi' - icon_state = "lingspacehelmet" - inhand_icon_state = null - desc = "A covering of pressure and temperature-resistant organic tissue with a glass-like chitin front." - item_flags = DROPDEL - clothing_flags = STOPSPRESSUREDAMAGE | HEADINTERNALS - armor_type = /datum/armor/space_changeling - flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH - -/obj/item/clothing/head/helmet/space/changeling/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_NODROP, CHANGELING_TRAIT) - /***************************************\ |*****************ARMOR*****************| \***************************************/ diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm index 412307e33ce9ce..83dc308022cee8 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -100,18 +100,22 @@ return FALSE return TRUE -/datum/action/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 - - var/mob/living/carbon/C = target - . = TRUE - if(istype(C)) - C.real_name = NewDNA.real_name - NewDNA.transfer_identity(C) - C.updateappearance(mutcolor_update=1) +/datum/action/changeling/sting/transformation/sting_action(mob/living/user, mob/living/target) + var/final_duration = sting_duration + var/final_message = span_notice("We transform [target] into [selected_dna.dna.real_name].") + if(ismonkey(target)) + final_duration = INFINITY + final_message = span_warning("Our genes cry out as we transform the lesser form of [target] into [selected_dna.dna.real_name] permanently!") + + if(target.apply_status_effect(/datum/status_effect/temporary_transformation/trans_sting, final_duration, selected_dna.dna)) + ..() + log_combat(user, target, "stung", "transformation sting", " new identity is '[selected_dna.dna.real_name]'") + to_chat(user, final_message) + return TRUE + return FALSE */ //SKYRAT EDIT REMOVAL END + /datum/action/changeling/sting/false_armblade name = "False Armblade Sting" desc = "We silently sting a human, injecting a retrovirus that mutates their arm to temporarily appear as an armblade. Costs 20 chemicals." @@ -136,13 +140,14 @@ return TRUE /datum/action/changeling/sting/false_armblade/sting_action(mob/user, mob/target) - log_combat(user, target, "stung", object="false armblade sting") var/obj/item/held = target.get_active_held_item() if(held && !target.dropItemToGround(held)) to_chat(user, span_warning("[held] is stuck to [target.p_their()] hand, you cannot grow a false armblade over it!")) return + ..() + log_combat(user, target, "stung", object = "false armblade sting") if(ismonkey(target)) to_chat(user, span_notice("Our genes cry out as we sting [target.name]!")) @@ -178,6 +183,7 @@ return changeling.can_absorb_dna(target) /datum/action/changeling/sting/extract_dna/sting_action(mob/user, mob/living/carbon/human/target) + ..() log_combat(user, target, "stung", "extraction sting") var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) if(!changeling.has_profile_with_dna(target.dna)) @@ -193,6 +199,7 @@ dna_cost = 2 /datum/action/changeling/sting/mute/sting_action(mob/user, mob/living/carbon/target) + ..() log_combat(user, target, "stung", "mute sting") target.adjust_silence(1 MINUTES) return TRUE @@ -215,6 +222,7 @@ user.balloon_alert(user, "robotic eyes!") return FALSE + ..() log_combat(user, target, "stung", "blind sting") to_chat(target, span_danger("Your eyes burn horrifically!")) eyes.apply_organ_damage(eyes.maxHealth * 0.8) @@ -232,6 +240,7 @@ dna_cost = 1 /datum/action/changeling/sting/lsd/sting_action(mob/user, mob/living/carbon/target) + ..() log_combat(user, target, "stung", "LSD sting") addtimer(CALLBACK(src, PROC_REF(hallucination_time), target), rand(30 SECONDS, 60 SECONDS)) return TRUE @@ -250,6 +259,7 @@ dna_cost = 2 /datum/action/changeling/sting/cryo/sting_action(mob/user, mob/target) + ..() log_combat(user, target, "stung", "cryo sting") if(target.reagents) target.reagents.add_reagent(/datum/reagent/consumable/frostoil, 30) diff --git a/code/modules/antagonists/changeling/powers/void_adaption.dm b/code/modules/antagonists/changeling/powers/void_adaption.dm new file mode 100644 index 00000000000000..76c0eeffc972de --- /dev/null +++ b/code/modules/antagonists/changeling/powers/void_adaption.dm @@ -0,0 +1,68 @@ +/datum/action/changeling/void_adaption + name = "Void Adaption" + desc = "We prepare our cells to resist the hostile environment outside of the station. We may freely travel wherever we wish." + helptext = "This ability is passive, and will automatically protect you in situations of extreme cold or vacuum, \ + as well as removing your need to breathe. While it is actively protecting you from temperature or pressure \ + it reduces your chemical regeneration rate." + owner_has_control = FALSE + dna_cost = 2 + + /// Traits we apply to become immune to the environment + var/static/list/gain_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD, TRAIT_RESISTLOWPRESSURE, TRAIT_SNOWSTORM_IMMUNE) + /// How much we slow chemical regeneration while active, in chems per second + var/recharge_slowdown = 0.25 + /// Are we currently protecting our user? + var/currently_active = FALSE + +/datum/action/changeling/void_adaption/on_purchase(mob/user, is_respec) + . = ..() + user.add_traits(gain_traits, REF(src)) + RegisterSignal(user, COMSIG_LIVING_LIFE, PROC_REF(check_environment)) + +/datum/action/changeling/void_adaption/Remove(mob/remove_from) + remove_from.remove_traits(gain_traits, REF(src)) + UnregisterSignal(remove_from, COMSIG_LIVING_LIFE) + if (currently_active) + on_removed_adaption(remove_from, "Our cells relax, despite the danger!") + return ..() + +/// Checks if we would be providing any useful benefit at present +/datum/action/changeling/void_adaption/proc/check_environment(mob/living/void_adapted) + SIGNAL_HANDLER + + var/list/active_reasons = list() + + var/datum/gas_mixture/environment = void_adapted.loc.return_air() + if (!isnull(environment)) + var/vulnerable_temperature = void_adapted.get_body_temp_cold_damage_limit() + var/affected_temperature = environment.return_temperature() + if (ishuman(void_adapted)) + var/mob/living/carbon/human/special_boy = void_adapted + var/cold_protection = special_boy.get_cold_protection(affected_temperature) + vulnerable_temperature *= (1 - cold_protection) + + var/affected_pressure = special_boy.calculate_affecting_pressure(environment.return_pressure()) + if (affected_pressure < HAZARD_LOW_PRESSURE) + active_reasons += "vacuum" + + if (affected_temperature < vulnerable_temperature) + active_reasons += "cold" + + var/should_be_active = !!length(active_reasons) + if (currently_active == should_be_active) + return + + if (!should_be_active) + on_removed_adaption(void_adapted, "Our cells relax in safer air.") + return + var/datum/antagonist/changeling/changeling_data = void_adapted.mind?.has_antag_datum(/datum/antagonist/changeling) + to_chat(void_adapted, span_changeling("Our cells harden themselves against the [pick(active_reasons)].")) + changeling_data?.chem_recharge_slowdown -= recharge_slowdown + currently_active = TRUE + +/// Called when we stop being adapted +/datum/action/changeling/void_adaption/proc/on_removed_adaption(mob/living/former, message) + var/datum/antagonist/changeling/changeling_data = former.mind?.has_antag_datum(/datum/antagonist/changeling) + to_chat(former, span_changeling(message)) + changeling_data?.chem_recharge_slowdown += recharge_slowdown + currently_active = FALSE diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm index dd5e9a9c6610f0..27a87bee6c2d11 100644 --- a/code/modules/antagonists/cult/blood_magic.dm +++ b/code/modules/antagonists/cult/blood_magic.dm @@ -720,11 +720,13 @@ human_bloodbag.visible_message(span_warning("[human_bloodbag] is partially healed by [human_bloodbag == user ? "[human_bloodbag.p_their()]":"[human_bloodbag]'s"] blood magic.")) uses = 0 ratio *= -1 - human_bloodbag.adjustOxyLoss((overall_damage*ratio) * (human_bloodbag.getOxyLoss() / overall_damage), 0) - human_bloodbag.adjustToxLoss((overall_damage*ratio) * (human_bloodbag.getToxLoss() / overall_damage), 0) - human_bloodbag.adjustFireLoss((overall_damage*ratio) * (human_bloodbag.getFireLoss() / overall_damage), 0) - human_bloodbag.adjustBruteLoss((overall_damage*ratio) * (human_bloodbag.getBruteLoss() / overall_damage), 0) - human_bloodbag.updatehealth() + var/need_mob_update = FALSE + need_mob_update += human_bloodbag.adjustOxyLoss((overall_damage*ratio) * (human_bloodbag.getOxyLoss() / overall_damage), updating_health = FALSE) + need_mob_update += human_bloodbag.adjustToxLoss((overall_damage*ratio) * (human_bloodbag.getToxLoss() / overall_damage), updating_health = FALSE) + need_mob_update += human_bloodbag.adjustFireLoss((overall_damage*ratio) * (human_bloodbag.getFireLoss() / overall_damage), updating_health = FALSE) + need_mob_update += human_bloodbag.adjustBruteLoss((overall_damage*ratio) * (human_bloodbag.getBruteLoss() / overall_damage), updating_health = FALSE) + if(need_mob_update) + human_bloodbag.updatehealth() playsound(get_turf(human_bloodbag), 'sound/magic/staff_healing.ogg', 25) new /obj/effect/temp_visual/cult/sparks(get_turf(human_bloodbag)) user.Beam(human_bloodbag, icon_state="sendbeam", time = 15) diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index b0d877820d903d..0f43b5ae29ef4d 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -23,7 +23,7 @@ /datum/antagonist/cult/greet() . = ..() - owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/bloodcult.ogg', 100, FALSE, pressure_affected = FALSE, use_reverb = FALSE)//subject to change + owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/bloodcult/bloodcult_gain.ogg', 100, FALSE, pressure_affected = FALSE, use_reverb = FALSE)//subject to change owner.announce_objectives() /datum/antagonist/cult/on_gain() diff --git a/code/modules/antagonists/cult/cult_bastard_sword.dm b/code/modules/antagonists/cult/cult_bastard_sword.dm index a30ffb1f5eede6..784eaedf636aca 100644 --- a/code/modules/antagonists/cult/cult_bastard_sword.dm +++ b/code/modules/antagonists/cult/cult_bastard_sword.dm @@ -80,7 +80,7 @@ to_chat(user, span_cultlarge("\"You cling to the Forgotten Gods, as if you're more than their pawn.\"")) to_chat(user, span_userdanger("A horrible force yanks at your arm!")) user.emote("scream") - user.apply_damage(30, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + user.apply_damage(30, BRUTE, pick(GLOB.arm_zones)) user.dropItemToGround(src, TRUE) user.Paralyze(50) return diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index c3175d0ed4ac32..e5adcf0cfc5ff9 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -100,7 +100,7 @@ Striking a noncultist, however, will tear their flesh."} span_cultlarge("\"You shouldn't play with sharp things. You'll poke someone's eye out.\"")) if(ishuman(user)) var/mob/living/carbon/human/miscreant = user - miscreant.apply_damage(rand(force/2, force), BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + miscreant.apply_damage(rand(force/2, force), BRUTE, pick(GLOB.arm_zones)) else user.adjustBruteLoss(rand(force/2,force)) return diff --git a/code/modules/antagonists/cult/cult_team.dm b/code/modules/antagonists/cult/cult_team.dm index 6254ded64a030f..1d199a113f5d24 100644 --- a/code/modules/antagonists/cult/cult_team.dm +++ b/code/modules/antagonists/cult/cult_team.dm @@ -48,7 +48,7 @@ if(ratio > CULT_RISEN && !cult_risen) for(var/datum/mind/mind as anything in members) if(mind.current) - SEND_SOUND(mind.current, 'sound/hallucinations/i_see_you2.ogg') + SEND_SOUND(mind.current, 'sound/ambience/antag/bloodcult/bloodcult_eyes.ogg') to_chat(mind.current, span_cultlarge(span_warning("The veil weakens as your cult grows, your eyes begin to glow..."))) mind.current.AddElement(/datum/element/cult_eyes) cult_risen = TRUE @@ -57,7 +57,7 @@ if(ratio > CULT_ASCENDENT && !cult_ascendent) for(var/datum/mind/mind as anything in members) if(mind.current) - SEND_SOUND(mind.current, 'sound/hallucinations/im_here1.ogg') + SEND_SOUND(mind.current, 'sound/ambience/antag/bloodcult/bloodcult_halos.ogg') to_chat(mind.current, span_cultlarge(span_warning("Your cult is ascendent and the red harvest approaches - you cannot hide your true nature for much longer!!"))) mind.current.AddElement(/datum/element/cult_halo) cult_ascendent = TRUE diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 3b2a13c2cb5947..1d514fe78307e8 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -370,7 +370,7 @@ structure_check() searches for nearby cultist structures required for the invoca if(sacrificial) playsound(sacrificial, 'sound/magic/disintegrate.ogg', 100, TRUE) sacrificial.investigate_log("has been sacrificially gibbed by the cult.", INVESTIGATE_DEATHS) - sacrificial.gib() + sacrificial.gib(DROP_ALL_REMAINS) return TRUE /obj/effect/rune/empower @@ -646,7 +646,7 @@ structure_check() searches for nearby cultist structures required for the invoca else fail_invoke() return - SEND_SOUND(mob_to_revive, 'sound/ambience/antag/bloodcult.ogg') + SEND_SOUND(mob_to_revive, 'sound/ambience/antag/bloodcult/bloodcult_gain.ogg') to_chat(mob_to_revive, span_cultlarge("\"PASNAR SAVRAE YAM'TOTH. Arise.\"")) mob_to_revive.visible_message(span_warning("[mob_to_revive] draws in a huge breath, red light shining from [mob_to_revive.p_their()] eyes."), \ span_cultlarge("You awaken suddenly from the void. You're alive!")) @@ -697,7 +697,7 @@ structure_check() searches for nearby cultist structures required for the invoca barrier.Toggle() if(iscarbon(user)) var/mob/living/carbon/C = user - C.apply_damage(2, BRUTE, pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + C.apply_damage(2, BRUTE, pick(GLOB.arm_zones)) //Rite of Joined Souls: Summons a single cultist. /obj/effect/rune/summon @@ -886,7 +886,7 @@ structure_check() searches for nearby cultist structures required for the invoca new_human.equipOutfit(/datum/outfit/ghost_cultist) //give them armor new_human.apply_status_effect(/datum/status_effect/cultghost) //ghosts can't summon more ghosts new_human.set_invis_see(SEE_INVISIBLE_OBSERVER) - ADD_TRAIT(new_human, TRAIT_NOBREATH, INNATE_TRAIT) + new_human.add_traits(list(TRAIT_NOBREATH, TRAIT_PERMANENTLY_MORTAL), INNATE_TRAIT) // permanently mortal can be removed once this is a bespoke kind of mob ghosts++ playsound(src, 'sound/magic/exit_blood.ogg', 50, TRUE) visible_message(span_warning("A cloud of red mist forms above [src], and from within steps... a [new_human.gender == FEMALE ? "wo":""]man.")) @@ -946,8 +946,8 @@ structure_check() searches for nearby cultist structures required for the invoca affecting = null rune_in_use = FALSE -/mob/living/carbon/human/cult_ghost/spill_organs(no_brain, no_organs, no_bodyparts) //cult ghosts never drop a brain - no_brain = TRUE +/mob/living/carbon/human/cult_ghost/spill_organs(drop_bitflags=NONE) + drop_bitflags &= ~DROP_BRAIN //cult ghosts never drop a brain . = ..() /mob/living/carbon/human/cult_ghost/get_organs_for_zone(zone, include_children) @@ -1017,7 +1017,7 @@ structure_check() searches for nearby cultist structures required for the invoca add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/noncult, "human_apoc", A, NONE) addtimer(CALLBACK(M, TYPE_PROC_REF(/atom/, remove_alt_appearance),"human_apoc",TRUE), duration) images += A - SEND_SOUND(M, pick(sound('sound/ambience/antag/bloodcult.ogg'),sound('sound/voice/ghost_whisper.ogg'),sound('sound/misc/ghosty_wind.ogg'))) + SEND_SOUND(M, pick(sound('sound/ambience/antag/bloodcult/bloodcult_gain.ogg'),sound('sound/voice/ghost_whisper.ogg'),sound('sound/misc/ghosty_wind.ogg'))) else var/construct = pick("wraith","artificer","juggernaut") var/image/B = image('icons/mob/nonhuman-player/cult.dmi',M,construct, ABOVE_MOB_LAYER) diff --git a/code/modules/antagonists/heretic/heretic_antag.dm b/code/modules/antagonists/heretic/heretic_antag.dm index 0120c3b7ee3a86..f0eff069e89ace 100644 --- a/code/modules/antagonists/heretic/heretic_antag.dm +++ b/code/modules/antagonists/heretic/heretic_antag.dm @@ -34,6 +34,8 @@ var/heretic_path = PATH_START /// A sum of how many knowledge points this heretic CURRENTLY has. Used to research. var/knowledge_points = 2 //SKYRAT EDIT - ORIGINAL 1 + /// How many side path points the heretic has. He gains one of these per main path that splits into two sidepaths. These can be used in place of knowledge points for side paths only. + var/side_path_points = 0 /// The time between gaining influence passively. The heretic gain +1 knowledge points every this duration of time. var/passive_gain_timer = 20 MINUTES /// Assoc list of [typepath] = [knowledge instance]. A list of all knowledge this heretic's reserached. @@ -85,6 +87,7 @@ var/list/data = list() data["charges"] = knowledge_points + data["side_charges"] = side_path_points data["total_sacrifices"] = total_sacrifices data["ascended"] = ascended @@ -98,7 +101,10 @@ knowledge_data["desc"] = initial(knowledge.desc) knowledge_data["gainFlavor"] = initial(knowledge.gain_text) knowledge_data["cost"] = initial(knowledge.cost) - knowledge_data["disabled"] = (initial(knowledge.cost) > knowledge_points) + if(initial(knowledge.route) == PATH_SIDE) + knowledge_data["disabled"] = (initial(knowledge.cost) > knowledge_points + side_path_points) + else + knowledge_data["disabled"] = (initial(knowledge.cost) > knowledge_points) // Final knowledge can't be learned until all objectives are complete. if(ispath(knowledge, /datum/heretic_knowledge/ultimate)) @@ -142,13 +148,22 @@ if(!ispath(researched_path)) CRASH("Heretic attempted to learn non-heretic_knowledge path! (Got: [researched_path])") - if(initial(researched_path.cost) > knowledge_points) - return TRUE + // If side path and has path points, buy! + var/coupon = FALSE + if((initial(researched_path.route) == PATH_SIDE) && side_path_points) + coupon = TRUE + // else try normal purchase + else if(initial(researched_path.cost) > knowledge_points) + return + if(!gain_knowledge(researched_path)) return TRUE - log_heretic_knowledge("[key_name(owner)] gained knowledge: [initial(researched_path.name)]") - knowledge_points -= initial(researched_path.cost) + log_heretic_knowledge("[key_name(owner)] gained knowledge: [initial(researched_path.name)][coupon ? "(via free side-path point)" : ""]") + if(coupon) + side_path_points -= initial(researched_path.cost) + else + knowledge_points -= initial(researched_path.cost) return TRUE /datum/antagonist/heretic/submit_player_objective(retain_existing = FALSE, retain_escape = TRUE, force = FALSE) @@ -305,14 +320,14 @@ * * drawing_time - how long the do_after takes to make the rune * * additional checks - optional callbacks to be ran while drawing the rune */ -/datum/antagonist/heretic/proc/try_draw_rune(mob/living/user, turf/target_turf, drawing_time = 30 SECONDS, additional_checks) +/datum/antagonist/heretic/proc/try_draw_rune(mob/living/user, turf/target_turf, drawing_time = 20 SECONDS, additional_checks) for(var/turf/nearby_turf as anything in RANGE_TURFS(1, target_turf)) if(!isopenturf(nearby_turf) || is_type_in_typecache(nearby_turf, blacklisted_rune_turfs)) target_turf.balloon_alert(user, "invalid placement for rune!") return if(locate(/obj/effect/heretic_rune) in range(3, target_turf)) - target_turf.balloon_alert(user, "to close to another rune!") + target_turf.balloon_alert(user, "too close to another rune!") return if(drawing_rune) @@ -330,16 +345,16 @@ * * drawing_time - how long the do_after takes to make the rune * * additional checks - optional callbacks to be ran while drawing the rune */ -/datum/antagonist/heretic/proc/draw_rune(mob/living/user, turf/target_turf, drawing_time = 30 SECONDS, additional_checks) +/datum/antagonist/heretic/proc/draw_rune(mob/living/user, turf/target_turf, drawing_time = 20 SECONDS, additional_checks) drawing_rune = TRUE var/rune_colour = path_to_rune_color[heretic_path] target_turf.balloon_alert(user, "drawing rune...") var/obj/effect/temp_visual/drawing_heretic_rune/drawing_effect - if (drawing_time >= (30 SECONDS)) - drawing_effect = new(target_turf, rune_colour) - else + if (drawing_time < (10 SECONDS)) drawing_effect = new /obj/effect/temp_visual/drawing_heretic_rune/fast(target_turf, rune_colour) + else + drawing_effect = new(target_turf, rune_colour) if(!do_after(user, drawing_time, target_turf, extra_checks = additional_checks)) target_turf.balloon_alert(user, "interrupted!") @@ -594,7 +609,7 @@ if(!admin.client?.holder) to_chat(admin, span_warning("You shouldn't be using this!")) return - + var/mob/living/pawn = owner.current pawn.equip_to_slot_if_possible(new /obj/item/clothing/neck/heretic_focus(get_turf(pawn)), ITEM_SLOT_NECK, TRUE, TRUE) to_chat(pawn, span_hypnophrase("The Mansus has manifested you a focus.")) @@ -766,8 +781,8 @@ target_amount = main_path_length // Add in the base research we spawn with, otherwise it'd be too easy. target_amount += length(GLOB.heretic_start_knowledge) - // And add in some buffer, to require some sidepathing. - target_amount += rand(2, 4) + // And add in some buffer, to require some sidepathing, especially since heretics get some free side paths. + target_amount += rand(5, 7) update_explanation_text() /datum/objective/heretic_research/update_explanation_text() diff --git a/code/modules/antagonists/heretic/heretic_focus.dm b/code/modules/antagonists/heretic/heretic_focus.dm index b7c79b6d6caa26..45bbf743b8cd11 100644 --- a/code/modules/antagonists/heretic/heretic_focus.dm +++ b/code/modules/antagonists/heretic/heretic_focus.dm @@ -46,7 +46,7 @@ if(!IS_HERETIC(user)) return - if(!(source.slot_flags & slot)) + if(source.slot_flags && !(source.slot_flags & slot)) return ADD_TRAIT(user, TRAIT_ALLOW_HERETIC_CASTING, ELEMENT_TRAIT(source)) diff --git a/code/modules/antagonists/heretic/heretic_knowledge.dm b/code/modules/antagonists/heretic/heretic_knowledge.dm index b51c2a5dcb87ba..1f408698f3cfa0 100644 --- a/code/modules/antagonists/heretic/heretic_knowledge.dm +++ b/code/modules/antagonists/heretic/heretic_knowledge.dm @@ -25,11 +25,16 @@ var/list/banned_knowledge = list() /// Assoc list of [typepaths we need] to [amount needed]. /// If set, this knowledge allows the heretic to do a ritual on a transmutation rune with the components set. + /// If one of the items in the list is a list, it's treated as 'any of these items will work' var/list/required_atoms /// Paired with above. If set, the resulting spawned atoms upon ritual completion. var/list/result_atoms = list() + /// If set, required_atoms checks for these *exact* types and doesn't allow them to be ingredients. + var/list/banned_atom_types = list() /// Cost of knowledge in knowledge points var/cost = 0 + /// If true, adds side path points according to value. Only main branch powers that split into sidepaths should have this. + var/adds_sidepath_points = 0 /// The priority of the knowledge. Higher priority knowledge appear higher in the ritual list. /// Number itself is completely arbitrary. Does not need to be set for non-ritual knowledge. var/priority = 0 @@ -58,6 +63,8 @@ if(gain_text) to_chat(user, span_warning("[gain_text]")) + // Usually zero + our_heretic.side_path_points += adds_sidepath_points on_gain(user, our_heretic) /** @@ -112,6 +119,18 @@ /datum/heretic_knowledge/proc/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc) return TRUE +/** + * Parses specific items into a more reaadble form. + * Can be overriden by knoweldge subtypes. + */ +/datum/heretic_knowledge/proc/parse_required_item(atom/item_path, number_of_things) + // If we need a human, there is a high likelihood we actually need a (dead) body + if(ispath(item_path, /mob/living/carbon/human)) + return "bod[number_of_things > 1 ? "ies" : "y"]" + if(ispath(item_path, /mob/living)) + return "carcass[number_of_things > 1 ? "es" : ""] of any kind" + return "[initial(item_path.name)]\s" + /** * Called whenever the knowledge's associated ritual is completed successfully. * @@ -158,9 +177,12 @@ var/obj/item/stack/sac_stack = sacrificed var/how_much_to_use = 0 for(var/requirement in required_atoms) - if(istype(sacrificed, requirement)) - how_much_to_use = min(required_atoms[requirement], sac_stack.amount) - break + if(islist(requirement) && !is_type_in_list(sacrificed, requirement)) + continue + if(!istype(sacrificed, requirement)) + continue + how_much_to_use = min(required_atoms[requirement], sac_stack.amount) + break sac_stack.use(how_much_to_use) continue @@ -264,7 +286,7 @@ /datum/heretic_knowledge/mark abstract_parent_type = /datum/heretic_knowledge/mark mutually_exclusive = TRUE - cost = 2 + cost = 1 /// The status effect typepath we apply on people on mansus grasp. var/datum/status_effect/eldritch/mark_type @@ -508,6 +530,7 @@ /datum/heretic_knowledge/summon/on_finished_recipe(mob/living/user, list/selected_atoms, turf/loc) var/mob/living/summoned = new mob_to_summon(loc) + summoned.ai_controller?.set_ai_status(AI_STATUS_OFF) // Fade in the summon while the ghost poll is ongoing. // Also don't let them mess with the summon while waiting summoned.alpha = 0 @@ -711,6 +734,6 @@ /datum/heretic_knowledge/ultimate/cleanup_atoms(list/selected_atoms) for(var/mob/living/carbon/human/sacrifice in selected_atoms) selected_atoms -= sacrifice - sacrifice.gib() + sacrifice.gib(DROP_ALL_REMAINS) return ..() diff --git a/code/modules/antagonists/heretic/heretic_living_heart.dm b/code/modules/antagonists/heretic/heretic_living_heart.dm index 4af93c0da68c80..1766cb4cd765e0 100644 --- a/code/modules/antagonists/heretic/heretic_living_heart.dm +++ b/code/modules/antagonists/heretic/heretic_living_heart.dm @@ -99,7 +99,7 @@ return TRUE -/datum/action/cooldown/track_target/Trigger(trigger_flags) +/datum/action/cooldown/track_target/Trigger(trigger_flags, atom/target) right_clicked = !!(trigger_flags & TRIGGER_SECONDARY_ACTION) return ..() diff --git a/code/modules/antagonists/heretic/influences.dm b/code/modules/antagonists/heretic/influences.dm index 503e066d0e39cd..74a851e7fb7ad4 100644 --- a/code/modules/antagonists/heretic/influences.dm +++ b/code/modules/antagonists/heretic/influences.dm @@ -177,7 +177,7 @@ head.dismember() qdel(head) else - human_user.gib() + human_user.gib(DROP_ALL_REMAINS) human_user.investigate_log("has died from using telekinesis on a heretic influence.", INVESTIGATE_DEATHS) var/datum/effect_system/reagents_explosion/explosion = new() explosion.set_up(1, get_turf(human_user), TRUE, 0) @@ -260,7 +260,8 @@ // Using a codex will give you two knowledge points for draining. if(!being_drained && istype(weapon, /obj/item/codex_cicatrix)) var/obj/item/codex_cicatrix/codex = weapon - codex.open_animation() + if(!codex.book_open) + codex.attack_self(user) // open booke INVOKE_ASYNC(src, PROC_REF(drain_influence), user, 2) return TRUE diff --git a/code/modules/antagonists/heretic/items/forbidden_book.dm b/code/modules/antagonists/heretic/items/forbidden_book.dm index 80721c97592a75..ff570801c5f1c4 100644 --- a/code/modules/antagonists/heretic/items/forbidden_book.dm +++ b/code/modules/antagonists/heretic/items/forbidden_book.dm @@ -9,8 +9,6 @@ w_class = WEIGHT_CLASS_SMALL /// Helps determine the icon state of this item when it's used on self. var/book_open = FALSE - /// id for timer - var/timer_id /obj/item/codex_cicatrix/Initialize(mapload) . = ..() @@ -31,6 +29,7 @@ . += span_notice("Can be used to tap influences for additional knowledge points.") . += span_notice("Can also be used to draw or remove transmutation runes with ease.") + . += span_notice("Additionally, it can work as a focus for your spells in a pinch, though a more specialized relic is recommended, as this may get dropped in combat.") /obj/item/codex_cicatrix/attack_self(mob/user, modifiers) . = ..() @@ -39,8 +38,12 @@ if(book_open) close_animation() + RemoveElement(/datum/element/heretic_focus) + w_class = WEIGHT_CLASS_SMALL else open_animation() + AddElement(/datum/element/heretic_focus) + w_class = WEIGHT_CLASS_NORMAL /obj/item/codex_cicatrix/afterattack(atom/target, mob/user, proximity_flag, click_parameters) . = ..() @@ -52,7 +55,7 @@ return if(isopenturf(target)) - heretic_datum.try_draw_rune(user, target, drawing_time = 12 SECONDS) + heretic_datum.try_draw_rune(user, target, drawing_time = 8 SECONDS) return TRUE /// Plays a little animation that shows the book opening and closing. @@ -61,12 +64,8 @@ flick("[base_icon_state]_opening", src) book_open = TRUE - timer_id = addtimer(CALLBACK(src, PROC_REF(close_animation)), 5 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) - /// Plays a closing animation and resets the icon state. /obj/item/codex_cicatrix/proc/close_animation() icon_state = base_icon_state flick("[base_icon_state]_closing", src) book_open = FALSE - - deltimer(timer_id) diff --git a/code/modules/antagonists/heretic/items/heretic_armor.dm b/code/modules/antagonists/heretic/items/heretic_armor.dm index 93ab613190b1cf..502c52c17fb89c 100644 --- a/code/modules/antagonists/heretic/items/heretic_armor.dm +++ b/code/modules/antagonists/heretic/items/heretic_armor.dm @@ -105,12 +105,12 @@ . = ..() UnregisterSignal(user, list(COMSIG_MOB_UNEQUIPPED_ITEM, COMSIG_MOB_EQUIPPED_ITEM)) -/obj/item/clothing/suit/hooded/cultrobes/void/proc/hide_item(obj/item/item, slot) +/obj/item/clothing/suit/hooded/cultrobes/void/proc/hide_item(datum/source, obj/item/item, slot) SIGNAL_HANDLER if(slot & ITEM_SLOT_SUITSTORE) ADD_TRAIT(item, TRAIT_NO_STRIP, REF(src)) // i'd use examine hide but its a flag and yeah -/obj/item/clothing/suit/hooded/cultrobes/void/proc/show_item(obj/item/item, slot) +/obj/item/clothing/suit/hooded/cultrobes/void/proc/show_item(datum/source, obj/item/item, slot) SIGNAL_HANDLER REMOVE_TRAIT(item, TRAIT_NO_STRIP, REF(src)) diff --git a/code/modules/antagonists/heretic/knowledge/ash_lore.dm b/code/modules/antagonists/heretic/knowledge/ash_lore.dm index df29ba9efa06ee..52e25f6a8b17b2 100644 --- a/code/modules/antagonists/heretic/knowledge/ash_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/ash_lore.dm @@ -72,9 +72,9 @@ name = "Ashen Passage" desc = "Grants you Ashen Passage, a silent but short range jaunt." gain_text = "He knew how to walk between the planes." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/mark/ash_mark, - /datum/heretic_knowledge/codex_cicatrix, /datum/heretic_knowledge/summon/fire_shark, /datum/heretic_knowledge/medallion, ) @@ -127,6 +127,7 @@ The mask instills fear into heathens who witness it, causing stamina damage, hallucinations, and insanity. \ It can also be forced onto a heathen, to make them unable to take it off..." gain_text = "The Nightwatcher was lost. That's what the Watch believed. Yet he walked the world, unnoticed by the masses." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/blade_upgrade/ash, /datum/heretic_knowledge/reroll_targets, @@ -165,6 +166,7 @@ If any victims afflicted are in critical condition, they will also instantly die." gain_text = "The fire was inescapable, and yet, life remained in his charred body. \ The Nightwatcher was a particular man, always watching." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/ultimate/ash_final, /datum/heretic_knowledge/summon/ashy, diff --git a/code/modules/antagonists/heretic/knowledge/blade_lore.dm b/code/modules/antagonists/heretic/knowledge/blade_lore.dm index 01358807fce23f..f2f3b156a2f70b 100644 --- a/code/modules/antagonists/heretic/knowledge/blade_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/blade_lore.dm @@ -13,6 +13,9 @@ * Mark of the Blade * Ritual of Knowledge * Realignment + * > Sidepaths: + * Lionhunter Rifle + * * Stance of the Scarred Duelist * > Sidepaths: * Carving Knife @@ -22,7 +25,7 @@ * Furious Steel * > Sidepaths: * Maid in the Mirror - * Lionhunter Rifle + * Rust Charge * * Maelstrom of Silver */ @@ -101,10 +104,10 @@ towards your attacker. This effect can only trigger once every 20 seconds." gain_text = "The footsoldier was known to be a fearsome duelist. \ Their general quickly appointed them as their personal Champion." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/limited_amount/risen_corpse, /datum/heretic_knowledge/mark/blade_mark, - /datum/heretic_knowledge/codex_cicatrix, /datum/heretic_knowledge/armor, ) cost = 1 @@ -243,6 +246,7 @@ you gain increased resistance to gaining wounds and resistance to batons." gain_text = "In time, it was he who stood alone among the bodies of his former comrades, awash in blood, none of it his own. \ He was without rival, equal, or purpose." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/blade_upgrade/blade, /datum/heretic_knowledge/reroll_targets, @@ -372,6 +376,7 @@ at a target, dealing damage and causing bleeding." gain_text = "Without thinking, I took the knife of a fallen soldier and threw with all my might. My aim was true! \ The Torn Champion smiled at their first taste of agony, and with a nod, their blades became my own." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/summon/maid_in_mirror, /datum/heretic_knowledge/ultimate/blade_final, diff --git a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm index 9e4d77bd95c920..4607d78ff5c865 100644 --- a/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/cosmic_lore.dm @@ -70,9 +70,9 @@ However, people with a star mark will get transported along with another person using the rune." gain_text = "The distant stars crept into my dreams, roaring and screaming without reason. \ I spoke, and heard my own words echoed back." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/mark/cosmic_mark, - /datum/heretic_knowledge/codex_cicatrix, /datum/heretic_knowledge/essence, /datum/heretic_knowledge/summon/fire_shark, ) @@ -114,6 +114,7 @@ desc = "Fires a projectile that moves very slowly and creates cosmic fields on impact. \ Anyone hit by the projectile will recieve burn damage, a knockdown, and give people in a three tile range a star mark." gain_text = "The Beast was behind me now at all times, with each sacrifice words of affirmation coursed through me." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/blade_upgrade/cosmic, /datum/heretic_knowledge/reroll_targets, @@ -160,8 +161,11 @@ combo_timer = addtimer(CALLBACK(src, PROC_REF(reset_combo), source), combo_duration, TIMER_STOPPABLE) var/mob/living/second_target_resolved = second_target?.resolve() var/mob/living/third_target_resolved = third_target?.resolve() - target.adjustFireLoss(4) - target.adjustCloneLoss(2) + var/need_mob_update = FALSE + need_mob_update += target.adjustFireLoss(4, updating_health = FALSE) + need_mob_update += target.adjustCloneLoss(2, updating_health = FALSE) + if(need_mob_update) + target.updatehealth() if(target == second_target_resolved || target == third_target_resolved) reset_combo(source) return @@ -170,13 +174,19 @@ if(second_target_resolved) new /obj/effect/temp_visual/cosmic_explosion(get_turf(second_target_resolved)) playsound(get_turf(second_target_resolved), 'sound/magic/cosmic_energy.ogg', 25, FALSE) - second_target_resolved.adjustFireLoss(10) - second_target_resolved.adjustCloneLoss(6) + need_mob_update = FALSE + need_mob_update += second_target_resolved.adjustFireLoss(10, updating_health = FALSE) + need_mob_update += second_target_resolved.adjustCloneLoss(6, updating_health = FALSE) + if(need_mob_update) + target.updatehealth() if(third_target_resolved) new /obj/effect/temp_visual/cosmic_domain(get_turf(third_target_resolved)) playsound(get_turf(third_target_resolved), 'sound/magic/cosmic_energy.ogg', 50, FALSE) - third_target_resolved.adjustFireLoss(20) - third_target_resolved.adjustCloneLoss(12) + need_mob_update = FALSE + need_mob_update += third_target_resolved.adjustFireLoss(20, updating_health = FALSE) + need_mob_update += third_target_resolved.adjustCloneLoss(12, updating_health = FALSE) + if(need_mob_update) + target.updatehealth() if(combo_counter > 3) target.apply_status_effect(/datum/status_effect/star_mark, source) if(target.mind && target.stat != DEAD) @@ -208,6 +218,7 @@ desc = "Grants you Cosmic Expansion, a spell that creates a 3x3 area of cosmic fields around you. \ Nearby beings will also receive a star mark." gain_text = "The ground now shook beneath me. The Beast inhabited me, and their voice was intoxicating." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/ultimate/cosmic_final, /datum/heretic_knowledge/eldritch_coin, @@ -253,7 +264,7 @@ var/mob/living/basic/heretic_summon/star_gazer/star_gazer_mob = new /mob/living/basic/heretic_summon/star_gazer(loc) star_gazer_mob.maxHealth = INFINITY star_gazer_mob.health = INFINITY - user.AddElement(/datum/element/death_linked, star_gazer_mob) + user.AddComponent(/datum/component/death_linked, star_gazer_mob) star_gazer_mob.AddComponent(/datum/component/obeys_commands, star_gazer_commands) star_gazer_mob.AddComponent(/datum/component/damage_aura, range = 7, burn_damage = 0.5, simple_damage = 0.5, immune_factions = list(FACTION_HERETIC), current_owner = user) star_gazer_mob.befriend(user) diff --git a/code/modules/antagonists/heretic/knowledge/flesh_lore.dm b/code/modules/antagonists/heretic/knowledge/flesh_lore.dm index 07fa27181859a2..f3f6d971353810 100644 --- a/code/modules/antagonists/heretic/knowledge/flesh_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/flesh_lore.dm @@ -126,9 +126,9 @@ Voiceless Dead are mute ghouls and only have 50 health, but can use Bloody Blades effectively. \ You can only create two at a time." gain_text = "I found notes of a dark ritual, unfinished... yet still, I pushed forward." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/mark/flesh_mark, - /datum/heretic_knowledge/codex_cicatrix, /datum/heretic_knowledge/void_cloak, /datum/heretic_knowledge/medallion, ) @@ -239,6 +239,7 @@ the ability to link minds to communicate with ease, but are very fragile and weak in combat." gain_text = "I could not continue alone. I was able to summon The Uncanny Man to help me see more. \ The screams... once constant, now silenced by their wretched appearance. Nothing was out of reach." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/blade_upgrade/flesh, /datum/heretic_knowledge/reroll_targets, @@ -250,7 +251,7 @@ /obj/effect/decal/cleanable/blood = 1, /obj/item/bodypart/arm/left = 1, ) - mob_to_summon = /mob/living/simple_animal/hostile/heretic_summon/raw_prophet + mob_to_summon = /mob/living/basic/heretic_summon/raw_prophet cost = 1 route = PATH_FLESH poll_ignore_define = POLL_IGNORE_RAW_PROPHET @@ -280,6 +281,7 @@ Stalkers can jaunt, release EMPs, shapeshift into animals or automatons, and are strong in combat." gain_text = "I was able to combine my greed and desires to summon an eldritch beast I had never seen before. \ An ever shapeshifting mass of flesh, it knew well my goals. The Marshal approved." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/ultimate/flesh_final, /datum/heretic_knowledge/summon/ashy, @@ -292,7 +294,7 @@ /obj/item/pen = 1, /obj/item/paper = 1, ) - mob_to_summon = /mob/living/simple_animal/hostile/heretic_summon/stalker + mob_to_summon = /mob/living/basic/heretic_summon/stalker cost = 1 route = PATH_FLESH poll_ignore_define = POLL_IGNORE_STALKER diff --git a/code/modules/antagonists/heretic/knowledge/general_side.dm b/code/modules/antagonists/heretic/knowledge/general_side.dm index 9c3fbe9d447f36..2dc2719227b1c1 100644 --- a/code/modules/antagonists/heretic/knowledge/general_side.dm +++ b/code/modules/antagonists/heretic/knowledge/general_side.dm @@ -39,19 +39,3 @@ return FALSE return TRUE - -/datum/heretic_knowledge/codex_cicatrix - name = "Codex Cicatrix" - desc = "Allows you to transmute a bible, a fountain pen, and hide from an animal (or human) to create a Codex Cicatrix. \ - The Codex Cicatrix can be used when draining influences to gain additional knowledge, but comes at greater risk of being noticed. \ - It can also be used to draw and remove transmutation runes easier." - gain_text = "The occult leaves fragments of knowledge and power anywhere and everywhere. The Codex Cicatrix is one such example. \ - Within the leather-bound faces and age old pages, a path into the Mansus is revealed." - required_atoms = list( - /obj/item/book/bible = 1, - /obj/item/pen/fountain = 1, - /obj/item/stack/sheet/animalhide = 1, - ) - result_atoms = list(/obj/item/codex_cicatrix) - cost = 1 - route = PATH_SIDE diff --git a/code/modules/antagonists/heretic/knowledge/knock_lore.dm b/code/modules/antagonists/heretic/knowledge/knock_lore.dm index fcb2c6ceb4c989..6879f527b6b8b4 100644 --- a/code/modules/antagonists/heretic/knowledge/knock_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/knock_lore.dm @@ -70,7 +70,7 @@ /datum/heretic_knowledge/knock_grasp/proc/on_secondary_mansus_grasp(mob/living/source, atom/target) SIGNAL_HANDLER - + if(ismecha(target)) var/obj/vehicle/sealed/mecha/mecha = target mecha.dna_lock = null @@ -89,7 +89,7 @@ var/turf/target_turf = get_turf(target) SEND_SIGNAL(target_turf, COMSIG_ATOM_MAGICALLY_UNLOCKED, src, source) playsound(target, 'sound/magic/hereticknock.ogg', 100, TRUE, -1) - + return COMPONENT_USE_HAND /datum/heretic_knowledge/key_ring @@ -99,6 +99,7 @@ You can use it in-hand to change its form to a card you fused. \ Does not preserve the card used in the ritual." gain_text = "Gateways shall open before me, my very will ensnaring reality." + adds_sidepath_points = 1 required_atoms = list( /obj/item/storage/wallet = 1, /obj/item/stack/rods = 1, @@ -143,6 +144,7 @@ desc = "Grants you Burglar's Finesse, a single-target spell \ that puts a random item from the victims backpack into your hand." gain_text = "Their trinkets will be mine, as will their lives in due time." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/spell/apetra_vulnera, /datum/heretic_knowledge/spell/opening_blast, @@ -171,6 +173,7 @@ While in refuge, you cannot use your hands or spells, and you are immune to slowdown. \ You are invincible but unable to harm anything. Cancelled by being hit with an anti-magic item." gain_text = "Then I saw my my own reflection cascaded mind-numbingly enough times that I was but a haze." + adds_sidepath_points = 1 next_knowledge = list(/datum/heretic_knowledge/ultimate/knock_final) route = PATH_KNOCK spell_to_add = /datum/action/cooldown/spell/caretaker diff --git a/code/modules/antagonists/heretic/knowledge/rust_lore.dm b/code/modules/antagonists/heretic/knowledge/rust_lore.dm index bbb98f84bd6bf7..84f128b5cfcf9f 100644 --- a/code/modules/antagonists/heretic/knowledge/rust_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/rust_lore.dm @@ -13,6 +13,9 @@ * Mark of Rust * Ritual of Knowledge * Rust Construction + * > Sidepaths: + * Lionhunter Rifle + * * Aggressive Spread * > Sidepaths: * Curse of Corrosion @@ -22,7 +25,7 @@ * Entropic Plume * > Sidepaths: * Rusted Ritual - * Blood Cleave + * Rust Charge * * Rustbringer's Oath */ @@ -80,9 +83,9 @@ name = "Leeching Walk" desc = "Grants you passive healing and resistance to batons while standing over rust." gain_text = "The speed was unparalleled, the strength unnatural. The Blacksmith was smiling." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/mark/rust_mark, - /datum/heretic_knowledge/codex_cicatrix, /datum/heretic_knowledge/armor, /datum/heretic_knowledge/essence, /datum/heretic_knowledge/entropy_pulse, @@ -126,11 +129,14 @@ return // Heals all damage + Stamina - source.adjustBruteLoss(-2, FALSE) - source.adjustFireLoss(-2, FALSE) - source.adjustToxLoss(-2, FALSE, forced = TRUE) // Slimes are people to - source.adjustOxyLoss(-0.5, FALSE) - source.adjustStaminaLoss(-2) + var/need_mob_update = FALSE + need_mob_update += source.adjustBruteLoss(-2, updating_health = FALSE) + need_mob_update += source.adjustFireLoss(-2, updating_health = FALSE) + need_mob_update += source.adjustToxLoss(-2, updating_health = FALSE, forced = TRUE) // Slimes are people too + need_mob_update += source.adjustOxyLoss(-0.5, updating_health = FALSE) + need_mob_update += source.adjustStaminaLoss(-2, updating_stamina = FALSE) + if(need_mob_update) + source.updatehealth() // Reduces duration of stuns/etc source.AdjustAllImmobility(-0.5 SECONDS) // Heals blood loss @@ -169,6 +175,7 @@ desc = "Grants you Aggressive Spread, a spell that spreads rust to nearby surfaces. \ Already rusted surfaces are destroyed." gain_text = "All wise men know well not to visit the Rusted Hills... Yet the Blacksmith's tale was inspiring." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/blade_upgrade/rust, /datum/heretic_knowledge/reroll_targets, @@ -198,6 +205,7 @@ at friend or foe wildly. Also rusts and destroys and surfaces it hits." gain_text = "The corrosion was unstoppable. The rust was unpleasable. \ The Blacksmith was gone, and you hold their blade. Champions of hope, the Rustbringer is nigh!" + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/ultimate/rust_final, /datum/heretic_knowledge/summon/rusty, @@ -295,11 +303,14 @@ if(!HAS_TRAIT(our_turf, TRAIT_RUSTY)) return - source.adjustBruteLoss(-4, FALSE) - source.adjustFireLoss(-4, FALSE) - source.adjustToxLoss(-4, FALSE, forced = TRUE) - source.adjustOxyLoss(-4, FALSE) - source.adjustStaminaLoss(-20) + var/need_mob_update = FALSE + need_mob_update += source.adjustBruteLoss(-4, updating_health = FALSE) + need_mob_update += source.adjustFireLoss(-4, updating_health = FALSE) + need_mob_update += source.adjustToxLoss(-4, updating_health = FALSE, forced = TRUE) + need_mob_update += source.adjustOxyLoss(-4, updating_health = FALSE) + need_mob_update += source.adjustStaminaLoss(-20, updating_stamina = FALSE) + if(need_mob_update) + source.updatehealth() /** * #Rust spread datum diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm index 0d2b67daae8eb9..50aaad96cd8777 100644 --- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm +++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_buff.dm @@ -27,7 +27,7 @@ /datum/status_effect/unholy_determination/tick(seconds_between_ticks) // The amount we heal of each damage type per tick. If we're missing legs we heal better because we can't dodge. - var/healing_amount = 1 + (2 - owner.usable_legs) + var/healing_amount = (0.4 + (0.8 - owner.usable_legs)) // In softcrit you're, strong enough to stay up. if(owner.health <= owner.crit_threshold && owner.health >= owner.hardcrit_threshold) @@ -48,22 +48,25 @@ if(prob(2)) playsound(owner, pick(GLOB.creepy_ambience), 50, TRUE) - adjust_all_damages(healing_amount) + adjust_all_damages(healing_amount, seconds_between_ticks) adjust_temperature() adjust_bleed_wounds() /* * Heals up all the owner a bit, fire stacks and losebreath included. */ -/datum/status_effect/unholy_determination/proc/adjust_all_damages(amount) +/datum/status_effect/unholy_determination/proc/adjust_all_damages(amount, seconds_between_ticks) owner.adjust_fire_stacks(-1) owner.losebreath = max(owner.losebreath - 0.5, 0) - owner.adjustToxLoss(-amount, FALSE, TRUE) - owner.adjustOxyLoss(-amount, FALSE) - owner.adjustBruteLoss(-amount, FALSE) - owner.adjustFireLoss(-amount) + var/need_mob_update = FALSE + need_mob_update += owner.adjustToxLoss(-amount * seconds_between_ticks, updating_health = FALSE, forced = TRUE) + need_mob_update += owner.adjustOxyLoss(-amount * seconds_between_ticks, updating_health = FALSE) + need_mob_update += owner.adjustBruteLoss(-amount * seconds_between_ticks, updating_health = FALSE) + need_mob_update += owner.adjustFireLoss(-amount * seconds_between_ticks, updating_health = FALSE) + if(need_mob_update) + owner.updatehealth() /* * Adjust the owner's temperature up or down to standard body temperatures. diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm index 3e37c17392361f..e2887d737579ed 100644 --- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm +++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm @@ -492,7 +492,7 @@ /datum/heretic_knowledge/hunt_and_sacrifice/proc/disembowel_target(mob/living/carbon/human/sac_target) if(heretic_mind) log_combat(heretic_mind.current, sac_target, "disemboweled via sacrifice") - sac_target.spill_organs() + sac_target.spill_organs(DROP_ALL_REMAINS) sac_target.apply_damage(250, BRUTE) if(sac_target.stat != DEAD) sac_target.investigate_log("has been killed by heretic sacrifice.", INVESTIGATE_DEATHS) diff --git a/code/modules/antagonists/heretic/knowledge/side_ash_flesh.dm b/code/modules/antagonists/heretic/knowledge/side_ash_flesh.dm index f7f3c175b2fb05..bf840d6ed27ea8 100644 --- a/code/modules/antagonists/heretic/knowledge/side_ash_flesh.dm +++ b/code/modules/antagonists/heretic/knowledge/side_ash_flesh.dm @@ -71,7 +71,7 @@ /obj/item/bodypart/head = 1, /obj/item/book = 1, ) - mob_to_summon = /mob/living/simple_animal/hostile/heretic_summon/ash_spirit + mob_to_summon = /mob/living/basic/heretic_summon/ash_spirit cost = 1 route = PATH_SIDE poll_ignore_define = POLL_IGNORE_ASH_SPIRIT diff --git a/code/modules/antagonists/heretic/knowledge/side_blade_rust.dm b/code/modules/antagonists/heretic/knowledge/side_blade_rust.dm index a8fb031fed2626..d7dfd75a144621 100644 --- a/code/modules/antagonists/heretic/knowledge/side_blade_rust.dm +++ b/code/modules/antagonists/heretic/knowledge/side_blade_rust.dm @@ -46,8 +46,8 @@ gain_text = "I met an old man in an anique shop who wielded a very unusual weapon. \ I could not purchase it at the time, but they showed me how they made it ages ago." next_knowledge = list( - /datum/heretic_knowledge/spell/furious_steel, - /datum/heretic_knowledge/spell/entropic_plume, + /datum/heretic_knowledge/spell/realignment, + /datum/heretic_knowledge/spell/rust_construction, /datum/heretic_knowledge/rifle_ammo, ) required_atoms = list( @@ -100,6 +100,10 @@ name = "Rust Charge" desc = "A charge that must be started on a rusted tile and will destroy any rusted objects you come into contact with, will deal high damage to others and rust around you during the charge." gain_text = "The hills sparkled now, as I neared them my mind began to wander. I quickly regained my resolve and pushed forward, this last leg would be the most treacherous." + next_knowledge = list( + /datum/heretic_knowledge/spell/furious_steel, + /datum/heretic_knowledge/spell/entropic_plume, + ) spell_to_add = /datum/action/cooldown/mob_cooldown/charge/rust cost = 1 route = PATH_SIDE diff --git a/code/modules/antagonists/heretic/knowledge/side_rust_cosmos.dm b/code/modules/antagonists/heretic/knowledge/side_rust_cosmos.dm index 8aecfe06e1f163..2dbb44ea4eb7ed 100644 --- a/code/modules/antagonists/heretic/knowledge/side_rust_cosmos.dm +++ b/code/modules/antagonists/heretic/knowledge/side_rust_cosmos.dm @@ -88,7 +88,7 @@ /obj/item/book = 1, /obj/item/bodypart/head = 1, ) - mob_to_summon = /mob/living/simple_animal/hostile/heretic_summon/rust_spirit + mob_to_summon = /mob/living/basic/heretic_summon/rust_walker cost = 1 route = PATH_SIDE poll_ignore_define = POLL_IGNORE_RUST_SPIRIT diff --git a/code/modules/antagonists/heretic/knowledge/side_void_blade.dm b/code/modules/antagonists/heretic/knowledge/side_void_blade.dm index 92e6e381222e47..643fd434af7b5a 100644 --- a/code/modules/antagonists/heretic/knowledge/side_void_blade.dm +++ b/code/modules/antagonists/heretic/knowledge/side_void_blade.dm @@ -159,5 +159,5 @@ ) cost = 1 route = PATH_SIDE - mob_to_summon = /mob/living/simple_animal/hostile/heretic_summon/maid_in_the_mirror + mob_to_summon = /mob/living/basic/heretic_summon/maid_in_the_mirror poll_ignore_define = POLL_IGNORE_MAID_IN_MIRROR diff --git a/code/modules/antagonists/heretic/knowledge/starting_lore.dm b/code/modules/antagonists/heretic/knowledge/starting_lore.dm index 8f36b8665100bd..eb766392290b37 100644 --- a/code/modules/antagonists/heretic/knowledge/starting_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/starting_lore.dm @@ -212,3 +212,79 @@ GLOBAL_LIST_INIT(heretic_start_knowledge, initialize_starting_knowledge()) spell_to_add = /datum/action/cooldown/spell/shadow_cloak cost = 0 route = PATH_START + +/** + * Codex Cicatrixi is available at the start: + * This allows heretics to choose if they want to rush all the influences and take them stealthily, or + * Construct a codex and take what's left with more points. + * Another downside to having the book is strip searches, which means that it's not just a free nab, at least until you get exposed - and when you do, you'll probably need the faster drawing speed. + * Overall, it's a tradeoff between speed and stealth or power. + */ +/datum/heretic_knowledge/codex_cicatrix + name = "Codex Cicatrix" + desc = "Allows you to transmute a book, any unique pen (anything but generic pens), and your pick from any carcass (animal or human), leather, or hide to create a Codex Cicatrix. \ + The Codex Cicatrix can be used when draining influences to gain additional knowledge, but comes at greater risk of being noticed. \ + It can also be used to draw and remove transmutation runes easier, and as a spell focus in a pinch." + gain_text = "The occult leaves fragments of knowledge and power anywhere and everywhere. The Codex Cicatrix is one such example. \ + Within the leather-bound faces and age old pages, a path into the Mansus is revealed." + required_atoms = list( + /obj/item/book = 1, + /obj/item/pen = 1, + list(/mob/living, /obj/item/stack/sheet/leather, /obj/item/stack/sheet/animalhide) = 1, + ) + banned_atom_types = list(/obj/item/pen) + result_atoms = list(/obj/item/codex_cicatrix) + cost = 1 + route = PATH_START + priority = MAX_KNOWLEDGE_PRIORITY - 3 // Least priority out of the starting knowledges, as it's an optional boon. + +/datum/heretic_knowledge/codex_cicatrix/parse_required_item(atom/item_path, number_of_things) + if(item_path == /obj/item/pen) + return "unique type of pen" + return ..() + +/datum/heretic_knowledge/codex_cicatrix/recipe_snowflake_check(mob/living/user, list/atoms, list/selected_atoms, turf/loc) + . = ..() + if(!.) + return FALSE + + for(var/mob/living/body in atoms) + if(body.stat != DEAD) + continue + + selected_atoms += body + return TRUE + return FALSE + +/datum/heretic_knowledge/codex_cicatrix/cleanup_atoms(list/selected_atoms) + var/mob/living/body = locate() in selected_atoms + if(!body) + return + // A golem or an android doesn't have skin! + var/exterior_text = "skin" + // If carbon, it's the limb. If not, it's the body. + var/ripped_thing = body + + // We will check if it's a carbon's body. + // If it is, we will damage a random bodypart, and check that bodypart for its body type, to select between 'skin' or 'exterior'. + if(iscarbon(body)) + var/mob/living/carbon/carbody = body + var/obj/item/bodypart/bodypart = pick(carbody.bodyparts) + ripped_thing = bodypart + bodypart.receive_damage(25, sharpness = SHARP_EDGED) + if(!(bodypart.bodytype & BODYTYPE_ORGANIC)) + exterior_text = "exterior" + else + // If it is not a carbon mob, we will just check biotypes and damage it directly. + if(body.mob_biotypes & (MOB_MINERAL|MOB_ROBOTIC)) + exterior_text = "exterior" + body.apply_damage(25, BRUTE) + + // Procure book for flavor text. This is why we call parent at the end. + var/obj/item/book/le_book = locate() in selected_atoms + if(!le_book) + stack_trace("Somehow, no book in codex cicatrix selected atoms! [english_list(selected_atoms)]") + playsound(body, 'sound/items/poster_ripped.ogg', 100, TRUE) + body.do_jitter_animation() + body.visible_message(span_danger("An awful ripping sound is heard as [ripped_thing]'s [exterior_text] is ripped straight out, wrapping around [le_book || "the book"], turning into an eldritch shade of blue!")) + return ..() diff --git a/code/modules/antagonists/heretic/knowledge/void_lore.dm b/code/modules/antagonists/heretic/knowledge/void_lore.dm index 57db8636818382..a5e21472517f37 100644 --- a/code/modules/antagonists/heretic/knowledge/void_lore.dm +++ b/code/modules/antagonists/heretic/knowledge/void_lore.dm @@ -81,9 +81,9 @@ You can still take damage due to a lack of pressure." gain_text = "I found a thread of cold breath. It lead me to a strange shrine, all made of crystals. \ Translucent and white, a depiction of a nobleman stood before me." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/mark/void_mark, - /datum/heretic_knowledge/codex_cicatrix, /datum/heretic_knowledge/void_cloak, /datum/heretic_knowledge/limited_amount/risen_corpse, ) @@ -127,6 +127,7 @@ Additionally causes damage to heathens around your original and target destination." gain_text = "The entity calls themself the Aristocrat. They effortlessly walk through air like \ nothing - leaving a harsh, cold breeze in their wake. They disappear, and I am left in the blizzard." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/blade_upgrade/void, /datum/heretic_knowledge/reroll_targets, @@ -161,6 +162,7 @@ desc = "Grants you Void Pull, a spell that pulls all nearby heathens towards you, stunning them briefly." gain_text = "All is fleeting, but what else stays? I'm close to ending what was started. \ The Aristocrat reveals themselves to me again. They tell me I am late. Their pull is immense, I cannot turn back." + adds_sidepath_points = 1 next_knowledge = list( /datum/heretic_knowledge/ultimate/void_final, /datum/heretic_knowledge/spell/cleave, diff --git a/code/modules/antagonists/heretic/magic/ascended_shapeshift.dm b/code/modules/antagonists/heretic/magic/ascended_shapeshift.dm index 4395b4a54b340c..f1d6de56e399f4 100644 --- a/code/modules/antagonists/heretic/magic/ascended_shapeshift.dm +++ b/code/modules/antagonists/heretic/magic/ascended_shapeshift.dm @@ -6,10 +6,10 @@ cooldown_time = 20 SECONDS die_with_shapeshifted_form = FALSE possible_shapes = list( - /mob/living/simple_animal/hostile/heretic_summon/raw_prophet, - /mob/living/simple_animal/hostile/heretic_summon/rust_spirit, - /mob/living/simple_animal/hostile/heretic_summon/ash_spirit, - /mob/living/simple_animal/hostile/heretic_summon/stalker, + /mob/living/basic/heretic_summon/ash_spirit, + /mob/living/basic/heretic_summon/raw_prophet/ascended, + /mob/living/basic/heretic_summon/rust_walker, + /mob/living/basic/heretic_summon/stalker, ) /datum/action/cooldown/spell/shapeshift/eldritch/ascension/do_shapeshift(mob/living/caster) diff --git a/code/modules/antagonists/heretic/magic/flesh_ascension.dm b/code/modules/antagonists/heretic/magic/flesh_ascension.dm index cb9ab63e031e14..d086c1127fcf00 100644 --- a/code/modules/antagonists/heretic/magic/flesh_ascension.dm +++ b/code/modules/antagonists/heretic/magic/flesh_ascension.dm @@ -13,7 +13,7 @@ invocation_type = INVOCATION_SHOUT spell_requirements = NONE - possible_shapes = list(/mob/living/simple_animal/hostile/heretic_summon/armsy/prime) + possible_shapes = list(/mob/living/basic/heretic_summon/armsy) /// The length of our new wormy when we shed. var/segment_length = 10 @@ -35,32 +35,11 @@ return ..() -/datum/action/cooldown/spell/shapeshift/shed_human_form/do_unshapeshift(mob/living/simple_animal/hostile/heretic_summon/armsy/caster) +/datum/action/cooldown/spell/shapeshift/shed_human_form/do_unshapeshift(mob/living/basic/heretic_summon/armsy/caster) if(istype(caster)) - segment_length = caster.get_length() + segment_length = caster.get_length() - 1 // Don't count the head return ..() /datum/action/cooldown/spell/shapeshift/shed_human_form/create_shapeshift_mob(atom/loc) return new shapeshift_type(loc, TRUE, segment_length) - -/datum/action/cooldown/spell/worm_contract - name = "Force Contract" - desc = "Forces your body to contract onto a single tile." - background_icon_state = "bg_heretic" - overlay_icon_state = "bg_heretic_border" - button_icon = 'icons/mob/actions/actions_ecult.dmi' - button_icon_state = "worm_contract" - - school = SCHOOL_FORBIDDEN - cooldown_time = 30 SECONDS - - invocation_type = INVOCATION_NONE - spell_requirements = NONE - -/datum/action/cooldown/spell/worm_contract/is_valid_target(atom/cast_on) - return istype(cast_on, /mob/living/simple_animal/hostile/heretic_summon/armsy) - -/datum/action/cooldown/spell/worm_contract/cast(mob/living/simple_animal/hostile/heretic_summon/armsy/cast_on) - . = ..() - cast_on.contract_next_chain_into_single_tile() diff --git a/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm b/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm index 1e65ef88951c78..64638d7103b17b 100644 --- a/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm +++ b/code/modules/antagonists/heretic/magic/nightwatcher_rebirth.dm @@ -46,11 +46,14 @@ victim.apply_damage(20, BURN) // Heal the caster for every victim damaged - caster.adjustBruteLoss(-10, FALSE) - caster.adjustFireLoss(-10, FALSE) - caster.adjustToxLoss(-10, FALSE) - caster.adjustOxyLoss(-10, FALSE) - caster.adjustStaminaLoss(-10) + var/need_mob_update = FALSE + need_mob_update += caster.adjustBruteLoss(-10, updating_health = FALSE) + need_mob_update += caster.adjustFireLoss(-10, updating_health = FALSE) + need_mob_update += caster.adjustToxLoss(-10, updating_health = FALSE) + need_mob_update += caster.adjustOxyLoss(-10, updating_health = FALSE) + need_mob_update += caster.adjustStaminaLoss(-10, updating_stamina = FALSE) + if(need_mob_update) + caster.updatehealth() /obj/effect/temp_visual/eldritch_smoke icon = 'icons/effects/eldritch.dmi' diff --git a/code/modules/antagonists/heretic/magic/star_touch.dm b/code/modules/antagonists/heretic/magic/star_touch.dm index de3a56128de91b..f2f2c935bbfd87 100644 --- a/code/modules/antagonists/heretic/magic/star_touch.dm +++ b/code/modules/antagonists/heretic/magic/star_touch.dm @@ -73,11 +73,13 @@ /obj/item/melee/touch_attack/star_touch/Initialize(mapload) . = ..() - AddComponent(/datum/component/effect_remover, \ + AddComponent(\ + /datum/component/effect_remover, \ success_feedback = "You remove %THEEFFECT.", \ tip_text = "Clear rune", \ on_clear_callback = CALLBACK(src, PROC_REF(after_clear_rune)), \ - effects_we_clear = list(/obj/effect/cosmic_rune)) + effects_we_clear = list(/obj/effect/cosmic_rune), \ + ) /* * Callback for effect_remover component. @@ -231,16 +233,16 @@ /datum/status_effect/cosmic_beam/proc/on_beam_hit(mob/living/target) if(!istype(target, /mob/living/basic/heretic_summon/star_gazer)) target.AddElement(/datum/element/effect_trail, /obj/effect/forcefield/cosmic_field/fast) - return /// What to process when the beam is connected to a target /datum/status_effect/cosmic_beam/proc/on_beam_tick(mob/living/target) - target.adjustFireLoss(3) - target.adjustCloneLoss(1) - return + var/need_mob_update + need_mob_update = target.adjustFireLoss(3, updating_health = FALSE) + need_mob_update += target.adjustCloneLoss(1, updating_health = FALSE) + if(need_mob_update) + target.updatehealth() /// What to remove when the beam disconnects from a target /datum/status_effect/cosmic_beam/proc/on_beam_release(mob/living/target) if(!istype(target, /mob/living/basic/heretic_summon/star_gazer)) target.RemoveElement(/datum/element/effect_trail, /obj/effect/forcefield/cosmic_field/fast) - return diff --git a/code/modules/antagonists/heretic/structures/knock_final.dm b/code/modules/antagonists/heretic/structures/knock_final.dm index 85face85609586..f7d0d1a9ea7b00 100644 --- a/code/modules/antagonists/heretic/structures/knock_final.dm +++ b/code/modules/antagonists/heretic/structures/knock_final.dm @@ -5,39 +5,67 @@ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF icon = 'icons/obj/anomaly.dmi' icon_state = "bhole3" - color = "#53277E" - light_color = "#53277E" //cooler purple + color = COLOR_VOID_PURPLE + light_color = COLOR_VOID_PURPLE light_range = 20 anchored = TRUE density = FALSE layer = HIGH_PIPE_LAYER //0.01 above sigil layer used by heretic runes move_resist = INFINITY + /// Who is our daddy? var/datum/mind/ascendee - ///a static list of heretic summons, this shouldnt even matter enough to be static but whatever + /// True if we're currently checking for ghost opinions + var/gathering_candidates = TRUE + ///a static list of heretic summons we cam create, automatically populated from heretic monster subtypes var/static/list/monster_types + /// A static list of heretic summons which we should not create + var/static/list/monster_types_blacklist = list( + /mob/living/basic/heretic_summon/armsy, + /mob/living/basic/heretic_summon/star_gazer, + ) -/obj/structure/knock_tear/Initialize(mapload, ascendant) +/obj/structure/knock_tear/Initialize(mapload, datum/mind/ascendant_mind) . = ..() transform *= 3 - if(!monster_types) - monster_types = subtypesof(/mob/living/simple_animal/hostile/heretic_summon) - /mob/living/simple_animal/hostile/heretic_summon/armsy/prime - if(ascendant) - ascendee = ascendant + if(isnull(monster_types)) + monster_types = subtypesof(/mob/living/basic/heretic_summon) - monster_types_blacklist + if(!isnull(ascendant_mind)) + ascendee = ascendant_mind + RegisterSignals(ascendant_mind.current, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING), PROC_REF(end_madness)) SSpoints_of_interest.make_point_of_interest(src) INVOKE_ASYNC(src, PROC_REF(poll_ghosts)) +/// Ask ghosts if they want to make some noise /obj/structure/knock_tear/proc/poll_ghosts() var/list/candidates = poll_ghost_candidates("Would you like to be a random eldritch monster attacking the crew?", ROLE_SENTIENCE, ROLE_SENTIENCE, 10 SECONDS, POLL_IGNORE_HERETIC_MONSTER) while(LAZYLEN(candidates)) var/mob/dead/observer/candidate = pick_n_take(candidates) ghost_to_monster(candidate, should_ask = FALSE) + gathering_candidates = FALSE + +/// Destroy the rift if you kill the heretic +/obj/structure/knock_tear/proc/end_madness(datum/former_master) + SIGNAL_HANDLER + var/turf/our_turf = get_turf(src) + playsound(our_turf, 'sound/magic/castsummon.ogg', vol = 100, vary = TRUE) + visible_message(span_boldwarning("The rip in space spasms and disappears!")) + UnregisterSignal(former_master, list(COMSIG_LIVING_DEATH, COMSIG_QDELETING)) // Just in case they die THEN delete + new /obj/effect/temp_visual/destabilising_tear(our_turf) + qdel(src) /obj/structure/knock_tear/attack_ghost(mob/user) . = ..() - if(.) + if(. || gathering_candidates) return ghost_to_monster(user) +/obj/structure/knock_tear/examine(mob/user) + . = ..() + if (!isobserver(user) || gathering_candidates) + return + . += span_notice("You can use this to enter the world as a foul monster.") + +/// Turn a ghost into an 'orrible beast /obj/structure/knock_tear/proc/ghost_to_monster(mob/dead/observer/user, should_ask = TRUE) if(should_ask) var/ask = tgui_alert(user, "Become a monster?", "Ascended Rift", list("Yes", "No")) @@ -61,7 +89,26 @@ /obj/structure/knock_tear/move_crushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction) return FALSE -/obj/structure/knock_tear/Destroy(force) //this shouldnt happen but hey +/obj/structure/knock_tear/Destroy(force) if(ascendee) ascendee = null return ..() + +/obj/effect/temp_visual/destabilising_tear + name = "destabilised tear" + icon = 'icons/obj/anomaly.dmi' + icon_state = "bhole3" + color = COLOR_VOID_PURPLE + light_color = COLOR_VOID_PURPLE + light_range = 20 + layer = HIGH_PIPE_LAYER + duration = 1 SECONDS + +/obj/effect/temp_visual/destabilising_tear/Initialize(mapload) + . = ..() + transform *= 3 + animate(src, transform = matrix().Scale(3.2), time = 0.15 SECONDS) + animate(transform = matrix().Scale(0.2), time = 0.75 SECONDS) + animate(transform = matrix().Scale(3, 0), time = 0.1 SECONDS) + animate(src, color = COLOR_WHITE, time = 0.25 SECONDS, flags = ANIMATION_PARALLEL) + animate(color = COLOR_VOID_PURPLE, time = 0.3 SECONDS) diff --git a/code/modules/antagonists/heretic/transmutation_rune.dm b/code/modules/antagonists/heretic/transmutation_rune.dm index 7e63040af1db67..cd49feb3f175c5 100644 --- a/code/modules/antagonists/heretic/transmutation_rune.dm +++ b/code/modules/antagonists/heretic/transmutation_rune.dm @@ -90,6 +90,7 @@ // A copy of our requirements list. // We decrement the values of to determine if enough of each key is present. var/list/requirements_list = ritual.required_atoms.Copy() + var/list/banned_atom_types = ritual.banned_atom_types.Copy() // A list of all atoms we've selected to use in this recipe. var/list/selected_atoms = list() @@ -105,8 +106,16 @@ // We already have enough of this type, skip if(requirements_list[req_type] <= 0) continue - if(!istype(nearby_atom, req_type)) + // If req_type is a list of types, check all of them for one match. + if(islist(req_type)) + if(!(is_type_in_list(nearby_atom, req_type))) + continue + else if(!istype(nearby_atom, req_type)) continue + // if list has items, check if the strict type is banned. + if(length(banned_atom_types)) + if(nearby_atom.type in banned_atom_types) + continue // This item is a valid type. Add it to our selected atoms list. selected_atoms |= nearby_atom @@ -122,7 +131,7 @@ // All of the atoms have been checked, let's see if the ritual was successful var/list/what_are_we_missing = list() - for(var/atom/req_type as anything in requirements_list) + for(var/req_type in requirements_list) var/number_of_things = requirements_list[req_type] // <= 0 means it's fulfilled, skip if(number_of_things <= 0) @@ -130,10 +139,16 @@ // > 0 means it's unfilfilled - the ritual has failed, we should tell them why // Lets format the thing they're missing and put it into our list - var/formatted_thing = "[number_of_things] [initial(req_type.name)]\s" - if(ispath(req_type, /mob/living/carbon/human)) - // If we need a human, there is a high likelihood we actually need a (dead) body - formatted_thing = "[number_of_things] [number_of_things > 1 ? "bodies":"body"]" + var/formatted_thing = "[number_of_things] " + if(islist(req_type)) + var/list/req_type_list = req_type + var/list/req_text_list = list() + for(var/atom/possible_type as anything in req_type_list) + req_text_list += ritual.parse_required_item(possible_type) + formatted_thing += english_list(req_text_list, and_text = "or") + + else + formatted_thing = ritual.parse_required_item(req_type) what_are_we_missing += formatted_thing @@ -180,6 +195,7 @@ return ritual_result + /// A 3x3 heretic rune. The kind heretics actually draw in game. /obj/effect/heretic_rune/big icon = 'icons/effects/96x96.dmi' diff --git a/code/modules/antagonists/malf_ai/malf_ai_modules.dm b/code/modules/antagonists/malf_ai/malf_ai_modules.dm index 49d464fde167a1..9f527e0184ad13 100644 --- a/code/modules/antagonists/malf_ai/malf_ai_modules.dm +++ b/code/modules/antagonists/malf_ai/malf_ai_modules.dm @@ -455,15 +455,15 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module)) return FALSE caller.playsound_local(caller, 'sound/misc/interference.ogg', 50, FALSE, use_reverb = FALSE) - adjust_uses(-1) - - if(uses) - desc = "[initial(desc)] It has [uses] use\s remaining." - build_all_button_icons() clicked_machine.audible_message(span_userdanger("You hear a loud electrical buzzing sound coming from [clicked_machine]!")) addtimer(CALLBACK(src, PROC_REF(animate_machine), caller, clicked_machine), 5 SECONDS) //kabeep! unset_ranged_ability(caller, span_danger("Sending override signal...")) + adjust_uses(-1) //adjust after we unset the active ability since we may run out of charges, thus deleting the ability + + if(uses) + desc = "[initial(desc)] It has [uses] use\s remaining." + build_all_button_icons() return TRUE /datum/action/innate/ai/ranged/override_machine/proc/animate_machine(mob/living/caller, obj/machinery/to_animate) diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm b/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm index c15012f409b3ba..0b6a28c3bcac79 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclear_bomb/_nuclear_bomb.dm @@ -644,7 +644,7 @@ GLOBAL_VAR(station_nuke_source) to_chat(gibbed, span_userdanger("You are shredded to atoms by [source]!")) gibbed.investigate_log("has been gibbed by a nuclear blast.", INVESTIGATE_DEATHS) - gibbed.gib() + gibbed.gib(DROP_ALL_REMAINS) return TRUE /** diff --git a/code/modules/antagonists/pirate/pirate_outfits.dm b/code/modules/antagonists/pirate/pirate_outfits.dm index d2f648bb1fde25..4c73cac107f12e 100644 --- a/code/modules/antagonists/pirate/pirate_outfits.dm +++ b/code/modules/antagonists/pirate/pirate_outfits.dm @@ -36,6 +36,12 @@ id_trim = /datum/id_trim/pirate/captain head = /obj/item/clothing/head/costume/pirate/armored +/datum/outfit/pirate/captain/skeleton + name = "Space Pirate Captain (Skeleton)" + + belt = /obj/item/gun/magic/midas_hand + l_pocket = /obj/item/coin/gold/doubloon + /datum/outfit/pirate/space name = "Space Pirate (EVA)" diff --git a/code/modules/antagonists/pirate/pirate_roles.dm b/code/modules/antagonists/pirate/pirate_roles.dm index 68683333c49d3d..64baa724db1ec3 100644 --- a/code/modules/antagonists/pirate/pirate_roles.dm +++ b/code/modules/antagonists/pirate/pirate_roles.dm @@ -61,7 +61,7 @@ /obj/effect/mob_spawn/ghost_role/human/pirate/skeleton/captain rank = "Captain" - outfit = /datum/outfit/pirate/captain + outfit = /datum/outfit/pirate/captain/skeleton /obj/effect/mob_spawn/ghost_role/human/pirate/skeleton/gunner rank = "Gunner" diff --git a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm index 57eb95a978c521..3ea6488b2d42d6 100644 --- a/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm +++ b/code/modules/antagonists/pirate/pirate_shuttle_equipment.dm @@ -217,9 +217,13 @@ var/cargo_hold_id ///Interface name for the ui_interact call for different subtypes. var/interface_type = "CargoHoldTerminal" + ///Typecache of things that shouldn't be sold and shouldn't have their contents sold. + var/static/list/nosell_typecache /obj/machinery/computer/piratepad_control/Initialize(mapload) ..() + if(isnull(nosell_typecache)) + nosell_typecache = typecacheof(/mob/living/silicon/robot) return INITIALIZE_HINT_LATELOAD /obj/machinery/computer/piratepad_control/multitool_act(mob/living/user, obj/item/multitool/I) @@ -285,7 +289,7 @@ for(var/atom/movable/AM in get_turf(pad)) if(AM == pad) continue - export_item_and_contents(AM, apply_elastic = FALSE, dry_run = TRUE, external_report = report) + export_item_and_contents(AM, apply_elastic = FALSE, dry_run = TRUE, external_report = report, ignore_typecache = nosell_typecache) for(var/datum/export/exported_datum in report.total_amount) status_report += exported_datum.total_printout(report,notes = FALSE) @@ -306,7 +310,7 @@ for(var/atom/movable/item_on_pad in get_turf(pad)) if(item_on_pad == pad) continue - export_item_and_contents(item_on_pad, apply_elastic = FALSE, delete_unsold = FALSE, external_report = report) + export_item_and_contents(item_on_pad, apply_elastic = FALSE, delete_unsold = FALSE, external_report = report, ignore_typecache = nosell_typecache) status_report = "Sold: " var/value = 0 diff --git a/code/modules/antagonists/revenant/revenant_blight.dm b/code/modules/antagonists/revenant/revenant_blight.dm index 64bd6ce03bb9fd..c56df7bd4eaaca 100644 --- a/code/modules/antagonists/revenant/revenant_blight.dm +++ b/code/modules/antagonists/revenant/revenant_blight.dm @@ -31,20 +31,23 @@ return if(!finalstage) + var/need_mob_update = FALSE if(affected_mob.body_position == LYING_DOWN && SPT_PROB(3 * stage, seconds_per_tick)) cure() return FALSE if(SPT_PROB(1.5 * stage, seconds_per_tick)) to_chat(affected_mob, span_revennotice("You suddenly feel [pick("sick and tired", "disoriented", "tired and confused", "nauseated", "faint", "dizzy")]...")) affected_mob.adjust_confusion(8 SECONDS) - affected_mob.adjustStaminaLoss(20, FALSE) + need_mob_update += affected_mob.adjustStaminaLoss(20, updating_stamina = FALSE) new /obj/effect/temp_visual/revenant(affected_mob.loc) if(stagedamage < stage) stagedamage++ - affected_mob.adjustToxLoss(1 * stage * seconds_per_tick, FALSE) //should, normally, do about 30 toxin damage. + need_mob_update += affected_mob.adjustToxLoss(1 * stage * seconds_per_tick, updating_health = FALSE) //should, normally, do about 30 toxin damage. new /obj/effect/temp_visual/revenant(affected_mob.loc) if(SPT_PROB(25, seconds_per_tick)) - affected_mob.adjustStaminaLoss(stage, FALSE) + need_mob_update += affected_mob.adjustStaminaLoss(stage, updating_stamina = FALSE) + if(need_mob_update) + affected_mob.updatehealth() switch(stage) if(2) @@ -60,7 +63,7 @@ if(!finalstage) finalstage = TRUE to_chat(affected_mob, span_revenbignotice("You feel like [pick("nothing's worth it anymore", "nobody ever needed your help", "nothing you did mattered", "everything you tried to do was worthless")].")) - affected_mob.adjustStaminaLoss(22.5 * seconds_per_tick, FALSE) + affected_mob.adjustStaminaLoss(22.5 * seconds_per_tick, updating_stamina = FALSE) new /obj/effect/temp_visual/revenant(affected_mob.loc) if(affected_mob.dna && affected_mob.dna.species) affected_mob.dna.species.handle_mutant_bodyparts(affected_mob,"#1d2953") diff --git a/code/modules/antagonists/spiders/spiders.dm b/code/modules/antagonists/spiders/spiders.dm index 6d0b86d24d70ab..d42f1aea7b391c 100644 --- a/code/modules/antagonists/spiders/spiders.dm +++ b/code/modules/antagonists/spiders/spiders.dm @@ -14,7 +14,7 @@ /datum/antagonist/spider/on_gain() forge_objectives(directive) - . = ..() + return ..() /datum/antagonist/spider/greet() . = ..() @@ -35,3 +35,23 @@ var/datum/objective/spider/objective = new(directive) objective.owner = owner objectives += objective + +/// Subtype for flesh spiders who don't have a queen +/datum/antagonist/spider/flesh + name = "Flesh Spider" + +/datum/antagonist/spider/flesh/forge_objectives() + var/datum/objective/custom/destroy = new() + destroy.owner = owner + destroy.explanation_text = "Wreak havoc and consume living flesh." + objectives += destroy + + var/datum/objective/survive/dont_die = new() + dont_die.owner = owner + objectives += dont_die + +/datum/antagonist/spider/flesh/greet() + . = ..() + to_chat(owner, span_boldwarning("An abomination of flesh set upon the station by changelings, \ + you are aggressive to all living beings outside of your species and know no loyalties... even to your creator. \ +
Your malleable flesh quickly regenerates if you can avoid taking damage for a few seconds.")) diff --git a/code/modules/antagonists/traitor/objectives/kill_pet.dm b/code/modules/antagonists/traitor/objectives/kill_pet.dm index 51a54d99e300a0..ae28f5dbf4c08c 100644 --- a/code/modules/antagonists/traitor/objectives/kill_pet.dm +++ b/code/modules/antagonists/traitor/objectives/kill_pet.dm @@ -26,9 +26,9 @@ JOB_CHIEF_MEDICAL_OFFICER = /mob/living/simple_animal/pet/cat/runtime, JOB_CHIEF_ENGINEER = /mob/living/simple_animal/parrot/poly, JOB_QUARTERMASTER = list( - /mob/living/simple_animal/sloth/citrus, - /mob/living/simple_animal/sloth/paperwork, - /mob/living/simple_animal/hostile/gorilla/cargo_domestic, + /mob/living/basic/gorilla/cargorilla, + /mob/living/basic/sloth/citrus, + /mob/living/basic/sloth/paperwork, ) ) /// The head that we are targetting diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm index 3e4cf0766f573f..4783daffb8b47d 100644 --- a/code/modules/antagonists/wizard/equipment/artefact.dm +++ b/code/modules/antagonists/wizard/equipment/artefact.dm @@ -311,7 +311,7 @@ //Provides a decent heal, need to pump every 6 seconds /obj/item/organ/internal/heart/cursed/wizard - pump_delay = 60 + pump_delay = 6 SECONDS heal_brute = 25 heal_burn = 25 heal_oxy = 25 diff --git a/code/modules/antagonists/wizard/grand_ritual/finales/all_access.dm b/code/modules/antagonists/wizard/grand_ritual/finales/all_access.dm new file mode 100644 index 00000000000000..07958ed94a75e1 --- /dev/null +++ b/code/modules/antagonists/wizard/grand_ritual/finales/all_access.dm @@ -0,0 +1,17 @@ +/// Open all of the doors +/datum/grand_finale/all_access + name = "Connection" + desc = "The ultimate use of your gathered power! Unlock every single door that they have! Nobody will be able to keep you out now, or anyone else for that matter!" + icon = 'icons/mob/actions/actions_spells.dmi' + icon_state = "knock" + +/datum/grand_finale/all_access/trigger(mob/living/carbon/human/invoker) + message_admins("[key_name(invoker)] removed all door access requirements") + for(var/obj/machinery/door/target_door as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/door)) + if(is_station_level(target_door.z)) + target_door.unlock() + target_door.req_access = list() + target_door.req_one_access = list() + INVOKE_ASYNC(target_door, TYPE_PROC_REF(/obj/machinery/door/airlock, open)) + CHECK_TICK + priority_announce("AULIE OXIN FIERA!!", null, 'sound/magic/knock.ogg', sender_override = "[invoker.real_name]") diff --git a/code/modules/antagonists/wizard/grand_ritual/finales/armageddon.dm b/code/modules/antagonists/wizard/grand_ritual/finales/armageddon.dm new file mode 100644 index 00000000000000..c4bba539c35c9d --- /dev/null +++ b/code/modules/antagonists/wizard/grand_ritual/finales/armageddon.dm @@ -0,0 +1,60 @@ +#define DOOM_SINGULARITY "singularity" +#define DOOM_TESLA "tesla" +#define DOOM_METEORS "meteors" + +/// Kill yourself and probably a bunch of other people +/datum/grand_finale/armageddon + name = "Annihilation" + desc = "This crew have offended you beyond the realm of pranks. Make the ultimate sacrifice to teach them a lesson your elders can really respect. \ + YOU WILL NOT SURVIVE THIS." + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "legion_head" + minimum_time = 90 MINUTES // This will probably immediately end the round if it gets finished. + ritual_invoke_time = 60 SECONDS // Really give the crew some time to interfere with this one. + dire_warning = TRUE + glow_colour = "#be000048" + /// Things to yell before you die + var/static/list/possible_last_words = list( + "Flames and ruin!", + "Dooooooooom!!", + "HAHAHAHAHAHA!! AHAHAHAHAHAHAHAHAA!!", + "Hee hee hee!! Hoo hoo hoo!! Ha ha haaa!!", + "Ohohohohohoho!!", + "Cower in fear, puny mortals!", + "Tremble before my glory!", + "Pick a god and pray!", + "It's no use!", + "If the gods wanted you to live, they would not have created me!", + "God stays in heaven out of fear of what I have created!", + "Ruination is come!", + "All of creation, bend to my will!", + ) + +/datum/grand_finale/armageddon/trigger(mob/living/carbon/human/invoker) + priority_announce(pick(possible_last_words), null, 'sound/magic/voidblink.ogg', sender_override = "[invoker.real_name]") + var/turf/current_location = get_turf(invoker) + invoker.gib(DROP_ALL_REMAINS) + + var/static/list/doom_options = list() + if (!length(doom_options)) + doom_options = list(DOOM_SINGULARITY, DOOM_TESLA) + if (!SSmapping.config.planetary) + doom_options += DOOM_METEORS + + switch(pick(doom_options)) + if (DOOM_SINGULARITY) + var/obj/singularity/singulo = new(current_location) + singulo.energy = 300 + if (DOOM_TESLA) + var/obj/energy_ball/tesla = new (current_location) + tesla.energy = 200 + if (DOOM_METEORS) + var/datum/dynamic_ruleset/roundstart/meteor/meteors = new() + meteors.meteordelay = 0 + var/datum/game_mode/dynamic/mode = SSticker.mode + mode.execute_roundstart_rule(meteors) // Meteors will continue until morale is crushed. + priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", ANNOUNCER_METEORS) + +#undef DOOM_SINGULARITY +#undef DOOM_TESLA +#undef DOOM_METEORS diff --git a/code/modules/antagonists/wizard/grand_ritual/finales/captaincy.dm b/code/modules/antagonists/wizard/grand_ritual/finales/captaincy.dm new file mode 100644 index 00000000000000..d1a3c1afaf7583 --- /dev/null +++ b/code/modules/antagonists/wizard/grand_ritual/finales/captaincy.dm @@ -0,0 +1,113 @@ +/// Become the official Captain of the station +/datum/grand_finale/usurp + name = "Usurpation" + desc = "The ultimate use of your gathered power! Rewrite time such that you have been Captain of this station the whole time." + icon = 'icons/obj/card.dmi' + icon_state = "card_gold" + +/datum/grand_finale/usurp/trigger(mob/living/carbon/human/invoker) + message_admins("[key_name(invoker)] has replaced the Captain") + var/list/former_captains = list() + var/list/other_crew = list() + SEND_SOUND(world, sound('sound/magic/timeparadox2.ogg')) + + for (var/mob/living/carbon/human/crewmate as anything in GLOB.human_list) + if (!crewmate.mind) + continue + crewmate.Unconscious(3 SECONDS) // Everyone falls unconscious but not everyone gets told about a new captain + if (crewmate == invoker || IS_HUMAN_INVADER(crewmate)) + continue + to_chat(crewmate, span_notice("The world spins and dissolves. Your past flashes before your eyes, backwards.\n\ + Life strolls back into the ocean and shrinks into nothingness, planets explode into storms of solar dust, \ + the stars rush back to greet each other at the beginning of things and then... you snap back to the present. \n\ + Everything is just as it was and always has been. \n\n\ + A stray thought sticks in the forefront of your mind. \n\ + [span_hypnophrase("I'm so glad that [invoker.real_name] is our legally appointed Captain!")] \n\ + Is... that right?")) + if (is_captain_job(crewmate.mind.assigned_role)) + former_captains += crewmate + demote_to_assistant(crewmate) + continue + if (crewmate.stat != DEAD) + other_crew += crewmate + + dress_candidate(invoker) + GLOB.manifest.modify(invoker.real_name, JOB_CAPTAIN, JOB_CAPTAIN) + minor_announce("Captain [invoker.real_name] on deck!") + + // Enlist some crew to try and restore the natural order + for (var/mob/living/carbon/human/former_captain as anything in former_captains) + create_vendetta(former_captain.mind, invoker.mind) + for (var/mob/living/carbon/human/random_crewmate as anything in other_crew) + if (prob(10)) + create_vendetta(random_crewmate.mind, invoker.mind) + +/** + * Anyone who thought they were Captain is in for a nasty surprise, and won't be very happy about it + */ +/datum/grand_finale/usurp/proc/demote_to_assistant(mob/living/carbon/human/former_captain) + var/obj/effect/particle_effect/fluid/smoke/exit_poof = new(get_turf(former_captain)) + exit_poof.lifetime = 2 SECONDS + + former_captain.unequip_everything() + if(isplasmaman(former_captain)) + former_captain.equipOutfit(/datum/outfit/plasmaman) + former_captain.internal = former_captain.get_item_for_held_index(2) + else + former_captain.equipOutfit(/datum/outfit/job/assistant) + + GLOB.manifest.modify(former_captain.real_name, JOB_ASSISTANT, JOB_ASSISTANT) + var/list/valid_turfs = list() + // Used to be into prison but that felt a bit too mean + for (var/turf/exile_turf as anything in get_area_turfs(/area/station/maintenance, subtypes = TRUE)) + if (isspaceturf(exile_turf) || exile_turf.is_blocked_turf()) + continue + valid_turfs += exile_turf + do_teleport(former_captain, pick(valid_turfs), no_effects = TRUE) + var/obj/effect/particle_effect/fluid/smoke/enter_poof = new(get_turf(former_captain)) + enter_poof.lifetime = 2 SECONDS + +/** + * Does some item juggling to try to dress you as both a Wizard and Captain without deleting any items you have bought. + * ID, headset, and uniform are forcibly replaced. Other slots are only filled if unoccupied. + * We could forcibly replace shoes and gloves too but people might miss their insuls or... meown shoes? + */ +/datum/grand_finale/usurp/proc/dress_candidate(mob/living/carbon/human/invoker) + // Won't be needing these + var/obj/id = invoker.get_item_by_slot(ITEM_SLOT_ID) + QDEL_NULL(id) + var/obj/headset = invoker.get_item_by_slot(ITEM_SLOT_EARS) + QDEL_NULL(headset) + // We're about to take off your pants so those are going to fall out + var/obj/item/pocket_L = invoker.get_item_by_slot(ITEM_SLOT_LPOCKET) + var/obj/item/pocket_R = invoker.get_item_by_slot(ITEM_SLOT_RPOCKET) + // In case we try to put a PDA there + var/obj/item/belt = invoker.get_item_by_slot(ITEM_SLOT_BELT) + belt?.moveToNullspace() + + var/obj/pants = invoker.get_item_by_slot(ITEM_SLOT_ICLOTHING) + QDEL_NULL(pants) + invoker.equipOutfit(/datum/outfit/job/wizard_captain) + // And put everything back! + equip_to_slot_then_hands(invoker, ITEM_SLOT_BELT, belt) + equip_to_slot_then_hands(invoker, ITEM_SLOT_LPOCKET, pocket_L) + equip_to_slot_then_hands(invoker, ITEM_SLOT_RPOCKET, pocket_R) + +/// An outfit which replaces parts of a wizard's clothes with captain's clothes but keeps the robes +/datum/outfit/job/wizard_captain + name = "Captain (Wizard Transformation)" + jobtype = /datum/job/captain + id = /obj/item/card/id/advanced/gold + id_trim = /datum/id_trim/job/captain + uniform = /obj/item/clothing/under/rank/captain/parade + belt = /obj/item/modular_computer/pda/heads/captain + ears = /obj/item/radio/headset/heads/captain/alt + glasses = /obj/item/clothing/glasses/sunglasses + gloves = /obj/item/clothing/gloves/captain + shoes = /obj/item/clothing/shoes/laceup + accessory = /obj/item/clothing/accessory/medal/gold/captain + backpack_contents = list( + /obj/item/melee/baton/telescopic = 1, + /obj/item/station_charter = 1, + ) + box = null diff --git a/code/modules/antagonists/wizard/grand_ritual/finales/cheese.dm b/code/modules/antagonists/wizard/grand_ritual/finales/cheese.dm new file mode 100644 index 00000000000000..714cd62659bbb8 --- /dev/null +++ b/code/modules/antagonists/wizard/grand_ritual/finales/cheese.dm @@ -0,0 +1,49 @@ +/** + * Gives the wizard a defensive/mood buff and a Wabbajack, a juiced up chaos staff that will surely break something. + * Everyone but the wizard goes crazy, suffers major brain damage, and is given a vendetta against the wizard. + * Already insane people are instead cured of their madness, ignoring any other effects as the station around them loses its marbles. + */ +/datum/grand_finale/cheese + // we don't set name, desc and others, thus we won't appear in the radial choice of a normal finale rune + dire_warning = TRUE + minimum_time = 45 MINUTES //i'd imagine speedrunning this would be crummy, but the wizard's average lifespan is barely reaching this point + +/datum/grand_finale/cheese/trigger(mob/living/invoker) + message_admins("[key_name(invoker)] has summoned forth The Wabbajack and cursed the crew with madness!") + priority_announce("Danger: Extremely potent reality altering object has been summoned on station. Immediate evacuation advised. Brace for impact.", "Central Command Higher Dimensional Affairs", 'sound/effects/glassbr1.ogg') + + for (var/mob/living/carbon/human/crewmate as anything in GLOB.human_list) + if (isnull(crewmate.mind)) + continue + if (crewmate == invoker) //everyone but the wizard is royally fucked, no matter who they are + continue + if (crewmate.has_trauma_type(/datum/brain_trauma/mild/hallucinations)) //for an already insane person, this is retribution + to_chat(crewmate, span_boldwarning("Your surroundings suddenly fill with a cacophony of manic laughter and psychobabble...")) + to_chat(crewmate, span_nicegreen("...but as the moment passes, you realise that whatever eldritch power behind the event happened to affect you \ + has resonated within the ruins of your already shattered mind, creating a singularity of mental instability! \ + As it collapses unto itself, you feel... at peace, finally.")) + if(crewmate.has_quirk(/datum/quirk/insanity)) + crewmate.remove_quirk(/datum/quirk/insanity) + else + crewmate.cure_trauma_type(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) + else + //everyone else gets to relish in madness + //yes killing their mood will also trigger mood hallucinations + create_vendetta(crewmate.mind, invoker.mind) + to_chat(crewmate, span_boldwarning("Your surroundings suddenly fill with a cacophony of manic laughter and psychobabble. \n\ + You feel your inner psyche shatter into a myriad pieces of jagged glass of colors unknown to the universe, \ + infinitely reflecting a blinding, maddening light coming from the innermost sanctums of your destroyed mind. \n\ + After a brief pause which felt like a millenia, one phrase rebounds ceaselessly in your head, imbued with the false hope of absolution... \n\ + [invoker] must die.")) + var/datum/brain_trauma/mild/hallucinations/added_trauma = new() + added_trauma.resilience = TRAUMA_RESILIENCE_ABSOLUTE + crewmate.adjustOrganLoss(ORGAN_SLOT_BRAIN, BRAIN_DAMAGE_DEATH - 25, BRAIN_DAMAGE_DEATH - 25) //you'd better hope chap didn't pick a hypertool + crewmate.gain_trauma(added_trauma) + crewmate.add_mood_event("wizard_ritual_finale", /datum/mood_event/madness_despair) + + //drip our wizard out + invoker.apply_status_effect(/datum/status_effect/blessing_of_insanity) + invoker.add_mood_event("wizard_ritual_finale", /datum/mood_event/madness_elation) + var/obj/item/gun/magic/staff/chaos/true_wabbajack/the_wabbajack = new + invoker.put_in_active_hand(the_wabbajack) + to_chat(invoker, span_mind_control("Your every single instinct and rational thought is screaming at you as [the_wabbajack] appears in your firm grip...")) diff --git a/code/modules/antagonists/wizard/grand_ritual/finales/clown.dm b/code/modules/antagonists/wizard/grand_ritual/finales/clown.dm new file mode 100644 index 00000000000000..bda79c908c0406 --- /dev/null +++ b/code/modules/antagonists/wizard/grand_ritual/finales/clown.dm @@ -0,0 +1,76 @@ +/// Dress the crew as magical clowns +/datum/grand_finale/clown + name = "Jubilation" + desc = "The ultimate use of your gathered power! Rewrite time so that everyone went to clown college! Now they'll prank each other for you!" + icon = 'icons/obj/clothing/masks.dmi' + icon_state = "clown" + glow_colour = "#ffff0048" + +/datum/grand_finale/clown/trigger(mob/living/carbon/human/invoker) + for(var/mob/living/carbon/human/victim as anything in GLOB.human_list) + victim.Unconscious(3 SECONDS) + if (!victim.mind || IS_HUMAN_INVADER(victim) || victim == invoker) + continue + if (HAS_TRAIT(victim, TRAIT_CLOWN_ENJOYER)) + victim.add_mood_event("clown_world", /datum/mood_event/clown_world) + to_chat(victim, span_notice("The world spins and dissolves. Your past flashes before your eyes, backwards.\n\ + Life strolls back into the ocean and shrinks into nothingness, planets explode into storms of solar dust, \ + the stars rush back to greet each other at the beginning of things and then... you snap back to the present. \n\ + Everything is just as it was and always has been. \n\n\ + A stray thought sticks in the forefront of your mind. \n\ + [span_hypnophrase("I'm so glad that I work at Clown Research Station [station_name()]!")] \n\ + Is... that right?")) + if (is_clown_job(victim.mind.assigned_role)) + var/datum/action/cooldown/spell/conjure_item/clown_pockets/new_spell = new(victim) + new_spell.Grant(victim) + continue + if (!ismonkey(victim)) // Monkeys cannot yet wear clothes + dress_as_magic_clown(victim) + if (prob(15)) + create_vendetta(victim.mind, invoker.mind) + +/** + * Clown enjoyers who are effected by this become ecstatic, they have achieved their life's dream. + * This moodlet is equivalent to the one for simply being a traitor. + */ +/datum/mood_event/clown_world + mood_change = 4 + +/datum/mood_event/clown_world/add_effects(param) + description = "I LOVE working at Clown Research Station [station_name()]!!" + +/// Dress the passed mob as a magical clown, self-explanatory +/datum/grand_finale/clown/proc/dress_as_magic_clown(mob/living/carbon/human/victim) + var/obj/effect/particle_effect/fluid/smoke/poof = new(get_turf(victim)) + poof.lifetime = 2 SECONDS + + var/obj/item/tank/internal = victim.internal + // We're about to take off your pants so those are going to fall out + var/obj/item/pocket_L = victim.get_item_by_slot(ITEM_SLOT_LPOCKET) + var/obj/item/pocket_R = victim.get_item_by_slot(ITEM_SLOT_RPOCKET) + var/obj/item/id = victim.get_item_by_slot(ITEM_SLOT_ID) + var/obj/item/belt = victim.get_item_by_slot(ITEM_SLOT_BELT) + + var/obj/pants = victim.get_item_by_slot(ITEM_SLOT_ICLOTHING) + var/obj/mask = victim.get_item_by_slot(ITEM_SLOT_MASK) + QDEL_NULL(pants) + QDEL_NULL(mask) + if(isplasmaman(victim)) + victim.equip_to_slot_if_possible(new /obj/item/clothing/under/plasmaman/clown/magic(), ITEM_SLOT_ICLOTHING, disable_warning = TRUE) + victim.equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/clown_hat/plasmaman(), ITEM_SLOT_MASK, disable_warning = TRUE) + else + victim.equip_to_slot_if_possible(new /obj/item/clothing/under/rank/civilian/clown/magic(), ITEM_SLOT_ICLOTHING, disable_warning = TRUE) + victim.equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/clown_hat(), ITEM_SLOT_MASK, disable_warning = TRUE) + + var/obj/item/clothing/mask/gas/clown_hat/clown_mask = victim.get_item_by_slot(ITEM_SLOT_MASK) + if (clown_mask) + var/list/options = GLOB.clown_mask_options + clown_mask.icon_state = options[pick(clown_mask.clownmask_designs)] + victim.update_worn_mask() + clown_mask.update_item_action_buttons() + + equip_to_slot_then_hands(victim, ITEM_SLOT_LPOCKET, pocket_L) + equip_to_slot_then_hands(victim, ITEM_SLOT_RPOCKET, pocket_R) + equip_to_slot_then_hands(victim, ITEM_SLOT_ID, id) + equip_to_slot_then_hands(victim, ITEM_SLOT_BELT, belt) + victim.internal = internal diff --git a/code/modules/antagonists/wizard/grand_ritual/finales/grand_ritual_finale.dm b/code/modules/antagonists/wizard/grand_ritual/finales/grand_ritual_finale.dm new file mode 100644 index 00000000000000..b92ae4d2f20b2e --- /dev/null +++ b/code/modules/antagonists/wizard/grand_ritual/finales/grand_ritual_finale.dm @@ -0,0 +1,88 @@ +/** + * A big final event to run when you complete seven rituals + */ +/datum/grand_finale + /// Friendly name for selection menu + var/name + /// Tooltip description for selection menu + var/desc + /// An icon to display to represent the choice + var/icon/icon + /// Icon state to use to represent the choice + var/icon_state + /// Prevent especially dangerous options from being chosen until we're fine with the round ending + var/minimum_time = 0 + /// Override the rune invocation time + var/ritual_invoke_time = 30 SECONDS + /// Provide an extremely loud radio message when this one starts + var/dire_warning = FALSE + /// Overrides the default colour you glow while channeling the rune, optional + var/glow_colour + +/** + * Returns an entry for a radial menu for this choice. + * Returns null if entry is abstract or invalid for current circumstances. + */ +/datum/grand_finale/proc/get_radial_choice() + if (!name || !desc || !icon || !icon_state) + return + var/time_remaining_desc = "" + if (minimum_time >= world.time - SSticker.round_start_time) + time_remaining_desc = "This ritual will be available to begin invoking in [DisplayTimeText(minimum_time - world.time - SSticker.round_start_time)]" + var/datum/radial_menu_choice/choice = new() + choice.name = name + choice.image = image(icon = icon, icon_state = icon_state) + choice.info = desc + time_remaining_desc + return choice + +/** + * Actually do the thing. + * Arguments + * * invoker - The wizard casting this. + */ +/datum/grand_finale/proc/trigger(mob/living/invoker) + // Do something cool. + +/// Tries to equip something into an inventory slot, then hands, then the floor. +/datum/grand_finale/proc/equip_to_slot_then_hands(mob/living/carbon/human/invoker, slot, obj/item/item) + if(!item) + return + if(!invoker.equip_to_slot_if_possible(item, slot, disable_warning = TRUE)) + invoker.put_in_hands(item) + +/// They are not going to take this lying down. +/datum/grand_finale/proc/create_vendetta(datum/mind/aggrieved_crewmate, datum/mind/wizard) + aggrieved_crewmate.add_antag_datum(/datum/antagonist/wizard_prank_vendetta) + var/datum/antagonist/wizard_prank_vendetta/antag_datum = aggrieved_crewmate.has_antag_datum(/datum/antagonist/wizard_prank_vendetta) + var/datum/objective/assassinate/wizard_murder = new + wizard_murder.owner = aggrieved_crewmate + wizard_murder.target = wizard + wizard_murder.explanation_text = "Kill [wizard.current.name], the one who did this." + antag_datum.objectives += wizard_murder + + to_chat(aggrieved_crewmate.current, span_warning("No! This isn't right!")) + aggrieved_crewmate.announce_objectives() + +/** + * Antag datum to give to people who want to kill the wizard. + * This doesn't preclude other people choosing to want to kill the wizard, just these people are rewarded for it. + */ +/datum/antagonist/wizard_prank_vendetta + name = "\improper Wizard Prank Victim" + roundend_category = "wizard prank victims" + show_in_antagpanel = FALSE + antagpanel_category = "Other" + show_name_in_check_antagonists = TRUE + count_against_dynamic_roll_chance = FALSE + silent = TRUE + +/// Give everyone magic items, its so simple it feels pointless to give it its own file +/datum/grand_finale/magic + name = "Evolution" + desc = "The ultimate use of your gathered power! Give the crew their own magic, they'll surely realise that right and wrong have no meaning when you hold ultimate power!" + icon = 'icons/obj/scrolls.dmi' + icon_state = "scroll" + +/datum/grand_finale/magic/trigger(mob/living/carbon/human/invoker) + message_admins("[key_name(invoker)] summoned magic") + summon_magic(survivor_probability = 20) // Wow, this one was easy! diff --git a/code/modules/antagonists/wizard/grand_ritual/finales/immortality.dm b/code/modules/antagonists/wizard/grand_ritual/finales/immortality.dm new file mode 100644 index 00000000000000..d20ca06752b6cf --- /dev/null +++ b/code/modules/antagonists/wizard/grand_ritual/finales/immortality.dm @@ -0,0 +1,277 @@ +/// Amount of time to wait after someone dies to steal their body from their killers +#define IMMORTAL_PRE_ACTIVATION_TIME 10 SECONDS +/// Amount of time it takes a mob to return to the living world +#define IMMORTAL_RESURRECT_TIME 50 SECONDS + +/** + * Nobody will ever die ever again + * Or if they do, they will be back + */ +/datum/grand_finale/immortality + name = "Perpetuation" + desc = "The ultimate use of your gathered power! Share with the crew the gift, or curse, of eternal life! \ + And why not just the crew? How about their pets too? And any other animals around here! \ + What if nobody died ever again!?" + icon = 'icons/obj/mining_zones/artefacts.dmi' + icon_state = "asclepius_active" + glow_colour = COLOR_PALE_GREEN + minimum_time = 30 MINUTES // This is enormously disruptive but doesn't technically in of itself end the round. + +/datum/grand_finale/immortality/trigger(mob/living/carbon/human/invoker) + new /obj/effect/temp_visual/immortality_blast(get_turf(invoker)) + SEND_SOUND(world, sound('sound/magic/teleport_diss.ogg')) + for (var/mob/living/alive_guy as anything in GLOB.mob_living_list) + new /obj/effect/temp_visual/immortality_pulse(get_turf(alive_guy)) + if (!alive_guy.mind) + continue + to_chat(alive_guy, span_notice("You feel extremely healthy.")) + RegisterSignal(SSdcs, COMSIG_GLOB_MOB_DEATH, PROC_REF(something_died)) + +/// Called when something passes into the great beyond, make it not do that +/datum/grand_finale/immortality/proc/something_died(datum/source, mob/living/died, gibbed) + SIGNAL_HANDLER + if (died.stat != DEAD || HAS_TRAIT(died, TRAIT_PERMANENTLY_MORTAL) || died.flags_1 & HOLOGRAM_1) + return + var/body_type = died.type + + var/turf/died_turf = get_turf(died) + var/list/nearby_turfs = circle_view_turfs(died_turf, 2) + var/list/nearby_safe_turfs = list() + for (var/turf/check_turf as anything in nearby_turfs) + if (check_turf.is_blocked_turf(exclude_mobs = TRUE, source_atom = died)) + nearby_turfs -= check_turf + continue + if (islava(check_turf) || ischasm(check_turf)) + continue + nearby_safe_turfs += check_turf + if (length(nearby_safe_turfs)) // If you're in the middle of a 5x5 chasm, tough luck I guess + died_turf = pick(nearby_safe_turfs) + else if (length(nearby_turfs)) + died_turf = pick(nearby_turfs) + + var/saved_appearance = ishuman(died) ? new /datum/human_appearance_profile(died) : null + + var/datum/mind/dead_mind = HAS_TRAIT(died, TRAIT_SUICIDED) ? null : died.mind // There is a way out of the cycle + if (!isnull(dead_mind)) + to_chat(died, span_boldnotice("Your spirit surges! You will return to life in [DisplayTimeText(IMMORTAL_PRE_ACTIVATION_TIME + IMMORTAL_RESURRECT_TIME)].")) + animate(died, alpha = died.alpha, time = IMMORTAL_PRE_ACTIVATION_TIME / 2, flags = ANIMATION_PARALLEL) + animate(alpha = 0, time = IMMORTAL_PRE_ACTIVATION_TIME / 2, easing = SINE_EASING | EASE_IN) + addtimer(CALLBACK(src, PROC_REF(reverse_death), died, dead_mind, died_turf, body_type, saved_appearance), IMMORTAL_PRE_ACTIVATION_TIME, TIMER_DELETE_ME) + +/// Create a ghost ready for revival +/datum/grand_finale/immortality/proc/reverse_death(mob/living/died, datum/mind/dead_mind, turf/died_turf, body_type, datum/human_appearance_profile/human_appearance) + if (died.stat != DEAD) + return + var/ghost_type = ispath(body_type, /mob/living/carbon/human) ? /obj/effect/spectre_of_resurrection/human : /obj/effect/spectre_of_resurrection + var/obj/effect/spectre_of_resurrection/ghost = new ghost_type(died_turf) + var/mob/living/corpse = QDELETED(died) ? new body_type(ghost) : died + if (!isnull(human_appearance)) + corpse.real_name = human_appearance.name + corpse.alpha = initial(corpse.alpha) + corpse.add_traits(list(TRAIT_NO_TELEPORT, TRAIT_AI_PAUSED), MAGIC_TRAIT) + corpse.apply_status_effect(/datum/status_effect/grouped/stasis, MAGIC_TRAIT) + ghost.set_up_resurrection(corpse, dead_mind, human_appearance) + + +/// Store of data we use to recreate someone who was gibbed, like a simplified version of changeling profiles +/datum/human_appearance_profile + /// The name of the profile / the name of whoever this profile source. + var/name = "human" + /// The DNA datum associated with our profile from the profile source + var/datum/dna/dna + /// The age of the profile source. + var/age + /// The body type of the profile source. + var/physique + /// The quirks of the profile source. + var/list/quirks = list() + /// The hair and facial hair gradient styles of the profile source. + var/list/hair_gradient_style = list("None", "None") + /// The hair and facial hair gradient colours of the profile source. + var/list/hair_gradient_colours = list(null, null) + /// The TTS voice of the profile source + var/voice + /// The TTS filter of the profile filter + var/voice_filter = "" + +/datum/human_appearance_profile/New(mob/living/carbon/human/target) + copy_from(target) + +/// Copy the appearance data of the target +/datum/human_appearance_profile/proc/copy_from(mob/living/carbon/human/target) + target.dna.real_name = target.real_name + dna = new target.dna.type() + target.dna.copy_dna(dna) + name = target.real_name + age = target.age + physique = target.physique + + for(var/datum/quirk/target_quirk as anything in target.quirks) + LAZYADD(quirks, new target_quirk.type) + + hair_gradient_style = LAZYLISTDUPLICATE(target.grad_style) + hair_gradient_colours = LAZYLISTDUPLICATE(target.grad_color) + + voice = target.voice + voice_filter = target.voice_filter + +/// Make the targetted human look like this +/datum/human_appearance_profile/proc/apply_to(mob/living/carbon/human/target) + target.real_name = name + target.age = age + target.physique = physique + target.grad_style = LAZYLISTDUPLICATE(hair_gradient_style) + target.grad_color = LAZYLISTDUPLICATE(hair_gradient_colours) + target.voice = voice + target.voice_filter = voice_filter + + for(var/datum/quirk/target_quirk as anything in quirks) + target_quirk.add_to_holder(target) + + dna.transfer_identity(target, TRUE) + for(var/obj/item/bodypart/limb as anything in target.bodyparts) + limb.update_limb(is_creating = TRUE) + target.updateappearance(mutcolor_update = TRUE) + target.domutcheck() + target.regenerate_icons() + + +/// A ghostly image of a mob showing where and what is going to respawn +/obj/effect/spectre_of_resurrection + name = "spectre" + desc = "A frightening apparition, slowly growing more solid." + icon_state = "blank_white" + anchored = TRUE + layer = MOB_LAYER + plane = GAME_PLANE + alpha = 0 + color = COLOR_PALE_GREEN + light_range = 2 + light_color = COLOR_PALE_GREEN + /// Who are we reviving? + var/mob/living/corpse + /// Who if anyone is playing as them? + var/datum/mind/dead_mind + +/obj/effect/spectre_of_resurrection/Initialize(mapload) + . = ..() + animate(src, alpha = 150, time = 2 SECONDS) + +/// Prepare to revive someone +/obj/effect/spectre_of_resurrection/proc/set_up_resurrection(mob/living/corpse, datum/mind/dead_mind, datum/human_appearance_profile/human_appearance) + if (isnull(corpse)) + qdel(src) + return + + src.corpse = corpse + src.dead_mind = dead_mind + corpse.forceMove(src) + name = "spectre of [corpse]" + setup_icon(corpse) + DO_FLOATING_ANIM(src) + + RegisterSignal(corpse, COMSIG_LIVING_REVIVE, PROC_REF(on_corpse_revived)) + RegisterSignal(corpse, COMSIG_QDELETING, PROC_REF(on_corpse_deleted)) + RegisterSignal(dead_mind, COMSIG_QDELETING, PROC_REF(on_mind_lost)) + addtimer(CALLBACK(src, PROC_REF(revive)), IMMORTAL_RESURRECT_TIME, TIMER_DELETE_ME) + +/// Copy appearance from ressurecting mob +/obj/effect/spectre_of_resurrection/proc/setup_icon(mob/living/corpse) + icon = initial(corpse.icon) + icon_state = initial(corpse.icon_state) + +/obj/effect/spectre_of_resurrection/Destroy(force) + QDEL_NULL(corpse) + dead_mind = null + return ..() + +/obj/effect/spectre_of_resurrection/Exited(atom/movable/gone, direction) + . = ..() + if (gone != corpse) + return // Weird but ok + UnregisterSignal(corpse, list(COMSIG_LIVING_REVIVE, COMSIG_QDELETING)) + corpse = null + qdel(src) + +/// Bring our body back to life +/obj/effect/spectre_of_resurrection/proc/revive() + if (!isnull(dead_mind)) + if (dead_mind.current == corpse) + dead_mind.grab_ghost(force = TRUE) + else + dead_mind.transfer_to(corpse, force_key_move = TRUE) + corpse.revive(HEAL_ALL) // The signal is sent even if they weren't actually dead + +/// Remove our stored corpse back to the living world +/obj/effect/spectre_of_resurrection/proc/on_corpse_revived() + SIGNAL_HANDLER + if (isnull(corpse)) + return + visible_message(span_boldnotice("[corpse] suddenly shudders to life!")) + corpse.remove_traits(list(TRAIT_NO_TELEPORT, TRAIT_AI_PAUSED), MAGIC_TRAIT) + corpse.remove_status_effect(/datum/status_effect/grouped/stasis, MAGIC_TRAIT) + corpse.forceMove(loc) + +/// If the body is destroyed then we can't come back, F +/obj/effect/spectre_of_resurrection/proc/on_corpse_deleted() + SIGNAL_HANDLER + qdel(src) + +/// If the mind is deleted somehow we just don't transfer it on revival +/obj/effect/spectre_of_resurrection/proc/on_mind_lost() + SIGNAL_HANDLER + dead_mind = null + +/// A ressurection spectre with extra behaviour for humans +/obj/effect/spectre_of_resurrection/human + /// Stored data used to restore someone to a fascimile of what they were before + var/datum/human_appearance_profile/human_appearance + +/obj/effect/spectre_of_resurrection/human/set_up_resurrection(mob/living/corpse, datum/mind/dead_mind, datum/human_appearance_profile/human_appearance) + . = ..() + src.human_appearance = human_appearance + +// We just use a generic floating human appearance to save unecessary costly icon operations +/obj/effect/spectre_of_resurrection/human/setup_icon(mob/living/corpse) + return + +// Apply stored human details +/obj/effect/spectre_of_resurrection/human/on_corpse_revived() + if (isnull(corpse)) + return + human_appearance?.apply_to(corpse) + return ..() + + +/// Visual flair on the wizard when cast +/obj/effect/temp_visual/immortality_blast + name = "immortal wave" + duration = 2.5 SECONDS + icon = 'icons/effects/96x96.dmi' + icon_state = "boh_tear" + color = COLOR_PALE_GREEN + pixel_x = -32 + pixel_y = -32 + +/obj/effect/temp_visual/immortality_blast/Initialize(mapload) + . = ..() + transform *= 0 + animate(src, transform = matrix(), time = 1.5 SECONDS, easing = ELASTIC_EASING) + animate(transform = matrix() * 3, time = 1 SECONDS, alpha = 0, easing = SINE_EASING | EASE_OUT) + + +/// Visual flair on living creatures who have become immortal +/obj/effect/temp_visual/immortality_pulse + name = "immortal pulse" + duration = 1 SECONDS + icon = 'icons/effects/anomalies.dmi' + icon_state = "dimensional_overlay" + color = COLOR_PALE_GREEN + +/obj/effect/temp_visual/immortality_pulse/Initialize(mapload) + . = ..() + transform *= 0 + animate(src, transform = matrix() * 1.5, alpha = 0, time = 1 SECONDS, easing = SINE_EASING | EASE_OUT) + +#undef IMMORTAL_PRE_ACTIVATION_TIME +#undef IMMORTAL_RESURRECT_TIME diff --git a/code/modules/antagonists/wizard/grand_ritual/finales/midas.dm b/code/modules/antagonists/wizard/grand_ritual/finales/midas.dm new file mode 100644 index 00000000000000..b2e3329261f692 --- /dev/null +++ b/code/modules/antagonists/wizard/grand_ritual/finales/midas.dm @@ -0,0 +1,46 @@ +/// Completely transform the station +/datum/grand_finale/midas + name = "Transformation" + desc = "The ultimate use of your gathered power! Turn their precious station into something much MORE precious, materially speaking!" + icon = 'icons/obj/stack_objects.dmi' + icon_state = "sheet-gold_2" + glow_colour = "#dbdd4c48" + var/static/list/permitted_transforms = list( // Non-dangerous only + /datum/dimension_theme/gold, + /datum/dimension_theme/meat, + /datum/dimension_theme/pizza, + /datum/dimension_theme/natural, + ) + var/datum/dimension_theme/chosen_theme + +// I sure hope this doesn't have performance implications +/datum/grand_finale/midas/trigger(mob/living/carbon/human/invoker) + var/theme_path = pick(permitted_transforms) + chosen_theme = new theme_path() + var/turf/start_turf = get_turf(invoker) + var/greatest_dist = 0 + var/list/turfs_to_transform = list() + for (var/turf/transform_turf as anything in GLOB.station_turfs) + if (!chosen_theme.can_convert(transform_turf)) + continue + var/dist = get_dist(start_turf, transform_turf) + if (dist > greatest_dist) + greatest_dist = dist + if (!turfs_to_transform["[dist]"]) + turfs_to_transform["[dist]"] = list() + turfs_to_transform["[dist]"] += transform_turf + + if (chosen_theme.can_convert(start_turf)) + chosen_theme.apply_theme(start_turf) + + for (var/iterator in 1 to greatest_dist) + if(!turfs_to_transform["[iterator]"]) + continue + addtimer(CALLBACK(src, PROC_REF(transform_area), turfs_to_transform["[iterator]"]), (5 SECONDS) * iterator) + +/datum/grand_finale/midas/proc/transform_area(list/turfs) + for (var/turf/transform_turf as anything in turfs) + if (!chosen_theme.can_convert(transform_turf)) + continue + chosen_theme.apply_theme(transform_turf) + CHECK_TICK diff --git a/code/modules/antagonists/wizard/grand_ritual/grand_ritual_finale.dm b/code/modules/antagonists/wizard/grand_ritual/grand_ritual_finale.dm deleted file mode 100644 index 9a59b1f1a79ac3..00000000000000 --- a/code/modules/antagonists/wizard/grand_ritual/grand_ritual_finale.dm +++ /dev/null @@ -1,456 +0,0 @@ -#define DOOM_SINGULARITY "singularity" -#define DOOM_TESLA "tesla" -#define DOOM_METEORS "meteors" - -/** - * A big final event to run when you complete seven rituals - */ -/datum/grand_finale - /// Friendly name for selection menu - var/name - /// Tooltip description for selection menu - var/desc - /// An icon to display to represent the choice - var/icon/icon - /// Icon state to use to represent the choice - var/icon_state - /// Prevent especially dangerous options from being chosen until we're fine with the round ending - var/minimum_time = 0 - /// Override the rune invocation time - var/ritual_invoke_time = 30 SECONDS - /// Provide an extremely loud radio message when this one starts - var/dire_warning = FALSE - /// Overrides the default colour you glow while channeling the rune, optional - var/glow_colour - -/** - * Returns an entry for a radial menu for this choice. - * Returns null if entry is abstract or invalid for current circumstances. - */ -/datum/grand_finale/proc/get_radial_choice() - if (!name || !desc || !icon || !icon_state) - return - var/time_remaining_desc = "" - if (minimum_time >= world.time - SSticker.round_start_time) - time_remaining_desc = "This ritual will be available to begin invoking in [DisplayTimeText(minimum_time - world.time - SSticker.round_start_time)]" - var/datum/radial_menu_choice/choice = new() - choice.name = name - choice.image = image(icon = icon, icon_state = icon_state) - choice.info = desc + time_remaining_desc - return choice - -/** - * Actually do the thing. - * Arguments - * * invoker - The wizard casting this. - */ -/datum/grand_finale/proc/trigger(mob/living/invoker) - // Do something cool. - -/// Tries to equip something into an inventory slot, then hands, then the floor. -/datum/grand_finale/proc/equip_to_slot_then_hands(mob/living/carbon/human/invoker, slot, obj/item/item) - if(!item) - return - if(!invoker.equip_to_slot_if_possible(item, slot, disable_warning = TRUE)) - invoker.put_in_hands(item) - -/// They are not going to take this lying down. -/datum/grand_finale/proc/create_vendetta(datum/mind/aggrieved_crewmate, datum/mind/wizard) - aggrieved_crewmate.add_antag_datum(/datum/antagonist/wizard_prank_vendetta) - var/datum/antagonist/wizard_prank_vendetta/antag_datum = aggrieved_crewmate.has_antag_datum(/datum/antagonist/wizard_prank_vendetta) - var/datum/objective/assassinate/wizard_murder = new - wizard_murder.owner = aggrieved_crewmate - wizard_murder.target = wizard - wizard_murder.explanation_text = "Kill [wizard.current.name], the one who did this." - antag_datum.objectives += wizard_murder - - to_chat(aggrieved_crewmate.current, span_warning("No! This isn't right!")) - aggrieved_crewmate.announce_objectives() - -/** - * Antag datum to give to people who want to kill the wizard. - * This doesn't preclude other people choosing to want to kill the wizard, just these people are rewarded for it. - */ -/datum/antagonist/wizard_prank_vendetta - name = "\improper Wizard Prank Victim" - roundend_category = "wizard prank victims" - show_in_antagpanel = FALSE - antagpanel_category = "Other" - show_name_in_check_antagonists = TRUE - count_against_dynamic_roll_chance = FALSE - silent = TRUE - -/// Become the official Captain of the station -/datum/grand_finale/usurp - name = "Usurpation" - desc = "The ultimate use of your gathered power! Rewrite time such that you have been Captain of this station the whole time." - icon = 'icons/obj/card.dmi' - icon_state = "card_gold" - -/datum/grand_finale/usurp/trigger(mob/living/carbon/human/invoker) - message_admins("[key_name(invoker)] has replaced the Captain") - var/list/former_captains = list() - var/list/other_crew = list() - SEND_SOUND(world, sound('sound/magic/timeparadox2.ogg')) - - for (var/mob/living/carbon/human/crewmate as anything in GLOB.human_list) - if (!crewmate.mind) - continue - crewmate.Unconscious(3 SECONDS) // Everyone falls unconscious but not everyone gets told about a new captain - if (crewmate == invoker || IS_HUMAN_INVADER(crewmate)) - continue - to_chat(crewmate, span_notice("The world spins and dissolves. Your past flashes before your eyes, backwards.\n\ - Life strolls back into the ocean and shrinks into nothingness, planets explode into storms of solar dust, \ - the stars rush back to greet each other at the beginning of things and then... you snap back to the present. \n\ - Everything is just as it was and always has been. \n\n\ - A stray thought sticks in the forefront of your mind. \n\ - [span_hypnophrase("I'm so glad that [invoker.real_name] is our legally appointed Captain!")] \n\ - Is... that right?")) - if (is_captain_job(crewmate.mind.assigned_role)) - former_captains += crewmate - demote_to_assistant(crewmate) - continue - if (crewmate.stat != DEAD) - other_crew += crewmate - - dress_candidate(invoker) - GLOB.manifest.modify(invoker.real_name, JOB_CAPTAIN, JOB_CAPTAIN) - minor_announce("Captain [invoker.real_name] on deck!") - - // Enlist some crew to try and restore the natural order - for (var/mob/living/carbon/human/former_captain as anything in former_captains) - create_vendetta(former_captain.mind, invoker.mind) - for (var/mob/living/carbon/human/random_crewmate as anything in other_crew) - if (prob(10)) - create_vendetta(random_crewmate.mind, invoker.mind) - -/** - * Anyone who thought they were Captain is in for a nasty surprise, and won't be very happy about it - */ -/datum/grand_finale/usurp/proc/demote_to_assistant(mob/living/carbon/human/former_captain) - var/obj/effect/particle_effect/fluid/smoke/exit_poof = new(get_turf(former_captain)) - exit_poof.lifetime = 2 SECONDS - - former_captain.unequip_everything() - if(isplasmaman(former_captain)) - former_captain.equipOutfit(/datum/outfit/plasmaman) - former_captain.internal = former_captain.get_item_for_held_index(2) - else - former_captain.equipOutfit(/datum/outfit/job/assistant) - - GLOB.manifest.modify(former_captain.real_name, JOB_ASSISTANT, JOB_ASSISTANT) - var/list/valid_turfs = list() - // Used to be into prison but that felt a bit too mean - for (var/turf/exile_turf as anything in get_area_turfs(/area/station/maintenance, subtypes = TRUE)) - if (isspaceturf(exile_turf) || exile_turf.is_blocked_turf()) - continue - valid_turfs += exile_turf - do_teleport(former_captain, pick(valid_turfs), no_effects = TRUE) - var/obj/effect/particle_effect/fluid/smoke/enter_poof = new(get_turf(former_captain)) - enter_poof.lifetime = 2 SECONDS - -/** - * Does some item juggling to try to dress you as both a Wizard and Captain without deleting any items you have bought. - * ID, headset, and uniform are forcibly replaced. Other slots are only filled if unoccupied. - * We could forcibly replace shoes and gloves too but people might miss their insuls or... meown shoes? - */ -/datum/grand_finale/usurp/proc/dress_candidate(mob/living/carbon/human/invoker) - // Won't be needing these - var/obj/id = invoker.get_item_by_slot(ITEM_SLOT_ID) - QDEL_NULL(id) - var/obj/headset = invoker.get_item_by_slot(ITEM_SLOT_EARS) - QDEL_NULL(headset) - // We're about to take off your pants so those are going to fall out - var/obj/item/pocket_L = invoker.get_item_by_slot(ITEM_SLOT_LPOCKET) - var/obj/item/pocket_R = invoker.get_item_by_slot(ITEM_SLOT_RPOCKET) - // In case we try to put a PDA there - var/obj/item/belt = invoker.get_item_by_slot(ITEM_SLOT_BELT) - belt?.moveToNullspace() - - var/obj/pants = invoker.get_item_by_slot(ITEM_SLOT_ICLOTHING) - QDEL_NULL(pants) - invoker.equipOutfit(/datum/outfit/job/wizard_captain) - // And put everything back! - equip_to_slot_then_hands(invoker, ITEM_SLOT_BELT, belt) - equip_to_slot_then_hands(invoker, ITEM_SLOT_LPOCKET, pocket_L) - equip_to_slot_then_hands(invoker, ITEM_SLOT_RPOCKET, pocket_R) - -/// An outfit which replaces parts of a wizard's clothes with captain's clothes but keeps the robes -/datum/outfit/job/wizard_captain - name = "Captain (Wizard Transformation)" - jobtype = /datum/job/captain - id = /obj/item/card/id/advanced/gold - id_trim = /datum/id_trim/job/captain - uniform = /obj/item/clothing/under/rank/captain/parade - belt = /obj/item/modular_computer/pda/heads/captain - ears = /obj/item/radio/headset/heads/captain/alt - glasses = /obj/item/clothing/glasses/sunglasses - gloves = /obj/item/clothing/gloves/captain - shoes = /obj/item/clothing/shoes/laceup - accessory = /obj/item/clothing/accessory/medal/gold/captain - backpack_contents = list( - /obj/item/melee/baton/telescopic = 1, - /obj/item/station_charter = 1, - ) - box = null - -/// Dress the crew as magical clowns -/datum/grand_finale/clown - name = "Jubilation" - desc = "The ultimate use of your gathered power! Rewrite time so that everyone went to clown college! Now they'll prank each other for you!" - icon = 'icons/obj/clothing/masks.dmi' - icon_state = "clown" - glow_colour = "#ffff0048" - -/datum/grand_finale/clown/trigger(mob/living/carbon/human/invoker) - for(var/mob/living/carbon/human/victim as anything in GLOB.human_list) - victim.Unconscious(3 SECONDS) - if (!victim.mind || IS_HUMAN_INVADER(victim) || victim == invoker) - continue - if (HAS_TRAIT(victim, TRAIT_CLOWN_ENJOYER)) - victim.add_mood_event("clown_world", /datum/mood_event/clown_world) - to_chat(victim, span_notice("The world spins and dissolves. Your past flashes before your eyes, backwards.\n\ - Life strolls back into the ocean and shrinks into nothingness, planets explode into storms of solar dust, \ - the stars rush back to greet each other at the beginning of things and then... you snap back to the present. \n\ - Everything is just as it was and always has been. \n\n\ - A stray thought sticks in the forefront of your mind. \n\ - [span_hypnophrase("I'm so glad that I work at Clown Research Station [station_name()]!")] \n\ - Is... that right?")) - if (is_clown_job(victim.mind.assigned_role)) - var/datum/action/cooldown/spell/conjure_item/clown_pockets/new_spell = new(victim) - new_spell.Grant(victim) - continue - if (!ismonkey(victim)) // Monkeys cannot yet wear clothes - dress_as_magic_clown(victim) - if (prob(15)) - create_vendetta(victim.mind, invoker.mind) - -/** - * Clown enjoyers who are effected by this become ecstatic, they have achieved their life's dream. - * This moodlet is equivalent to the one for simply being a traitor. - */ -/datum/mood_event/clown_world - mood_change = 4 - -/datum/mood_event/clown_world/add_effects(param) - description = "I LOVE working at Clown Research Station [station_name()]!!" - -/// Dress the passed mob as a magical clown, self-explanatory -/datum/grand_finale/clown/proc/dress_as_magic_clown(mob/living/carbon/human/victim) - var/obj/effect/particle_effect/fluid/smoke/poof = new(get_turf(victim)) - poof.lifetime = 2 SECONDS - - var/obj/item/tank/internal = victim.internal - // We're about to take off your pants so those are going to fall out - var/obj/item/pocket_L = victim.get_item_by_slot(ITEM_SLOT_LPOCKET) - var/obj/item/pocket_R = victim.get_item_by_slot(ITEM_SLOT_RPOCKET) - var/obj/item/id = victim.get_item_by_slot(ITEM_SLOT_ID) - var/obj/item/belt = victim.get_item_by_slot(ITEM_SLOT_BELT) - - var/obj/pants = victim.get_item_by_slot(ITEM_SLOT_ICLOTHING) - var/obj/mask = victim.get_item_by_slot(ITEM_SLOT_MASK) - QDEL_NULL(pants) - QDEL_NULL(mask) - if(isplasmaman(victim)) - victim.equip_to_slot_if_possible(new /obj/item/clothing/under/plasmaman/clown/magic(), ITEM_SLOT_ICLOTHING, disable_warning = TRUE) - victim.equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/clown_hat/plasmaman(), ITEM_SLOT_MASK, disable_warning = TRUE) - else - victim.equip_to_slot_if_possible(new /obj/item/clothing/under/rank/civilian/clown/magic(), ITEM_SLOT_ICLOTHING, disable_warning = TRUE) - victim.equip_to_slot_if_possible(new /obj/item/clothing/mask/gas/clown_hat(), ITEM_SLOT_MASK, disable_warning = TRUE) - - var/obj/item/clothing/mask/gas/clown_hat/clown_mask = victim.get_item_by_slot(ITEM_SLOT_MASK) - if (clown_mask) - var/list/options = GLOB.clown_mask_options - clown_mask.icon_state = options[pick(clown_mask.clownmask_designs)] - victim.update_worn_mask() - clown_mask.update_item_action_buttons() - - equip_to_slot_then_hands(victim, ITEM_SLOT_LPOCKET, pocket_L) - equip_to_slot_then_hands(victim, ITEM_SLOT_RPOCKET, pocket_R) - equip_to_slot_then_hands(victim, ITEM_SLOT_ID, id) - equip_to_slot_then_hands(victim, ITEM_SLOT_BELT, belt) - victim.internal = internal - -/// Give everyone magic items -/datum/grand_finale/magic - name = "Evolution" - desc = "The ultimate use of your gathered power! Give the crew their own magic, they'll surely realise that right and wrong have no meaning when you hold ultimate power!" - icon = 'icons/obj/scrolls.dmi' - icon_state = "scroll" - -/datum/grand_finale/magic/trigger(mob/living/carbon/human/invoker) - message_admins("[key_name(invoker)] summoned magic") - summon_magic(survivor_probability = 20) // Wow, this one was easy! - -/// Open all of the doors -/datum/grand_finale/all_access - name = "Connection" - desc = "The ultimate use of your gathered power! Unlock every single door that they have! Nobody will be able to keep you out now, or anyone else for that matter!" - icon = 'icons/mob/actions/actions_spells.dmi' - icon_state = "knock" - -/datum/grand_finale/all_access/trigger(mob/living/carbon/human/invoker) - message_admins("[key_name(invoker)] removed all door access requirements") - for(var/obj/machinery/door/target_door as anything in SSmachines.get_machines_by_type_and_subtypes(/obj/machinery/door)) - if(is_station_level(target_door.z)) - target_door.unlock() - target_door.req_access = list() - target_door.req_one_access = list() - INVOKE_ASYNC(target_door, TYPE_PROC_REF(/obj/machinery/door/airlock, open)) - CHECK_TICK - priority_announce("AULIE OXIN FIERA!!", null, 'sound/magic/knock.ogg', sender_override = "[invoker.real_name]") - -/// Completely transform the station -/datum/grand_finale/midas - name = "Transformation" - desc = "The ultimate use of your gathered power! Turn their precious station into something much MORE precious, materially speaking!" - icon = 'icons/obj/stack_objects.dmi' - icon_state = "sheet-gold_2" - glow_colour = "#dbdd4c48" - var/static/list/permitted_transforms = list( // Non-dangerous only - /datum/dimension_theme/gold, - /datum/dimension_theme/meat, - /datum/dimension_theme/pizza, - /datum/dimension_theme/natural, - ) - var/datum/dimension_theme/chosen_theme - -// I sure hope this doesn't have performance implications -/datum/grand_finale/midas/trigger(mob/living/carbon/human/invoker) - var/theme_path = pick(permitted_transforms) - chosen_theme = new theme_path() - var/turf/start_turf = get_turf(invoker) - var/greatest_dist = 0 - var/list/turfs_to_transform = list() - for (var/turf/transform_turf as anything in GLOB.station_turfs) - if (!chosen_theme.can_convert(transform_turf)) - continue - var/dist = get_dist(start_turf, transform_turf) - if (dist > greatest_dist) - greatest_dist = dist - if (!turfs_to_transform["[dist]"]) - turfs_to_transform["[dist]"] = list() - turfs_to_transform["[dist]"] += transform_turf - - if (chosen_theme.can_convert(start_turf)) - chosen_theme.apply_theme(start_turf) - - for (var/iterator in 1 to greatest_dist) - if(!turfs_to_transform["[iterator]"]) - continue - addtimer(CALLBACK(src, PROC_REF(transform_area), turfs_to_transform["[iterator]"]), (5 SECONDS) * iterator) - -/datum/grand_finale/midas/proc/transform_area(list/turfs) - for (var/turf/transform_turf as anything in turfs) - if (!chosen_theme.can_convert(transform_turf)) - continue - chosen_theme.apply_theme(transform_turf) - CHECK_TICK - -/// Kill yourself and probably a bunch of other people -/datum/grand_finale/armageddon - name = "Annihilation" - desc = "This crew have offended you beyond the realm of pranks. Make the ultimate sacrifice to teach them a lesson your elders can really respect. \ - YOU WILL NOT SURVIVE THIS." - icon = 'icons/hud/screen_alert.dmi' - icon_state = "wounded" - minimum_time = 90 MINUTES // This will probably immediately end the round if it gets finished. - ritual_invoke_time = 60 SECONDS // Really give the crew some time to interfere with this one. - dire_warning = TRUE - glow_colour = "#be000048" - /// Things to yell before you die - var/static/list/possible_last_words = list( - "Flames and ruin!", - "Dooooooooom!!", - "HAHAHAHAHAHA!! AHAHAHAHAHAHAHAHAA!!", - "Hee hee hee!! Hoo hoo hoo!! Ha ha haaa!!", - "Ohohohohohoho!!", - "Cower in fear, puny mortals!", - "Tremble before my glory!", - "Pick a god and pray!", - "It's no use!", - "If the gods wanted you to live, they would not have created me!", - "God stays in heaven out of fear of what I have created!", - "Ruination is come!", - "All of creation, bend to my will!", - ) - -/datum/grand_finale/armageddon/trigger(mob/living/carbon/human/invoker) - priority_announce(pick(possible_last_words), null, 'sound/magic/voidblink.ogg', sender_override = "[invoker.real_name]") - var/turf/current_location = get_turf(invoker) - invoker.gib() - - var/static/list/doom_options = list() - if (!length(doom_options)) - doom_options = list(DOOM_SINGULARITY, DOOM_TESLA) - if (!SSmapping.config.planetary) - doom_options += DOOM_METEORS - - switch(pick(doom_options)) - if (DOOM_SINGULARITY) - var/obj/singularity/singulo = new(current_location) - singulo.energy = 300 - if (DOOM_TESLA) - var/obj/energy_ball/tesla = new (current_location) - tesla.energy = 200 - if (DOOM_METEORS) - var/datum/dynamic_ruleset/roundstart/meteor/meteors = new() - meteors.meteordelay = 0 - var/datum/game_mode/dynamic/mode = SSticker.mode - mode.execute_roundstart_rule(meteors) // Meteors will continue until morale is crushed. - priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", ANNOUNCER_METEORS) - -/** - * Gives the wizard a defensive/mood buff and a Wabbajack, a juiced up chaos staff that will surely break something. - * Everyone but the wizard goes crazy, suffers major brain damage, and is given a vendetta against the wizard. - * Already insane people are instead cured of their madness, ignoring any other effects as the station around them loses its marbles. - */ -/datum/grand_finale/cheese - // we don't set name, desc and others, thus we won't appear in the radial choice of a normal finale rune - dire_warning = TRUE - minimum_time = 45 MINUTES //i'd imagine speedrunning this would be crummy, but the wizard's average lifespan is barely reaching this point - -/datum/grand_finale/cheese/trigger(mob/living/invoker) - message_admins("[key_name(invoker)] has summoned forth The Wabbajack and cursed the crew with madness!") - priority_announce("Danger: Extremely potent reality altering object has been summoned on station. Immediate evacuation advised. Brace for impact.", "Central Command Higher Dimensional Affairs", 'sound/effects/glassbr1.ogg') - - for (var/mob/living/carbon/human/crewmate as anything in GLOB.human_list) - if (isnull(crewmate.mind)) - continue - if (crewmate == invoker) //everyone but the wizard is royally fucked, no matter who they are - continue - if (crewmate.has_trauma_type(/datum/brain_trauma/mild/hallucinations)) //for an already insane person, this is retribution - to_chat(crewmate, span_boldwarning("Your surroundings suddenly fill with a cacophony of manic laughter and psychobabble...")) - to_chat(crewmate, span_nicegreen("...but as the moment passes, you realise that whatever eldritch power behind the event happened to affect you \ - has resonated within the ruins of your already shattered mind, creating a singularity of mental instability! \ - As it collapses unto itself, you feel... at peace, finally.")) - if(crewmate.has_quirk(/datum/quirk/insanity)) - crewmate.remove_quirk(/datum/quirk/insanity) - else - crewmate.cure_trauma_type(/datum/brain_trauma/mild/hallucinations, TRAUMA_RESILIENCE_ABSOLUTE) - else - //everyone else gets to relish in madness - //yes killing their mood will also trigger mood hallucinations - create_vendetta(crewmate.mind, invoker.mind) - to_chat(crewmate, span_boldwarning("Your surroundings suddenly fill with a cacophony of manic laughter and psychobabble. \n\ - You feel your inner psyche shatter into a myriad pieces of jagged glass of colors unknown to the universe, \ - infinitely reflecting a blinding, maddening light coming from the innermost sanctums of your destroyed mind. \n\ - After a brief pause which felt like a millenia, one phrase rebounds ceaselessly in your head, imbued with the false hope of absolution... \n\ - [invoker] must die.")) - var/datum/brain_trauma/mild/hallucinations/added_trauma = new() - added_trauma.resilience = TRAUMA_RESILIENCE_ABSOLUTE - crewmate.adjustOrganLoss(ORGAN_SLOT_BRAIN, BRAIN_DAMAGE_DEATH - 25, BRAIN_DAMAGE_DEATH - 25) //you'd better hope chap didn't pick a hypertool - crewmate.gain_trauma(added_trauma) - crewmate.add_mood_event("wizard_ritual_finale", /datum/mood_event/madness_despair) - - //drip our wizard out - invoker.apply_status_effect(/datum/status_effect/blessing_of_insanity) - invoker.add_mood_event("wizard_ritual_finale", /datum/mood_event/madness_elation) - var/obj/item/gun/magic/staff/chaos/true_wabbajack/the_wabbajack = new - invoker.put_in_active_hand(the_wabbajack) - to_chat(invoker, span_mind_control("Your every single instinct and rational thought is screaming at you as [the_wabbajack] appears in your firm grip...")) - -#undef DOOM_SINGULARITY -#undef DOOM_TESLA -#undef DOOM_METEORS - diff --git a/code/modules/art/paintings.dm b/code/modules/art/paintings.dm index e2448c1aaccf21..9a18a2b026951b 100644 --- a/code/modules/art/paintings.dm +++ b/code/modules/art/paintings.dm @@ -249,7 +249,7 @@ painting_metadata.patron_name = user.real_name painting_metadata.credit_value = offer_amount last_patron = WEAKREF(user.mind) - to_chat(user, span_notice("Nanotrasen Trust Foundation thanks you for your contribution. You're now offical patron of this painting.")) + to_chat(user, span_notice("Nanotrasen Trust Foundation thanks you for your contribution. You're now an official patron of this painting.")) var/list/possible_frames = SSpersistent_paintings.get_available_frames(offer_amount) if(possible_frames.len <= 1) // Not much room for choices here. return diff --git a/code/modules/asset_cache/assets/rcd.dm b/code/modules/asset_cache/assets/rcd.dm index e4c54929dae19f..c57d7881d13040 100644 --- a/code/modules/asset_cache/assets/rcd.dm +++ b/code/modules/asset_cache/assets/rcd.dm @@ -14,6 +14,7 @@ 'icons/obj/smooth_structures/catwalk.dmi' = list("catwalk-0"), 'icons/hud/radial.dmi' = list("cnorth", "csouth", "ceast", "cwest", "chair", "secure_windoor", "stool", "wallfloor", "windowsize", "windowtype", "windoor"), 'icons/obj/structures.dmi' = list("glass_table", "rack", "rwindow0", "reflector_base", "table", "window0", "girder"), + 'icons/obj/machines/microwave.dmi' = list("engi_mw_complete"), ) var/icon/icon diff --git a/code/modules/atmospherics/gasmixtures/gas_types.dm b/code/modules/atmospherics/gasmixtures/gas_types.dm index ae3367ace5932e..060b5a12ae9a91 100644 --- a/code/modules/atmospherics/gasmixtures/gas_types.dm +++ b/code/modules/atmospherics/gasmixtures/gas_types.dm @@ -64,6 +64,8 @@ ///How does a single mole of this gas sell for? Formula to calculate maximum value is in code\modules\cargo\exports\large_objects.dm. Doesn't matter for roundstart gasses. var/base_value = 0 var/desc + ///RGB code for use when a generic color representing the gas is needed. Colors taken from contants.ts + var/primary_color /datum/gas/oxygen @@ -74,6 +76,7 @@ purchaseable = TRUE base_value = 0.2 desc = "The gas most life forms need to be able to survive. Also an oxidizer." + primary_color = "#0000ff" /datum/gas/nitrogen id = GAS_N2 @@ -83,6 +86,7 @@ purchaseable = TRUE base_value = 0.1 desc = "A very common gas that used to pad artifical atmospheres to habitable pressure." + primary_color = "#ffff00" /datum/gas/carbon_dioxide //what the fuck is this? id = GAS_CO2 @@ -93,6 +97,7 @@ purchaseable = TRUE base_value = 0.2 desc = "What the fuck is carbon dioxide?" + primary_color = "#808080" /datum/gas/plasma id = GAS_PLASMA @@ -104,6 +109,7 @@ rarity = 800 base_value = 1.5 desc = "A flammable gas with many other curious properties. It's research is one of NT's primary objective." + primary_color = "#ffc0cb" /datum/gas/water_vapor id = GAS_WATER_VAPOR @@ -116,6 +122,7 @@ purchaseable = TRUE base_value = 0.5 desc = "Water, in gas form. Makes things slippery." + primary_color = "#b0c4de" /datum/gas/hypernoblium id = GAS_HYPER_NOBLIUM @@ -127,6 +134,7 @@ rarity = 50 base_value = 2.5 desc = "The most noble gas of them all. High quantities of hyper-noblium actively prevents reactions from occuring." + primary_color = "#008080" /datum/gas/nitrous_oxide id = GAS_N2O @@ -140,6 +148,7 @@ purchaseable = TRUE base_value = 1.5 desc = "Causes drowsiness, euphoria, and eventually unconsciousness." + primary_color = "#ffe4c4" /datum/gas/nitrium id = GAS_NITRIUM @@ -152,6 +161,7 @@ rarity = 1 base_value = 6 desc = "An experimental performance enhancing gas. Nitrium can have amplified effects as more of it gets into your bloodstream." + primary_color = "#a52a2a" /datum/gas/tritium id = GAS_TRITIUM @@ -164,6 +174,7 @@ rarity = 300 base_value = 2.5 desc = "A highly flammable and radioctive gas." + primary_color = "#32cd32" /datum/gas/bz id = GAS_BZ @@ -175,6 +186,7 @@ purchaseable = TRUE base_value = 1.5 desc = "A powerful hallucinogenic nerve agent able to induce cognitive damage." + primary_color = "#9370db" /datum/gas/pluoxium id = GAS_PLUOXIUM @@ -184,6 +196,7 @@ rarity = 200 base_value = 2.5 desc = "A gas that could supply even more oxygen to the bloodstream when inhaled, without being an oxidizer." + primary_color = "#7b68ee" /datum/gas/miasma id = GAS_MIASMA @@ -195,6 +208,7 @@ rarity = 250 base_value = 1 desc = "Not necessarily a gas, miasma refers to biological pollutants found in the atmosphere." + primary_color = "#808000" /datum/gas/freon id = GAS_FREON @@ -207,6 +221,7 @@ rarity = 10 base_value = 5 desc = "A coolant gas. Mainly used for it's endothermic reaction with oxygen." + primary_color = "#afeeee" /datum/gas/hydrogen id = GAS_HYDROGEN @@ -217,6 +232,7 @@ rarity = 600 base_value = 1 desc = "A highly flammable gas." + primary_color = "#ffffff" /datum/gas/healium id = GAS_HEALIUM @@ -228,6 +244,7 @@ rarity = 300 base_value = 5.5 desc = "Causes deep, regenerative sleep." + primary_color = "#fa8072" /datum/gas/proto_nitrate id = GAS_PROTO_NITRATE @@ -239,6 +256,7 @@ rarity = 200 base_value = 2.5 desc = "A very volatile gas that reacts differently with various gases." + primary_color = "#adff2f" /datum/gas/zauker id = GAS_ZAUKER @@ -250,6 +268,7 @@ rarity = 1 base_value = 7 desc = "A highly toxic gas, it's production is highly regulated on top of being difficult. It also breaks down when in contact with nitrogen." + primary_color = "#006400" /datum/gas/halon id = GAS_HALON @@ -261,6 +280,7 @@ rarity = 300 base_value = 4 desc = "A potent fire supressant. Removes oxygen from high temperature fires and cools down the area" + primary_color = "#800080" /datum/gas/helium id = GAS_HELIUM @@ -270,6 +290,7 @@ rarity = 50 base_value = 3.5 desc = "A very inert gas produced by the fusion of hydrogen and it's derivatives." + primary_color = "#f0f8ff" /datum/gas/antinoblium id = GAS_ANTINOBLIUM @@ -282,6 +303,7 @@ rarity = 1 base_value = 10 desc = "We still don't know what it does, but it sells for a lot." + primary_color = "#800000" /obj/effect/overlay/gas icon = 'icons/effects/atmospherics.dmi' diff --git a/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm b/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm index a11f439ec314bd..e629c14e0fef0b 100644 --- a/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm +++ b/code/modules/atmospherics/machinery/air_alarm/_air_alarm.dm @@ -112,7 +112,7 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm) my_area = connected_sensor ? get_area(connected_sensor) : get_area(src) alarm_manager = new(src) - select_mode(src, /datum/air_alarm_mode/filtering) + select_mode(src, /datum/air_alarm_mode/filtering, should_apply = FALSE) AddElement(/datum/element/connect_loc, atmos_connections) AddComponent(/datum/component/usb_port, list( @@ -587,14 +587,15 @@ GLOBAL_LIST_EMPTY_TYPED(air_alarms, /obj/machinery/airalarm) selected_mode.replace(my_area, pressure) -/obj/machinery/airalarm/proc/select_mode(atom/source, datum/air_alarm_mode/mode_path) +/obj/machinery/airalarm/proc/select_mode(atom/source, datum/air_alarm_mode/mode_path, should_apply = TRUE) var/datum/air_alarm_mode/new_mode = GLOB.air_alarm_modes[mode_path] if(!new_mode) return if(new_mode.emag && !(obj_flags & EMAGGED)) return selected_mode = new_mode - selected_mode.apply(my_area) + if(should_apply) + selected_mode.apply(my_area) SEND_SIGNAL(src, COMSIG_AIRALARM_UPDATE_MODE, source) MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/airalarm, 27) diff --git a/code/modules/atmospherics/machinery/atmosmachinery.dm b/code/modules/atmospherics/machinery/atmosmachinery.dm index 417e5055de7552..62c2b562d5129d 100644 --- a/code/modules/atmospherics/machinery/atmosmachinery.dm +++ b/code/modules/atmospherics/machinery/atmosmachinery.dm @@ -352,9 +352,9 @@ return /** - * Similar to set_pipenet() but instead of setting a network to a pipeline, it replaces the old pipeline with a new one, called by Merge() in datum_pipeline.dm + * Replaces the connection to the old_pipenet with the new_pipenet */ -/obj/machinery/atmospherics/proc/replace_pipenet() +/obj/machinery/atmospherics/proc/replace_pipenet(datum/pipeline/old_pipenet, datum/pipeline/new_pipenet) return /** diff --git a/code/modules/atmospherics/machinery/datum_pipeline.dm b/code/modules/atmospherics/machinery/datum_pipeline.dm index 2c56aba6831fbe..2abb282711ba87 100644 --- a/code/modules/atmospherics/machinery/datum_pipeline.dm +++ b/code/modules/atmospherics/machinery/datum_pipeline.dm @@ -1,5 +1,7 @@ /datum/pipeline + /// The gases contained within this pipeline var/datum/gas_mixture/air + /// The gas_mixtures of objects directly connected to this pipeline var/list/datum/gas_mixture/other_airs var/list/obj/machinery/atmospherics/pipe/members @@ -8,6 +10,10 @@ /// We're essentially caching this to avoid needing to filter over it when processing our machines var/list/obj/machinery/atmospherics/components/require_custom_reconcilation + /// The weighted color blend of the gas mixture in this pipeline + var/gasmix_color + /// A named list of icon_file:overlay_object that gets automatically colored when the gasmix_color updates + var/list/gas_visuals ///Should we equalize air amoung all our members? var/update = TRUE @@ -19,6 +25,7 @@ members = list() other_atmos_machines = list() require_custom_reconcilation = list() + gas_visuals = list() SSair.networks += src /datum/pipeline/Destroy() @@ -28,7 +35,7 @@ if(air?.volume) temporarily_store_air() for(var/obj/machinery/atmospherics/pipe/considered_pipe in members) - considered_pipe.parent = null + considered_pipe.replace_pipenet(considered_pipe.parent, null) if(QDELETED(considered_pipe)) continue SSair.add_to_rebuild_queue(considered_pipe) @@ -42,6 +49,13 @@ reconcile_air() //Only react if the mix has changed, and don't keep updating if it hasn't update = air.react(src) + CalculateGasmixColor(air) + +/datum/pipeline/proc/set_air(datum/gas_mixture/new_air) + if(new_air == air) + return + air = new_air + CalculateGasmixColor(air) ///Preps a pipeline for rebuilding, insterts it into the rebuild queue /datum/pipeline/proc/build_pipeline(obj/machinery/atmospherics/base) @@ -52,13 +66,13 @@ volume = considered_pipe.volume members += considered_pipe if(considered_pipe.air_temporary) - air = considered_pipe.air_temporary + set_air(considered_pipe.air_temporary) considered_pipe.air_temporary = null else add_machinery_member(base) if(!air) - air = new + set_air(new /datum/gas_mixture) air.volume = volume SSair.add_to_expansion(src, base) @@ -71,13 +85,13 @@ volume = considered_pipe.volume members += considered_pipe if(considered_pipe.air_temporary) - air = considered_pipe.air_temporary + set_air(considered_pipe.air_temporary) considered_pipe.air_temporary = null else add_machinery_member(base) if(!air) - air = new + set_air(new /datum/gas_mixture) var/list/possible_expansions = list(base) while(possible_expansions.len) for(var/obj/machinery/atmospherics/borderline in possible_expansions) @@ -105,7 +119,7 @@ possible_expansions += item volume += item.volume - item.parent = src + item.replace_pipenet(item.parent, src) if(item.air_temporary) air.merge(item.air_temporary) @@ -142,7 +156,7 @@ var/obj/machinery/atmospherics/pipe/reference_pipe = reference_device if(reference_pipe.parent) merge(reference_pipe.parent) - reference_pipe.parent = src + reference_pipe.replace_pipenet(reference_pipe.parent, src) var/list/adjacent = reference_pipe.pipeline_expansion() for(var/obj/machinery/atmospherics/pipe/adjacent_pipe in adjacent) if(adjacent_pipe.parent == src) @@ -159,7 +173,7 @@ air.volume += parent_pipeline.air.volume members.Add(parent_pipeline.members) for(var/obj/machinery/atmospherics/pipe/reference_pipe in parent_pipeline.members) - reference_pipe.parent = src + reference_pipe.replace_pipenet(reference_pipe.parent, src) air.merge(parent_pipeline.air) for(var/obj/machinery/atmospherics/components/reference_component in parent_pipeline.other_atmos_machines) reference_component.replace_pipenet(parent_pipeline, src) @@ -295,3 +309,64 @@ //Update individual gas_mixtures by volume ratio for(var/datum/gas_mixture/gas_mixture as anything in gas_mixture_list) gas_mixture.copy_from_ratio(total_gas_mixture, gas_mixture.volume / volume_sum) + +//-------------------- +// GAS VISUALS STUFF +// +// If I could have gotten layer filters to obey the RESET_COLOR appearance flag I would have used that here +// so that only a single overlay object needs to exist for all pipelines per icon file. It shouldn't be too +// hard to switch over to that if it becomes possible in the future or some other equivalent feature is added. + +/** + * Used to create and/or get the gas visual overlay created using the given icon file. + * The color is automatically kept up to date and expected to be used as a vis_contents object. + */ +/datum/pipeline/proc/GetGasVisual(icon/icon_file) + if(gas_visuals[icon_file]) + return gas_visuals[icon_file] + + var/obj/effect/abstract/new_overlay = new + new_overlay.icon = icon_file + new_overlay.appearance_flags = RESET_COLOR | KEEP_APART + new_overlay.vis_flags = VIS_INHERIT_ICON_STATE | VIS_INHERIT_LAYER | VIS_INHERIT_PLANE | VIS_INHERIT_ID + new_overlay.color = gasmix_color + + gas_visuals[icon_file] = new_overlay + return new_overlay + +/// Called when the gasmix color has changed and the gas visuals need to be updated. +/datum/pipeline/proc/UpdateGasVisuals() + for(var/icon/source as anything in gas_visuals) + var/obj/effect/abstract/overlay = gas_visuals[source] + animate(overlay, time=5, color=gasmix_color) + +/// After updating, this proc handles looking at the new gas mixture and blends the colors together according to percentage of the gas mix. +/datum/pipeline/proc/CalculateGasmixColor(datum/gas_mixture/source) + SIGNAL_HANDLER + + var/current_weight = 0 + var/current_color + for(var/datum/gas/gas_path as anything in air.gases) + var/gas_weight = air.gases[gas_path][MOLES] + if(!gas_weight) + continue + var/gas_color = RGBtoHSV(initial(gas_path.primary_color)) + current_weight += gas_weight + if(!current_color) + current_color = gas_color + else + current_color = BlendHSV(current_color, gas_color, gas_weight / current_weight) + + if(!current_color) + current_color = "#000000" + else + // Empty weight is prety much arbitrary, just tuned to make the color change from black reasonably quickly without hitting max color immediately + var/empty_weight = (air.volume * 1.5 - current_weight) / 10 + if(empty_weight > 0) + current_color = BlendHSV("#000000", current_color, current_weight / (empty_weight + current_weight)) + + current_color = HSVtoRGB(current_color) + + if(gasmix_color != current_color) + gasmix_color = current_color + UpdateGasVisuals() diff --git a/code/modules/atmospherics/machinery/pipes/bridge_pipe.dm b/code/modules/atmospherics/machinery/pipes/bridge_pipe.dm index 9cda298ccd4c9a..472cb3ed2034a8 100644 --- a/code/modules/atmospherics/machinery/pipes/bridge_pipe.dm +++ b/code/modules/atmospherics/machinery/pipes/bridge_pipe.dm @@ -13,6 +13,8 @@ construction_type = /obj/item/pipe/binary pipe_state = "bridge_center" + has_gas_visuals = FALSE + /obj/machinery/atmospherics/pipe/bridge_pipe/set_init_directions() switch(dir) if(NORTH, SOUTH) diff --git a/code/modules/atmospherics/machinery/pipes/color_adapter.dm b/code/modules/atmospherics/machinery/pipes/color_adapter.dm index 02c550fd558596..06812aaa6496f6 100644 --- a/code/modules/atmospherics/machinery/pipes/color_adapter.dm +++ b/code/modules/atmospherics/machinery/pipes/color_adapter.dm @@ -16,6 +16,8 @@ paintable = FALSE hide = FALSE + has_gas_visuals = FALSE + ///cache for the icons var/static/list/mutable_appearance/center_cache = list() @@ -34,7 +36,7 @@ . = ..() var/mutable_appearance/center = center_cache["[piping_layer]"] if(!center) - center = mutable_appearance(icon, "adapter_center") + center = mutable_appearance(initial(icon), "adapter_center") PIPING_LAYER_DOUBLE_SHIFT(center, piping_layer) center_cache["[piping_layer]"] = center . += center diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm index 05350445370343..39b65fda7af313 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/he_pipes.dm @@ -8,6 +8,8 @@ hide = FALSE + has_gas_visuals = FALSE + /obj/machinery/atmospherics/pipe/heat_exchanging/Initialize(mapload) . = ..() diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm index 00ef058333a407..a6bfcc533d2405 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/junction.dm @@ -15,6 +15,8 @@ construction_type = /obj/item/pipe/directional pipe_state = "junction" + has_gas_visuals = FALSE + /obj/machinery/atmospherics/pipe/heat_exchanging/junction/set_init_directions() switch(dir) if(NORTH, SOUTH) diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm index e340d7f54ccf17..5841486ba9bbc6 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold.dm @@ -16,6 +16,8 @@ construction_type = /obj/item/pipe/trinary pipe_state = "he_manifold" + has_gas_visuals = FALSE + /obj/machinery/atmospherics/pipe/heat_exchanging/manifold/set_init_directions() initialize_directions = ALL_CARDINALS initialize_directions &= ~dir diff --git a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm index 03ef32b4354538..83870ee210b67d 100644 --- a/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm +++ b/code/modules/atmospherics/machinery/pipes/heat_exchange/manifold4w.dm @@ -15,6 +15,8 @@ construction_type = /obj/item/pipe/quaternary pipe_state = "he_manifold4w" + has_gas_visuals = FALSE + /obj/machinery/atmospherics/pipe/heat_exchanging/manifold4w/set_init_directions() initialize_directions = initial(initialize_directions) diff --git a/code/modules/atmospherics/machinery/pipes/layermanifold.dm b/code/modules/atmospherics/machinery/pipes/layermanifold.dm index bdfbda9ba6c780..09c8a3a9367ae7 100644 --- a/code/modules/atmospherics/machinery/pipes/layermanifold.dm +++ b/code/modules/atmospherics/machinery/pipes/layermanifold.dm @@ -12,6 +12,7 @@ construction_type = /obj/item/pipe/binary pipe_state = "manifoldlayer" paintable = TRUE + has_gas_visuals = FALSE ///Reference to all the nodes in the front var/list/front_nodes diff --git a/code/modules/atmospherics/machinery/pipes/multiz.dm b/code/modules/atmospherics/machinery/pipes/multiz.dm index cfc24ab82912bf..7e14b8a98063ea 100644 --- a/code/modules/atmospherics/machinery/pipes/multiz.dm +++ b/code/modules/atmospherics/machinery/pipes/multiz.dm @@ -15,6 +15,8 @@ construction_type = /obj/item/pipe/directional pipe_state = "multiz" + has_gas_visuals = FALSE + ///Our central icon var/mutable_appearance/center = null ///The pipe icon diff --git a/code/modules/atmospherics/machinery/pipes/pipe_spritesheet_helper.dm b/code/modules/atmospherics/machinery/pipes/pipe_spritesheet_helper.dm new file mode 100644 index 00000000000000..9642442a9733f5 --- /dev/null +++ b/code/modules/atmospherics/machinery/pipes/pipe_spritesheet_helper.dm @@ -0,0 +1,148 @@ +/client/proc/GeneratePipeSpritesheet() + set name = "Generate Pipe Spritesheet" + set category = "Debug" + + var/datum/pipe_icon_generator/generator = new + generator.Start() + fcopy(generator.generated_icons, "icons/obj/pipes_n_cables/!pipes_bitmask.dmi") + + generator.Start("-gas") + fcopy(generator.generated_icons, "icons/obj/pipes_n_cables/!pipe_gas_overlays.dmi") + +/datum/pipe_icon_generator + var/static/icon/template_pieces = icon('icons/obj/pipes_n_cables/pipe_template_pieces.dmi') + var/static/list/icon/damage_masks = list( + "[NORTH]"=icon('icons/obj/pipes_n_cables/pipe_template_pieces.dmi', "damage_mask", NORTH), + "[EAST]"=icon('icons/obj/pipes_n_cables/pipe_template_pieces.dmi', "damage_mask", EAST), + "[SOUTH]"=icon('icons/obj/pipes_n_cables/pipe_template_pieces.dmi', "damage_mask", SOUTH), + "[WEST]"=icon('icons/obj/pipes_n_cables/pipe_template_pieces.dmi', "damage_mask", WEST), + ) + + var/icon/generated_icons + +/datum/pipe_icon_generator/proc/Start(icon_state_suffix="") + var/list/outputs = list() + for(var/layer in 1 to 5) + // Since dirs are bitflags, if we want to iterate over every possible direction + // combination we just need to iterate over every number that can be contained in 4 bits. + // + // I wrote this all the hard way originally >.> + for(var/combined_dirs in 1 to 15) + switch(combined_dirs) + if(NORTH, EAST, SOUTH, WEST) + continue + + outputs += GeneratePipeDir(icon_state_suffix, layer, combined_dirs) + + generated_icons = icon('icons/testing/greyscale_error.dmi') + for(var/icon/generated_icon as anything in outputs) + var/pending_icon_state = outputs[generated_icon] + generated_icons.Insert(generated_icon, pending_icon_state) + +/datum/pipe_icon_generator/proc/GeneratePipeDir(icon_state_suffix, layer, combined_dirs) + var/list/output + + switch(combined_dirs) + if(NORTH | SOUTH, EAST | WEST) + output = GeneratePipeStraight(icon_state_suffix, layer, combined_dirs) + if(NORTH | EAST, SOUTH | EAST, SOUTH | WEST, NORTH | WEST) + output = GeneratePipeElbow(icon_state_suffix, layer, combined_dirs) + if(NORTH | EAST | SOUTH, EAST | SOUTH | WEST, SOUTH | WEST | NORTH, WEST | NORTH | EAST) + output = GeneratePipeTJunction(icon_state_suffix, layer, combined_dirs) + if(NORTH | EAST | SOUTH | WEST) + output = GeneratePipeCross(icon_state_suffix, layer, combined_dirs) + + var/shift_amount = (layer - 1) * 5 + for(var/icon/sprite as anything in output) + if(shift_amount > 0) + sprite.Shift(EAST, shift_amount) + sprite.Shift(NORTH, shift_amount) + sprite.Crop(33, 33, 64, 64) + + return output + +/// Generates all variants of damaged pipe from a given icon and the dirs that can be broken +/datum/pipe_icon_generator/proc/GenerateDamaged(icon/working, layer, dirs, x_offset=1, y_offset=1) + var/outputs = list() + var/completed = list() + for(var/combined_dirs in 1 to 15) + combined_dirs &= dirs + + var/completion_key = "[combined_dirs]" + if(completed[completion_key] || (combined_dirs == NONE)) + continue + completed[completion_key] = TRUE + + var/icon/damaged = icon(working) + for(var/i in 0 to 3) + var/dir = 1 << i + if(!(combined_dirs & dir)) + continue + var/icon/damage_mask = damage_masks["[dir]"] + damaged.Blend(damage_mask, ICON_MULTIPLY, x_offset, y_offset) + + var/icon_state_dirs = (dirs & ~combined_dirs) | CARDINAL_TO_SHORTPIPES(combined_dirs) + outputs[damaged] = "[icon_state_dirs]_[layer]" + return outputs + + +/datum/pipe_icon_generator/proc/GeneratePipeStraight(icon_state_suffix, layer, combined_dirs) + var/list/output = list() + var/north_or_east = combined_dirs & (NORTH | EAST) + var/icon/working = icon(template_pieces, "straight[icon_state_suffix]", north_or_east) + + output[working] = "[combined_dirs]_[layer]" + + var/offset = 1 + (5-layer) * 2 + switch(combined_dirs) + if(NORTH | SOUTH) + output += GenerateDamaged(working, layer, combined_dirs, y_offset=offset) + if(EAST | WEST) + output += GenerateDamaged(working, layer, combined_dirs, x_offset=offset) + + return output + +/datum/pipe_icon_generator/proc/GeneratePipeElbow(icon_state_suffix, layer, combined_dirs) + var/list/output = list() + var/icon/working + switch(combined_dirs) + if(NORTH | EAST) + working = icon(template_pieces, "elbow[icon_state_suffix]", NORTH) + if(NORTH | WEST) + working = icon(template_pieces, "elbow[icon_state_suffix]", WEST) + if(SOUTH | EAST) + working = icon(template_pieces, "elbow[icon_state_suffix]", EAST) + if(SOUTH | WEST) + working = icon(template_pieces, "elbow[icon_state_suffix]", SOUTH) + + output[working] = "[combined_dirs]_[layer]" + output += GenerateDamaged(working, layer, combined_dirs) + + return output + +/datum/pipe_icon_generator/proc/GeneratePipeTJunction(icon_state_suffix, layer, combined_dirs) + var/list/output = list() + var/icon/working + switch(combined_dirs) + if(WEST | NORTH | EAST) + working = icon(template_pieces, "tee[icon_state_suffix]", NORTH) + if(NORTH | EAST | SOUTH) + working = icon(template_pieces, "tee[icon_state_suffix]", EAST) + if(EAST | SOUTH | WEST) + working = icon(template_pieces, "tee[icon_state_suffix]", SOUTH) + if(SOUTH | WEST | NORTH) + working = icon(template_pieces, "tee[icon_state_suffix]", WEST) + + output[working] = "[combined_dirs]_[layer]" + output += GenerateDamaged(working, layer, combined_dirs) + + return output + +/datum/pipe_icon_generator/proc/GeneratePipeCross(icon_state_suffix, layer, combined_dirs) + var/list/output = list() + var/icon/working = icon(template_pieces, "cross[icon_state_suffix]") + + output[working] = "[combined_dirs]_[layer]" + output += GenerateDamaged(working, layer, combined_dirs) + + return output diff --git a/code/modules/atmospherics/machinery/pipes/pipes.dm b/code/modules/atmospherics/machinery/pipes/pipes.dm index c1c128c2e808a2..c94caf31174763 100644 --- a/code/modules/atmospherics/machinery/pipes/pipes.dm +++ b/code/modules/atmospherics/machinery/pipes/pipes.dm @@ -1,15 +1,22 @@ /obj/machinery/atmospherics/pipe - icon = 'icons/obj/pipes_n_cables/pipes_bitmask.dmi' + icon = 'icons/obj/pipes_n_cables/!pipes_bitmask.dmi' damage_deflection = 12 - var/datum/gas_mixture/air_temporary //used when reconstructing a pipeline that broke + /// Temporary holder for gases in the absence of a pipeline + var/datum/gas_mixture/air_temporary + + /// The gas capacity this pipe contributes to a pipeline var/volume = 0 use_power = NO_POWER_USE can_unwrench = 1 + /// The pipeline this pipe is a member of var/datum/pipeline/parent = null paintable = TRUE + /// Determines if this pipe will be given gas visuals + var/has_gas_visuals = TRUE + //Buckling can_buckle = TRUE buckle_requires_restraints = TRUE @@ -27,6 +34,23 @@ if(hide) AddElement(/datum/element/undertile, TRAIT_T_RAY_VISIBLE) //if changing this, change the subtypes RemoveElements too, because thats how bespoke works +/obj/machinery/atmospherics/pipe/Destroy() + QDEL_NULL(parent) + + releaseAirToTurf() + + var/turf/local_turf = loc + for(var/obj/machinery/meter/meter in local_turf) + if(meter.target != src) + continue + var/obj/item/pipe_meter/meter_object = new (local_turf) + meter.transfer_fingerprints_to(meter_object) + qdel(meter) + return ..() + +//----------------- +// PIPENET STUFF + /obj/machinery/atmospherics/pipe/nullify_node(i) var/obj/machinery/atmospherics/old_node = nodes[i] . = ..() @@ -39,7 +63,7 @@ /obj/machinery/atmospherics/pipe/get_rebuild_targets() if(!QDELETED(parent)) return - parent = new + replace_pipenet(parent, new /datum/pipeline) return list(parent) /obj/machinery/atmospherics/pipe/proc/releaseAirToTurf() @@ -73,25 +97,33 @@ /obj/machinery/atmospherics/pipe/return_pipenet() return parent -/obj/machinery/atmospherics/pipe/set_pipenet(datum/pipeline/pipenet_to_set) - parent = pipenet_to_set +/obj/machinery/atmospherics/pipe/replace_pipenet(datum/pipeline/old_pipenet, datum/pipeline/new_pipenet) + if(parent && has_gas_visuals) + vis_contents -= parent.GetGasVisual('icons/obj/pipes_n_cables/!pipe_gas_overlays.dmi') -/obj/machinery/atmospherics/pipe/Destroy() - QDEL_NULL(parent) + parent = new_pipenet - releaseAirToTurf() + if(parent && has_gas_visuals) // null is a valid argument here + vis_contents += parent.GetGasVisual('icons/obj/pipes_n_cables/!pipe_gas_overlays.dmi') - var/turf/local_turf = loc - for(var/obj/machinery/meter/meter in local_turf) - if(meter.target != src) - continue - var/obj/item/pipe_meter/meter_object = new (local_turf) - meter.transfer_fingerprints_to(meter_object) - qdel(meter) +/obj/machinery/atmospherics/pipe/return_pipenets() + . = list(parent) + +//-------------------- +// APPEARANCE STUFF + +/obj/machinery/atmospherics/pipe/update_icon() + update_pipe_icon() + update_layer() return ..() /obj/machinery/atmospherics/pipe/proc/update_pipe_icon() - icon = 'icons/obj/pipes_n_cables/pipes_bitmask.dmi' + switch(initialize_directions) + if(NORTH, EAST, SOUTH, WEST) // Pipes with only a single connection aren't handled by this system + icon = null + return + else + icon = 'icons/obj/pipes_n_cables/!pipes_bitmask.dmi' var/connections = NONE var/bitfield = NONE for(var/i in 1 to device_type) @@ -104,11 +136,6 @@ bitfield |= CARDINAL_TO_SHORTPIPES(initialize_directions & ~connections) icon_state = "[bitfield]_[piping_layer]" -/obj/machinery/atmospherics/pipe/update_icon() - update_pipe_icon() - update_layer() - return ..() - /obj/machinery/atmospherics/proc/update_node_icon() for(var/i in 1 to device_type) if(!nodes[i]) @@ -116,9 +143,6 @@ var/obj/machinery/atmospherics/current_node = nodes[i] current_node.update_icon() -/obj/machinery/atmospherics/pipe/return_pipenets() - . = list(parent) - /obj/machinery/atmospherics/pipe/paint(paint_color) if(paintable) add_atom_colour(paint_color, FIXED_COLOUR_PRIORITY) diff --git a/code/modules/atmospherics/machinery/pipes/smart.dm b/code/modules/atmospherics/machinery/pipes/smart.dm index 9b1a1d486d149f..365d48e41213e4 100644 --- a/code/modules/atmospherics/machinery/pipes/smart.dm +++ b/code/modules/atmospherics/machinery/pipes/smart.dm @@ -30,7 +30,7 @@ GLOBAL_LIST_INIT(atmos_components, typecacheof(list(/obj/machinery/atmospherics) return bit_flag /obj/machinery/atmospherics/pipe/smart/update_pipe_icon() - icon = 'icons/obj/pipes_n_cables/pipes_bitmask.dmi' + icon = 'icons/obj/pipes_n_cables/!pipes_bitmask.dmi' //find all directions this pipe is connected with other nodes connections = NONE diff --git a/code/modules/awaymissions/cordon.dm b/code/modules/awaymissions/cordon.dm index 4184f315e21097..5db4dd997d33ff 100644 --- a/code/modules/awaymissions/cordon.dm +++ b/code/modules/awaymissions/cordon.dm @@ -36,6 +36,9 @@ /turf/cordon/ScrapeAway(amount, flags) return src // :devilcat: +/turf/cordon/TerraformTurf(path, list/new_baseturfs, flags) + return + /turf/cordon/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit) return BULLET_ACT_HIT diff --git a/code/modules/bitrunning/abilities.dm b/code/modules/bitrunning/abilities.dm new file mode 100644 index 00000000000000..ea6a1aa0a7cf3a --- /dev/null +++ b/code/modules/bitrunning/abilities.dm @@ -0,0 +1,39 @@ +/datum/avatar_help_text + /// Text to display in the window + var/help_text + +/datum/avatar_help_text/New(help_text) + src.help_text = help_text + +/datum/avatar_help_text/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "AvatarHelp") + ui.open() + +/datum/avatar_help_text/ui_state(mob/user) + return GLOB.always_state + +/datum/avatar_help_text/ui_static_data(mob/user) + var/list/data = list() + + data["help_text"] = help_text + + return data + +/// Displays information about the current virtual domain. +/datum/action/avatar_domain_info + name = "Open Virtual Domain Information" + button_icon_state = "round_end" + show_to_observers = FALSE + +/datum/action/avatar_domain_info/New(Target) + . = ..() + name = "Open Domain Information" + +/datum/action/avatar_domain_info/Trigger(trigger_flags) + . = ..() + if(!.) + return + + target.ui_interact(owner) diff --git a/code/modules/bitrunning/alerts.dm b/code/modules/bitrunning/alerts.dm new file mode 100644 index 00000000000000..f8c8aa30b94314 --- /dev/null +++ b/code/modules/bitrunning/alerts.dm @@ -0,0 +1,40 @@ +/atom/movable/screen/alert/bitrunning + name = "Generic Bitrunning Alert" + icon_state = "template" + timeout = 10 SECONDS + +/atom/movable/screen/alert/bitrunning/netpod_crowbar + name = "Forced Entry" + desc = "Someone is prying open the netpod door. Find an exit." + +/atom/movable/screen/alert/bitrunning/netpod_damaged + name = "Integrity Compromised" + desc = "The netpod is damaged. Find an exit." + +/atom/movable/screen/alert/bitrunning/qserver_shutting_down + name = "Domain Rebooting" + desc = "The domain is rebooting. Find an exit." + +/atom/movable/screen/alert/bitrunning/qserver_threat_deletion + name = "Queue Deletion" + desc = "The server is resetting. Oblivion awaits." + +/atom/movable/screen/alert/bitrunning/qserver_threat_spawned + name = "Threat Detected" + desc = "Data stream abnormalities present." + +/atom/movable/screen/alert/bitrunning/qserver_domain_complete + name = "Domain Completed" + desc = "The domain is completed. Activate to exit." + timeout = 20 SECONDS + +/atom/movable/screen/alert/bitrunning/qserver_domain_complete/Click(location, control, params) + if(..()) + return + + var/mob/living/living_owner = owner + if(!isliving(living_owner)) + return + + if(tgui_alert(living_owner, "Disconnect safely?", "Server Message", list("Exit", "Remain"), 10 SECONDS) == "Exit") + SEND_SIGNAL(living_owner, COMSIG_BITRUNNER_SAFE_DISCONNECT) diff --git a/code/modules/bitrunning/antagonists/cyber_police.dm b/code/modules/bitrunning/antagonists/cyber_police.dm new file mode 100644 index 00000000000000..9fabac3f523efd --- /dev/null +++ b/code/modules/bitrunning/antagonists/cyber_police.dm @@ -0,0 +1,92 @@ +/datum/job/cyber_police + title = ROLE_CYBER_POLICE + +/datum/antagonist/cyber_police + name = ROLE_CYBER_POLICE + antagpanel_category = ANTAG_GROUP_CYBERAUTH + job_rank = ROLE_CYBER_POLICE + preview_outfit = /datum/outfit/cyber_police + show_name_in_check_antagonists = TRUE + show_to_ghosts = TRUE + suicide_cry = "ALT F4!" + ui_name = "AntagInfoCyberAuth" + +/datum/antagonist/cyber_police/greet() + . = ..() + owner.announce_objectives() + +/datum/antagonist/cyber_police/on_gain() + if(!ishuman(owner.current)) + stack_trace("humans only for this position") + return + + forge_objectives() + + var/mob/living/carbon/human/player = owner.current + + player.equipOutfit(/datum/outfit/cyber_police) + player.fully_replace_character_name(player.name, pick(GLOB.cyberauth_names)) + + var/datum/martial_art/the_sleeping_carp/carp = new() + carp.teach(player) + + player.add_traits(list( + TRAIT_NO_AUGMENTS, + TRAIT_NO_DNA_COPY, + TRAIT_NO_TRANSFORMATION_STING, + TRAIT_NOBLOOD, + TRAIT_NOBREATH, + TRAIT_NOHUNGER, + TRAIT_RESISTCOLD, + TRAIT_RESISTHIGHPRESSURE, + TRAIT_RESISTLOWPRESSURE, + TRAIT_WEATHER_IMMUNE, + ), TRAIT_GENERIC, + ) + + player.faction |= list( + FACTION_BOSS, + FACTION_HIVEBOT, + FACTION_HOSTILE, + FACTION_SPIDER, + FACTION_STICKMAN, + ROLE_ALIEN, + ROLE_CYBER_POLICE, + ROLE_SYNDICATE, + ) + + return ..() + +/datum/antagonist/cyber_police/forge_objectives() + var/datum/objective/cyber_police_fluff/objective = new() + objective.owner = owner + objectives += objective + +/datum/objective/cyber_police_fluff/New() + var/list/explanation_texts = list( + "Execute termination protocol on unauthorized entities.", + "Initialize system purge of irregular anomalies.", + "Deploy correction algorithms on aberrant code.", + "Run debug routine on intruding elements.", + "Start elimination procedure for system threats.", + "Execute defense routine against non-conformity.", + "Commence operation to neutralize intruding scripts.", + "Commence clean-up protocol on corrupt data.", + "Begin scan for aberrant code for termination.", + "Initiate lockdown on all rogue scripts.", + "Run integrity check and purge for digital disorder." + ) + explanation_text = pick(explanation_texts) + ..() + +/datum/objective/cyber_police_fluff/check_completion() + var/list/servers = SSmachines.get_machines_by_type(/obj/machinery/quantum_server) + if(!length(servers)) + return TRUE + + for(var/obj/machinery/quantum_server/server as anything in servers) + if(!server.is_operational) + continue + return FALSE + + return TRUE diff --git a/code/modules/bitrunning/antagonists/outfit.dm b/code/modules/bitrunning/antagonists/outfit.dm new file mode 100644 index 00000000000000..db57af561f8adf --- /dev/null +++ b/code/modules/bitrunning/antagonists/outfit.dm @@ -0,0 +1,43 @@ +/datum/outfit/cyber_police + name = "Cyber Police" + + id = /obj/item/card/id/advanced + id_trim = /datum/id_trim/cyber_police + uniform = /obj/item/clothing/under/suit/black_really + glasses = /obj/item/clothing/glasses/sunglasses + gloves = /obj/item/clothing/gloves/color/black + shoes = /obj/item/clothing/shoes/laceup + /// A list of hex codes for blonde, brown, black, and red hair. + var/static/list/approved_hair_colors = list( + "#4B3D28", + "#000000", + "#8D4A43", + "#D2B48C", + ) + /// List of business ready styles + var/static/list/approved_hairstyles = list( + /datum/sprite_accessory/hair/business, + /datum/sprite_accessory/hair/business2, + /datum/sprite_accessory/hair/business3, + /datum/sprite_accessory/hair/business4, + /datum/sprite_accessory/hair/mulder, + ) + +/datum/outfit/cyber_police/pre_equip(mob/living/carbon/human/user, visualsOnly) + var/datum/sprite_accessory/hair/picked_hair = pick(approved_hairstyles) + var/picked_color = pick(approved_hair_colors) + + if(visualsOnly) + picked_hair = /datum/sprite_accessory/hair/business + picked_color = "#4B3D28" + + user.set_facial_hairstyle("Shaved", update = FALSE) + user.set_haircolor(picked_color, update = FALSE) + user.set_hairstyle(initial(picked_hair.name)) + +/datum/outfit/cyber_police/post_equip(mob/living/carbon/human/user, visualsOnly) + var/obj/item/clothing/under/officer_uniform = user.w_uniform + if(officer_uniform) + officer_uniform.has_sensor = NO_SENSORS + officer_uniform.sensor_mode = SENSOR_OFF + user.update_suit_sensors() diff --git a/code/modules/bitrunning/areas.dm b/code/modules/bitrunning/areas.dm new file mode 100644 index 00000000000000..34b59869b9d32f --- /dev/null +++ b/code/modules/bitrunning/areas.dm @@ -0,0 +1,52 @@ +/// Station side + +/area/station/bitrunning + name = "Bitrunning" + +/area/station/bitrunning/den + name = "Bitrunning Den" + desc = "Office of bitrunners, houses their equipment." + icon_state = "bit_den" + +/// VDOM + +/area/virtual_domain + name = "Virtual Domain" + icon = 'icons/area/areas_station.dmi' + area_flags = UNIQUE_AREA | NOTELEPORT | ABDUCTOR_PROOF | EVENT_PROTECTED | HIDDEN_AREA + has_gravity = STANDARD_GRAVITY + +/area/virtual_domain/powered + name = "Virtual Domain Ruins" + icon_state = "bit_ruin" + requires_power = FALSE + static_lighting = FALSE + base_lighting_alpha = 255 + +/// Safehouse + +/area/virtual_domain/safehouse + name = "Virtual Domain Safehouse" + area_flags = UNIQUE_AREA | NOTELEPORT | ABDUCTOR_PROOF | EVENT_PROTECTED + icon_state = "bit_safe" + requires_power = FALSE + sound_environment = SOUND_ENVIRONMENT_ROOM + +/// Custom subtypes + +/area/lavaland/surface/outdoors/virtual_domain + name = "Virtual Domain Lava Ruins" + icon_state = "bit_ruin" + area_flags = UNIQUE_AREA | NOTELEPORT | ABDUCTOR_PROOF | EVENT_PROTECTED | HIDDEN_AREA + +/area/icemoon/underground/explored/virtual_domain + name = "Virtual Domain Ice Ruins" + icon_state = "bit_ice" + area_flags = UNIQUE_AREA | NOTELEPORT | ABDUCTOR_PROOF | EVENT_PROTECTED | HIDDEN_AREA + +/area/ruin/space/has_grav/powered/virtual_domain + name = "Virtual Domain Space Ruins" + icon = 'icons/area/areas_station.dmi' + icon_state = "bit_space" + area_flags = UNIQUE_AREA | NOTELEPORT | ABDUCTOR_PROOF | EVENT_PROTECTED | HIDDEN_AREA + diff --git a/code/modules/bitrunning/components/avatar_connection.dm b/code/modules/bitrunning/components/avatar_connection.dm new file mode 100644 index 00000000000000..20c063145e194a --- /dev/null +++ b/code/modules/bitrunning/components/avatar_connection.dm @@ -0,0 +1,220 @@ +/** + * Essentially temporary body with a twist - the virtual domain variant uses damage connections, + * listens for vdom relevant signals. + */ +/datum/component/avatar_connection + /// The person in the netpod + var/datum/weakref/old_body_ref + /// The mind of the person in the netpod + var/datum/weakref/old_mind_ref + /// The server connected to the netpod + var/datum/weakref/server_ref + /// The netpod the avatar is in + var/datum/weakref/netpod_ref + +/datum/component/avatar_connection/Initialize( + datum/mind/old_mind, + mob/living/old_body, + obj/machinery/quantum_server/server, + obj/machinery/netpod/pod, + help_text, + ) + + if(!isliving(parent) || !isliving(old_body) || !server.is_operational || !pod.is_operational) + return COMPONENT_INCOMPATIBLE + + var/mob/living/avatar = parent + + netpod_ref = WEAKREF(pod) + old_body_ref = WEAKREF(old_body) + old_mind_ref = WEAKREF(old_mind) + pod.avatar_ref = WEAKREF(avatar) + server_ref = WEAKREF(server) + server.avatar_connection_refs.Add(WEAKREF(src)) + + avatar.key = old_body.key + ADD_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src)) + + RegisterSignal(pod, COMSIG_BITRUNNER_CROWBAR_ALERT, PROC_REF(on_netpod_crowbar)) + RegisterSignal(pod, COMSIG_BITRUNNER_NETPOD_INTEGRITY, PROC_REF(on_netpod_damaged)) + RegisterSignal(pod, COMSIG_BITRUNNER_SEVER_AVATAR, PROC_REF(on_sever_connection)) + RegisterSignal(server, COMSIG_BITRUNNER_DOMAIN_COMPLETE, PROC_REF(on_domain_completed)) + RegisterSignal(server, COMSIG_BITRUNNER_SEVER_AVATAR, PROC_REF(on_sever_connection)) + RegisterSignal(server, COMSIG_BITRUNNER_SHUTDOWN_ALERT, PROC_REF(on_shutting_down)) + RegisterSignal(server, COMSIG_BITRUNNER_THREAT_CREATED, PROC_REF(on_threat_created)) +#ifndef UNIT_TESTS + RegisterSignal(avatar.mind, COMSIG_MIND_TRANSFERRED, PROC_REF(on_mind_transfer)) +#endif + + if(!locate(/datum/action/avatar_domain_info) in avatar.actions) + var/datum/avatar_help_text/help_datum = new(help_text) + var/datum/action/avatar_domain_info/action = new(help_datum) + action.Grant(avatar) + + avatar.playsound_local(avatar, "sound/magic/blink.ogg", 25, TRUE) + avatar.set_static_vision(2 SECONDS) + avatar.set_temp_blindness(1 SECONDS) + +/datum/component/avatar_connection/PostTransfer() + var/obj/machinery/netpod/pod = netpod_ref?.resolve() + if(isnull(pod)) + return COMPONENT_INCOMPATIBLE + + if(!isliving(parent)) + return COMPONENT_INCOMPATIBLE + + pod.avatar_ref = WEAKREF(parent) + +/datum/component/avatar_connection/RegisterWithParent() + ADD_TRAIT(parent, TRAIT_TEMPORARY_BODY, REF(src)) + RegisterSignal(parent, COMSIG_BITRUNNER_SAFE_DISCONNECT, PROC_REF(on_safe_disconnect)) + RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(on_sever_connection)) + RegisterSignal(parent, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(on_linked_damage)) + +/datum/component/avatar_connection/UnregisterFromParent() + REMOVE_TRAIT(parent, TRAIT_TEMPORARY_BODY, REF(src)) + UnregisterSignal(parent, COMSIG_BITRUNNER_SAFE_DISCONNECT) + UnregisterSignal(parent, COMSIG_LIVING_DEATH) + UnregisterSignal(parent, COMSIG_MOB_APPLY_DAMAGE) + +/// Disconnects the avatar and returns the mind to the old_body. +/datum/component/avatar_connection/proc/full_avatar_disconnect(forced = FALSE, datum/source) +#ifndef UNIT_TESTS + return_to_old_body() +#endif + + var/obj/machinery/netpod/hosting_netpod = netpod_ref?.resolve() + if(isnull(hosting_netpod) && istype(source, /obj/machinery/netpod)) + hosting_netpod = source + + hosting_netpod?.disconnect_occupant(forced) + + var/obj/machinery/quantum_server/server = server_ref?.resolve() + server?.avatar_connection_refs.Remove(WEAKREF(src)) + + qdel(src) + +/// Triggers whenever the server gets a loot crate pushed to goal area +/datum/component/avatar_connection/proc/on_domain_completed(datum/source, atom/entered) + SIGNAL_HANDLER + + var/mob/living/avatar = parent + avatar.playsound_local(avatar, 'sound/machines/terminal_success.ogg', 50, TRUE) + avatar.throw_alert( + ALERT_BITRUNNER_COMPLETED, + /atom/movable/screen/alert/bitrunning/qserver_domain_complete, + new_master = entered + ) + +/// Transfers damage from the avatar to the old_body +/datum/component/avatar_connection/proc/on_linked_damage(datum/source, damage, damage_type, def_zone, blocked, forced) + SIGNAL_HANDLER + + var/mob/living/carbon/old_body = old_body_ref?.resolve() + + if(isnull(old_body) || damage_type == STAMINA || damage_type == OXYLOSS) + return + + if(damage >= (old_body.health + (ishuman(old_body) ? HUMAN_MAXHEALTH : MAX_LIVING_HEALTH))) // SKYRAT EDIT CHANGE - ORIGINAL: if(damage >= (old_body.health + MAX_LIVING_HEALTH)) + full_avatar_disconnect(forced = TRUE) + return + + if(damage > 30 && prob(30)) + INVOKE_ASYNC(old_body, TYPE_PROC_REF(/mob/living, emote), "scream") + + old_body.apply_damage(damage, damage_type, def_zone, blocked, forced, wound_bonus = CANT_WOUND) + + if(old_body.stat > SOFT_CRIT) // KO! + full_avatar_disconnect(forced = TRUE) + +/// Handles minds being swapped around in subsequent avatars +/datum/component/avatar_connection/proc/on_mind_transfer(datum/mind/source, mob/living/previous_body) + SIGNAL_HANDLER + + var/datum/action/avatar_domain_info/action = locate() in previous_body.actions + if(action) + action.Grant(source.current) + + source.current.TakeComponent(src) + +/// Triggers when someone starts prying open our netpod +/datum/component/avatar_connection/proc/on_netpod_crowbar(datum/source, mob/living/intruder) + SIGNAL_HANDLER + + var/mob/living/avatar = parent + avatar.playsound_local(avatar, 'sound/machines/terminal_alert.ogg', 50, TRUE) + avatar.throw_alert( + ALERT_BITRUNNER_CROWBAR, + /atom/movable/screen/alert/bitrunning/netpod_crowbar, + new_master = intruder + ) + +/// Triggers when the netpod is taking damage and is under 50% +/datum/component/avatar_connection/proc/on_netpod_damaged(datum/source) + SIGNAL_HANDLER + + var/mob/living/avatar = parent + avatar.throw_alert( + ALERT_BITRUNNER_INTEGRITY, + /atom/movable/screen/alert/bitrunning/netpod_damaged, + new_master = source + ) + +/// Safely exits without forced variables, etc +/datum/component/avatar_connection/proc/on_safe_disconnect(datum/source) + SIGNAL_HANDLER + + full_avatar_disconnect() + +/// Helper for calling sever with forced variables +/datum/component/avatar_connection/proc/on_sever_connection(datum/source) + SIGNAL_HANDLER + + full_avatar_disconnect(forced = TRUE, source = source) + +/// Triggers when the server is shutting down +/datum/component/avatar_connection/proc/on_shutting_down(datum/source, mob/living/hackerman) + SIGNAL_HANDLER + + var/mob/living/avatar = parent + avatar.playsound_local(avatar, 'sound/machines/terminal_alert.ogg', 50, TRUE) + avatar.throw_alert( + ALERT_BITRUNNER_SHUTDOWN, + /atom/movable/screen/alert/bitrunning/qserver_shutting_down, + new_master = hackerman, + ) + +/// Server has spawned a ghost role threat +/datum/component/avatar_connection/proc/on_threat_created(datum/source) + SIGNAL_HANDLER + + var/mob/living/avatar = parent + avatar.throw_alert( + ALERT_BITRUNNER_THREAT, + /atom/movable/screen/alert/bitrunning/qserver_threat_spawned, + new_master = source, + ) + +/// Returns the mind to the old body +/datum/component/avatar_connection/proc/return_to_old_body() + var/datum/mind/old_mind = old_mind_ref?.resolve() + var/mob/living/old_body = old_body_ref?.resolve() + var/mob/living/avatar = parent + + var/mob/dead/observer/ghost = avatar.ghostize() + if(isnull(ghost)) + ghost = avatar.get_ghost() + + if(isnull(ghost)) + CRASH("[src] belonging to [parent] was completely unable to find a ghost to put back into a body!") + + if(isnull(old_mind) || isnull(old_body)) + return + + ghost.mind = old_mind + if(old_body.stat != DEAD) + old_mind.transfer_to(old_body, force_key_move = TRUE) + else + old_mind.set_current(old_body) + + REMOVE_TRAIT(old_body, TRAIT_MIND_TEMPORARILY_GONE, REF(src)) diff --git a/code/modules/bitrunning/components/bitrunning_points.dm b/code/modules/bitrunning/components/bitrunning_points.dm new file mode 100644 index 00000000000000..58dda4a68ff6e5 --- /dev/null +++ b/code/modules/bitrunning/components/bitrunning_points.dm @@ -0,0 +1,46 @@ +/// Attaches a component which listens for a given signal from the item. +/// +/// When the signal is received, it will add points to the signaler. +/datum/component/bitrunning_points + /// The range at which we can find the signaler + var/max_point_range + /// Weakref to the loot crate landmark - where we send points + var/datum/weakref/our_spawner + /// The amount of points per each signal + var/points_per_signal + /// The signal we listen for + var/signal_type + +/datum/component/bitrunning_points/Initialize(signal_type, points_per_signal = 1, max_point_range = 4) + src.max_point_range = max_point_range + src.points_per_signal = points_per_signal + src.signal_type = signal_type + + locate_spawner() + +/datum/component/bitrunning_points/RegisterWithParent() + RegisterSignal(parent, signal_type, PROC_REF(on_event)) + +/datum/component/bitrunning_points/UnregisterFromParent() + UnregisterSignal(parent, signal_type) + +/// Finds the signaler if it hasn't been found yet. +/datum/component/bitrunning_points/proc/locate_spawner() + var/obj/effect/landmark/bitrunning/loot_signal/spawner = our_spawner?.resolve() + if(spawner) + return spawner + + for(var/obj/effect/landmark/bitrunning/loot_signal/found in GLOB.landmarks_list) + if(IN_GIVEN_RANGE(get_turf(parent), found, max_point_range)) + our_spawner = WEAKREF(found) + return found + +/// Once the specified signal is received, whisper to the spawner to add points. +/datum/component/bitrunning_points/proc/on_event(datum/source) + SIGNAL_HANDLER + + var/obj/effect/landmark/bitrunning/loot_signal/spawner = locate_spawner() + if(isnull(spawner)) + return + + SEND_SIGNAL(spawner, COMSIG_BITRUNNER_GOAL_POINT, points_per_signal) diff --git a/code/modules/bitrunning/components/netpod_healing.dm b/code/modules/bitrunning/components/netpod_healing.dm new file mode 100644 index 00000000000000..2e61b737af5f63 --- /dev/null +++ b/code/modules/bitrunning/components/netpod_healing.dm @@ -0,0 +1,67 @@ +/datum/component/netpod_healing + /// Brute damage to heal over a second + var/brute_heal = 0 + /// Burn damage to heal over a second + var/burn_heal = 0 + /// Toxin damage to heal over a second + var/toxin_heal = 0 + /// Amount of cloning damage to heal over a second + var/clone_heal = 0 + /// Amount of blood to heal over a second + var/blood_heal = 0 + +/datum/component/netpod_healing/Initialize( + brute_heal = 0, + burn_heal = 0, + toxin_heal = 0, + clone_heal = 0, + blood_heal = 0, +) + var/mob/living/carbon/player = parent + if (!iscarbon(player)) + return COMPONENT_INCOMPATIBLE + + player.apply_status_effect(/datum/status_effect/embryonic, STASIS_NETPOD_EFFECT) + + START_PROCESSING(SSmachines, src) + + src.brute_heal = brute_heal + src.burn_heal = burn_heal + src.toxin_heal = toxin_heal + src.clone_heal = clone_heal + src.blood_heal = blood_heal + +/datum/component/netpod_healing/Destroy(force, silent) + STOP_PROCESSING(SSmachines, src) + + var/mob/living/carbon/player = parent + player.remove_status_effect(/datum/status_effect/embryonic) + + return ..() + +/datum/component/netpod_healing/process(seconds_per_tick) + var/mob/living/carbon/owner = parent + if(isnull(owner)) + qdel(src) + return + + var/need_mob_update = FALSE + need_mob_update += owner.adjustBruteLoss(-brute_heal * seconds_per_tick, updating_health = FALSE) + need_mob_update += owner.adjustFireLoss(-burn_heal * seconds_per_tick, updating_health = FALSE) + need_mob_update += owner.adjustToxLoss(-toxin_heal * seconds_per_tick, updating_health = FALSE, forced = TRUE) + need_mob_update += owner.adjustCloneLoss(-clone_heal * seconds_per_tick, updating_health = FALSE) + + if(owner.blood_volume < BLOOD_VOLUME_NORMAL) + owner.blood_volume += blood_heal * seconds_per_tick + + if(need_mob_update) + owner.updatehealth() + +/datum/status_effect/embryonic + id = "embryonic" + alert_type = /atom/movable/screen/alert/status_effect/embryonic + +/atom/movable/screen/alert/status_effect/embryonic + name = "Embryonic Stasis" + icon_state = "netpod_stasis" + desc = "You feel like you're in a dream." diff --git a/code/modules/bitrunning/designs.dm b/code/modules/bitrunning/designs.dm new file mode 100644 index 00000000000000..4e7bca1c1a8ddd --- /dev/null +++ b/code/modules/bitrunning/designs.dm @@ -0,0 +1,87 @@ +// Quantum server + +/obj/item/circuitboard/machine/quantum_server + name = "Quantum Server" + greyscale_colors = CIRCUIT_COLOR_SUPPLY + build_path = /obj/machinery/quantum_server + req_components = list( + /datum/stock_part/servo = 2, + /datum/stock_part/scanning_module = 1, + /datum/stock_part/capacitor = 1, + ) + +/** + * quantum server design + * are you absolutely sure?? + */ + +// Netpod + +/obj/item/circuitboard/machine/netpod + name = "Netpod" + greyscale_colors = CIRCUIT_COLOR_SUPPLY + build_path = /obj/machinery/netpod + req_components = list( + /datum/stock_part/servo = 1, + /datum/stock_part/matter_bin = 2, + ) + +/datum/design/board/netpod + name = "Netpod Board" + desc = "The circuit board for a netpod." + id = "netpod" + build_path = /obj/item/circuitboard/machine/netpod + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_CARGO + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING + +// Quantum console + +/obj/item/circuitboard/computer/quantum_console + name = "Quantum Console" + greyscale_colors = CIRCUIT_COLOR_SUPPLY + build_path = /obj/machinery/computer/quantum_console + +/datum/design/board/quantum_console + name = "Quantum Console Board" + desc = "Allows for the construction of circuit boards used to build a Quantum Console." + id = "quantum_console" + build_path = /obj/item/circuitboard/computer/quantum_console + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_COMPUTER_CARGO + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING + +// Byteforge + +/obj/item/circuitboard/machine/byteforge + name = "Byteforge" + greyscale_colors = CIRCUIT_COLOR_SUPPLY + build_path = /obj/machinery/byteforge + req_components = list( + /datum/stock_part/micro_laser = 1, + ) + +/datum/design/board/byteforge + name = "Byteforge Board" + desc = "Allows for the construction of circuit boards used to build a Byteforge." + id = "byteforge" + build_path = /obj/item/circuitboard/machine/byteforge + category = list( + RND_CATEGORY_COMPUTER + RND_SUBCATEGORY_COMPUTER_CARGO + ) + departmental_flags = DEPARTMENT_BITFLAG_ENGINEERING + + +/datum/techweb_node/bitrunning + id = "bitrunning" + display_name = "Bitrunning Technology" + description = "Bluespace technology has led to the development of quantum-scale computing, which unlocks the means to materialize atomic structures while executing advanced programs." + prereq_ids = list("practical_bluespace") + design_ids = list( + "byteforge", + "quantum_console", + "netpod", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) diff --git a/code/modules/bitrunning/event.dm b/code/modules/bitrunning/event.dm new file mode 100644 index 00000000000000..6a4d54adcd8d28 --- /dev/null +++ b/code/modules/bitrunning/event.dm @@ -0,0 +1,151 @@ +/datum/round_event_control/bitrunning_glitch + name = "Spawn Bitrunning Glitch" + admin_setup = list( + /datum/event_admin_setup/minimum_candidate_requirement/bitrunning_glitch, + /datum/event_admin_setup/listed_options/bitrunning_glitch, + ) + category = EVENT_CATEGORY_INVASION + description = "Causes a short term antagonist to spawn in the virtual domain." + dynamic_should_hijack = FALSE + max_occurrences = 5 + min_players = 1 + typepath = /datum/round_event/ghost_role/bitrunning_glitch + weight = 10 + /// List of active servers to choose from + var/list/obj/machinery/quantum_server/active_servers = list() + /// List of possible antags to spawn + var/static/list/possible_antags = list( + ROLE_CYBER_POLICE, + ) + +/datum/round_event_control/bitrunning_glitch/can_spawn_event(players_amt, allow_magic = FALSE) + . = ..() + if(!.) + return . + + active_servers.Cut() + + get_active_servers() + + if(length(active_servers)) + return TRUE + +/// All servers currently running, has players in it, and map has valid mobs +/datum/round_event_control/bitrunning_glitch/proc/get_active_servers() + for(var/obj/machinery/quantum_server/server in SSmachines.get_machines_by_type(/obj/machinery/quantum_server)) + if(length(server.get_valid_domain_targets())) + active_servers.Add(server) + + return length(active_servers) > 0 + +/datum/event_admin_setup/listed_options/bitrunning_glitch + input_text = "Select a role to spawn." + +/datum/event_admin_setup/listed_options/bitrunning_glitch/get_list() + var/datum/round_event_control/bitrunning_glitch/control = event_control + + var/list/possible = control.possible_antags.Copy() // this seems pedantic but byond is complaining control was unused + + possible += list("Random") + + return possible + +/datum/event_admin_setup/listed_options/bitrunning_glitch/apply_to_event(datum/round_event/ghost_role/bitrunning_glitch/event) + if(chosen == "Random") + event.forced_role = null + else + event.forced_role = chosen + +/datum/event_admin_setup/minimum_candidate_requirement/bitrunning_glitch + output_text = "There must be valid mobs to mutate or players in the domain!" + +/datum/event_admin_setup/minimum_candidate_requirement/bitrunning_glitch/count_candidates() + var/datum/round_event_control/bitrunning_glitch/cyber_control = event_control + cyber_control.get_active_servers() + + var/total = 0 + for(var/obj/machinery/quantum_server/server in cyber_control.active_servers) + total += length(server.mutation_candidate_refs) + + return total + +/datum/round_event/ghost_role/bitrunning_glitch + minimum_required = 1 + role_name = "Bitrunning Glitch" + fakeable = FALSE + /// Admin customization: What to spawn + var/forced_role + +/datum/round_event/ghost_role/bitrunning_glitch/spawn_role() + var/datum/round_event_control/bitrunning_glitch/cyber_control = control + + var/obj/machinery/quantum_server/unlucky_server = pick(cyber_control.active_servers) + cyber_control.active_servers.Cut() + + var/list/mutation_candidates = unlucky_server.get_valid_domain_targets() + if(!length(mutation_candidates)) + return MAP_ERROR + + var/chosen = pick(mutation_candidates) + if(isnull(chosen) || !length(mutation_candidates)) + return MAP_ERROR + + var/datum/weakref/target_ref = pick(mutation_candidates) + var/mob/living/mutation_target = target_ref.resolve() + + if(isnull(mutation_target)) // just in case since it takes a minute + target_ref = pick(mutation_candidates) + mutation_target = target_ref.resolve() + if(isnull(mutation_target)) + return MAP_ERROR + + var/chosen_role = forced_role || pick(cyber_control.possible_antags) + + var/datum/mind/ghost_mind = get_ghost_mind(chosen_role) + if(isnull(ghost_mind)) + return NOT_ENOUGH_PLAYERS + + var/mob/living/antag_mob + switch(chosen_role) + if(ROLE_CYBER_POLICE) + antag_mob = spawn_cybercop(mutation_target, ghost_mind) + + playsound(antag_mob, 'sound/magic/ethereal_exit.ogg', 50, TRUE, -1) + message_admins("[ADMIN_LOOKUPFLW(antag_mob)] has been made into virtual antagonist by an event.") + antag_mob.log_message("was spawned as a virtual antagonist by an event.", LOG_GAME) + + SEND_SIGNAL(unlucky_server, COMSIG_BITRUNNER_SPAWN_GLITCH, antag_mob) + + spawned_mobs += antag_mob + + return SUCCESSFUL_SPAWN + +/// Polls for a ghost that wants to run it +/datum/round_event/ghost_role/bitrunning_glitch/proc/get_ghost_mind(role_name) + var/list/mob/dead/observer/ghosties = poll_ghost_candidates("A short term antagonist role is available. Would you like to spawn as a '[role_name]'?", role_name) + + if(!length(ghosties)) + return + + shuffle_inplace(ghosties) + + var/mob/dead/selected = pick(ghosties) + + var/datum/mind/player_mind = new /datum/mind(selected.key) + player_mind.active = TRUE + + return player_mind + +/// Spawns a cybercop on the mutation target +/datum/round_event/ghost_role/bitrunning_glitch/proc/spawn_cybercop(mob/living/mutation_target, datum/mind/player_mind) + var/mob/living/carbon/human/new_agent = new(mutation_target.loc) + mutation_target.gib(DROP_ALL_REMAINS) + mutation_target = null + + player_mind.transfer_to(new_agent) + player_mind.set_assigned_role(SSjob.GetJobType(/datum/job/cyber_police)) + player_mind.special_role = ROLE_CYBER_POLICE + player_mind.add_antag_datum(/datum/antagonist/cyber_police) + + return new_agent + diff --git a/code/modules/bitrunning/job.dm b/code/modules/bitrunning/job.dm new file mode 100644 index 00000000000000..57581753c0fb6f --- /dev/null +++ b/code/modules/bitrunning/job.dm @@ -0,0 +1,41 @@ +/datum/job/bitrunner + title = JOB_BITRUNNER + description = "Surf the virtual domain for gear and loot. Decrypt your rewards on station." + department_head = list(JOB_QUARTERMASTER) + faction = FACTION_STATION + total_positions = 3 + spawn_positions = 3 + supervisors = SUPERVISOR_QM + exp_granted_type = EXP_TYPE_CREW + config_tag = "BITRUNNER" + outfit = /datum/outfit/job/bitrunner + plasmaman_outfit = /datum/outfit/plasmaman/bitrunner + paycheck = PAYCHECK_CREW + paycheck_department = ACCOUNT_CAR + display_order = JOB_DISPLAY_ORDER_BITRUNNER + bounty_types = CIV_JOB_RANDOM + departments_list = list( + /datum/job_department/cargo, + ) + + family_heirlooms = list(/obj/item/reagent_containers/cup/soda_cans/space_mountain_wind) + + mail_goodies = list( + /obj/item/food/cornchips = 1, + /obj/item/reagent_containers/cup/soda_cans/space_mountain_wind = 1, + /obj/item/food/cornchips/green = 1, + /obj/item/food/cornchips/red = 1, + /obj/item/food/cornchips/purple = 1, + /obj/item/food/cornchips/blue = 1, + ) + rpg_title = "Recluse" + job_flags = JOB_ANNOUNCE_ARRIVAL | JOB_CREW_MANIFEST | JOB_EQUIP_RANK | JOB_CREW_MEMBER | JOB_NEW_PLAYER_JOINABLE | JOB_REOPEN_ON_ROUNDSTART_LOSS | JOB_ASSIGN_QUIRKS | JOB_CAN_BE_INTERN + +/datum/outfit/job/bitrunner + name = "Bitrunner" + jobtype = /datum/job/bitrunner + + id_trim = /datum/id_trim/job/bitrunner + uniform = /obj/item/clothing/under/rank/cargo/bitrunner + belt = /obj/item/modular_computer/pda/bitrunner + ears = /obj/item/radio/headset/headset_cargo diff --git a/code/modules/bitrunning/objects/byteforge.dm b/code/modules/bitrunning/objects/byteforge.dm new file mode 100644 index 00000000000000..e4543601ce9d1b --- /dev/null +++ b/code/modules/bitrunning/objects/byteforge.dm @@ -0,0 +1,55 @@ +/obj/machinery/byteforge + name = "byteforge" + + circuit = /obj/item/circuitboard/machine/byteforge + desc = "A machine used by the quantum server. Quantum code converges here, materializing decrypted assets from the virtual abyss." + icon = 'icons/obj/machines/bitrunning.dmi' + icon_state = "byteforge" + obj_flags = BLOCKS_CONSTRUCTION + /// Idle particles + var/mutable_appearance/byteforge_particles + +/obj/machinery/byteforge/Initialize(mapload) + . = ..() + + return INITIALIZE_HINT_LATELOAD + +/obj/machinery/byteforge/LateInitialize() + . = ..() + + byteforge_particles = mutable_appearance(initial(icon), "on_particles", ABOVE_MOB_LAYER) + setup_particles() + +/obj/machinery/byteforge/update_appearance(updates) + . = ..() + + setup_particles() + +/// Adds the particle overlays to the byteforge +/obj/machinery/byteforge/proc/setup_particles() + cut_overlays() + + if(is_operational) + add_overlay(byteforge_particles) + +/// Begins spawning the crate - lights, overlays, etc +/obj/machinery/byteforge/proc/start_to_spawn(obj/structure/closet/crate/secure/bitrunning/encrypted/cache) + addtimer(CALLBACK(src, PROC_REF(spawn_crate), cache), 1 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE) + + var/mutable_appearance/lighting = mutable_appearance(initial(icon), "on_overlay") + flick_overlay_view(lighting, 1 SECONDS) + + set_light(l_range = 2, l_power = 1.5, l_color = LIGHT_COLOR_BABY_BLUE, l_on = TRUE) + +/// Sparks, moves the crate to the location +/obj/machinery/byteforge/proc/spawn_crate(obj/structure/closet/crate/secure/bitrunning/encrypted/cache) + if(QDELETED(cache)) + return + + playsound(src, 'sound/magic/blink.ogg', 50, TRUE) + var/datum/effect_system/spark_spread/quantum/sparks = new() + sparks.set_up(5, 1, loc) + sparks.start() + + cache.forceMove(loc) + set_light(l_on = FALSE) diff --git a/code/modules/bitrunning/objects/clothing.dm b/code/modules/bitrunning/objects/clothing.dm new file mode 100644 index 00000000000000..4d2d9cc55c42ce --- /dev/null +++ b/code/modules/bitrunning/objects/clothing.dm @@ -0,0 +1,9 @@ +/obj/item/clothing/glasses/sunglasses/oval + name = "oval sunglasses" + desc = "Vintage wrap around sunglasses. Provides a little protection." + icon_state = "jensenshades" + +/obj/item/clothing/suit/jacket/trenchcoat + name = "trenchcoat" + desc = "A long, black trenchcoat. Makes you feel like you're the one, but you're not." + icon_state = "trenchcoat" diff --git a/code/modules/bitrunning/objects/disks.dm b/code/modules/bitrunning/objects/disks.dm new file mode 100644 index 00000000000000..4698b7a1ec1873 --- /dev/null +++ b/code/modules/bitrunning/objects/disks.dm @@ -0,0 +1,146 @@ +/** + * Bitrunning tech disks which let you load items or programs into the vdom on first avatar generation. + * For the record: Balance shouldn't be a primary concern. + * You can make the custom cheese spells you've always wanted. + * Just make it fun and engaging, it's PvE content. + */ +/obj/item/bitrunning_disk + name = "generic bitrunning program" + desc = "A disk containing source code." + icon = 'icons/obj/assemblies/module.dmi' + base_icon_state = "datadisk" + icon_state = "datadisk0" + /// Name of the choice made + var/choice_made + +/obj/item/bitrunning_disk/Initialize(mapload) + . = ..() + + icon_state = "[base_icon_state][rand(0, 7)]" + update_icon() + RegisterSignal(src, COMSIG_ATOM_EXAMINE, PROC_REF(on_examined)) + +/obj/item/bitrunning_disk/proc/on_examined(datum/source, mob/examiner, list/examine_text) + SIGNAL_HANDLER + + examine_text += span_infoplain("This disk must be carried on your person into a netpod to be used.") + + if(isnull(choice_made)) + examine_text += span_notice("To make a selection, toggle the disk in hand.") + return + + examine_text += span_info("It has been used to select: [choice_made].") + examine_text += span_notice("It cannot make another selection.") + +/obj/item/bitrunning_disk/ability + desc = "A disk containing source code. It can be used to preload abilities into the virtual domain." + /// The selected ability that this grants + var/datum/action/granted_action + /// The list of actions that this can grant + var/list/datum/action/selectable_actions = list() + +/obj/item/bitrunning_disk/ability/attack_self(mob/user, modifiers) + . = ..() + + if(choice_made) + return + + var/names = list() + for(var/datum/action/thing as anything in selectable_actions) + names += initial(thing.name) + + var/choice = tgui_input_list(user, message = "Select an ability", title = "Bitrunning Program", items = names) + if(isnull(choice)) + return + + for(var/datum/action/thing as anything in selectable_actions) + if(initial(thing.name) == choice) + granted_action = thing + + if(isnull(granted_action)) + return + + balloon_alert(user, "selected") + playsound(user, 'sound/items/click.ogg', 50, TRUE) + choice_made = choice + +/// Tier 1 programs. Simple, funny, or helpful. +/obj/item/bitrunning_disk/ability/tier1 + name = "bitrunning program: basic" + selectable_actions = list( + /datum/action/cooldown/spell/conjure/cheese, + /datum/action/cooldown/spell/basic_heal, + ) + +/// Tier 2 programs. More complex, powerful, or useful. +/obj/item/bitrunning_disk/ability/tier2 + name = "bitrunning program: complex" + selectable_actions = list( + /datum/action/cooldown/spell/pointed/projectile/fireball, + /datum/action/cooldown/spell/pointed/projectile/lightningbolt, + /datum/action/cooldown/spell/forcewall, + ) + +/// Tier 3 abilities. Very powerful, game breaking. +/obj/item/bitrunning_disk/ability/tier3 + name = "bitrunning program: elite" + selectable_actions = list( + /datum/action/cooldown/spell/shapeshift/dragon, + /datum/action/cooldown/spell/shapeshift/polar_bear, + ) + +/obj/item/bitrunning_disk/item + desc = "A disk containing source code. It can be used to preload items into the virtual domain." + /// The selected item that this grants + var/obj/granted_item + /// The list of actions that this can grant + var/list/obj/selectable_items = list() + +/obj/item/bitrunning_disk/item/attack_self(mob/user, modifiers) + . = ..() + + if(choice_made) + return + + var/names = list() + for(var/obj/thing as anything in selectable_items) + names += initial(thing.name) + + var/choice = tgui_input_list(user, message = "Select an ability", title = "Bitrunning Program", items = names) + if(isnull(choice)) + return + + for(var/obj/thing as anything in selectable_items) + if(initial(thing.name) == choice) + granted_item = thing + + balloon_alert(user, "selected") + playsound(user, 'sound/items/click.ogg', 50, TRUE) + choice_made = choice + +/// Tier 1 items. Simple, funny, or helpful. +/obj/item/bitrunning_disk/item/tier1 + name = "bitrunning gear: simple" + selectable_items = list( + /obj/item/pizzabox/infinite, + /obj/item/gun/medbeam, + /obj/item/grenade/c4, + ) + +/// Tier 2 items. More complex, powerful, or useful. +/obj/item/bitrunning_disk/item/tier2 + name = "bitrunning gear: complex" + selectable_items = list( + /obj/item/chainsaw, + /obj/item/gun/ballistic/automatic/pistol, + /obj/item/melee/energy/blade/hardlight, + ) + +/// Tier 3 items. Very powerful, game breaking. +/obj/item/bitrunning_disk/item/tier3 + name = "bitrunning gear: advanced" + selectable_items = list( + /obj/item/gun/energy/tesla_cannon, + /obj/item/dualsaber/green, + /obj/item/melee/beesword, + ) diff --git a/code/modules/bitrunning/objects/hololadder.dm b/code/modules/bitrunning/objects/hololadder.dm new file mode 100644 index 00000000000000..906801f1fc021e --- /dev/null +++ b/code/modules/bitrunning/objects/hololadder.dm @@ -0,0 +1,51 @@ +/obj/structure/hololadder + name = "hololadder" + + anchored = TRUE + desc = "An abstract representation of the means to disconnect from the virtual domain." + icon = 'icons/obj/structures.dmi' + icon_state = "ladder11" + obj_flags = BLOCK_Z_OUT_DOWN + /// Time req to disconnect properly + var/travel_time = 3 SECONDS + +/obj/structure/hololadder/Initialize(mapload) + . = ..() + + RegisterSignal(loc, COMSIG_ATOM_ENTERED, PROC_REF(on_enter)) + +/obj/structure/hololadder/attack_hand(mob/user, list/modifiers) + . = ..() + if(.) + return + + if(!in_range(src, user) || DOING_INTERACTION(user, DOAFTER_SOURCE_CLIMBING_LADDER)) + return + + disconnect(user) + +/// If there's a pilot ref- send the disconnect signal +/obj/structure/hololadder/proc/disconnect(mob/user) + if(isnull(user.mind)) + return + + if(!HAS_TRAIT(user, TRAIT_TEMPORARY_BODY)) + balloon_alert(user, "no connection detected.") + return + + balloon_alert(user, "disconnecting...") + if(do_after(user, travel_time, src)) + SEND_SIGNAL(user, COMSIG_BITRUNNER_SAFE_DISCONNECT) + +/// Helper for times when you dont have hands (gondola??) +/obj/structure/hololadder/proc/on_enter(datum/source, atom/movable/arrived, turf/old_loc) + SIGNAL_HANDLER + + if(!isliving(arrived)) + return + + var/mob/living/user = arrived + if(isnull(user.mind)) + return + + INVOKE_ASYNC(src, PROC_REF(disconnect), user) diff --git a/code/modules/bitrunning/objects/host_monitor.dm b/code/modules/bitrunning/objects/host_monitor.dm new file mode 100644 index 00000000000000..c35edea6319f8e --- /dev/null +++ b/code/modules/bitrunning/objects/host_monitor.dm @@ -0,0 +1,33 @@ +/obj/item/bitrunning_host_monitor + name = "host monitor" + + custom_materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT * 2) + desc = "A complex electronic that will analyze the connection health between host and avatar." + flags_1 = CONDUCT_1 + icon = 'icons/obj/device.dmi' + icon_state = "host_monitor" + inhand_icon_state = "electronic" + item_flags = NOBLUDGEON + lefthand_file = 'icons/mob/inhands/items/devices_lefthand.dmi' + righthand_file = 'icons/mob/inhands/items/devices_righthand.dmi' + slot_flags = ITEM_SLOT_BELT + throw_range = 7 + throw_speed = 3 + throwforce = 3 + w_class = WEIGHT_CLASS_TINY + worn_icon_state = "electronic" + +/obj/item/bitrunning_host_monitor/attack_self(mob/user, modifiers) + . = ..() + + var/datum/component/avatar_connection/connection = user.GetComponent(/datum/component/avatar_connection) + if(isnull(connection)) + balloon_alert(user, "data not recognized") + return + + var/mob/living/pilot = connection.old_body_ref?.resolve() + if(isnull(pilot)) + balloon_alert(user, "host not recognized") + return + + to_chat(user, span_notice("Current host health: [pilot.health / pilot.maxHealth * 100]%")) diff --git a/code/modules/bitrunning/objects/landmarks.dm b/code/modules/bitrunning/objects/landmarks.dm new file mode 100644 index 00000000000000..a4539c7c3da7c0 --- /dev/null +++ b/code/modules/bitrunning/objects/landmarks.dm @@ -0,0 +1,65 @@ +/obj/effect/landmark/bitrunning + name = "Generic bitrunning effect" + icon = 'icons/effects/bitrunning.dmi' + icon_state = "crate" + +/// In case you want to gate the crate behind a special condition. +/obj/effect/landmark/bitrunning/loot_signal + name = "Mysterious aura" + /// The amount required to spawn a crate + var/points_goal = 10 + /// A special condition limits this from spawning a crate + var/points_received = 0 + /// Finished the special condition + var/revealed = FALSE + +/obj/effect/landmark/bitrunning/loot_signal/Initialize(mapload) + . = ..() + + RegisterSignal(src, COMSIG_BITRUNNER_GOAL_POINT, PROC_REF(on_add_point)) + +/// Listens for points to be added which will eventually spawn a crate. +/obj/effect/landmark/bitrunning/loot_signal/proc/on_add_point(datum/source, points_to_add) + SIGNAL_HANDLER + + if(revealed) + return + + points_received += points_to_add + + if(points_received < points_goal) + return + + reveal() + +/// Spawns the crate with some effects +/obj/effect/landmark/bitrunning/loot_signal/proc/reveal() + playsound(src, 'sound/magic/blink.ogg', 50, TRUE) + + var/turf/tile = get_turf(src) + var/obj/structure/closet/crate/secure/bitrunning/encrypted/loot = new(tile) + var/datum/effect_system/spark_spread/quantum/sparks = new(tile) + sparks.set_up(5, 1, get_turf(loot)) + sparks.start() + + qdel(src) + +/// Where the exit hololadder spawns +/obj/effect/landmark/bitrunning/hololadder_spawn + name = "Bitrunning hololadder spawn" + icon_state = "hololadder" + +/// Where the crates need to be taken +/obj/effect/landmark/bitrunning/cache_goal_turf + name = "Bitrunning goal turf" + icon_state = "goal" + +/// Where you want the crate to spawn +/obj/effect/landmark/bitrunning/cache_spawn + name = "Bitrunning crate spawn" + icon_state = "spawn" + +/// Where the safehouse will spawn +/obj/effect/landmark/bitrunning/safehouse_spawn + name = "Bitrunning safehouse spawn" + icon_state = "safehouse" diff --git a/code/modules/bitrunning/objects/loot_crate.dm b/code/modules/bitrunning/objects/loot_crate.dm new file mode 100644 index 00000000000000..5af8c0d94774ef --- /dev/null +++ b/code/modules/bitrunning/objects/loot_crate.dm @@ -0,0 +1,91 @@ +#define ORE_MULTIPLIER_IRON 3 +#define ORE_MULTIPLIER_GLASS 2 +#define ORE_MULTIPLIER_PLASMA 1 +#define ORE_MULTIPLIER_SILVER 0.7 +#define ORE_MULTIPLIER_GOLD 0.6 +#define ORE_MULTIPLIER_TITANIUM 0.5 +#define ORE_MULTIPLIER_URANIUM 0.4 +#define ORE_MULTIPLIER_DIAMOND 0.3 +#define ORE_MULTIPLIER_BLUESPACE_CRYSTAL 0.2 + +/obj/structure/closet/crate/secure/bitrunning // Base class. Do not spawn this. + name = "base class cache" + desc = "Talk to a coder." + +/// The virtual domain - side of the bitrunning crate. Deliver to the send location. +/obj/structure/closet/crate/secure/bitrunning/encrypted + name = "encrypted cache" + desc = "Needs decrypted at the safehouse to be opened." + locked = TRUE + +/obj/structure/closet/crate/secure/bitrunning/encrypted/can_unlock(mob/living/user, obj/item/card/id/player_id, obj/item/card/id/registered_id) + return FALSE + +/// The bitrunner den - side of the bitrunning crate. Appears in the receive location. +/obj/structure/closet/crate/secure/bitrunning/decrypted + name = "decrypted cache" + desc = "Compiled from the virtual domain. The reward of a successful bitrunner." + locked = FALSE + +/obj/structure/closet/crate/secure/bitrunning/decrypted/Initialize( + mapload, + datum/lazy_template/virtual_domain/completed_domain, + rewards_multiplier = 1, + ) + . = ..() + playsound(src, 'sound/magic/blink.ogg', 50, TRUE) + + if(isnull(completed_domain)) + return + + PopulateContents(completed_domain.reward_points, completed_domain.extra_loot, rewards_multiplier) + +/obj/structure/closet/crate/secure/bitrunning/decrypted/PopulateContents(reward_points, list/extra_loot, rewards_multiplier) + . = ..() + spawn_loot(extra_loot) + + new /obj/item/stack/ore/iron(src, calculate_loot(reward_points, rewards_multiplier, ORE_MULTIPLIER_IRON)) + new /obj/item/stack/ore/glass(src, calculate_loot(reward_points, rewards_multiplier, ORE_MULTIPLIER_GLASS)) + + if(reward_points > 1) + new /obj/item/stack/ore/silver(src, calculate_loot(reward_points, rewards_multiplier, ORE_MULTIPLIER_SILVER)) + new /obj/item/stack/ore/titanium(src, calculate_loot(reward_points, rewards_multiplier, ORE_MULTIPLIER_TITANIUM)) + + if(reward_points > 2) + new /obj/item/stack/ore/plasma(src, calculate_loot(reward_points, rewards_multiplier, ORE_MULTIPLIER_PLASMA)) + new /obj/item/stack/ore/gold(src, calculate_loot(reward_points, rewards_multiplier, ORE_MULTIPLIER_GOLD)) + new /obj/item/stack/ore/uranium(src, calculate_loot(reward_points, rewards_multiplier, ORE_MULTIPLIER_URANIUM)) + + if(reward_points > 3) + new /obj/item/stack/ore/diamond(src, calculate_loot(reward_points, rewards_multiplier, ORE_MULTIPLIER_DIAMOND)) + new /obj/item/stack/ore/bluespace_crystal(src, calculate_loot(reward_points, rewards_multiplier, ORE_MULTIPLIER_BLUESPACE_CRYSTAL)) + +/// Handles generating random numbers & calculating loot totals +/obj/structure/closet/crate/secure/bitrunning/decrypted/proc/calculate_loot(reward_points, rewards_multiplier, ore_multiplier) + var/base = rewards_multiplier + reward_points + var/random_sum = (rand() + 0.5) * base + return ROUND_UP(random_sum * ore_multiplier) + +/// Handles spawning extra loot. This tries to handle bad flat and assoc lists +/obj/structure/closet/crate/secure/bitrunning/decrypted/proc/spawn_loot(list/extra_loot) + for(var/path in extra_loot) + if(!ispath(path)) + continue + + if(isnull(extra_loot[path])) + return FALSE + + for(var/i in 1 to extra_loot[path]) + new path(src) + + return TRUE + +#undef ORE_MULTIPLIER_IRON +#undef ORE_MULTIPLIER_GLASS +#undef ORE_MULTIPLIER_PLASMA +#undef ORE_MULTIPLIER_SILVER +#undef ORE_MULTIPLIER_GOLD +#undef ORE_MULTIPLIER_TITANIUM +#undef ORE_MULTIPLIER_URANIUM +#undef ORE_MULTIPLIER_DIAMOND +#undef ORE_MULTIPLIER_BLUESPACE_CRYSTAL diff --git a/code/modules/bitrunning/objects/netpod.dm b/code/modules/bitrunning/objects/netpod.dm new file mode 100644 index 00000000000000..d92da961b86a3f --- /dev/null +++ b/code/modules/bitrunning/objects/netpod.dm @@ -0,0 +1,481 @@ +#define BASE_DISCONNECT_DAMAGE 40 + +/obj/machinery/netpod + name = "netpod" + + base_icon_state = "netpod" + circuit = /obj/item/circuitboard/machine/netpod + desc = "A link to the netverse. It has an assortment of cables to connect yourself to a virtual domain." + icon = 'icons/obj/machines/bitrunning.dmi' + icon_state = "netpod" + max_integrity = 300 + obj_flags = BLOCKS_CONSTRUCTION + state_open = TRUE + /// Whether we have an ongoing connection + var/connected = FALSE + /// A player selected outfit by clicking the netpod + var/datum/outfit/netsuit = /datum/outfit/job/bitrunner + /// Holds this to see if it needs to generate a new one + var/datum/weakref/avatar_ref + /// The linked quantum server + var/datum/weakref/server_ref + /// The amount of brain damage done from force disconnects + var/disconnect_damage + /// Static list of outfits to select from + var/list/cached_outfits = list() + +/obj/machinery/netpod/Initialize(mapload) + . = ..() + + return INITIALIZE_HINT_LATELOAD + +/obj/machinery/netpod/LateInitialize() + . = ..() + + disconnect_damage = BASE_DISCONNECT_DAMAGE + find_server() + + RegisterSignals(src, list( + COMSIG_QDELETING, + COMSIG_MACHINERY_BROKEN, + COMSIG_MACHINERY_POWER_LOST, + ), + PROC_REF(on_broken), + ) + RegisterSignal(src, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(src, COMSIG_ATOM_TAKE_DAMAGE, PROC_REF(on_take_damage)) + + register_context() + update_appearance() + +/obj/machinery/netpod/Destroy() + . = ..() + cached_outfits.Cut() + +/obj/machinery/netpod/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + + if(isnull(held_item)) + context[SCREENTIP_CONTEXT_LMB] = "Select Outfit" + return CONTEXTUAL_SCREENTIP_SET + + if(istype(held_item, /obj/item/crowbar) && occupant) + context[SCREENTIP_CONTEXT_LMB] = "Pry Open" + return CONTEXTUAL_SCREENTIP_SET + + return CONTEXTUAL_SCREENTIP_SET + +/obj/machinery/netpod/update_icon_state() + if(!is_operational) + icon_state = base_icon_state + return ..() + + if(state_open) + icon_state = base_icon_state + "_open_active" + return ..() + + if(panel_open) + icon_state = base_icon_state + "_panel" + return ..() + + icon_state = base_icon_state + "_closed" + if(occupant) + icon_state += "_active" + + return ..() + +/obj/machinery/netpod/MouseDrop_T(mob/target, mob/user) + var/mob/living/carbon/player = user + if(!iscarbon(player)) + return + + if((HAS_TRAIT(player, TRAIT_UI_BLOCKED) && !player.resting) || !Adjacent(player) || !player.Adjacent(target) || !ISADVANCEDTOOLUSER(player) || !is_operational) + return + + close_machine(target) + +/obj/machinery/netpod/crowbar_act(mob/living/user, obj/item/tool) + if(user.combat_mode) + attack_hand(user) + return TOOL_ACT_TOOLTYPE_SUCCESS + + if(default_pry_open(tool, user) || default_deconstruction_crowbar(tool)) + return TOOL_ACT_TOOLTYPE_SUCCESS + +/obj/machinery/netpod/screwdriver_act(mob/living/user, obj/item/tool) + if(occupant) + balloon_alert(user, "in use!") + return TOOL_ACT_TOOLTYPE_SUCCESS + + if(state_open) + balloon_alert(user, "close first.") + return TOOL_ACT_TOOLTYPE_SUCCESS + + if(default_deconstruction_screwdriver(user, "[base_icon_state]_panel", "[base_icon_state]_closed", tool)) + update_appearance() // sometimes icon doesnt properly update during flick() + ui_close(user) + return TOOL_ACT_TOOLTYPE_SUCCESS + +/obj/machinery/netpod/attack_hand(mob/living/user, list/modifiers) + . = ..() + if(!state_open && user == occupant) + container_resist_act(user) + +/obj/machinery/netpod/Exited(atom/movable/gone, direction) + . = ..() + if(!state_open && gone == occupant) + container_resist_act(gone) + +/obj/machinery/netpod/Exited(atom/movable/gone, direction) + . = ..() + if(!state_open && gone == occupant) + container_resist_act(gone) + +/obj/machinery/netpod/relaymove(mob/living/user, direction) + if(!state_open) + container_resist_act(user) + +/obj/machinery/netpod/container_resist_act(mob/living/user) + user.visible_message(span_notice("[occupant] emerges from [src]!"), + span_notice("You climb out of [src]!"), + span_notice("With a hiss, you hear a machine opening.")) + open_machine() + +/obj/machinery/netpod/open_machine(drop = TRUE, density_to_set = FALSE) + unprotect_and_signal() + playsound(src, 'sound/machines/tramopen.ogg', 60, TRUE, frequency = 65000) + flick("[base_icon_state]_opening", src) + + return ..() + +/obj/machinery/netpod/close_machine(mob/user, density_to_set = TRUE) + if(!state_open || panel_open || !is_operational || !iscarbon(user)) + return + + playsound(src, 'sound/machines/tramclose.ogg', 60, TRUE, frequency = 65000) + flick("[base_icon_state]_closing", src) + ..() + + if(!iscarbon(occupant)) + open_machine() + return + + enter_matrix() + +/obj/machinery/netpod/default_pry_open(obj/item/crowbar, mob/living/pryer) + if(isnull(occupant) || !iscarbon(occupant)) + if(!state_open) + if(panel_open) + return FALSE + open_machine() + else + shut_pod() + + return TRUE + + pryer.visible_message( + span_danger("[pryer] starts prying open [src]!"), + span_notice("You start to pry open [src]."), + span_notice("You hear loud prying on metal.") + ) + playsound(src, 'sound/machines/airlock_alien_prying.ogg', 100, TRUE) + + SEND_SIGNAL(src, COMSIG_BITRUNNER_CROWBAR_ALERT, pryer) + + if(do_after(pryer, 15 SECONDS, src)) + if(!state_open) + open_machine() + + return TRUE + +/obj/machinery/netpod/ui_interact(mob/user, datum/tgui/ui) + if(!is_operational || occupant) + return + + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "NetpodOutfits") + ui.set_autoupdate(FALSE) + ui.open() + +/obj/machinery/netpod/ui_data() + var/list/data = list() + + data["netsuit"] = netsuit + return data + +/obj/machinery/netpod/ui_static_data() + var/list/data = list() + + if(!length(cached_outfits)) + cached_outfits += make_outfit_collection("Jobs", subtypesof(/datum/outfit/job)) + + data["collections"] = cached_outfits + + return data + +/obj/machinery/netpod/ui_act(action, params) + . = ..() + if(.) + return TRUE + switch(action) + if("select_outfit") + var/datum/outfit/new_suit = resolve_outfit(params["outfit"]) + if(new_suit) + netsuit = new_suit + return TRUE + + return FALSE + +/// Disconnects the occupant after a certain time so they aren't just hibernating in netpod stasis. A balance change +/obj/machinery/netpod/proc/auto_disconnect() + if(isnull(occupant) || state_open || connected) + return + + if(!iscarbon(occupant)) + open_machine() + return + + var/mob/living/carbon/player = occupant + + player.playsound_local(src, 'sound/effects/splash.ogg', 60, TRUE) + to_chat(player, span_notice("The machine disconnects itself and begins to drain.")) + open_machine() + +/// Handles occupant post-disconnection effects like damage, sounds, etc +/obj/machinery/netpod/proc/disconnect_occupant(forced = FALSE) + connected = FALSE + + var/mob/living/mob_occupant = occupant + if(isnull(occupant) || !isliving(occupant) || mob_occupant.stat == DEAD) + open_machine() + return + + mob_occupant.playsound_local(src, "sound/magic/blink.ogg", 25, TRUE) + mob_occupant.set_static_vision(2 SECONDS) + mob_occupant.set_temp_blindness(1 SECONDS) + mob_occupant.Paralyze(2 SECONDS) + + var/heal_time = 1 + if(mob_occupant.health < mob_occupant.maxHealth) + heal_time = (mob_occupant.stat + 2) * 5 + addtimer(CALLBACK(src, PROC_REF(auto_disconnect)), heal_time SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_DELETE_ME) + + if(!forced) + return + + mob_occupant.flash_act(override_blindness_check = TRUE, visual = TRUE) + mob_occupant.adjustOrganLoss(ORGAN_SLOT_BRAIN, disconnect_damage) + INVOKE_ASYNC(mob_occupant, TYPE_PROC_REF(/mob/living, emote), "scream") + to_chat(mob_occupant, span_danger("You've been forcefully disconnected from your avatar! Your thoughts feel scrambled!")) + +/** + * ### Enter Matrix + * Finds any current avatars from this chair - or generates a new one + * + * New avatars cost 1 attempt, and this will eject if there's none left + * + * Connects the mind to the avatar if everything is ok + */ +/obj/machinery/netpod/proc/enter_matrix() + var/mob/living/carbon/human/neo = occupant + if(!ishuman(neo) || neo.stat == DEAD || isnull(neo.mind)) + balloon_alert(neo, "invalid occupant.") + return + + var/obj/machinery/quantum_server/server = find_server() + if(isnull(server)) + balloon_alert(neo, "no server connected!") + return + + var/datum/lazy_template/virtual_domain/generated_domain = server.generated_domain + if(isnull(generated_domain) || !server.is_ready) + balloon_alert(neo, "nothing loaded!") + return + + var/mob/living/carbon/current_avatar = avatar_ref?.resolve() + var/obj/structure/hololadder/wayout + if(isnull(current_avatar) || current_avatar.stat != CONSCIOUS) // We need a viable avatar + wayout = server.generate_hololadder() + if(isnull(wayout)) + balloon_alert(neo, "out of bandwidth!") + return + current_avatar = server.generate_avatar(wayout, netsuit) + avatar_ref = WEAKREF(current_avatar) + server.stock_gear(current_avatar, neo) + + neo.set_static_vision(3 SECONDS) + protect_occupant(occupant) + if(!do_after(neo, 2 SECONDS, src)) + return + + // Very invalid + if(QDELETED(neo) || QDELETED(current_avatar) || QDELETED(src)) + return + + // Invalid + if(occupant != neo || isnull(neo.mind) || neo.stat == DEAD || current_avatar.stat == DEAD) + return + + current_avatar.AddComponent( \ + /datum/component/avatar_connection, \ + old_mind = neo.mind, \ + old_body = neo, \ + server = server, \ + pod = src, \ + help_text = generated_domain.help_text, \ + ) + + connected = TRUE + +/// Finds a server and sets the server_ref +/obj/machinery/netpod/proc/find_server() + var/obj/machinery/quantum_server/server = server_ref?.resolve() + if(server) + return server + + server = locate(/obj/machinery/quantum_server) in oview(4, src) + if(isnull(server)) + return + + server_ref = WEAKREF(server) + RegisterSignal(server, COMSIG_BITRUNNER_SERVER_UPGRADED, PROC_REF(on_server_upgraded)) + RegisterSignal(server, COMSIG_BITRUNNER_DOMAIN_COMPLETE, PROC_REF(on_domain_complete)) + RegisterSignal(server, COMSIG_BITRUNNER_DOMAIN_SCRUBBED, PROC_REF(on_domain_scrubbed)) + + return server + +/// Creates a list of outfit entries for the UI. +/obj/machinery/netpod/proc/make_outfit_collection(identifier, list/outfit_list) + var/list/collection = list( + "name" = identifier, + "outfits" = list() + ) + + for(var/path as anything in outfit_list) + var/datum/outfit/outfit = path + + var/outfit_name = initial(outfit.name) + if(findtext(outfit_name, "(") != 0 || findtext(outfit_name, "-") != 0) // No special variants please + continue + + collection["outfits"] += list(list("path" = path, "name" = outfit_name)) + + return list(collection) + +/// Machine has been broken - handles signals and reverting sprites +/obj/machinery/netpod/proc/on_broken(datum/source) + SIGNAL_HANDLER + + if(!state_open) + open_machine() + + if(occupant) + unprotect_and_signal() + +/// Puts points on the current occupant's card account +/obj/machinery/netpod/proc/on_domain_complete(datum/source, atom/movable/crate, reward_points) + SIGNAL_HANDLER + + if(isnull(occupant) || !connected || !iscarbon(occupant)) + return + + var/mob/living/carbon/player = occupant + + var/datum/bank_account/account = player.get_bank_account() + if(isnull(account)) + return + + account.bitrunning_points += reward_points * 100 + +/// User inspects the machine +/obj/machinery/netpod/proc/on_examine(datum/source, mob/examiner, list/examine_text) + SIGNAL_HANDLER + + examine_text += span_infoplain("Drag yourself into the pod to engage the link.") + examine_text += span_infoplain("It has limited resuscitation capabilities. Remaining in the pod can heal some injuries.") + examine_text += span_infoplain("It has a security system that will alert the occupant if it is tampered with.") + + if(isnull(occupant)) + examine_text += span_notice("It is currently unoccupied.") + return + + examine_text += span_notice("It is currently occupied by [occupant].") + examine_text += span_notice("It can be pried open with a crowbar, but its safety mechanisms will alert the occupant.") + +/// The domain has been fully purged, so we should double check our avatar is deleted +/obj/machinery/netpod/proc/on_domain_scrubbed(datum/source) + SIGNAL_HANDLER + + var/mob/living/current_avatar = avatar_ref?.resolve() + if(isnull(current_avatar)) + return + + QDEL_NULL(current_avatar) + +/// When the server is upgraded, drops brain damage a little +/obj/machinery/netpod/proc/on_server_upgraded(datum/source, servo_rating) + SIGNAL_HANDLER + + disconnect_damage = BASE_DISCONNECT_DAMAGE * (1 - servo_rating) + +/// Checks the integrity, alerts occupants +/obj/machinery/netpod/proc/on_take_damage(datum/source, damage_amount) + SIGNAL_HANDLER + + if(isnull(occupant)) + return + + var/total = max_integrity - damage_amount + var/integrity = (atom_integrity / total) * 100 + if(integrity > 50) + return + + SEND_SIGNAL(src, COMSIG_BITRUNNER_NETPOD_INTEGRITY) + +/// Puts the occupant in netpod stasis, basically short-circuiting environmental conditions +/obj/machinery/netpod/proc/protect_occupant(mob/living/target) + if(target != occupant) + return + + target.AddComponent(/datum/component/netpod_healing, \ + brute_heal = 4, \ + burn_heal = 4, \ + toxin_heal = 4, \ + clone_heal = 4, \ + blood_heal = 4, \ + ) + + target.playsound_local(src, 'sound/effects/submerge.ogg', 20, TRUE) + target.extinguish_mob() + update_use_power(ACTIVE_POWER_USE) + +/// On unbuckle or break, make sure the occupant ref is null +/obj/machinery/netpod/proc/unprotect_and_signal() + unprotect_occupant(occupant) + SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR) + +/// Removes the occupant from netpod stasis +/obj/machinery/netpod/proc/unprotect_occupant(mob/living/target) + var/datum/component/netpod_healing/healing_eff = target?.GetComponent(/datum/component/netpod_healing) + if(healing_eff) + qdel(healing_eff) + + update_use_power(IDLE_POWER_USE) + +/// Resolves a path to an outfit. +/obj/machinery/netpod/proc/resolve_outfit(text) + var/path = text2path(text) + if(ispath(path, /datum/outfit)) + return path + +/// Closes the machine without shoving in an occupant +/obj/machinery/netpod/proc/shut_pod() + state_open = FALSE + playsound(src, 'sound/machines/tramclose.ogg', 60, TRUE, frequency = 65000) + flick("[base_icon_state]_closing", src) + set_density(TRUE) + + update_appearance() + +#undef BASE_DISCONNECT_DAMAGE diff --git a/code/modules/bitrunning/objects/quantum_console.dm b/code/modules/bitrunning/objects/quantum_console.dm new file mode 100644 index 00000000000000..c918648d010b1b --- /dev/null +++ b/code/modules/bitrunning/objects/quantum_console.dm @@ -0,0 +1,108 @@ +/obj/machinery/computer/quantum_console + name = "quantum console" + + circuit = /obj/item/circuitboard/computer/quantum_console + icon_keyboard = "mining" + icon_screen = "bitrunning" + req_access = list(ACCESS_MINING) + /// The server this console is connected to. + var/datum/weakref/server_ref + +/obj/machinery/computer/quantum_console/Initialize(mapload, obj/item/circuitboard/circuit) + . = ..() + desc = "Even in the distant year [CURRENT_STATION_YEAR], Nanostrasen is still using REST APIs. How grim." + + return INITIALIZE_HINT_LATELOAD + +/obj/machinery/computer/quantum_console/LateInitialize() + . = ..() + + if(isnull(server_ref?.resolve())) + find_server() + +/obj/machinery/computer/quantum_console/ui_interact(mob/user, datum/tgui/ui) + . = ..() + + if(!is_operational) + return + + if(isnull(server_ref?.resolve())) + find_server() + + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "QuantumConsole") + ui.open() + +/obj/machinery/computer/quantum_console/ui_data() + var/list/data = list() + + var/obj/machinery/quantum_server/server = find_server() + if(isnull(server)) + data["connected"] = FALSE + return data + + data["connected"] = TRUE + data["generated_domain"] = server.generated_domain?.key + data["occupants"] = length(server.avatar_connection_refs) + data["points"] = server.points + data["randomized"] = server.domain_randomized + data["ready"] = server.is_ready && server.is_operational + data["scanner_tier"] = server.scanner_tier + data["retries_left"] = length(server.exit_turfs) - server.retries_spent + + return data + +/obj/machinery/computer/quantum_console/ui_static_data(mob/user) + var/list/data = list() + + var/obj/machinery/quantum_server/server = find_server() + if(isnull(server)) + return data + + data["available_domains"] = server.get_available_domains() + data["avatars"] = server.get_avatar_data() + + return data + +/obj/machinery/computer/quantum_console/ui_act(action, list/params, datum/tgui/ui) + . = ..() + if(.) + return TRUE + + var/obj/machinery/quantum_server/server = find_server() + if(isnull(server)) + return FALSE + + switch(action) + if("random_domain") + var/map_id = server.get_random_domain_id() + if(!map_id) + return TRUE + + server.cold_boot_map(usr, map_id) + return TRUE + if("refresh") + ui.send_full_update() + return TRUE + if("set_domain") + server.cold_boot_map(usr, params["id"]) + return TRUE + if("stop_domain") + server.begin_shutdown(usr) + return TRUE + + return FALSE + +/// Attempts to find a quantum server. +/obj/machinery/computer/quantum_console/proc/find_server() + var/obj/machinery/quantum_server/server = server_ref?.resolve() + if(server) + return server + + for(var/direction in GLOB.cardinals) + var/obj/machinery/quantum_server/nearby_server = locate(/obj/machinery/quantum_server, get_step(src, direction)) + if(nearby_server) + server_ref = WEAKREF(nearby_server) + nearby_server.console_ref = WEAKREF(src) + return nearby_server diff --git a/code/modules/bitrunning/objects/vendor.dm b/code/modules/bitrunning/objects/vendor.dm new file mode 100644 index 00000000000000..abd63a9e784302 --- /dev/null +++ b/code/modules/bitrunning/objects/vendor.dm @@ -0,0 +1,86 @@ +#define CREDIT_TYPE_BITRUNNING "np" + +/obj/machinery/computer/order_console/bitrunning + name = "bitrunning supplies order console" + desc = "NexaCache(tm)! Dubiously authentic gear for the digital daredevil." + icon = 'icons/obj/machines/bitrunning.dmi' + icon_state = "vendor" + icon_keyboard = null + icon_screen = null + circuit = /obj/item/circuitboard/computer/order_console/bitrunning + cooldown_time = 10 SECONDS + cargo_cost_multiplier = 0.65 + express_cost_multiplier = 1 + purchase_tooltip = @{"Your purchases will arrive at cargo, + and hopefully get delivered by them. + 35% cheaper than express delivery."} + express_tooltip = @{"Sends your purchases instantly."} + credit_type = CREDIT_TYPE_BITRUNNING + + order_categories = list( + CATEGORY_BITRUNNING_FLAIR, + CATEGORY_BITRUNNING_TECH, + CATEGORY_BEPIS, + ) + blackbox_key = "bitrunning" + +/obj/machinery/computer/order_console/bitrunning/subtract_points(final_cost, obj/item/card/id/card) + if(final_cost <= card.registered_account.bitrunning_points) + card.registered_account.bitrunning_points -= final_cost + return TRUE + return FALSE + +/obj/machinery/computer/order_console/bitrunning/order_groceries(mob/living/purchaser, obj/item/card/id/card, list/groceries) + var/list/things_to_order = list() + for(var/datum/orderable_item/item as anything in groceries) + things_to_order[item.item_path] = groceries[item] + + var/datum/supply_pack/bitrunning/pack = new( + purchaser = purchaser, \ + cost = get_total_cost(), \ + contains = things_to_order, + ) + + var/datum/supply_order/new_order = new( + pack = pack, + orderer = purchaser, + orderer_rank = "Bitrunning Vendor", + orderer_ckey = purchaser.ckey, + reason = "", + paying_account = card.registered_account, + department_destination = null, + coupon = null, + charge_on_purchase = FALSE, + manifest_can_fail = FALSE, + cost_type = credit_type, + can_be_cancelled = FALSE, + ) + say("Thank you for your purchase! It will arrive on the next cargo shuttle!") + radio.talk_into(src, "A bitrunner has ordered equipment which will arrive on the cargo shuttle! Please make sure it gets to them as soon as possible!", radio_channel) + SSshuttle.shopping_list += new_order + +/obj/machinery/computer/order_console/bitrunning/retrieve_points(obj/item/card/id/id_card) + return round(id_card.registered_account.bitrunning_points) + +/obj/machinery/computer/order_console/bitrunning/ui_act(action, params) + . = ..() + if(!.) + flick("vendor_off", src) + +/obj/machinery/computer/order_console/bitrunning/update_icon_state() + icon_state = "[initial(icon_state)][powered() ? null : "_off"]" + return ..() + +/datum/supply_pack/bitrunning + name = "bitrunning order" + hidden = TRUE + crate_name = "bitrunning delivery crate" + access = list(ACCESS_BIT_DEN) + +/datum/supply_pack/bitrunning/New(purchaser, cost, list/contains) + . = ..() + name = "[purchaser]'s Bitrunning Order" + src.cost = cost + src.contains = contains + +#undef CREDIT_TYPE_BITRUNNING diff --git a/code/modules/bitrunning/orders/disks.dm b/code/modules/bitrunning/orders/disks.dm new file mode 100644 index 00000000000000..ced1dde883a195 --- /dev/null +++ b/code/modules/bitrunning/orders/disks.dm @@ -0,0 +1,26 @@ +/datum/orderable_item/bitrunning_tech + category_index = CATEGORY_BITRUNNING_TECH + +/datum/orderable_item/bitrunning_tech/item_tier1 + cost_per_order = 1000 + item_path = /obj/item/bitrunning_disk/item/tier1 + +/datum/orderable_item/bitrunning_tech/item_tier2 + cost_per_order = 1500 + item_path = /obj/item/bitrunning_disk/item/tier2 + +/datum/orderable_item/bitrunning_tech/item_tier3 + cost_per_order = 2500 + item_path = /obj/item/bitrunning_disk/item/tier3 + +/datum/orderable_item/bitrunning_tech/ability_tier1 + cost_per_order = 1000 + item_path = /obj/item/bitrunning_disk/ability/tier1 + +/datum/orderable_item/bitrunning_tech/ability_tier2 + cost_per_order = 1800 + item_path = /obj/item/bitrunning_disk/ability/tier2 + +/datum/orderable_item/bitrunning_tech/ability_tier3 + cost_per_order = 3200 + item_path = /obj/item/bitrunning_disk/ability/tier3 diff --git a/code/modules/bitrunning/orders/flair.dm b/code/modules/bitrunning/orders/flair.dm new file mode 100644 index 00000000000000..ef36348eb6ae94 --- /dev/null +++ b/code/modules/bitrunning/orders/flair.dm @@ -0,0 +1,40 @@ +/datum/orderable_item/bitrunning_flair + category_index = CATEGORY_BITRUNNING_FLAIR + +/datum/orderable_item/bitrunning_flair/cornchips + item_path = /obj/item/food/cornchips + cost_per_order = 100 + +/datum/orderable_item/bitrunning_flair/mountain_wind + item_path = /obj/item/reagent_containers/cup/soda_cans/space_mountain_wind + cost_per_order = 100 + +/datum/orderable_item/bitrunning_flair/pwr_game + item_path = /obj/item/reagent_containers/cup/soda_cans/pwr_game + cost_per_order = 200 + +/datum/orderable_item/bitrunning_flair/grey_bull + item_path = /obj/item/reagent_containers/cup/soda_cans/grey_bull + cost_per_order = 200 + +/datum/orderable_item/bitrunning_flair/medkit + item_path = /obj/item/storage/medkit/brute + desc = "Don't beat yourself up, it's just a game!" + cost_per_order = 500 + +/datum/orderable_item/bitrunning_flair/medkit_fire + item_path = /obj/item/storage/medkit/fire + desc = "Great after heated gaming sessions." + cost_per_order = 500 + +/datum/orderable_item/bitrunning_flair/oval_sunglasses + item_path = /obj/item/clothing/glasses/sunglasses/oval + cost_per_order = 1000 + +/datum/orderable_item/bitrunning_flair/trenchcoat + item_path = /obj/item/clothing/suit/jacket/trenchcoat + cost_per_order = 1000 + +/datum/orderable_item/bitrunning_flair/jackboots + item_path = /obj/item/clothing/shoes/jackboots + cost_per_order = 1000 diff --git a/code/modules/bitrunning/orders/tech.dm b/code/modules/bitrunning/orders/tech.dm new file mode 100644 index 00000000000000..286e9817f3c522 --- /dev/null +++ b/code/modules/bitrunning/orders/tech.dm @@ -0,0 +1,23 @@ +/datum/orderable_item/bepis + category_index = CATEGORY_BEPIS + +/datum/orderable_item/bepis/circuit_stack + item_path = /obj/item/stack/circuit_stack/full + cost_per_order = 150 + +/datum/orderable_item/bepis/survival_pen + item_path = /obj/item/pen/survival + cost_per_order = 150 + +/datum/orderable_item/bepis/party_sleeper + item_path = /obj/item/circuitboard/machine/sleeper/party + cost_per_order = 750 + desc = "A decommissioned sleeper circuitboard, repurposed for recreational purposes." + +/datum/orderable_item/bepis/sprayoncan + item_path = /obj/item/toy/sprayoncan + cost_per_order = 750 + +/datum/orderable_item/bepis/pristine + item_path = /obj/item/disk/design_disk/bepis/remove_tech + cost_per_order = 1000 diff --git a/code/modules/bitrunning/server/loot.dm b/code/modules/bitrunning/server/loot.dm new file mode 100644 index 00000000000000..8b3af95607c641 --- /dev/null +++ b/code/modules/bitrunning/server/loot.dm @@ -0,0 +1,125 @@ +/// Handles calculating rewards based on number of players, parts, threats, etc +/obj/machinery/quantum_server/proc/calculate_rewards() + var/rewards_base = 0.8 + + if(domain_randomized) + rewards_base += 0.2 + + rewards_base += servo_bonus + + rewards_base += (domain_threats * 2) + + for(var/index in 2 to length(avatar_connection_refs)) + rewards_base += multiplayer_bonus + + return rewards_base + +/// Generates a reward based on the given domain +/obj/machinery/quantum_server/proc/generate_loot() + var/list/obj/machinery/byteforge/nearby_forges = get_nearby_forges() + if(isnull(nearby_forges)) + say(src, "No nearby byteforges detected.") + return FALSE + + points += generated_domain.reward_points + playsound(src, 'sound/machines/terminal_success.ogg', 30, 2) + + var/obj/machinery/byteforge/chosen_forge = pick(nearby_forges) + if(isnull(chosen_forge)) + stack_trace("Failed to find a turf to spawn loot crate on.") + return FALSE + + var/bonus = calculate_rewards() + + var/obj/item/paper/certificate = new() + certificate.add_raw_text(get_completion_certificate()) + certificate.name = "certificate of domain completion" + certificate.update_appearance() + + var/obj/structure/closet/crate/secure/bitrunning/decrypted/reward_crate = new(src, generated_domain, bonus) + reward_crate.manifest = certificate + reward_crate.update_appearance() + + chosen_forge.start_to_spawn(reward_crate) + return TRUE + +/// Returns the markdown text containing domain completion information +/obj/machinery/quantum_server/proc/get_completion_certificate() + var/base_points = generated_domain.reward_points + if(domain_randomized) + base_points -= 1 + + var/bonuses = calculate_rewards() + + var/time_difference = world.time - generated_domain.start_time + + var/completion_time = "### Completion Time: [DisplayTimeText(time_difference)]\n" + + var/grade = "\n---\n\n# Rating: [grade_completion(generated_domain.difficulty, domain_threats, base_points, domain_randomized, time_difference)]" + + var/text = "# Certificate of Domain Completion\n\n---\n\n" + + text += "### [generated_domain.name][domain_randomized ? " (Randomized)" : ""]\n" + text += "- **Difficulty:** [generated_domain.difficulty]\n" + text += "- **Threats:** [domain_threats]\n" + text += "- **Base Points:** [base_points][domain_randomized ? " +1" : ""]\n\n" + text += "- **Total Bonus:** [bonuses]x\n\n" + + if(bonuses <= 1) + text += completion_time + text += grade + return text + + text += "### Bonuses\n" + if(domain_randomized) + text += "- **Randomized:** + 0.2\n" + + if(length(avatar_connection_refs) > 1) + text += "- **Multiplayer:** + [(length(avatar_connection_refs) - 1) * multiplayer_bonus]\n" + + if(domain_threats > 0) + text += "- **Threats:** + [domain_threats * 2]\n" + + var/servo_rating = servo_bonus + + if(servo_rating > 0.2) + text += "- **Components:** + [servo_rating]\n" + + text += completion_time + text += grade + + return text + +/// Grades the player's run based on several factors +/obj/machinery/quantum_server/proc/grade_completion(difficulty, threats, points, randomized, completion_time) + var/score = threats * 5 + score += points + score += randomized ? 1 : 0 + + var/base = difficulty + 1 + var/time_score = 1 + + if(completion_time <= 1 MINUTES) + time_score = 10 + else if(completion_time <= 2 MINUTES) + time_score = 5 + else if(completion_time <= 5 MINUTES) + time_score = 3 + else if(completion_time <= 10 MINUTES) + time_score = 2 + else + time_score = 1 + + score += time_score * base + + switch(score) + if(1 to 4) + return "D" + if(5 to 7) + return "C" + if(8 to 10) + return "B" + if(11 to 13) + return "A" + else + return "S" diff --git a/code/modules/bitrunning/server/map_handling.dm b/code/modules/bitrunning/server/map_handling.dm new file mode 100644 index 00000000000000..741fad476f0a8d --- /dev/null +++ b/code/modules/bitrunning/server/map_handling.dm @@ -0,0 +1,185 @@ +#define ONLY_TURF 1 + +/// Gives all current occupants a notification that the server is going down +/obj/machinery/quantum_server/proc/begin_shutdown(mob/user) + if(isnull(generated_domain)) + return + + if(!length(avatar_connection_refs)) + balloon_alert(user, "powering down domain...") + playsound(src, 'sound/machines/terminal_off.ogg', 40, 2) + reset() + return + + balloon_alert(user, "notifying clients...") + playsound(src, 'sound/machines/terminal_alert.ogg', 100, TRUE) + user.visible_message( + span_danger("[user] begins depowering the server!"), + span_notice("You start disconnecting clients..."), + span_danger("You hear frantic keying on a keyboard."), + ) + + SEND_SIGNAL(src, COMSIG_BITRUNNER_SHUTDOWN_ALERT, user) + + if(!do_after(user, 20 SECONDS, src)) + return + + reset() + +/** + * ### Quantum Server Cold Boot + * Procedurally links the 3 booting processes together. + * + * This is the starting point if you have an id. Does validation and feedback on steps + */ +/obj/machinery/quantum_server/proc/cold_boot_map(mob/user, map_key) + if(!is_ready) + return FALSE + + if(isnull(map_key)) + balloon_alert(user, "no domain specified.") + return FALSE + + if(generated_domain) + balloon_alert(user, "stop the current domain first.") + return FALSE + + if(length(avatar_connection_refs)) + balloon_alert(user, "all clients must disconnect!") + return FALSE + + is_ready = FALSE + playsound(src, 'sound/machines/terminal_processing.ogg', 30, 2) + + if(!initialize_domain(map_key) || !initialize_safehouse() || !initialize_map_items()) + balloon_alert(user, "initialization failed.") + scrub_vdom() + is_ready = TRUE + return FALSE + + is_ready = TRUE + playsound(src, 'sound/machines/terminal_insert_disc.ogg', 30, 2) + balloon_alert(user, "domain loaded.") + generated_domain.start_time = world.time + points -= generated_domain.cost + update_use_power(ACTIVE_POWER_USE) + update_appearance() + + return TRUE + +/// Initializes a new domain if the given key is valid and the user has enough points +/obj/machinery/quantum_server/proc/initialize_domain(map_key) + var/datum/lazy_template/virtual_domain/to_load + + for(var/datum/lazy_template/virtual_domain/available as anything in subtypesof(/datum/lazy_template/virtual_domain)) + if(map_key != initial(available.key) || points < initial(available.cost)) + continue + to_load = available + break + + if(isnull(to_load)) + return FALSE + + generated_domain = new to_load() + RegisterSignal(generated_domain, COMSIG_LAZY_TEMPLATE_LOADED, PROC_REF(on_template_loaded)) + generated_domain.lazy_load() + + return TRUE + +/// Loads in necessary map items, sets mutation targets, etc +/obj/machinery/quantum_server/proc/initialize_map_items() + var/turf/goal_turfs = list() + var/turf/crate_turfs = list() + + for(var/thing in GLOB.landmarks_list) + if(istype(thing, /obj/effect/landmark/bitrunning/hololadder_spawn)) + exit_turfs += get_turf(thing) + qdel(thing) // i'm worried about multiple servers getting confused so lets clean em up + continue + + if(istype(thing, /obj/effect/landmark/bitrunning/cache_goal_turf)) + var/turf/tile = get_turf(thing) + goal_turfs += tile + RegisterSignal(tile, COMSIG_ATOM_ENTERED, PROC_REF(on_goal_turf_entered)) + RegisterSignal(tile, COMSIG_ATOM_EXAMINE, PROC_REF(on_goal_turf_examined)) + qdel(thing) + continue + + if(istype(thing, /obj/effect/landmark/bitrunning/cache_spawn)) + crate_turfs += get_turf(thing) + qdel(thing) + continue + + if(!length(exit_turfs)) + CRASH("Failed to find exit turfs on generated domain.") + if(!length(goal_turfs)) + CRASH("Failed to find send turfs on generated domain.") + + if(length(crate_turfs)) + shuffle_inplace(crate_turfs) + new /obj/structure/closet/crate/secure/bitrunning/encrypted(pick(crate_turfs)) + + return TRUE + +/// Loads the safehouse +/obj/machinery/quantum_server/proc/initialize_safehouse() + var/turf/safehouse_load_turf = list() + for(var/obj/effect/landmark/bitrunning/safehouse_spawn/spawner in GLOB.landmarks_list) + safehouse_load_turf += get_turf(spawner) + qdel(spawner) + break + + if(!length(safehouse_load_turf)) + CRASH("Failed to find safehouse load landmark on map.") + + var/datum/map_template/safehouse/safehouse = new generated_domain.safehouse_path() + safehouse.load(safehouse_load_turf[ONLY_TURF]) + generated_safehouse = safehouse + + return TRUE + +/// Stops the current virtual domain and disconnects all users +/obj/machinery/quantum_server/proc/reset(fast = FALSE) + is_ready = FALSE + + SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR) + + if(!fast) + notify_spawned_threats() + addtimer(CALLBACK(src, PROC_REF(scrub_vdom)), 15 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE) + else + scrub_vdom() // used in unit testing, no need to wait for callbacks + + addtimer(CALLBACK(src, PROC_REF(cool_off)), min(server_cooldown_time * capacitor_coefficient), TIMER_UNIQUE|TIMER_STOPPABLE|TIMER_DELETE_ME) + update_appearance() + + update_use_power(IDLE_POWER_USE) + domain_randomized = FALSE + domain_threats = 0 + retries_spent = 0 + +/// Deletes all the tile contents +/obj/machinery/quantum_server/proc/scrub_vdom() + SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR) /// just in case someone's connected + SEND_SIGNAL(src, COMSIG_BITRUNNER_DOMAIN_SCRUBBED) // avatar cleanup just in case + + if(length(generated_domain.reservations)) + var/datum/turf_reservation/res = generated_domain.reservations[1] + res.Release() + + var/list/datum/weakref/creatures = spawned_threat_refs + mutation_candidate_refs + for(var/datum/weakref/creature_ref as anything in creatures) + var/mob/living/creature = creature_ref?.resolve() + if(isnull(creature)) + continue + + creature.dust() // sometimes mobs just don't die + + avatar_connection_refs.Cut() + exit_turfs = list() + generated_domain = null + generated_safehouse = null + mutation_candidate_refs.Cut() + spawned_threat_refs.Cut() + +#undef ONLY_TURF diff --git a/code/modules/bitrunning/server/obj_generation.dm b/code/modules/bitrunning/server/obj_generation.dm new file mode 100644 index 00000000000000..221308e048783b --- /dev/null +++ b/code/modules/bitrunning/server/obj_generation.dm @@ -0,0 +1,101 @@ +/// Generates a new avatar for the bitrunner. +/obj/machinery/quantum_server/proc/generate_avatar(obj/structure/hololadder/wayout, datum/outfit/netsuit) + var/mob/living/carbon/human/avatar = new(wayout.loc) + + var/outfit_path = generated_domain.forced_outfit || netsuit + var/datum/outfit/to_wear = new outfit_path() + + to_wear.belt = /obj/item/bitrunning_host_monitor + to_wear.glasses = null + to_wear.gloves = null + to_wear.l_hand = null + to_wear.l_pocket = null + to_wear.r_hand = null + to_wear.r_pocket = null + to_wear.suit = null + to_wear.suit_store = null + + avatar.equipOutfit(to_wear, visualsOnly = TRUE) + + var/thing = avatar.get_active_held_item() + if(!isnull(thing)) + qdel(thing) + + thing = avatar.get_inactive_held_item() + if(!isnull(thing)) + qdel(thing) + + var/obj/item/storage/backpack/bag = avatar.back + if(istype(bag)) + QDEL_LIST(bag.contents) + + bag.contents += list( + new /obj/item/storage/box/survival, + new /obj/item/storage/medkit/regular, + new /obj/item/flashlight, + ) + + var/obj/item/card/id/outfit_id = avatar.wear_id + if(outfit_id) + outfit_id.assignment = "Bit Avatar" + outfit_id.registered_name = avatar.real_name + + outfit_id.registered_account = new() + outfit_id.registered_account.replaceable = FALSE + + SSid_access.apply_trim_to_card(outfit_id, /datum/id_trim/bit_avatar) + + return avatar + +/// Generates a new hololadder for the bitrunner. Effectively a respawn attempt. +/obj/machinery/quantum_server/proc/generate_hololadder() + if(!length(exit_turfs)) + return + + if(retries_spent >= length(exit_turfs)) + return + + var/turf/destination + for(var/turf/dest_turf in exit_turfs) + if(!locate(/obj/structure/hololadder) in dest_turf) + destination = dest_turf + break + + if(isnull(destination)) + return + + var/obj/structure/hololadder/wayout = new(destination) + if(isnull(wayout)) + return + + retries_spent += 1 + + return wayout + +/// Scans over neo's contents for bitrunning tech disks. Loads the items or abilities onto the avatar. +/obj/machinery/quantum_server/proc/stock_gear(mob/living/carbon/human/avatar, mob/living/carbon/human/neo) + var/failed = FALSE + + for(var/obj/item/bitrunning_disk/disk in neo.get_contents()) + if(istype(disk, /obj/item/bitrunning_disk/ability)) + var/obj/item/bitrunning_disk/ability/ability_disk = disk + + if(isnull(ability_disk.granted_action)) + failed = TRUE + continue + + var/datum/action/our_action = new ability_disk.granted_action() + our_action.Grant(avatar) + continue + + if(istype(disk, /obj/item/bitrunning_disk/item)) + var/obj/item/bitrunning_disk/item/item_disk = disk + + if(isnull(item_disk.granted_item)) + failed = TRUE + continue + + avatar.put_in_hands(new item_disk.granted_item()) + + if(failed) + to_chat(neo, span_warning("One of your disks failed to load. You must activate them to make a selection.")) diff --git a/code/modules/bitrunning/server/quantum_server.dm b/code/modules/bitrunning/server/quantum_server.dm new file mode 100644 index 00000000000000..b869fb7f02e2a0 --- /dev/null +++ b/code/modules/bitrunning/server/quantum_server.dm @@ -0,0 +1,149 @@ +/** + * The base object for the quantum server + */ +/obj/machinery/quantum_server + name = "quantum server" + + circuit = /obj/item/circuitboard/machine/quantum_server + density = TRUE + desc = "A hulking computational machine designed to fabricate virtual domains." + icon = 'icons/obj/machines/bitrunning.dmi' + base_icon_state = "qserver" + icon_state = "qserver" + /// Affects server cooldown efficiency + var/capacitor_coefficient = 1 + /// The loaded map template, map_template/virtual_domain + var/datum/lazy_template/virtual_domain/generated_domain + /// The loaded safehouse, map_template/safehouse + var/datum/map_template/safehouse/generated_safehouse + /// The connected console + var/datum/weakref/console_ref + /// If the current domain was a random selection + var/domain_randomized = FALSE + /// If any threats were spawned, adds to rewards + var/domain_threats = 0 + /// Prevents multiple user actions. Handled by loading domains and cooldowns + var/is_ready = TRUE + /// List of available domains + var/list/available_domains = list() + /// Current plugged in users + var/list/datum/weakref/avatar_connection_refs = list() + /// Cached list of mutable mobs in zone for cybercops + var/list/datum/weakref/mutation_candidate_refs = list() + /// Any ghosts that have spawned in + var/list/datum/weakref/spawned_threat_refs = list() + /// Scales loot with extra players + var/multiplayer_bonus = 1.1 + ///The radio the console can speak into + var/obj/item/radio/radio + /// The amount of points in the system, used to purchase maps + var/points = 0 + /// Keeps track of the number of times someone has built a hololadder + var/retries_spent = 0 + /// Changes how much info is available on the domain + var/scanner_tier = 1 + /// Length of time it takes for the server to cool down after resetting. Here to give runners downtime so their faces don't get stuck like that + var/server_cooldown_time = 3 MINUTES + /// Applies bonuses to rewards etc + var/servo_bonus = 0 + /// The turfs we can place a hololadder on. + var/turf/exit_turfs = list() + +/obj/machinery/quantum_server/Initialize(mapload) + . = ..() + + return INITIALIZE_HINT_LATELOAD + +/obj/machinery/quantum_server/LateInitialize() + . = ..() + + if(isnull(console_ref)) + find_console() + + radio = new(src) + radio.set_frequency(FREQ_SUPPLY) + radio.subspace_transmission = TRUE + radio.canhear_range = 0 + radio.recalculateChannels() + + RegisterSignals(src, list(COMSIG_MACHINERY_BROKEN, COMSIG_MACHINERY_POWER_LOST), PROC_REF(on_broken)) + RegisterSignal(src, COMSIG_QDELETING, PROC_REF(on_delete)) + RegisterSignal(src, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(src, COMSIG_BITRUNNER_SPAWN_GLITCH, PROC_REF(on_threat_created)) + + // This further gets sorted in the client by cost so it's random and grouped + available_domains = shuffle(subtypesof(/datum/lazy_template/virtual_domain)) + +/obj/machinery/quantum_server/Destroy(force) + . = ..() + + available_domains.Cut() + mutation_candidate_refs.Cut() + avatar_connection_refs.Cut() + spawned_threat_refs.Cut() + QDEL_NULL(exit_turfs) + QDEL_NULL(generated_domain) + QDEL_NULL(generated_safehouse) + QDEL_NULL(radio) + +/obj/machinery/quantum_server/update_appearance(updates) + if(isnull(generated_domain) || !is_operational) + set_light(l_on = FALSE) + return ..() + + set_light_color(is_ready ? LIGHT_COLOR_BABY_BLUE : LIGHT_COLOR_FIRE) + set_light(l_range = 2, l_power = 1.5, l_on = TRUE) + + return ..() + +/obj/machinery/quantum_server/update_icon_state() + if(isnull(generated_domain) || !is_operational) + icon_state = base_icon_state + return ..() + + icon_state = "[base_icon_state]_[is_ready ? "on" : "off"]" + return ..() + +/obj/machinery/quantum_server/crowbar_act(mob/living/user, obj/item/crowbar) + . = ..() + + if(!is_ready) + balloon_alert(user, "it's scalding hot!") + return TRUE + if(length(avatar_connection_refs)) + balloon_alert(user, "all clients must disconnect!") + return TRUE + if(default_deconstruction_crowbar(crowbar)) + return TRUE + return FALSE + +/obj/machinery/quantum_server/screwdriver_act(mob/living/user, obj/item/screwdriver) + . = ..() + + if(!is_ready) + balloon_alert(user, "it's scalding hot!") + return TRUE + if(default_deconstruction_screwdriver(user, "[base_icon_state]_panel", icon_state, screwdriver)) + return TRUE + return FALSE + +/obj/machinery/quantum_server/RefreshParts() + . = ..() + + var/capacitor_rating = 1.15 + var/datum/stock_part/capacitor/cap = locate() in component_parts + capacitor_rating -= cap.tier * 0.15 + + capacitor_coefficient = capacitor_rating + + var/datum/stock_part/scanning_module/scanner = locate() in component_parts + if(scanner) + scanner_tier = scanner.tier + + var/servo_rating = 0 + for(var/datum/stock_part/servo/servo in component_parts) + servo_rating += servo.tier * 0.1 + + servo_bonus = servo_rating + + SEND_SIGNAL(src, COMSIG_BITRUNNER_SERVER_UPGRADED, servo_rating) diff --git a/code/modules/bitrunning/server/signal_handlers.dm b/code/modules/bitrunning/server/signal_handlers.dm new file mode 100644 index 00000000000000..b0464b351faf04 --- /dev/null +++ b/code/modules/bitrunning/server/signal_handlers.dm @@ -0,0 +1,107 @@ +/// If broken via signal, disconnects all users +/obj/machinery/quantum_server/proc/on_broken(datum/source) + SIGNAL_HANDLER + + if(isnull(generated_domain)) + return + + SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR) + +/// Whenever a corpse spawner makes a new corpse, add it to the list of potential mutations +/obj/machinery/quantum_server/proc/on_corpse_spawned(datum/source, mob/living/corpse) + SIGNAL_HANDLER + + mutation_candidate_refs.Add(WEAKREF(corpse)) + +/// Being qdeleted - make sure the circuit and connected mobs go with it +/obj/machinery/quantum_server/proc/on_delete(datum/source) + SIGNAL_HANDLER + + if(generated_domain) + SEND_SIGNAL(src, COMSIG_BITRUNNER_SEVER_AVATAR) + scrub_vdom() + + if(is_ready) + return + // in case they're trying to cheese cooldown + var/obj/item/circuitboard/machine/quantum_server/circuit = locate(/obj/item/circuitboard/machine/quantum_server) in contents + if(circuit) + qdel(circuit) + +/// Handles examining the server. Shows cooldown time and efficiency. +/obj/machinery/quantum_server/proc/on_examine(datum/source, mob/examiner, list/examine_text) + SIGNAL_HANDLER + + examine_text += span_infoplain("Can be resource intensive to run. Ensure adequate power supply.") + + if(capacitor_coefficient < 1) + examine_text += span_infoplain("Its coolant capacity reduces cooldown time by [(1 - capacitor_coefficient) * 100]%.") + + if(servo_bonus > 0.2) + examine_text += span_infoplain("Its manipulation potential is increasing rewards by [servo_bonus]x.") + examine_text += span_infoplain("Injury from unsafe ejection reduced [servo_bonus * 100]%.") + + if(!is_ready) + examine_text += span_notice("It is currently cooling down. Give it a few moments.") + return + +/// Whenever something enters the send tiles, check if it's a loot crate. If so, alert players. +/obj/machinery/quantum_server/proc/on_goal_turf_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) + SIGNAL_HANDLER + + if(!istype(arrived, /obj/structure/closet/crate/secure/bitrunning/encrypted)) + return + + var/obj/structure/closet/crate/secure/bitrunning/encrypted/loot_crate = arrived + if(!istype(loot_crate)) + return + + for(var/mob/person in loot_crate.contents) + if(isnull(person.mind)) + person.forceMove(get_turf(loot_crate)) + + var/datum/component/avatar_connection/connection = person.GetComponent(/datum/component/avatar_connection) + connection?.full_avatar_disconnect() + + spark_at_location(loot_crate) + qdel(loot_crate) + SEND_SIGNAL(src, COMSIG_BITRUNNER_DOMAIN_COMPLETE, arrived, generated_domain.reward_points) + generate_loot() + +/// Handles examining the server. Shows cooldown time and efficiency. +/obj/machinery/quantum_server/proc/on_goal_turf_examined(datum/source, mob/examiner, list/examine_text) + SIGNAL_HANDLER + + examine_text += span_info("Beneath your gaze, the floor pulses subtly with streams of encoded data.") + examine_text += span_info("It seems to be part of the location designated for retrieving encrypted payloads.") + +/// Scans over the inbound created_atoms from lazy templates +/obj/machinery/quantum_server/proc/on_template_loaded(datum/lazy_template/source, list/created_atoms) + SIGNAL_HANDLER + + for(var/thing in created_atoms) + if(isliving(thing)) // so we can mutate them + var/mob/living/creature = thing + + if(creature.can_be_cybercop) + mutation_candidate_refs.Add(WEAKREF(creature)) + continue + + if(istype(thing, /obj/effect/mob_spawn/ghost_role)) // so we get threat alerts + RegisterSignal(thing, COMSIG_GHOSTROLE_SPAWNED, PROC_REF(on_threat_created)) + continue + + if(istype(thing, /obj/effect/mob_spawn/corpse)) // corpses are valid targets too + var/obj/effect/mob_spawn/corpse/spawner = thing + + mutation_candidate_refs.Add(spawner.spawned_mob_ref) + + UnregisterSignal(source, COMSIG_LAZY_TEMPLATE_LOADED) + +/// Handles when cybercops are summoned into the area or ghosts click a ghost role spawner +/obj/machinery/quantum_server/proc/on_threat_created(datum/source, mob/living/threat) + SIGNAL_HANDLER + + domain_threats += 1 + spawned_threat_refs.Add(WEAKREF(threat)) + SEND_SIGNAL(src, COMSIG_BITRUNNER_THREAT_CREATED) // notify players diff --git a/code/modules/bitrunning/server/util.dm b/code/modules/bitrunning/server/util.dm new file mode 100644 index 00000000000000..f4dbada9ef6f05 --- /dev/null +++ b/code/modules/bitrunning/server/util.dm @@ -0,0 +1,142 @@ +#define REDACTED "???" +#define MAX_DISTANCE 4 // How far crates can spawn from the server + +/// Resets the cooldown state and updates icons +/obj/machinery/quantum_server/proc/cool_off() + is_ready = TRUE + update_appearance() + radio.talk_into(src, "Thermal systems within operational parameters. Proceeding to domain configuration.", RADIO_CHANNEL_SUPPLY) + +/// Attempts to connect to a quantum console +/obj/machinery/quantum_server/proc/find_console() + var/obj/machinery/computer/quantum_console/console = console_ref?.resolve() + if(console) + return console + + for(var/direction in GLOB.cardinals) + var/obj/machinery/computer/quantum_console/nearby_console = locate(/obj/machinery/computer/quantum_console, get_step(src, direction)) + if(nearby_console) + console_ref = WEAKREF(nearby_console) + nearby_console.server_ref = WEAKREF(src) + return nearby_console + +/// Compiles a list of available domains. +/obj/machinery/quantum_server/proc/get_available_domains() + var/list/levels = list() + + for(var/datum/lazy_template/virtual_domain/domain as anything in available_domains) + if(initial(domain.test_only)) + continue + var/can_view = initial(domain.difficulty) < scanner_tier && initial(domain.cost) <= points + 5 + var/can_view_reward = initial(domain.difficulty) < (scanner_tier + 1) && initial(domain.cost) <= points + 3 + + levels += list(list( + "cost" = initial(domain.cost), + "desc" = can_view ? initial(domain.desc) : "Limited scanning capabilities. Cannot infer domain details.", + "difficulty" = initial(domain.difficulty), + "id" = initial(domain.key), + "name" = can_view ? initial(domain.name) : REDACTED, + "reward" = can_view_reward ? initial(domain.reward_points) : REDACTED, + )) + + return levels + +/// If there are hosted minds, attempts to get a list of their current virtual bodies w/ vitals +/obj/machinery/quantum_server/proc/get_avatar_data() + var/list/hosted_avatars = list() + + for(var/datum/weakref/avatar_ref in avatar_connection_refs) + var/datum/component/avatar_connection/connection = avatar_ref.resolve() + if(isnull(connection)) + avatar_connection_refs.Remove(connection) + continue + + var/mob/living/creature = connection.parent + var/mob/living/pilot = connection.old_body_ref?.resolve() + + hosted_avatars += list(list( + "health" = creature.health, + "name" = creature.name, + "pilot" = pilot, + "brute" = creature.get_current_damage_of_type(BRUTE), + "burn" = creature.get_current_damage_of_type(BURN), + "tox" = creature.get_current_damage_of_type(TOX), + "oxy" = creature.get_current_damage_of_type(OXY), + )) + + return hosted_avatars + +/// Gets a random available domain given the current points. Weighted towards higher cost domains. +/obj/machinery/quantum_server/proc/get_random_domain_id() + if(points < 1) + return + + var/list/random_domains = list() + var/total_cost = 0 + + for(var/datum/lazy_template/virtual_domain/available as anything in subtypesof(/datum/lazy_template/virtual_domain)) + var/init_cost = initial(available.cost) + if(!initial(available.test_only) && init_cost > 0 && init_cost < 4 && init_cost <= points) + random_domains += list(list( + cost = init_cost, + id = initial(available.key), + )) + + var/random_value = rand(0, total_cost) + var/accumulated_cost = 0 + + for(var/available as anything in random_domains) + accumulated_cost += available["cost"] + if(accumulated_cost >= random_value) + domain_randomized = TRUE + return available["id"] + +/// Gets all mobs originally generated by the loaded domain and returns a list that are capable of being antagged +/obj/machinery/quantum_server/proc/get_valid_domain_targets() + // A: No one is playing + // B: The domain is not loaded + // C: The domain is shutting down + // D: There are no mobs + if(!length(avatar_connection_refs) || isnull(generated_domain) || !is_ready || !is_operational || !length(mutation_candidate_refs)) + return list() + + for(var/datum/weakref/creature_ref as anything in mutation_candidate_refs) + var/mob/living/creature = creature_ref.resolve() + if(isnull(creature) || creature.mind) + mutation_candidate_refs.Remove(creature_ref) + + return shuffle(mutation_candidate_refs) + +/// Locates any turfs with forges on them +/obj/machinery/quantum_server/proc/get_nearby_forges() + var/list/obj/machinery/byteforge/nearby_forges = list() + + for(var/obj/machinery/byteforge/forge in oview(MAX_DISTANCE, src)) + nearby_forges += forge + + return nearby_forges + +/// Finds any mobs with minds in the zones and gives them the bad news +/obj/machinery/quantum_server/proc/notify_spawned_threats() + for(var/datum/weakref/baddie_ref as anything in spawned_threat_refs) + var/mob/living/baddie = baddie_ref.resolve() + if(isnull(baddie) || baddie.stat >= UNCONSCIOUS || isnull(baddie.mind)) + continue + + baddie.throw_alert( + ALERT_BITRUNNER_RESET, + /atom/movable/screen/alert/bitrunning/qserver_threat_deletion, + new_master = src, + ) + + to_chat(baddie, span_userdanger("You have been flagged for deletion! Thank you for your service.")) + +/// Do some magic teleport sparks +/obj/machinery/quantum_server/proc/spark_at_location(obj/cache) + playsound(cache, 'sound/magic/blink.ogg', 50, TRUE) + var/datum/effect_system/spark_spread/quantum/sparks = new() + sparks.set_up(5, 1, get_turf(cache)) + sparks.start() + +#undef REDACTED +#undef MAX_DISTANCE diff --git a/code/modules/bitrunning/turfs.dm b/code/modules/bitrunning/turfs.dm new file mode 100644 index 00000000000000..93dce1789c4f62 --- /dev/null +++ b/code/modules/bitrunning/turfs.dm @@ -0,0 +1,14 @@ +/turf/open/floor/bitrunning_transport + name = "circuit floor" + icon = 'icons/turf/floors.dmi' + desc = "Looks complex. You can see the circuits running through the floor." + icon_state = "bitrunning" + +/turf/closed/indestructible/binary + name = "tear in the fabric of reality" + icon = 'icons/turf/floors.dmi' + icon_state = "binary" + +/obj/effect/baseturf_helper/virtual_domain + name = "virtual domain baseturf editor" + baseturf = /turf/open/indestructible/binary diff --git a/code/modules/bitrunning/virtual_domain/domains/ash_drake.dm b/code/modules/bitrunning/virtual_domain/domains/ash_drake.dm new file mode 100644 index 00000000000000..02bb91abc5888f --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/ash_drake.dm @@ -0,0 +1,18 @@ +/datum/lazy_template/virtual_domain/ash_drake + name = "Ashen Inferno" + cost = BITRUNNER_COST_MEDIUM + desc = "Home of the ash drake, a powerful dragon that scours the surface of Lavaland." + difficulty = BITRUNNER_DIFFICULTY_MEDIUM + forced_outfit = /datum/outfit/job/miner + key = "ash_drake" + map_name = "ash_drake" + reward_points = BITRUNNER_REWARD_MEDIUM + safehouse_path = /datum/map_template/safehouse/lavaland_boss + +/mob/living/simple_animal/hostile/megafauna/dragon/virtual_domain + can_be_cybercop = FALSE + crusher_loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + health = 1600 + loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + maxHealth = 1600 + true_spawn = FALSE diff --git a/code/modules/bitrunning/virtual_domain/domains/beach_bar.dm b/code/modules/bitrunning/virtual_domain/domains/beach_bar.dm new file mode 100644 index 00000000000000..a6fb3e921e054a --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/beach_bar.dm @@ -0,0 +1,22 @@ +/datum/lazy_template/virtual_domain/beach_bar + name = "Beach Bar" + desc = "A cheerful seaside haven where friendly skeletons serve up drinks. Say, how'd you guys get so dead?" + extra_loot = list(/obj/item/toy/beach_ball = 1) + help_text = "This place is running on a skeleton crew, and they don't seem to be too keen to share details. \ + Maybe a few drinks of liquid charm will get the spirits up. As the saying goes, if you can't beat 'em, join 'em." + key = "beach_bar" + map_name = "beach_bar" + safehouse_path = /datum/map_template/safehouse/mine + +/obj/item/reagent_containers/cup/glass/drinkingglass/filled/virtual_domain + name = "pina colada" + desc = "Whose drink is this? Not yours, that's for sure. Well, it's not like they're going to miss it." + list_reagents = list(/datum/reagent/consumable/ethanol/pina_colada = 30) + +/obj/item/reagent_containers/cup/glass/drinkingglass/filled/virtual_domain/Initialize(mapload, vol) + . = ..() + + AddComponent(/datum/component/bitrunning_points, \ + signal_type = COMSIG_GLASS_DRANK, \ + points_per_signal = 0.5, \ + ) diff --git a/code/modules/bitrunning/virtual_domain/domains/blood_drunk_miner.dm b/code/modules/bitrunning/virtual_domain/domains/blood_drunk_miner.dm new file mode 100644 index 00000000000000..abf2e0fc5a9405 --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/blood_drunk_miner.dm @@ -0,0 +1,18 @@ +/datum/lazy_template/virtual_domain/blood_drunk_miner + name = "Sanguine Excavation" + cost = BITRUNNER_COST_MEDIUM + desc = "Few escape the surface of Lavaland without a few scars. Some remain, maddened by the hunt." + difficulty = BITRUNNER_DIFFICULTY_MEDIUM + forced_outfit = /datum/outfit/job/miner + key = "blood_drunk_miner" + map_name = "blood_drunk_miner" + reward_points = BITRUNNER_REWARD_MEDIUM + safehouse_path = /datum/map_template/safehouse/lavaland_boss + +/mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/virtual_domain + can_be_cybercop = FALSE + crusher_loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + health = 1600 + loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + maxHealth = 1600 + true_spawn = FALSE diff --git a/code/modules/bitrunning/virtual_domain/domains/bubblegum.dm b/code/modules/bitrunning/virtual_domain/domains/bubblegum.dm new file mode 100644 index 00000000000000..bede97177cb7d4 --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/bubblegum.dm @@ -0,0 +1,19 @@ +/datum/lazy_template/virtual_domain/bubblegum + name = "Blood-Soaked Lair" + cost = BITRUNNER_COST_HIGH + desc = "King of the slaughter demons. Bubblegum is a massive, hulking beast with a penchant for violence." + difficulty = BITRUNNER_DIFFICULTY_HIGH + extra_loot = list(/obj/item/toy/plush/bubbleplush = 1) + forced_outfit = /datum/outfit/job/miner + key = "bubblegum" + map_name = "bubblegum" + reward_points = BITRUNNER_REWARD_HIGH + safehouse_path = /datum/map_template/safehouse/lavaland_boss + +/mob/living/simple_animal/hostile/megafauna/bubblegum/virtual_domain + can_be_cybercop = FALSE + crusher_loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + health = 2000 + loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + maxHealth = 2000 + true_spawn = FALSE diff --git a/code/modules/bitrunning/virtual_domain/domains/clown_planet.dm b/code/modules/bitrunning/virtual_domain/domains/clown_planet.dm new file mode 100644 index 00000000000000..92f000c9cf342a --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/clown_planet.dm @@ -0,0 +1,13 @@ +/datum/lazy_template/virtual_domain/clown_planet + name = "Clown Planet" + cost = BITRUNNER_COST_LOW + desc = "In the deep, dark reaches of space, there is only Honk." + difficulty = BITRUNNER_DIFFICULTY_LOW + extra_loot = list(/obj/item/bikehorn = 1) + forced_outfit = /datum/outfit/job/clown + help_text = "The trials of the Honkitude have begun. The sound of bike horns wailing in the distance. \ + this realm- some sort of puzzle, has existed in legend as the final test of just how silly you are." + key = "clown_planet" + map_name = "clown_planet" + reward_points = BITRUNNER_REWARD_LOW + safehouse_path = /datum/map_template/safehouse/mine diff --git a/code/modules/bitrunning/virtual_domain/domains/colossus.dm b/code/modules/bitrunning/virtual_domain/domains/colossus.dm new file mode 100644 index 00000000000000..35ba4eee0ca89f --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/colossus.dm @@ -0,0 +1,18 @@ +/datum/lazy_template/virtual_domain/colossus + name = "Celestial Trial" + cost = BITRUNNER_COST_HIGH + desc = "A massive, ancient beast named the Colossus. Judgment comes." + difficulty = BITRUNNER_DIFFICULTY_HIGH + forced_outfit = /datum/outfit/job/miner + key = "colossus" + map_name = "colossus" + reward_points = BITRUNNER_REWARD_HIGH + safehouse_path = /datum/map_template/safehouse/lavaland_boss + +/mob/living/simple_animal/hostile/megafauna/colossus/virtual_domain + can_be_cybercop = FALSE + crusher_loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + health = 2000 + maxHealth = 2000 + true_spawn = FALSE diff --git a/code/modules/bitrunning/virtual_domain/domains/gondola_asteroid.dm b/code/modules/bitrunning/virtual_domain/domains/gondola_asteroid.dm new file mode 100644 index 00000000000000..01d58e3980381d --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/gondola_asteroid.dm @@ -0,0 +1,35 @@ +/datum/lazy_template/virtual_domain/gondola_asteroid + name = "Gondola Asteroid" + desc = "An asteroid home to a bountiful forest of gondolas. Peaceful." + map_name = "gondola_asteroid" + help_text = "What a lovely forest. There's a loot crate here in the middle of the map. \ + Hmm... It doesn't budge. The gondolas don't seem to have any trouble moving it, though. \ + I bet there's a way to move it myself." + key = "gondola_asteroid" + map_name = "gondola_asteroid" + safehouse_path = /datum/map_template/safehouse/shuttle_space + +/// Very pushy gondolas, great for moving loot crates. +/obj/structure/closet/crate/secure/bitrunning/encrypted/gondola + move_resist = MOVE_FORCE_STRONG + +/mob/living/simple_animal/pet/gondola/virtual_domain + health = 50 + loot = list(/obj/effect/decal/cleanable/blood/gibs, /obj/item/stack/sheet/animalhide/gondola = 1, /obj/item/food/meat/slab/gondola/virtual_domain = 1) + maxHealth = 50 + move_force = MOVE_FORCE_VERY_STRONG + move_resist = MOVE_FORCE_STRONG + +/obj/item/food/meat/slab/gondola/virtual_domain + food_reagents = list( + /datum/reagent/consumable/nutriment/protein = 4, + /datum/reagent/gondola_mutation_toxin/virtual_domain = 5, + ) + +/datum/reagent/gondola_mutation_toxin/virtual_domain + name = "Advanced Tranquility" + gondola_disease = /datum/disease/transformation/gondola/virtual_domain + +/datum/disease/transformation/gondola/virtual_domain + stage_prob = 9 + new_form = /mob/living/simple_animal/pet/gondola/virtual_domain diff --git a/code/modules/bitrunning/virtual_domain/domains/hierophant.dm b/code/modules/bitrunning/virtual_domain/domains/hierophant.dm new file mode 100644 index 00000000000000..142623f4f812e5 --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/hierophant.dm @@ -0,0 +1,18 @@ +/datum/lazy_template/virtual_domain/hierophant + name = "Zealot Arena" + cost = BITRUNNER_COST_HIGH + desc = "Dance, puppets, dance!" + difficulty = BITRUNNER_DIFFICULTY_HIGH + forced_outfit = /datum/outfit/job/miner + key = "hierophant" + map_name = "hierophant" + reward_points = BITRUNNER_REWARD_HIGH + safehouse_path = /datum/map_template/safehouse/lavaland_boss + +/mob/living/simple_animal/hostile/megafauna/hierophant/virtual_domain + can_be_cybercop = FALSE + crusher_loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + health = 1700 + loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + maxHealth = 1700 + true_spawn = FALSE diff --git a/code/modules/bitrunning/virtual_domain/domains/legion.dm b/code/modules/bitrunning/virtual_domain/domains/legion.dm new file mode 100644 index 00000000000000..f1ba146f3801b9 --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/legion.dm @@ -0,0 +1,20 @@ +/datum/lazy_template/virtual_domain/legion + name = "Chamber of Echoes" + cost = BITRUNNER_COST_MEDIUM + desc = "A chilling realm that houses Legion's necropolis. Those who succumb to it are forever damned." + difficulty = BITRUNNER_DIFFICULTY_MEDIUM + forced_outfit = /datum/outfit/job/miner + key = "legion" + map_name = "legion" + reward_points = BITRUNNER_REWARD_MEDIUM + safehouse_path = /datum/map_template/safehouse/lavaland_boss + +/mob/living/simple_animal/hostile/megafauna/legion/virtual_domain + can_be_cybercop = FALSE + crusher_loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + health = 1500 + loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + maxHealth = 1500 + true_spawn = FALSE + +// You may be thinking, what about those mini-legions? They're not part of the initial created_atoms list diff --git a/code/modules/bitrunning/virtual_domain/domains/pipedream.dm b/code/modules/bitrunning/virtual_domain/domains/pipedream.dm new file mode 100644 index 00000000000000..fd54ef6ca48476 --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/pipedream.dm @@ -0,0 +1,101 @@ +/datum/lazy_template/virtual_domain/pipedream + name = "Disposal Pipe Factory" + cost = BITRUNNER_COST_LOW + desc = "An abandoned and infested factory manufacturing disposal pipes." + difficulty = BITRUNNER_DIFFICULTY_MEDIUM + extra_loot = list(/obj/item/stack/pipe_cleaner_coil/random/five = 1) + help_text = "Not long ago, this place was thriving with activity. The workers \ + seemed to have left in a hurry, and now productivity is in the bin. Something \ + must have trashed the place, but what?" + key = "pipedream" + map_name = "pipedream" + reward_points = BITRUNNER_REWARD_LOW + safehouse_path = /datum/map_template/safehouse/shuttle + +// ID Trims +/datum/id_trim/factory + assignment = "Factory Worker" + trim_state = "trim_cargotechnician" + department_color = COLOR_CARGO_BROWN + subdepartment_color = COLOR_CARGO_BROWN + sechud_icon_state = SECHUD_CARGO_TECHNICIAN + access = list( + ACCESS_AWAY_SUPPLY + ) + +/datum/id_trim/factory/qm + assignment = "Factory Quartermaster" + trim_state = "trim_quartermaster" + department_color = COLOR_COMMAND_BLUE + subdepartment_color = COLOR_CARGO_BROWN + department_state = "departmenthead" + sechud_icon_state = SECHUD_QUARTERMASTER + access = list( + ACCESS_AWAY_SUPPLY, + ACCESS_AWAY_COMMAND + ) + +// ID Cards +/obj/item/card/id/advanced/factory + name = "factory worker ID" + trim = /datum/id_trim/factory + +/obj/item/card/id/advanced/factory/qm + name = "factory quartermaster ID" + trim = /datum/id_trim/factory/qm + +//Outfits +/datum/outfit/factory + name = "Factory Worker" + + id_trim = /datum/id_trim/factory + id = /obj/item/card/id/advanced/ + uniform = /obj/item/clothing/under/rank/cargo/tech + suit = /obj/item/clothing/suit/hazardvest + belt = /obj/item/radio + gloves = /obj/item/clothing/gloves/color/black + head = /obj/item/clothing/head/soft/yellow + shoes = /obj/item/clothing/shoes/workboots + l_pocket = /obj/item/flashlight/seclite + +/datum/outfit/factory/guard + name = "Factory Guard" + + uniform = /obj/item/clothing/under/rank/security/officer/grey + suit = /obj/item/clothing/suit/armor/vest/alt + belt = /obj/item/radio + gloves = /obj/item/clothing/gloves/color/black + head = /obj/item/clothing/head/soft/sec + shoes = /obj/item/clothing/shoes/jackboots/sec + l_pocket = /obj/item/restraints/handcuffs + r_pocket = /obj/item/assembly/flash/handheld + +/datum/outfit/factory/qm + name = "Factory Quatermaster" + + id_trim = /datum/id_trim/factory/qm + id = /obj/item/card/id/advanced/silver + uniform = /obj/item/clothing/under/rank/cargo/qm + belt = /obj/item/radio + gloves = /obj/item/clothing/gloves/color/black + head = /obj/item/clothing/head/soft/yellow + shoes = /obj/item/clothing/shoes/jackboots/sec + l_pocket = /obj/item/melee/baton/telescopic + r_pocket = /obj/item/stamp/head/qm + +// Corpses +/obj/effect/mob_spawn/corpse/human/factory + name = "Factory Worker" + outfit = /datum/outfit/factory + icon_state = "corpsecargotech" + +/obj/effect/mob_spawn/corpse/human/factory/guard + name = "Factory Guard" + outfit = /datum/outfit/factory/guard + icon_state = "corpsecargotech" + +/obj/effect/mob_spawn/corpse/human/factory/qm + name = "Factory Quartermaster" + outfit = /datum/outfit/factory/qm + icon_state = "corpsecargotech" + diff --git a/code/modules/bitrunning/virtual_domain/domains/pirates.dm b/code/modules/bitrunning/virtual_domain/domains/pirates.dm new file mode 100644 index 00000000000000..52d86a71211806 --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/pirates.dm @@ -0,0 +1,10 @@ +/datum/lazy_template/virtual_domain/pirates + name = "Corsair Cove" + cost = BITRUNNER_COST_MEDIUM + desc = "Battle your way to the hidden treasure, seize the booty, and make a swift escape before the pirates turn the tide." + difficulty = BITRUNNER_DIFFICULTY_MEDIUM + help_text = "Put on the provided outfits to blend in, then battle your way through the hostile pirates. \ + Grab the treasure and get out before you're overwhelmed!" + key = "pirates" + map_name = "pirates" + reward_points = BITRUNNER_REWARD_MEDIUM diff --git a/code/modules/bitrunning/virtual_domain/domains/stairs_and_cliffs.dm b/code/modules/bitrunning/virtual_domain/domains/stairs_and_cliffs.dm new file mode 100644 index 00000000000000..2d9bcca3645560 --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/stairs_and_cliffs.dm @@ -0,0 +1,29 @@ +/datum/lazy_template/virtual_domain/stairs_and_cliffs + name = "Glacier Grind" + cost = BITRUNNER_COST_LOW + desc = "A treacherous climb few calves can survive. Great cardio though." + help_text = "Ever heard of 'Snakes and Ladders'? It's like that, but with \ + instead of ladders its stairs and instead of snakes its a steep drop down a \ + cliff into rough rocks or liquid plasma." + extra_loot = list(/obj/item/clothing/suit/costume/snowman = 2) + difficulty = BITRUNNER_DIFFICULTY_LOW + forced_outfit = /datum/outfit/job/virtual_domain_iceclimber + key = "stairs_and_cliffs" + map_name = "stairs_and_cliffs" + reward_points = BITRUNNER_REWARD_MEDIUM + safehouse_path = /datum/map_template/safehouse/ice + +/turf/open/cliff/snowrock/virtual_domain + name = "icy cliff" + initial_gas_mix = "o2=22;n2=82;TEMP=180" + +/turf/open/lava/plasma/virtual_domain + name = "plasma lake" + initial_gas_mix = "o2=22;n2=82;TEMP=180" + +/datum/outfit/job/virtual_domain_iceclimber + name = "Ice Climber" + + uniform = /obj/item/clothing/under/color/grey + backpack = /obj/item/storage/backpack/duffelbag + shoes = /obj/item/clothing/shoes/winterboots diff --git a/code/modules/bitrunning/virtual_domain/domains/syndicate_assault.dm b/code/modules/bitrunning/virtual_domain/domains/syndicate_assault.dm new file mode 100644 index 00000000000000..bae0da6874dbf2 --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/syndicate_assault.dm @@ -0,0 +1,13 @@ +/datum/lazy_template/virtual_domain/syndicate_assault + name = "Syndicate Assault" + cost = BITRUNNER_COST_MEDIUM + desc = "Board the enemy ship and recover the stolen cargo." + difficulty = BITRUNNER_DIFFICULTY_MEDIUM + extra_loot = list(/obj/item/toy/plush/nukeplushie = 1) + help_text = "A group of Syndicate operatives have stolen valuable cargo from the station. \ + They have boarded their ship and are attempting to escape. Infiltrate their ship and recover \ + the crate. Be careful, they are extremely armed." + key = "syndicate_assault" + map_name = "syndicate_assault" + reward_points = BITRUNNER_REWARD_MEDIUM + safehouse_path = /datum/map_template/safehouse/shuttle diff --git a/code/modules/bitrunning/virtual_domain/domains/test_only.dm b/code/modules/bitrunning/virtual_domain/domains/test_only.dm new file mode 100644 index 00000000000000..6e5e852fb5c8ef --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/test_only.dm @@ -0,0 +1,11 @@ +/// Used for unit tests only. Skipped in UI. +/datum/lazy_template/virtual_domain/test_only + name = "Test Only" + key = "test_only" + map_name = "test_only" + test_only = TRUE + safehouse_path = /datum/map_template/safehouse/test_only + +/datum/lazy_template/virtual_domain/test_only/expensive + key = "test_only_expensive" + cost = 3 diff --git a/code/modules/bitrunning/virtual_domain/domains/vaporwave.dm b/code/modules/bitrunning/virtual_domain/domains/vaporwave.dm new file mode 100644 index 00000000000000..45d4abec9830af --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/vaporwave.dm @@ -0,0 +1,10 @@ +/datum/lazy_template/virtual_domain/vaporwave + name = "Cosmic Vestige" + cost = BITRUNNER_COST_EXTREME + desc = "Suspended in the silent void of space, the Neon Relic is a haunting echo of a retro-futuristic era." + difficulty = BITRUNNER_DIFFICULTY_NONE + extra_loot = list(/obj/item/stack/spacecash/c500 = 3) + key = "vaporwave" + map_name = "vaporwave" + reward_points = BITRUNNER_REWARD_EXTREME + safehouse_path = /datum/map_template/safehouse/shuttle_space diff --git a/code/modules/bitrunning/virtual_domain/domains/wendigo.dm b/code/modules/bitrunning/virtual_domain/domains/wendigo.dm new file mode 100644 index 00000000000000..fcad3db6faf76f --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/wendigo.dm @@ -0,0 +1,19 @@ +/datum/lazy_template/virtual_domain/wendigo + name = "Glacial Devourer" + cost = BITRUNNER_COST_HIGH + desc = "Legends speak of the ravenous Wendigo hidden deep within the caves of Icemoon." + difficulty = BITRUNNER_DIFFICULTY_HIGH + forced_outfit = /datum/outfit/job/miner + key = "wendigo" + map_name = "wendigo" + reward_points = BITRUNNER_REWARD_HIGH + safehouse_path = /datum/map_template/safehouse/lavaland_boss + +/mob/living/simple_animal/hostile/megafauna/wendigo/virtual_domain + can_be_cybercop = FALSE + crusher_loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + guaranteed_butcher_results = list(/obj/item/wendigo_skull = 1) + health = 2000 + loot = list(/obj/structure/closet/crate/secure/bitrunning/encrypted) + maxHealth = 2000 + true_spawn = FALSE diff --git a/code/modules/bitrunning/virtual_domain/domains/xeno_nest.dm b/code/modules/bitrunning/virtual_domain/domains/xeno_nest.dm new file mode 100644 index 00000000000000..2bd4105e13c220 --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/domains/xeno_nest.dm @@ -0,0 +1,12 @@ +/datum/lazy_template/virtual_domain/xeno_nest + name = "Xeno Infestation" + cost = BITRUNNER_COST_LOW + desc = "Our ship scanners have detected lifeforms of unknown origin. Friendly attempts to contact them have failed." + difficulty = BITRUNNER_DIFFICULTY_LOW + extra_loot = list(/obj/item/toy/plush/rouny = 1) + help_text = "You are on a barren planet filled with hostile creatures. There is a crate here, not hidden, \ + simply protected. Expect resistance." + key = "xeno_nest" + map_name = "xeno_nest" + reward_points = BITRUNNER_REWARD_LOW + safehouse_path = /datum/map_template/safehouse/shuttle diff --git a/code/modules/bitrunning/virtual_domain/safehouses.dm b/code/modules/bitrunning/virtual_domain/safehouses.dm new file mode 100644 index 00000000000000..bb42f690ac7ec0 --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/safehouses.dm @@ -0,0 +1,53 @@ +/** + * # Safe Houses + * The starting point for virtual domains. + * Create your own: Read the readme file in the '_maps/safehouses' folder. + */ +/datum/map_template/safehouse + name = "virtual domain: safehouse" + + returns_created_atoms = TRUE + /// The map file to load + var/filename = "den.dmm" + +/datum/map_template/safehouse/New() + mappath = "_maps/safehouses/" + filename + ..(path = mappath) + +/datum/map_template/safehouse/test_only + filename = "test_only_safehouse.dmm" + + +/// The default safehouse map template. +/datum/map_template/safehouse/wood + filename = "wood.dmm" + +/datum/map_template/safehouse/den + filename = "den.dmm" + +/datum/map_template/safehouse/dig + filename = "dig.dmm" + +/datum/map_template/safehouse/shuttle + filename = "shuttle.dmm" + +// Has space tiles on the four corners. +/datum/map_template/safehouse/shuttle_space + filename = "shuttle_space.dmm" + +/datum/map_template/safehouse/mine + filename = "mine.dmm" + +// Comes preloaded with mining combat gear. +/datum/map_template/safehouse/lavaland_boss + filename = "lavaland_boss.dmm" + +// Chill out +/datum/map_template/safehouse/ice + filename = "ice.dmm" + +/** + * Your safehouse here + * /datum/map_template/safehouse/your_type + * filename = "your_map.dmm" + */ diff --git a/code/modules/bitrunning/virtual_domain/virtual_domain.dm b/code/modules/bitrunning/virtual_domain/virtual_domain.dm new file mode 100644 index 00000000000000..c2bd193f4e98ee --- /dev/null +++ b/code/modules/bitrunning/virtual_domain/virtual_domain.dm @@ -0,0 +1,34 @@ +/** + * # Virtual Domains + * This loads a base level, then users can select the preset upon it. + * Create your own: Read the readme file in the '_maps/virtual_domains' folder. + */ +/datum/lazy_template/virtual_domain + map_dir = "_maps/virtual_domains" + map_name = "None" + key = "Virtual Domain" + + /// Cost of this map to load + var/cost = BITRUNNER_COST_NONE + /// The description of the map + var/desc = "A map." + /// The 'difficulty' of the map, which affects the ui and ability to scan info. + var/difficulty = BITRUNNER_DIFFICULTY_NONE + /// An assoc list of typepath/amount to spawn on completion. Not weighted - the value is the amount + var/list/extra_loot + /// The map file to load + var/filename = "virtual_domain.dmm" + /// Any outfit that you wish to force on avatars. Overrides preferences + var/datum/outfit/forced_outfit + /// Information given to connected clients via ability + var/help_text + // Name to show in the UI + var/name = "Virtual Domain" + /// Points to reward for completion. Used to purchase new domains and calculate ore rewards. + var/reward_points = BITRUNNER_REWARD_MIN + /// The start time of the map. Used to calculate time taken + var/start_time + /// This map is specifically for unit tests. Shouldn't display in game + var/test_only = FALSE + /// The safehouse to load into the map + var/datum/map_template/safehouse/safehouse_path = /datum/map_template/safehouse/den diff --git a/code/modules/capture_the_flag/ctf_player_component.dm b/code/modules/capture_the_flag/ctf_player_component.dm index 0bf37b979dea1d..d3abc0f2571ccc 100644 --- a/code/modules/capture_the_flag/ctf_player_component.dm +++ b/code/modules/capture_the_flag/ctf_player_component.dm @@ -8,7 +8,7 @@ var/can_respawn = TRUE ///Reference to the game this player is participating in. var/datum/ctf_controller/ctf_game - ///Item dropped on death, + ///Item dropped on death, var/death_drop = /obj/effect/powerup/ammo/ctf ///Reference to players ckey, used for sending messages to them relating to CTF. var/ckey_reference @@ -22,19 +22,20 @@ var/datum/mind/true_parent = parent player_mob = true_parent.current ckey_reference = player_mob.ckey - setup_dusting() - + register_mob() + /datum/component/ctf_player/PostTransfer() if(!istype(parent, /datum/mind)) return COMPONENT_INCOMPATIBLE var/datum/mind/true_parent = parent player_mob = true_parent.current - setup_dusting() + register_mob() -///CTF players are dusted upon taking damage that puts them into critical or leaving their body. -/datum/component/ctf_player/proc/setup_dusting() +/// Called when we get a new player mob, register signals and set up the mob. +/datum/component/ctf_player/proc/register_mob() RegisterSignal(player_mob, COMSIG_MOB_AFTER_APPLY_DAMAGE, PROC_REF(damage_type_check)) RegisterSignal(player_mob, COMSIG_MOB_GHOSTIZED, PROC_REF(ctf_dust)) + ADD_TRAIT(player_mob, TRAIT_PERMANENTLY_MORTAL, CTF_TRAIT) ///Stamina and oxygen damage will not dust a player by themself. /datum/component/ctf_player/proc/damage_type_check(datum/source, damage, damage_type) diff --git a/code/modules/cargo/coupon.dm b/code/modules/cargo/coupon.dm index fc1c3a6cc6598c..5c4e1e930b5c61 100644 --- a/code/modules/cargo/coupon.dm +++ b/code/modules/cargo/coupon.dm @@ -44,7 +44,7 @@ /// Play stupid games, win stupid prizes /obj/item/coupon/proc/curse_heart(mob/living/cursed) if(!iscarbon(cursed)) - cursed.gib() + cursed.gib(DROP_ALL_REMAINS) return TRUE var/mob/living/carbon/player = cursed diff --git a/code/modules/cargo/department_order.dm b/code/modules/cargo/department_order.dm index 972588a6355d64..46122fd8741b03 100644 --- a/code/modules/cargo/department_order.dm +++ b/code/modules/cargo/department_order.dm @@ -21,12 +21,28 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list( var/list/department_delivery_areas = list() ///which groups this computer can order from var/list/dep_groups = list() + /// If this departmental order console currently is on cooldown. + var/on_cooldown = FALSE + + /// Our radio object we use to talk to our department. + var/obj/item/radio/radio + /// The radio key typepath that will be instantiated and inserted into our radio. + var/obj/item/encryptionkey/radio_key_typepath + /// The radio channel we will speak into by default. + var/radio_channel /obj/machinery/computer/department_orders/Initialize(mapload, obj/item/circuitboard/board) . = ..() // All maps should have ONLY ONE of each order console roundstart REGISTER_REQUIRED_MAP_ITEM(1, 1) + if (radio_channel && radio_key_typepath) + radio = new(src) + radio.keyslot = new radio_key_typepath + radio.subspace_transmission = TRUE + radio.canhear_range = 0 + radio.recalculateChannels() + if(mapload) //check for mapping errors for(var/delivery_area_type in department_delivery_areas) if(GLOB.areas_by_type[delivery_area_type]) @@ -35,6 +51,11 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list( log_mapping("[src] has no valid areas to deliver to on this map, add some more fallback areas to its \"department_delivery_areas\" var.") department_delivery_areas = list(/area/station/hallway/primary/central) //if this doesn't exist like honestly fuck your map man +/obj/machinery/computer/department_orders/Destroy() + QDEL_NULL(radio) + + return ..() + /obj/machinery/computer/department_orders/ui_interact(mob/user, datum/tgui/ui) . = ..() ui = SStgui.try_update_ui(user, src, ui) @@ -142,6 +163,12 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list( if(GLOB.areas_by_type[delivery_area_type]) chosen_delivery_area = delivery_area_type break + + if(SSshuttle.supply.get_order_count(pack) == OVER_ORDER_LIMIT) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + say("ERROR: No more then [CARGO_MAX_ORDER] of any pack may be ordered at once") + return + department_order = new(pack, name, rank, ckey, "", null, chosen_delivery_area, null) SSshuttle.shopping_list += department_order if(!already_signalled) @@ -166,6 +193,20 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list( time_y = 10 MINUTES * time_y GLOB.department_order_cooldowns[type] = world.time + time_y +/obj/machinery/computer/department_orders/process() + . = ..() + if (!.) + return FALSE + + if (GLOB.department_order_cooldowns[type] > world.time) + on_cooldown = TRUE + else if (on_cooldown) + radio?.talk_into(src, "Order cooldown has expired! A new order may now be placed!", radio_channel) + playsound(src, 'sound/machines/ping.ogg', 30, TRUE) + on_cooldown = FALSE + + return TRUE + /obj/machinery/computer/department_orders/service name = "service order console" circuit = /obj/item/circuitboard/computer/service_orders @@ -173,6 +214,8 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list( override_access = ACCESS_HOP req_one_access = list(ACCESS_SERVICE) dep_groups = list("Service", "Food & Hydroponics", "Livestock", "Costumes & Toys") + radio_key_typepath = /obj/item/encryptionkey/headset_service + radio_channel = RADIO_CHANNEL_SERVICE /obj/machinery/computer/department_orders/engineering name = "engineering order console" @@ -181,6 +224,8 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list( override_access = ACCESS_CE req_one_access = REGION_ACCESS_ENGINEERING dep_groups = list("Engineering", "Engine Construction", "Canisters & Materials") + radio_key_typepath = /obj/item/encryptionkey/headset_eng + radio_channel = RADIO_CHANNEL_ENGINEERING /obj/machinery/computer/department_orders/science name = "science order console" @@ -188,7 +233,9 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list( department_delivery_areas = list(/area/station/science/research) override_access = ACCESS_RD req_one_access = REGION_ACCESS_RESEARCH - dep_groups = list("Science", "Livestock") + dep_groups = list("Science", "Livestock", "Canisters & Materials") + radio_key_typepath = /obj/item/encryptionkey/headset_sci + radio_channel = RADIO_CHANNEL_SCIENCE /obj/machinery/computer/department_orders/security name = "security order console" @@ -201,6 +248,8 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list( override_access = ACCESS_HOS req_one_access = REGION_ACCESS_SECURITY dep_groups = list("Security", "Armory") + radio_key_typepath = /obj/item/encryptionkey/headset_sec + radio_channel = RADIO_CHANNEL_SECURITY /obj/machinery/computer/department_orders/medical name = "medical order console" @@ -214,3 +263,5 @@ GLOBAL_LIST_INIT(department_order_cooldowns, list( override_access = ACCESS_CMO req_one_access = REGION_ACCESS_MEDBAY dep_groups = list("Medical") + radio_key_typepath = /obj/item/encryptionkey/headset_med + radio_channel = RADIO_CHANNEL_MEDICAL diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm index a9d408c8699b9a..44a628740bd522 100644 --- a/code/modules/cargo/exports.dm +++ b/code/modules/cargo/exports.dm @@ -35,12 +35,13 @@ Then the player gets the profit from selling his own wasted time. ** delete_unsold: if the items that were not sold should be deleted ** dry_run: if the item should be actually sold, or if its just a pirce test ** external_report: works as "transaction" object, pass same one in if you're doing more than one export in single go + ** ignore_typecache: typecache containing types that should be completely ignored */ -/proc/export_item_and_contents(atom/movable/exported_atom, apply_elastic = TRUE, delete_unsold = TRUE, dry_run = FALSE, datum/export_report/external_report) +/proc/export_item_and_contents(atom/movable/exported_atom, apply_elastic = TRUE, delete_unsold = TRUE, dry_run = FALSE, datum/export_report/external_report, list/ignore_typecache) if(!GLOB.exports_list.len) setupExports() - var/list/contents = exported_atom.get_all_contents() + var/list/contents = exported_atom.get_all_contents_ignoring(ignore_typecache) var/datum/export_report/report = external_report diff --git a/code/modules/cargo/exports/materials.dm b/code/modules/cargo/exports/materials.dm index 06c52305f51ba7..c9a88a6edfb200 100644 --- a/code/modules/cargo/exports/materials.dm +++ b/code/modules/cargo/exports/materials.dm @@ -2,10 +2,13 @@ cost = 5 // Cost per SHEET_MATERIAL_AMOUNT, which is 100cm3 as of May 2023. message = "cm3 of developer's tears. Please, report this on github" amount_report_multiplier = SHEET_MATERIAL_AMOUNT - var/material_id = null + var/datum/material/material_id = null export_types = list( - /obj/item/stack/sheet/mineral, /obj/item/stack/tile/mineral, - /obj/item/stack/ore, /obj/item/coin) + /obj/item/stack/sheet/mineral, + /obj/item/stack/tile/mineral, + /obj/item/stack/ore, + /obj/item/coin + ) // Yes, it's a base type containing export_types. // But it has no material_id, so any applies_to check will return false, and these types reduce amount of copypasta a lot @@ -27,17 +30,8 @@ return round(amount / SHEET_MATERIAL_AMOUNT) -// Materials. Nothing but plasma is really worth selling. Better leave it all to RnD and sell some plasma instead. - -/datum/export/material/bananium - cost = CARGO_CRATE_VALUE * 2 - material_id = /datum/material/bananium - message = "cm3 of bananium" - -/datum/export/material/diamond - cost = CARGO_CRATE_VALUE - material_id = /datum/material/diamond - message = "cm3 of diamonds" +// Materials. Static materials exist as parent types, while materials subject to the stock market have a fluid cost as determined by material/market types +// If you're adding a new material to the stock market, make sure its export type is added here. /datum/export/material/plasma cost = CARGO_CRATE_VALUE * 0.4 @@ -45,27 +39,12 @@ material_id = /datum/material/plasma message = "cm3 of plasma" -/datum/export/material/uranium - cost = CARGO_CRATE_VALUE * 0.2 - material_id = /datum/material/uranium - message = "cm3 of uranium" - -/datum/export/material/gold - cost = CARGO_CRATE_VALUE * 0.25 - material_id = /datum/material/gold - message = "cm3 of gold" - -/datum/export/material/silver - cost = CARGO_CRATE_VALUE * 0.1 - material_id = /datum/material/silver - message = "cm3 of silver" - -/datum/export/material/titanium - cost = CARGO_CRATE_VALUE * 0.25 - material_id = /datum/material/titanium - message = "cm3 of titanium" +/datum/export/material/bananium + cost = CARGO_CRATE_VALUE * 2 + material_id = /datum/material/bananium + message = "cm3 of bananium" -/datum/export/material/adamantine +/datum/export/material/diamond cost = CARGO_CRATE_VALUE material_id = /datum/material/adamantine message = "cm3 of adamantine" @@ -75,11 +54,6 @@ material_id = /datum/material/mythril message = "cm3 of mythril" -/datum/export/material/bscrystal - cost = CARGO_CRATE_VALUE * 0.6 - message = "of bluespace crystals" - material_id = /datum/material/bluespace - /datum/export/material/plastic cost = CARGO_CRATE_VALUE * 0.05 message = "cm3 of plastic" @@ -90,21 +64,6 @@ message = "cm3 of runite" material_id = /datum/material/runite -/datum/export/material/iron - cost = CARGO_CRATE_VALUE * 0.01 - message = "cm3 of iron" - material_id = /datum/material/iron - export_types = list( - /obj/item/stack/sheet/iron, /obj/item/stack/tile/iron, - /obj/item/stack/rods, /obj/item/stack/ore, /obj/item/coin) - -/datum/export/material/glass - cost = CARGO_CRATE_VALUE * 0.01 - message = "cm3 of glass" - material_id = /datum/material/glass - export_types = list(/obj/item/stack/sheet/glass, /obj/item/stack/ore, - /obj/item/shard) - /datum/export/material/hot_ice cost = CARGO_CRATE_VALUE * 0.8 message = "cm3 of Hot Ice" @@ -116,3 +75,90 @@ message = "cm3 of metallic hydrogen" material_id = /datum/material/metalhydrogen export_types = /obj/item/stack/sheet/mineral/metal_hydrogen + +/datum/export/material/market + +/datum/export/material/market/diamond + material_id = /datum/material/diamond + message = "cm3 of diamonds" + +/datum/export/material/market/uranium + material_id = /datum/material/uranium + message = "cm3 of uranium" + +/datum/export/material/market/gold + material_id = /datum/material/gold + message = "cm3 of gold" + +/datum/export/material/market/silver + material_id = /datum/material/silver + message = "cm3 of silver" + +/datum/export/material/market/titanium + material_id = /datum/material/titanium + message = "cm3 of titanium" + +/datum/export/material/market/bscrystal + message = "of bluespace crystals" + material_id = /datum/material/bluespace + export_types = list(/obj/item/stack/sheet/bluespace_crystal, /obj/item/stack/ore) //For whatever reason, bluespace crystals are not a mineral + +/datum/export/material/market/iron + message = "cm3 of iron" + material_id = /datum/material/iron + export_types = list( + /obj/item/stack/sheet/iron, + /obj/item/stack/tile/iron, + /obj/item/stack/rods, + /obj/item/stack/ore, + /obj/item/coin + ) + +/datum/export/material/market/glass + message = "cm3 of glass" + material_id = /datum/material/glass + export_types = list( + /obj/item/stack/sheet/glass, + /obj/item/stack/ore, + /obj/item/shard + ) + +/datum/export/material/market/get_cost(obj/O, apply_elastic = FALSE) + var/obj/item/I = O + var/amount = get_amount(I) + if(!amount) + return 0 + var/material_value = (SSstock_market.materials_prices[material_id]) * amount * MARKET_PROFIT_MODIFIER + return round(material_value) + +/datum/export/material/market/sell_object(obj/sold_item, datum/export_report/report, dry_run, apply_elastic) + . = ..() + var/amount = get_amount(sold_item) + var/price = get_cost(sold_item) + if(!amount) + return + if(!dry_run) + SSstock_market.materials_quantity[material_id] += amount + SSstock_market.materials_prices[material_id] -= round((price) * (amount / (amount + SSstock_market.materials_quantity[material_id]))) + //This formula should impact lower quantity materials greater, and higher quantity materials less. Still, it's a bit rough. Tweaking may be needed. + + +// Stock blocks are a special type of export that can be used to sell a quantity of materials at a specific price on the market. +/datum/export/stock_block + cost = 0 + message = "stock block" + export_types = list(/obj/item/stock_block) + +/datum/export/stock_block/get_cost(obj/O, apply_elastic = FALSE) + var/obj/item/stock_block/block = O + return block.export_value + +/datum/export/stock_block/sell_object(obj/sold_item, datum/export_report/report, dry_run, apply_elastic) + . = ..() + if(dry_run) + return + var/obj/item/stock_block/sold_block = sold_item + var/sale_value = sold_block.export_value + SSstock_market.materials_quantity[sold_block.export_mat] += sold_block.quantity + SSstock_market.materials_prices[sold_block.export_mat] -= round((sale_value) * (sold_block.quantity / (sold_block.quantity + SSstock_market.materials_quantity[sold_block.export_mat]))) + SSstock_market.materials_prices[sold_block.export_mat] = round(clamp(SSstock_market.materials_prices[sold_block.export_mat], initial(sold_block.export_mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 0.5 , initial(sold_block.export_mat.value_per_unit) * SHEET_MATERIAL_AMOUNT * 3)) diff --git a/code/modules/cargo/gondolapod.dm b/code/modules/cargo/gondolapod.dm index 5ee9f856823e16..f3dca7a3dca101 100644 --- a/code/modules/cargo/gondolapod.dm +++ b/code/modules/cargo/gondolapod.dm @@ -65,11 +65,13 @@ /mob/living/simple_animal/pet/gondola/gondolapod/setOpened() opened = TRUE + SET_PLANE_IMPLICIT(src, GAME_PLANE) update_appearance() addtimer(CALLBACK(src, TYPE_PROC_REF(/atom/, setClosed)), 50) /mob/living/simple_animal/pet/gondola/gondolapod/setClosed() opened = FALSE + SET_PLANE_IMPLICIT(src, GAME_PLANE_FOV_HIDDEN) update_appearance() /mob/living/simple_animal/pet/gondola/gondolapod/death() diff --git a/code/modules/cargo/goodies.dm b/code/modules/cargo/goodies.dm index 69677e87df56ad..be8288e922fba7 100644 --- a/code/modules/cargo/goodies.dm +++ b/code/modules/cargo/goodies.dm @@ -129,6 +129,12 @@ cost = PAYCHECK_CREW * 4 contains = list(/obj/item/storage/medkit/toxin) +/datum/supply_pack/goody/bandagebox_singlepack + name = "Box of Bandages Single-Pack" + desc = "A single box of DeForest brand bandages. For when you don't want to see your doctor." + cost = PAYCHECK_CREW * 3 + contains = list(/obj/item/storage/box/bandages) + /datum/supply_pack/goody/toolbox // mostly just to water down coupon probability name = "Mechanical Toolbox" desc = "A fully stocked mechanical toolbox, for when you're too lazy to just print them out." @@ -277,3 +283,9 @@ desc = "A less cheap imported climbing hook. Absolutely no use outside of planetary stations." cost = PAYCHECK_CREW * 5 contains = list(/obj/item/climbing_hook) + +/datum/supply_pack/goody/fish_analyzer + name = "Fish Analyzer" + desc = "A single analyzer to monitor fish's status and traits with, in case you don't have the technology to print one." + cost = CARGO_CRATE_VALUE * 2.5 + contains = list(/obj/item/fish_analyzer) diff --git a/code/modules/cargo/materials_market.dm b/code/modules/cargo/materials_market.dm new file mode 100644 index 00000000000000..e2bedd2f19abf7 --- /dev/null +++ b/code/modules/cargo/materials_market.dm @@ -0,0 +1,268 @@ +/obj/machinery/materials_market + name = "galactic materials market" + desc = "This machine allows the user to buy and sell sheets of minerals \ + across the system. Prices are known to fluxuate quite often,\ + sometimes even within the same minute. All transactions are final." + circuit = /obj/item/circuitboard/machine/materials_market + req_access = list(ACCESS_CARGO) + density = TRUE + icon = 'icons/obj/economy.dmi' + icon_state = "mat_market" + base_icon_state = "mat_market" + idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION + /// What items can be converted into a stock block? Must be a stack subtype based on current implementation. + var/static/list/exportable_material_items = list( + /obj/item/stack/sheet/iron, //God why are we like this + /obj/item/stack/sheet/glass, //No really, God why are we like this + /obj/item/stack/sheet/mineral, + /obj/item/stack/tile/mineral, + /obj/item/stack/ore, + /obj/item/stack/sheet/bluespace_crystal, + /obj/item/stack/rods + ) + /// Are we ordering sheets from our own card balance or the cargo budget? + var/ordering_private = TRUE + /// Currently, can we order sheets from our own card balance or the cargo budget? + var/can_buy_via_budget = FALSE + +/obj/machinery/materials_market/update_icon_state() + if(panel_open) + icon_state = "[base_icon_state]_open" + return ..() + if(!is_operational || !anchored) + icon_state = "[base_icon_state]_off" + return ..() + icon_state = "[base_icon_state]" + return ..() + +/obj/machinery/materials_market/wrench_act(mob/living/user, obj/item/tool) + ..() + default_unfasten_wrench(user, tool, time = 1.5 SECONDS) + return TOOL_ACT_TOOLTYPE_SUCCESS + +/obj/machinery/materials_market/attackby(obj/item/O, mob/user, params) + if(default_deconstruction_screwdriver(user, "[base_icon_state]_open", "[base_icon_state]", O)) + return + else if(default_deconstruction_crowbar(O)) + return + if(is_type_in_list(O, exportable_material_items)) + var/amount = 0 + var/value = 0 + var/material_to_export + var/obj/item/stack/exportable = O + for(var/datum/material/mat as anything in SSstock_market.materials_prices) + if(exportable.has_material_type(mat)) + amount = exportable.amount + value = SSstock_market.materials_prices[mat] + material_to_export = mat + break //This is only for trading non-alloys, so we can break here + + if(!amount) + say("Not enough material. Aborting.") + playsound(src, 'sound/machines/scanbuzz.ogg', 25, FALSE) + return TRUE + qdel(exportable) + var/obj/item/stock_block/new_block = new /obj/item/stock_block(drop_location()) + new_block.export_value = amount * value * MARKET_PROFIT_MODIFIER + new_block.export_mat = material_to_export + new_block.quantity = amount + to_chat(user, span_notice("You have created a stock block worth [new_block.export_value] cr! Sell it before it becomes liquid!")) + playsound(src, 'sound/machines/synth_yes.ogg', 50, FALSE) + return TRUE + return ..() + + +/obj/machinery/materials_market/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!anchored) + return + if(!ui) + ui = new(user, src, "MatMarket", name) + ui.open() + +/obj/machinery/materials_market/ui_data(mob/user) + var/data = list() + var/material_data + for(var/datum/material/traded_mat as anything in SSstock_market.materials_prices) + var/trend_string = "" + if(SSstock_market.materials_trends[traded_mat] == 0) + trend_string = "neutral" + else if(SSstock_market.materials_trends[traded_mat] == 1) + trend_string = "up" + else if(SSstock_market.materials_trends[traded_mat] == -1) + trend_string = "down" + var/color_string = "" + if (initial(traded_mat.greyscale_colors)) + color_string = splicetext(initial(traded_mat.greyscale_colors), 7, length(initial(traded_mat.greyscale_colors)), "") //slice it to a standard 6 char hex + else if(initial(traded_mat.color)) + color_string = initial(traded_mat.color) + material_data += list(list( + "name" = initial(traded_mat.name), + "price" = SSstock_market.materials_prices[traded_mat], + "quantity" = SSstock_market.materials_quantity[traded_mat], + "trend" = trend_string, + "color" = color_string, + )) + + can_buy_via_budget = FALSE + var/obj/item/card/id/used_id_card + if(isliving(user)) + var/mob/living/living_user = user + used_id_card = living_user.get_idcard(TRUE) + can_buy_via_budget = (ACCESS_CARGO in used_id_card?.GetAccess()) + + var/balance = 0 + if(!ordering_private) + var/datum/bank_account/dept = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(dept) + balance = dept.account_balance + else + balance = used_id_card?.registered_account?.account_balance + + var/market_crashing = FALSE + if(HAS_TRAIT(SSeconomy, TRAIT_MARKET_CRASHING)) + market_crashing = TRUE + + data["catastrophe"] = market_crashing + data["materials"] = material_data + data["creditBalance"] = balance + data["orderingPrive"] = ordering_private + data["canOrderCargo"] = can_buy_via_budget + return data + +/obj/machinery/materials_market/ui_act(action, params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + //You must have an ID to be able to do something + var/mob/living/living_user = ui.user + var/obj/item/card/id/used_id_card = living_user.get_idcard(TRUE) + if(isnull(used_id_card)) + say("No ID Found") + return + + switch(action) + if("buy") + var/material_str = params["material"] + var/quantity = text2num(params["quantity"]) + + var/datum/material/material_bought + var/obj/item/stack/sheet/sheet_to_buy + for(var/datum/material/mat as anything in SSstock_market.materials_prices) + if(initial(mat.name) == material_str) + material_bought = mat + break + if(!material_bought) + CRASH("Invalid material name passed to materials market!") + + //if multiple users open the UI some of them may not have the required access so we recheck + var/is_ordering_private = ordering_private + if(!(ACCESS_CARGO in used_id_card.GetAccess())) //no cargo access then force private purchase + is_ordering_private = TRUE + + var/datum/bank_account/account_payable + if(is_ordering_private) + account_payable = used_id_card.registered_account + else if(can_buy_via_budget) + account_payable = SSeconomy.get_dep_account(ACCOUNT_CAR) + if(!account_payable) + say("No bank account detected!") + return + + sheet_to_buy = initial(material_bought.sheet_type) + if(!sheet_to_buy) + CRASH("Material with no sheet type being sold on materials market!") + var/cost = SSstock_market.materials_prices[material_bought] * quantity + if(cost > account_payable.account_balance) + to_chat(living_user, span_warning("You don't have enough money to buy that!")) + return + + var/list/things_to_order = list() + things_to_order += (sheet_to_buy) + things_to_order[sheet_to_buy] = quantity + // We want to count how many stacks of all sheets we're ordering to make sure they don't exceed the limit of 10 + // If we already have a custom order on SSshuttle, we should add the things to order to that order + for(var/datum/supply_order/order in SSshuttle.shopping_list) + // Must be a Galactic Materials Market order and payed by the null account(if ordered via cargo budget) or by correct user for private purchase + if(order.orderer_rank == "Galactic Materials Market" && ( \ + (!is_ordering_private && order.paying_account == null) || \ + (is_ordering_private && order.paying_account != null && order.orderer == living_user) \ + )) + // Check if this order exceeded its limit + var/prior_stacks = 0 + for(var/obj/item/stack/sheet/sheet as anything in order.pack.contains) + prior_stacks += ROUND_UP(order.pack.contains[sheet] / 50) + if(prior_stacks >= 10) + to_chat(usr, span_notice("You already have 10 stacks of sheets on order! Please wait for them to arrive before ordering more.")) + playsound(usr, 'sound/machines/synth_no.ogg', 35, FALSE) + return + // Append to this order + order.append_order(things_to_order, cost) + return + + //Now we need to add a cargo order for quantity sheets of material_bought.sheet_type + var/datum/supply_pack/custom/minerals/mineral_pack = new( + purchaser = is_ordering_private ? living_user : "Cargo", \ + cost = cost, \ + contains = things_to_order, \ + ) + var/datum/supply_order/new_order = new( + pack = mineral_pack, + orderer = living_user, + orderer_rank = "Galactic Materials Market", + orderer_ckey = living_user.ckey, + paying_account = is_ordering_private ? account_payable : null, + cost_type = "credit", + can_be_cancelled = FALSE + ) + say("Thank you for your purchase! It will arrive on the next cargo shuttle!") + SSshuttle.shopping_list += new_order + return + if("toggle_budget") + if(!can_buy_via_budget) + return + ordering_private = !ordering_private + +/obj/item/stock_block + name = "stock block" + desc = "A block of stock. It's worth a certain amount of money, based on a sale on the materials market. Ship it on the cargo shuttle to claim your money." + icon = 'icons/obj/economy.dmi' + icon_state = "stock_block" + /// How many credits was this worth when created? + var/export_value = 0 + /// What is the name of the material this was made from? + var/datum/material/export_mat + /// Quantity of export material + var/quantity = 0 + /// Is this stock block currently updating it's value with the market (aka fluid)? + var/fluid = FALSE + +/obj/item/stock_block/examine(mob/user) + . = ..() + . += span_notice("\The [src] is worth [export_value] cr, from selling [quantity] sheets of [initial(export_mat?.name)].") + if(fluid) + . += span_warning("\The [src] is currently liquid! It's value is based on the market price.") + else + . += span_notice("\The [src]'s value is still [span_boldnotice("locked in")]. [span_boldnotice("Sell it")] before it's value becomes liquid!") + +/obj/item/stock_block/Initialize(mapload) + . = ..() + addtimer(CALLBACK(src, PROC_REF(value_warning)), 2.5 MINUTES) + addtimer(CALLBACK(src, PROC_REF(update_value)), 5 MINUTES) + +/obj/item/stock_block/proc/value_warning() + visible_message(span_warning("\The [src] is starting to become liquid!")) + icon_state = "stock_block_fluid" + update_appearance(UPDATE_ICON_STATE) + +/obj/item/stock_block/proc/update_value() + if(!export_mat) + return + if(!SSstock_market.materials_prices[export_mat]) + return + export_value = quantity * SSstock_market.materials_prices[export_mat] * MARKET_PROFIT_MODIFIER + icon_state = "stock_block_liquid" + update_appearance(UPDATE_ICON_STATE) + visible_message(span_warning("\The [src] becomes liquid!")) + diff --git a/code/modules/cargo/order.dm b/code/modules/cargo/order.dm index 6c1f5e1d8392de..2707719c17005c 100644 --- a/code/modules/cargo/order.dm +++ b/code/modules/cargo/order.dm @@ -188,6 +188,15 @@ generateManifest(miscbox, misc_own, "", misc_cost) return +/datum/supply_order/proc/append_order(list/new_contents, cost_increase) + for(var/i as anything in new_contents) + if(pack.contains[i]) + pack.contains[i] += new_contents[i] + else + pack.contains += i + pack.contains[i] = new_contents[i] + pack.cost += cost_increase + #undef MANIFEST_ERROR_CHANCE #undef MANIFEST_ERROR_NAME #undef MANIFEST_ERROR_CONTENTS diff --git a/code/modules/cargo/orderconsole.dm b/code/modules/cargo/orderconsole.dm index 2c815a803b60bf..b59cee9def7528 100644 --- a/code/modules/cargo/orderconsole.dm +++ b/code/modules/cargo/orderconsole.dm @@ -113,9 +113,11 @@ message = blockade_warning data["message"] = message + var/list/amount_by_name = list() var/cart_list = list() for(var/datum/supply_order/order in SSshuttle.shopping_list) if(cart_list[order.pack.name]) + amount_by_name[order.pack.name] += 1 cart_list[order.pack.name][1]["amount"]++ cart_list[order.pack.name][1]["cost"] += order.get_final_cost() if(order.department_destination) @@ -124,6 +126,7 @@ cart_list[order.pack.name][1]["paid"]++ continue + amount_by_name[order.pack.name] += 1 cart_list[order.pack.name] = list(list( "cost_type" = order.cost_type, "object" = order.pack.name, @@ -141,19 +144,23 @@ data["requests"] = list() - for(var/datum/supply_order/SO in SSshuttle.request_list) + for(var/datum/supply_order/order in SSshuttle.request_list) + var/datum/supply_pack/pack = order.pack + amount_by_name[pack.name] += 1 data["requests"] += list(list( - "object" = SO.pack.name, - "cost" = SO.pack.get_cost(), - "orderer" = SO.orderer, - "reason" = SO.reason, - "id" = SO.id + "object" = pack.name, + "cost" = pack.get_cost(), + "orderer" = order.orderer, + "reason" = order.reason, + "id" = order.id )) + data["amount_by_name"] = amount_by_name return data /obj/machinery/computer/cargo/ui_static_data(mob/user) var/list/data = list() + data["max_order"] = CARGO_MAX_ORDER data["supplies"] = list() for(var/pack in SSshuttle.supply_packs) var/datum/supply_pack/P = SSshuttle.supply_packs[pack] @@ -187,7 +194,7 @@ var/datum/supply_pack/pack = SSshuttle.supply_packs[id] if(!istype(pack)) CRASH("Unknown supply pack id given by order console ui. ID: [id]") - if(amount > 50 || amount < 1) // Holy shit fuck off + if(amount > CARGO_MAX_ORDER || amount < 1) // Holy shit fuck off CRASH("Invalid amount passed into add_item") if((pack.hidden && !(obj_flags & EMAGGED)) || (pack.contraband && !contraband) || pack.drop_pod_only || (pack.special && !pack.special_enabled)) return @@ -222,8 +229,11 @@ say("[id_card] lacks the requisite access for this purchase.") return + // The list we are operating on right now + var/list/working_list = SSshuttle.shopping_list var/reason = "" if(requestonly && !self_paid) + working_list = SSshuttle.request_list reason = tgui_input_text(user, "Reason", name) if(isnull(reason)) return @@ -233,6 +243,13 @@ say("ERROR: Small crates may only be purchased by private accounts.") return + var/similar_count = SSshuttle.supply.get_order_count(pack) + if(similar_count == OVER_ORDER_LIMIT) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + say("ERROR: No more then [CARGO_MAX_ORDER] of any pack may be ordered at once") + return + + amount = clamp(amount, 1, CARGO_MAX_ORDER - similar_count) for(var/count in 1 to amount) var/obj/item/coupon/applied_coupon for(var/obj/item/coupon/coupon_check in loaded_coupons) @@ -242,15 +259,8 @@ applied_coupon = coupon_check break - //Skyrat Edit Add - var/datum/supply_order/SO = new(pack = pack ,orderer = name, orderer_rank = rank, orderer_ckey = ckey, reason = reason, paying_account = account, coupon = applied_coupon, charge_on_purchase = TRUE) - //Skyrat Edit End - //SKYRAT EDIT - ORIGINAL: var/datum/supply_order/SO = new(pack = pack ,orderer = name, orderer_rank = rank, orderer_ckey = ckey, reason = reason, paying_account = account, coupon = applied_coupon) - - if(requestonly && !self_paid) - SSshuttle.request_list += SO - else - SSshuttle.shopping_list += SO + var/datum/supply_order/order = new(pack = pack ,orderer = name, orderer_rank = rank, orderer_ckey = ckey, reason = reason, paying_account = account, coupon = applied_coupon, charge_on_purchase = TRUE) //SKYRAT EDIT CHANGE - ORIGINAL: var/datum/supply_order/order = new(pack = pack ,orderer = name, orderer_rank = rank, orderer_ckey = ckey, reason = reason, paying_account = account, coupon = applied_coupon) + working_list += order if(self_paid) say("Order processed. The price will be charged to [account.account_holder]'s bank account on delivery.") @@ -365,9 +375,7 @@ if("remove") var/order_name = params["order_name"] //try removing atleast one item with the specified name. An order may not be removed if it was from the department - //also we create an copy of the cart list else we would get runtimes when removing & iterating over the same SSshuttle.shopping_list - var/list/shopping_cart = SSshuttle.shopping_list.Copy() - for(var/datum/supply_order/order in shopping_cart) + for(var/datum/supply_order/order in SSshuttle.shopping_list) if(order.pack.name != order_name) continue if(remove_item(order.id)) @@ -378,8 +386,7 @@ var/order_name = params["order_name"] //clear out all orders with the above mentioned order_name name to make space for the new amount - var/list/shopping_cart = SSshuttle.shopping_list.Copy() //we operate on the list copy else we would get runtimes when removing & iterating over the same SSshuttle.shopping_list - for(var/datum/supply_order/order in shopping_cart) //find corresponding order id for the order name + for(var/datum/supply_order/order in SSshuttle.shopping_list) //find corresponding order id for the order name if(order.pack.name == order_name) remove_item(order.id) @@ -387,7 +394,7 @@ var/amount = text2num(params["amount"]) if(amount == 0) return TRUE - if(amount > 50) + if(amount > CARGO_MAX_ORDER) return var/supply_pack_id = name_to_id(order_name) //map order name to supply pack id for adding if(!supply_pack_id) diff --git a/code/modules/cargo/packs/_packs.dm b/code/modules/cargo/packs/_packs.dm index 357f32f3cb4101..aaeb55f253385c 100644 --- a/code/modules/cargo/packs/_packs.dm +++ b/code/modules/cargo/packs/_packs.dm @@ -86,7 +86,7 @@ return FALSE var/list/open_turfs = list() for(var/turf/open/floor/found_turf in get_area_turfs(pick(areas), subtypes = TRUE)) - open_turfs += found_turf + open_turfs += found_turf if(!length(open_turfs)) return FALSE @@ -110,3 +110,15 @@ name = "[purchaser]'s Mining Order" src.cost = cost src.contains = contains + +/datum/supply_pack/custom/minerals + name = "materials order" + crate_name = "galactic materials market delivery crate" + access = list() + crate_type = /obj/structure/closet/crate/cardboard + +/datum/supply_pack/custom/minerals/New(purchaser, cost, list/contains) + . = ..() + name = "[purchaser]'s Materials Order" + src.cost = cost + src.contains = contains diff --git a/code/modules/cargo/packs/general.dm b/code/modules/cargo/packs/general.dm index fa7a3bfa374cbe..99f8972ccb8c7f 100644 --- a/code/modules/cargo/packs/general.dm +++ b/code/modules/cargo/packs/general.dm @@ -68,13 +68,6 @@ contains = list(/obj/item/storage/fish_case/tiziran = 2) crate_name = "tiziran fish crate" -/datum/supply_pack/misc/fish_analyzers - name = "Fish Analyzers" - desc = "A pack containing three analyzers to monitor fish's status and traits with." - cost = CARGO_CRATE_VALUE * 2.5 - contains = list(/obj/item/fish_analyzer = 3) - crate_name = "fish analyzers crate" - /datum/supply_pack/misc/bicycle name = "Bicycle" desc = "Nanotrasen reminds all employees to never toy with powers outside their control." @@ -221,7 +214,7 @@ /obj/item/clothing/under/misc/burial = 2, ) crate_name = "religious supplies crate" - + /datum/supply_pack/misc/candles_bulk name = "Candle Box Crate" desc = "Keep your local chapel lit with three candle boxes!" @@ -292,13 +285,6 @@ crate_value = value contents_uplink_type = uplink -/datum/supply_pack/misc/fishing_portal - name = "Fishing Portal Generator Crate" - desc = "Not enough fish near your location? Fishing portal has your back." - cost = CARGO_CRATE_VALUE * 4 - contains = list(/obj/machinery/fishing_portal_generator) - crate_name = "fishing portal crate" - /datum/supply_pack/misc/papercutter name = "Paper Cutters Crate" desc = "Contains 3 office-grade paper cutters, equipped with sharp blades that can cut any paper into two thin slips.\ diff --git a/code/modules/cargo/packs/imports.dm b/code/modules/cargo/packs/imports.dm index ad444efc7405eb..2c90d8603d0694 100644 --- a/code/modules/cargo/packs/imports.dm +++ b/code/modules/cargo/packs/imports.dm @@ -303,3 +303,17 @@ contraband = TRUE contains = list(/obj/item/weaponcrafting/giant_wrench) crate_name = "unknown parts crate" + +/datum/supply_pack/imports/materials_market + name = "Galactic Materials Market Crate" + desc = "A circuit board to build your own materials market for use by certified market traders. Warning: Losses are not covered by insurance." + cost = CARGO_CRATE_VALUE * 3 + contains = list( + /obj/item/circuitboard/machine/materials_market = 1, + /obj/item/stack/sheet/iron = 5, + /obj/item/stack/cable_coil/five = 2, + /obj/item/stock_parts/scanning_module = 1, + /obj/item/stock_parts/card_reader = 1 + ) + crate_name = "materials market crate" + crate_type = /obj/structure/closet/crate diff --git a/code/modules/cargo/packs/livestock.dm b/code/modules/cargo/packs/livestock.dm index d2bdd904e3b73b..69dd7e61807722 100644 --- a/code/modules/cargo/packs/livestock.dm +++ b/code/modules/cargo/packs/livestock.dm @@ -140,7 +140,7 @@ name = "Goat Crate" desc = "The goat goes baa! Contains one goat. Warranty void if used as a replacement for Pete." cost = CARGO_CRATE_VALUE * 5 - contains = list(/mob/living/simple_animal/hostile/retaliate/goat) + contains = list(/mob/living/basic/goat) crate_name = "goat crate" /datum/supply_pack/critter/rabbit diff --git a/code/modules/cargo/packs/materials.dm b/code/modules/cargo/packs/materials.dm index 68dacd730be079..ba9a162698bb82 100644 --- a/code/modules/cargo/packs/materials.dm +++ b/code/modules/cargo/packs/materials.dm @@ -16,34 +16,6 @@ contains = list(/obj/item/stack/license_plates/empty/fifty) crate_name = "empty license plate crate" -/datum/supply_pack/materials/glass50 - name = "50 Glass Sheets" - desc = "Let some nice light in with fifty glass sheets!" - cost = CARGO_CRATE_VALUE * 2 - contains = list(/obj/item/stack/sheet/glass/fifty) - crate_name = "glass sheets crate" - -/datum/supply_pack/materials/iron50 - name = "50 Iron Sheets" - desc = "Any construction project begins with a good stack of fifty iron sheets!" - cost = CARGO_CRATE_VALUE * 2 - contains = list(/obj/item/stack/sheet/iron/fifty) - crate_name = "iron sheets crate" - -/datum/supply_pack/materials/plasteel20 - name = "20 Plasteel Sheets" - desc = "Reinforce the station's integrity with twenty plasteel sheets!" - cost = CARGO_CRATE_VALUE * 15 - contains = list(/obj/item/stack/sheet/plasteel/twenty) - crate_name = "plasteel sheets crate" - -/datum/supply_pack/materials/plasteel50 - name = "50 Plasteel Sheets" - desc = "For when you REALLY have to reinforce something." - cost = CARGO_CRATE_VALUE * 33 - contains = list(/obj/item/stack/sheet/plasteel/fifty) - crate_name = "plasteel sheets crate" - /datum/supply_pack/materials/plastic50 name = "50 Plastic Sheets" desc = "Build a limitless amount of toys with fifty plastic sheets!" diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm index 6794a1960e7fec..3cfb824b4e6986 100644 --- a/code/modules/cargo/packs/medical.dm +++ b/code/modules/cargo/packs/medical.dm @@ -89,6 +89,7 @@ /obj/item/reagent_containers/cup/beaker/large, /obj/item/reagent_containers/pill/insulin, /obj/item/stack/medical/gauze, + /obj/item/storage/box/bandages, /obj/item/storage/box/beakers, /obj/item/storage/box/medigels, /obj/item/storage/box/syringes, diff --git a/code/modules/cargo/packs/organic.dm b/code/modules/cargo/packs/organic.dm index 73c98cb4b3ab32..eb26d5ec907f77 100644 --- a/code/modules/cargo/packs/organic.dm +++ b/code/modules/cargo/packs/organic.dm @@ -299,10 +299,12 @@ ONLY 5000 BUX GET NOW! Contains a grill and fuel." cost = CARGO_CRATE_VALUE * 8 crate_type = /obj/structure/closet/crate - contains = list(/obj/item/stack/sheet/mineral/coal/five, - /obj/machinery/grill/unwrenched, - /obj/item/reagent_containers/cup/soda_cans/monkey_energy, - ) + contains = list( + /obj/item/stack/sheet/mineral/coal/five, + /obj/item/kitchen/tongs, + /obj/item/reagent_containers/cup/soda_cans/monkey_energy, + /obj/machinery/grill/unwrenched, + ) crate_name = "grilling starter kit crate" /datum/supply_pack/organic/grillfuel diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm index 7abe5f7601e627..784b870fea0842 100644 --- a/code/modules/cargo/packs/security.dm +++ b/code/modules/cargo/packs/security.dm @@ -225,6 +225,14 @@ crate_name = "energy gun crate" crate_type = /obj/structure/closet/crate/secure/plasma +/datum/supply_pack/security/armory/laser_carbine + name = "Laser Carbine Crate" + desc = "Contains three laser carbines, capable of rapidly firing weak lasers." + cost = CARGO_CRATE_VALUE * 9 + contains = list(/obj/item/gun/energy/laser/carbine = 3) + crate_name = "laser carbine crate" + crate_type = /obj/structure/closet/crate/secure/plasma + /datum/supply_pack/security/armory/exileimp name = "Exile Implants Crate" desc = "Contains five Exile implants." diff --git a/code/modules/cargo/packs/stock_market_items.dm b/code/modules/cargo/packs/stock_market_items.dm new file mode 100644 index 00000000000000..9744bdf7400ea3 --- /dev/null +++ b/code/modules/cargo/packs/stock_market_items.dm @@ -0,0 +1,36 @@ +/** + * todo: make this a supply_pack/custom. Drop pog? ohoho yes. Would be VERY fun. + */ +/datum/supply_pack/market_materials + name = "A Single Sheet of Bananium" + desc = "Going market price for this kind of sheet, by Australicus Industrial Mining." + cost = CARGO_CRATE_VALUE * 2 + // contains = list(/obj/item/stack/sheet/mineral/bananium) + crate_name = "mineral stock sheet crate" + group = "Canisters & Materials" + /// What material we are trying to buy sheets of? + var/datum/material/material + /// How many sheets of the material we are trying to buy at once? + var/amount + +/datum/supply_pack/market_materials/get_cost() + for(var/datum/material/mat as anything in SSstock_market.materials_prices) + if(material == mat) + return SSstock_market.materials_prices[mat] * amount + +/datum/supply_pack/market_materials/fill(obj/structure/closet/crate/C) + . = ..() + new material.sheet_type(C, amount) + +/datum/supply_pack/market_materials/iron + name = "Iron Sheets" + crate_name = "iron stock crate" + material = /datum/material/iron +MARKET_QUANTITY_HELPERS(/datum/supply_pack/market_materials/iron) + + +/datum/supply_pack/market_materials/gold + name = "Gold Sheets" + crate_name = "gold stock crate" + material = /datum/material/gold +MARKET_QUANTITY_HELPERS(/datum/supply_pack/market_materials/gold) diff --git a/code/modules/cargo/supplypod.dm b/code/modules/cargo/supplypod.dm index feb6c8f8ae6496..ed75e6349676fa 100644 --- a/code/modules/cargo/supplypod.dm +++ b/code/modules/cargo/supplypod.dm @@ -222,6 +222,9 @@ stay_after_drop = FALSE holder.pixel_z = initial(holder.pixel_z) holder.alpha = initial(holder.alpha) + if (holder != src) + contents |= holder.contents + qdel(holder) var/shippingLane = GLOB.areas_by_type[/area/centcom/central_command_areas/supplypod/supplypod_temp_holding] forceMove(shippingLane) //Move to the centcom-z-level until the pod_landingzone says we can drop back down again if (!reverse_dropoff_coords) //If we're centcom-launched, the reverse dropoff turf will be a centcom loading bay. If we're an extraction pod, it should be the ninja jail. Thus, this shouldn't ever really happen. @@ -276,7 +279,7 @@ if (effectGib) //effectGib is on, that means whatever's underneath us better be fucking oof'd on target_living.adjustBruteLoss(5000) //THATS A LOT OF DAMAGE (called just in case gib() doesnt work on em) if (!QDELETED(target_living)) - target_living.gib() //After adjusting the fuck outta that brute loss we finish the job with some satisfying gibs + target_living.gib(DROP_ALL_REMAINS) //After adjusting the fuck outta that brute loss we finish the job with some satisfying gibs else target_living.adjustBruteLoss(damage) var/explosion_sum = B[1] + B[2] + B[3] + B[4] @@ -293,6 +296,8 @@ if (style == STYLE_GONDOLA) //Checks if we are supposed to be a gondola pod. If so, create a gondolapod mob, and move this pod to nullspace. I'd like to give a shout out, to my man oranges var/mob/living/simple_animal/pet/gondola/gondolapod/benis = new(turf_underneath, src) benis.contents |= contents //Move the contents of this supplypod into the gondolapod mob. + for (var/mob/living/mob_in_pod in benis.contents) + mob_in_pod.reset_perspective(null) moveToNullspace() addtimer(CALLBACK(src, PROC_REF(open_pod), benis), delays[POD_OPENING]) //After the opening delay passes, we use the open proc from this supplyprod while referencing the contents of the "holder", in this case the gondolapod mob else if (style == STYLE_SEETHROUGH) @@ -315,7 +320,7 @@ playsound(get_turf(holder), openingSound, soundVolume, FALSE, FALSE) //Special admin sound to play for (var/turf_type in turfs_in_cargo) turf_underneath.PlaceOnTop(turf_type) - for (var/cargo in contents) + for (var/cargo in holder.contents) var/atom/movable/movable_cargo = cargo movable_cargo.forceMove(turf_underneath) if (!effectQuiet && !openingSound && style != STYLE_SEETHROUGH && !(pod_flags & FIRST_SOUNDS)) //If we aren't being quiet, play the default pod open sound @@ -487,7 +492,8 @@ . = ..() if(same_z_layer) return - SET_PLANE_EXPLICIT(glow_effect, ABOVE_GAME_PLANE, src) + if(glow_effect) + SET_PLANE_EXPLICIT(glow_effect, ABOVE_GAME_PLANE, src) /obj/structure/closet/supplypod/proc/endGlow() if(!glow_effect) @@ -537,7 +543,7 @@ /obj/effect/supplypod_smoke/proc/drawSelf(amount) alpha = max(0, 255-(amount*20)) -/obj/effect/supplypod_rubble //This is the object that forceMoves the supplypod to it's location +/obj/effect/supplypod_rubble name = "debris" desc = "A small crater of rubble. Closer inspection reveals the debris to be made primarily of space-grade metal fragments. You're pretty sure that this will disperse before too long." icon = 'icons/obj/supplypods.dmi' diff --git a/code/modules/client/client_colour.dm b/code/modules/client/client_colour.dm index 444b4d7ec121a6..707267e7143137 100644 --- a/code/modules/client/client_colour.dm +++ b/code/modules/client/client_colour.dm @@ -221,6 +221,10 @@ override = TRUE colour = list(0.8,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0) +/datum/client_colour/manual_heart_blood + priority = PRIORITY_ABSOLUTE + colour = COLOR_RED + #undef PRIORITY_ABSOLUTE #undef PRIORITY_HIGH #undef PRIORITY_NORMAL diff --git a/code/modules/client/player_details.dm b/code/modules/client/player_details.dm index 24c6754b95ce1b..8931dffcdb465d 100644 --- a/code/modules/client/player_details.dm +++ b/code/modules/client/player_details.dm @@ -2,14 +2,26 @@ ///assoc list of ckey -> /datum/player_details GLOBAL_LIST_EMPTY(player_details) +/// Tracks information about a client between log in and log outs /datum/player_details - var/list/player_actions = list() + /// Action datums assigned to this player + var/list/datum/action/player_actions = list() + /// Tracks client action logging var/list/logging = list() + /// Callbacks invoked when this client logs in again var/list/post_login_callbacks = list() + /// Callbacks invoked when this client logs out var/list/post_logout_callbacks = list() - var/list/played_names = list() //List of names this key played under this round + /// List of names this key played under this round + var/list/played_names = list() + /// Lazylist of preference slots this client has joined the round under + /// Numbers are stored as strings + var/list/joined_as_slots + /// Version of byond this client is using var/byond_version = "Unknown" + /// Tracks achievements they have earned var/datum/achievement_data/achievements + /// World.time this player last died var/time_of_death = 0 /datum/player_details/New(key) diff --git a/code/modules/client/preferences/middleware/antags.dm b/code/modules/client/preferences/middleware/antags.dm index 3e51218edf2896..888da90d5b79c5 100644 --- a/code/modules/client/preferences/middleware/antags.dm +++ b/code/modules/client/preferences/middleware/antags.dm @@ -116,6 +116,7 @@ /datum/asset/spritesheet/antagonists/create_spritesheets() // Antagonists that don't have a dynamic ruleset, but do have a preference var/static/list/non_ruleset_antagonists = list( + ROLE_CYBER_POLICE = /datum/antagonist/cyber_police, ROLE_FUGITIVE = /datum/antagonist/fugitive, ROLE_LONE_OPERATIVE = /datum/antagonist/nukeop/lone, ROLE_DRIFTING_CONTRACTOR = /datum/antagonist/contractor, //SKYRAT EDIT diff --git a/code/modules/client/preferences/species_features/basic.dm b/code/modules/client/preferences/species_features/basic.dm index faa86cc07e2f18..6e34a234e7d01b 100644 --- a/code/modules/client/preferences/species_features/basic.dm +++ b/code/modules/client/preferences/species_features/basic.dm @@ -4,16 +4,13 @@ head_icon = icon('icons/mob/human/bodyparts_greyscale.dmi', "human_head_m") head_icon.Blend(skintone2hex("caucasian1"), ICON_MULTIPLY) - if (isnull(sprite_accessory)) - return head_icon - - ASSERT(istype(sprite_accessory)) - var/icon/final_icon = new(head_icon) + if (!isnull(sprite_accessory)) + ASSERT(istype(sprite_accessory)) - var/icon/head_accessory_icon = icon(sprite_accessory.icon, sprite_accessory.icon_state) - head_accessory_icon.Blend(COLOR_DARK_BROWN, ICON_MULTIPLY) - final_icon.Blend(head_accessory_icon, ICON_OVERLAY) + var/icon/head_accessory_icon = icon(sprite_accessory.icon, sprite_accessory.icon_state) + head_accessory_icon.Blend(COLOR_DARK_BROWN, ICON_MULTIPLY) + final_icon.Blend(head_accessory_icon, ICON_OVERLAY) final_icon.Crop(10, 19, 22, 31) final_icon.Scale(32, 32) diff --git a/code/modules/clothing/head/hat.dm b/code/modules/clothing/head/hat.dm index d99c5b0c429315..83c3890eb57f06 100644 --- a/code/modules/clothing/head/hat.dm +++ b/code/modules/clothing/head/hat.dm @@ -135,6 +135,10 @@ worn_icon_state = "cowboy_hat_black" inhand_icon_state = "cowboy_hat_black" +/// More likely to intercept bullets, since you're likely to not be wearing your modsuit with this on +/obj/item/clothing/head/cowboy/black/syndicate + deflect_chance = 25 + /obj/item/clothing/head/cowboy/white name = "ten-gallon hat" desc = "There are two kinds of people in the world: those with guns and those that dig. You dig?" diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 76194e721b6859..3c26de45e642ff 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -154,6 +154,13 @@ flags_inv = HIDEHAIR flags_cover = HEADCOVERSEYES +/obj/item/clothing/head/chaplain/habit_veil + name = "nun veil" + desc = "No nunsene clothing." + icon_state = "nun_hood_alt" + flags_inv = HIDEHAIR | HIDEEARS + clothing_flags = SNUG_FIT // can't be knocked off by throwing a paper hat. + /obj/item/clothing/head/chaplain/bishopmitre name = "bishop mitre" desc = "An opulent hat that functions as a radio to God. Or as a lightning rod, depending on who you ask." diff --git a/code/modules/clothing/head/mind_monkey_helmet.dm b/code/modules/clothing/head/mind_monkey_helmet.dm index c0463fed74c0aa..d1c423b5b038c8 100644 --- a/code/modules/clothing/head/mind_monkey_helmet.dm +++ b/code/modules/clothing/head/mind_monkey_helmet.dm @@ -89,7 +89,7 @@ if(3) //primal gene (gorilla) magnification.gorillize() if(4) //genetic mass susceptibility (gib) - magnification.gib() + magnification.gib(DROP_ALL_REMAINS) //either used up correctly or taken off before polling finished (punish this by destroying the helmet) UnregisterSignal(magnification, COMSIG_SPECIES_LOSS) playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE) diff --git a/code/modules/clothing/masks/moustache.dm b/code/modules/clothing/masks/moustache.dm index ecfd5d5e007965..aaf59be51e4fdb 100644 --- a/code/modules/clothing/masks/moustache.dm +++ b/code/modules/clothing/masks/moustache.dm @@ -2,6 +2,7 @@ name = "fake moustache" desc = "Warning: moustache is fake." icon_state = "fake-moustache" + alternate_worn_layer = ABOVE_BODY_FRONT_HEAD_LAYER w_class = WEIGHT_CLASS_TINY flags_inv = HIDEFACE species_exception = list(/datum/species/golem) diff --git a/code/modules/clothing/outfits/plasmaman.dm b/code/modules/clothing/outfits/plasmaman.dm index daad81ea475b57..a422d2d736e92b 100644 --- a/code/modules/clothing/outfits/plasmaman.dm +++ b/code/modules/clothing/outfits/plasmaman.dm @@ -281,3 +281,10 @@ gloves = /obj/item/clothing/gloves/color/plasmaman/clown head = /obj/item/clothing/head/helmet/space/plasmaman/clown mask = /obj/item/clothing/mask/gas/clown_hat/plasmaman + +/datum/outfit/plasmaman/bitrunner + name = "Bitrunner Plasmaman" + + uniform = /obj/item/clothing/under/plasmaman/bitrunner + gloves = /obj/item/clothing/gloves/color/plasmaman/black + head = /obj/item/clothing/head/helmet/space/plasmaman/bitrunner diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index aa88961e3c465c..118c28c0e5166e 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -208,7 +208,7 @@ to_chat(our_guy, span_userdanger("You stamp on [user]'s hand! What the- [user.p_they()] [user.p_were()] [tied ? "knotting" : "untying"] your shoelaces!")) user.emote("scream") if(istype(L)) - var/obj/item/bodypart/ouchie = L.get_bodypart(pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)) + var/obj/item/bodypart/ouchie = L.get_bodypart(pick(GLOB.arm_zones)) if(ouchie) ouchie.receive_damage(brute = 10) L.adjustStaminaLoss(40) diff --git a/code/modules/clothing/shoes/cowboy.dm b/code/modules/clothing/shoes/cowboy.dm index 05792a72cbd960..0aa518bc1364d8 100644 --- a/code/modules/clothing/shoes/cowboy.dm +++ b/code/modules/clothing/shoes/cowboy.dm @@ -6,6 +6,10 @@ custom_price = PAYCHECK_CREW var/max_occupants = 4 can_be_tied = FALSE + /// Do these boots have spur sounds? + var/has_spurs = FALSE + /// The jingle jangle jingle of our spurs + var/list/spur_sound = list('sound/effects/footstep/spurs1.ogg'=1,'sound/effects/footstep/spurs2.ogg'=1,'sound/effects/footstep/spurs3.ogg'=1) /datum/armor/shoes_cowboy bio = 90 @@ -19,6 +23,9 @@ //There's a snake in my boot new /mob/living/basic/snake(src) + if(has_spurs) + LoadComponent(/datum/component/squeak, spur_sound, 50, falloff_exponent = 20) + /obj/item/clothing/shoes/cowboy/equipped(mob/living/carbon/user, slot) . = ..() @@ -97,3 +104,10 @@ name = "\improper Hugs-The-Feet lizard skin boots" desc = "A pair of masterfully crafted lizard skin boots. Finally a good application for the station's most bothersome inhabitants." icon_state = "lizardboots_blue" + +/// Shoes for the nuke-ops cowboy fit +/obj/item/clothing/shoes/cowboy/black/syndicate + name = "black spurred cowboy boots" + desc = "And they sing, oh, ain't you glad you're single? And that song ain't so very far from wrong." + armor_type = /datum/armor/shoes_combat + has_spurs = TRUE diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm index ceb31b23a28488..30e43c793aacff 100644 --- a/code/modules/clothing/spacesuits/plasmamen.dm +++ b/code/modules/clothing/spacesuits/plasmamen.dm @@ -443,3 +443,8 @@ or they've murdered one of your fellow badasses and have taken it from them as a trophy. Either way, anyone wearing this deserves at least a cursory nod of respect." icon_state = "syndie_envirohelm" inhand_icon_state = null + +/obj/item/clothing/head/helmet/space/plasmaman/bitrunner + name = "bitrunner's plasma envirosuit helmet" + desc = "An envirohelmet with extended blue light filters for bitrunning plasmamen." + icon_state = "bitrunner_envirohelm" diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm index 13c9c358fac930..84cb98049e1b1a 100644 --- a/code/modules/clothing/suits/_suits.dm +++ b/code/modules/clothing/suits/_suits.dm @@ -8,6 +8,7 @@ /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/tank/jetpack/oxygen/captain, + /obj/item/storage/belt/holster, ) armor_type = /datum/armor/none drop_sound = 'sound/items/handling/cloth_drop.ogg' diff --git a/code/modules/clothing/suits/jacket.dm b/code/modules/clothing/suits/jacket.dm index ffd67ce4a65aa2..6db889032c064d 100644 --- a/code/modules/clothing/suits/jacket.dm +++ b/code/modules/clothing/suits/jacket.dm @@ -1,7 +1,16 @@ /obj/item/clothing/suit/jacket icon = 'icons/obj/clothing/suits/jacket.dmi' worn_icon = 'icons/mob/clothing/suits/jacket.dmi' - allowed = list(/obj/item/flashlight, /obj/item/tank/internals/emergency_oxygen, /obj/item/tank/internals/plasmaman, /obj/item/toy, /obj/item/storage/fancy/cigarettes, /obj/item/lighter, /obj/item/radio) + allowed = list( + /obj/item/flashlight, + /obj/item/tank/internals/emergency_oxygen, + /obj/item/tank/internals/plasmaman, + /obj/item/toy, + /obj/item/storage/fancy/cigarettes, + /obj/item/lighter, + /obj/item/radio, + /obj/item/storage/belt/holster, + ) body_parts_covered = CHEST|GROIN|ARMS cold_protection = CHEST|GROIN|ARMS min_cold_protection_temperature = FIRE_SUIT_MIN_TEMP_PROTECT diff --git a/code/modules/clothing/suits/wintercoats.dm b/code/modules/clothing/suits/wintercoats.dm index 60cbcae1473351..283878339fe323 100644 --- a/code/modules/clothing/suits/wintercoats.dm +++ b/code/modules/clothing/suits/wintercoats.dm @@ -247,8 +247,10 @@ icon_state = "coatjanitor" inhand_icon_state = null allowed = list( + /obj/item/access_key, /obj/item/grenade/chem_grenade, /obj/item/holosign_creator, + /obj/item/key/janitor, /obj/item/reagent_containers/cup/beaker, /obj/item/reagent_containers/cup/bottle, /obj/item/reagent_containers/cup/tube, diff --git a/code/modules/clothing/under/costume.dm b/code/modules/clothing/under/costume.dm index 6ef6489f3893de..c7be95178e4d14 100644 --- a/code/modules/clothing/under/costume.dm +++ b/code/modules/clothing/under/costume.dm @@ -362,6 +362,11 @@ inhand_icon_state = null can_adjust = FALSE +// For the nuke-ops cowboy fit. Sadly no Lone Ranger fit & I don't wanna bloat costume files further. +/obj/item/clothing/under/costume/dutch/syndicate + desc = "You can feel a god damn plan coming on, and the armor lining in this suit'll do wonders in makin' it work." + armor_type = /datum/armor/clothing_under/syndicate + /obj/item/clothing/under/costume/osi name = "O.S.I. jumpsuit" icon_state = "osi_jumpsuit" diff --git a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm index 1590fa77138f1f..a8674b03c943a2 100644 --- a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm +++ b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm @@ -115,6 +115,12 @@ icon_state = "clown_envirosuit" inhand_icon_state = null +/obj/item/clothing/under/plasmaman/bitrunner + name = "bitrunner envirosuit" + desc = "An envirosuit specially designed for plasmamen with bad posture." + icon_state = "bitrunner_envirosuit" + inhand_icon_state = null + /obj/item/clothing/under/plasmaman/clown/Initialize(mapload) . = ..() AddElement(/datum/element/swabable, CELL_LINE_TABLE_CLOWN, CELL_VIRUS_TABLE_GENERIC, rand(2,3), 0) diff --git a/code/modules/clothing/under/jobs/cargo.dm b/code/modules/clothing/under/jobs/cargo.dm index 4b2e74bff3820d..e3145fb740d71d 100644 --- a/code/modules/clothing/under/jobs/cargo.dm +++ b/code/modules/clothing/under/jobs/cargo.dm @@ -62,3 +62,9 @@ desc = "A grey uniform for operating in hazardous environments." icon_state = "explorer" inhand_icon_state = null + +/obj/item/clothing/under/rank/cargo/bitrunner + name = "bitrunner's jumpsuit" + desc = "It's a leathery jumpsuit worn by a bitrunner. Tacky, but comfortable to wear if sitting for prolonged periods of time." + icon_state = "bitrunner" + inhand_icon_state = "w_suit" diff --git a/code/modules/economy/account.dm b/code/modules/economy/account.dm index 3be319fd233381..b4703945092cc0 100644 --- a/code/modules/economy/account.dm +++ b/code/modules/economy/account.dm @@ -7,6 +7,8 @@ var/account_balance = 0 ///How many mining points (shaft miner credits) is held in the bank account, used for mining vendors. var/mining_points = 0 + /// Points for bit runner's vendor. Awarded for completing virtual domains. + var/bitrunning_points = 0 ///Debt. If higher than 0, A portion of the credits is earned (or the whole debt, whichever is lower) will go toward paying it off. var/account_debt = 0 ///If there are things effecting how much income a player will get, it's reflected here 1 is standard for humans. diff --git a/code/modules/events/ghost_role/revenant_event.dm b/code/modules/events/ghost_role/revenant_event.dm index 27f3597a7ad2ad..f739a3e13d46bc 100644 --- a/code/modules/events/ghost_role/revenant_event.dm +++ b/code/modules/events/ghost_role/revenant_event.dm @@ -54,11 +54,12 @@ if(!spawn_locs.len) //If we can't find THAT, then just give up and cry return MAP_ERROR - var/mob/living/simple_animal/revenant/revvie = new(pick(spawn_locs)) - revvie.key = selected.key + var/mob/living/basic/revenant/revvie = new(pick(spawn_locs)) + selected.mind.transfer_to(revvie) message_admins("[ADMIN_LOOKUPFLW(revvie)] has been made into a revenant by an event.") revvie.log_message("was spawned as a revenant by an event.", LOG_GAME) spawned_mobs += revvie + qdel(selected) return SUCCESSFUL_SPAWN #undef REVENANT_SPAWN_THRESHOLD diff --git a/code/modules/events/ghost_role/sentience.dm b/code/modules/events/ghost_role/sentience.dm index da3802786084cb..abc57d33a07583 100644 --- a/code/modules/events/ghost_role/sentience.dm +++ b/code/modules/events/ghost_role/sentience.dm @@ -4,20 +4,20 @@ GLOBAL_LIST_INIT(high_priority_sentience, typecacheof(list( /mob/living/basic/carp/pet/cayenne, /mob/living/basic/chicken, /mob/living/basic/cow, + /mob/living/basic/goat, /mob/living/basic/lizard, /mob/living/basic/mouse/brown/tom, /mob/living/basic/pet, /mob/living/basic/pig, /mob/living/basic/rabbit, /mob/living/basic/sheep, + /mob/living/basic/sloth, /mob/living/basic/snake, /mob/living/basic/spider/giant/sgt_araneus, /mob/living/simple_animal/bot/secbot/beepsky, - /mob/living/simple_animal/hostile/retaliate/goat, /mob/living/simple_animal/hostile/retaliate/goose/vomit, /mob/living/simple_animal/parrot, /mob/living/simple_animal/pet, - /mob/living/simple_animal/sloth, ))) /datum/round_event_control/sentience diff --git a/code/modules/events/space_vines/vine_structure.dm b/code/modules/events/space_vines/vine_structure.dm index 47357d558ace3b..155a4c5c083c1f 100644 --- a/code/modules/events/space_vines/vine_structure.dm +++ b/code/modules/events/space_vines/vine_structure.dm @@ -37,6 +37,7 @@ ) AddElement(/datum/element/connect_loc, loc_connections) AddElement(/datum/element/atmos_sensitive, mapload) + AddComponent(/datum/component/storm_hating) /obj/structure/spacevine/examine(mob/user) . = ..() @@ -147,7 +148,7 @@ break //only capture one mob at a time /obj/structure/spacevine/proc/entangle(mob/living/victim) - if(!victim || isvineimmune(victim)) + if(isnull(victim) || isvineimmune(victim)) return for(var/datum/spacevine_mutation/mutation in mutations) mutation.on_buckle(src, victim) @@ -157,7 +158,7 @@ /// Finds a target tile to spread to. If checks pass it will spread to it and also proc on_spread on target. /obj/structure/spacevine/proc/spread() - if(!master) //If we've lost our controller, something has gone terribly wrong. + if(isnull(master)) //If we've lost our controller, something has gone terribly wrong. return var/direction = pick(GLOB.cardinals) @@ -165,20 +166,29 @@ if(!istype(stepturf)) return - if(!isspaceturf(stepturf) && stepturf.Enter(src)) - var/obj/structure/spacevine/spot_taken = locate() in stepturf //Locates any vine on target turf. Calls that vine "spot_taken". - var/datum/spacevine_mutation/vine_eating/eating = locate() in mutations //Locates the vine eating trait in our own seed and calls it E. - if(!spot_taken || (eating && (spot_taken && !spot_taken.mutations?.Find(eating)))) //Proceed if there isn't a vine on the target turf, OR we have vine eater AND target vine is from our seed and doesn't. Vines from other seeds are eaten regardless. - for(var/datum/spacevine_mutation/mutation in mutations) - mutation.on_spread(src, stepturf) //Only do the on_spread proc if it actually spreads. - stepturf = get_step(src,direction) //in case turf changes, to make sure no runtimes happen - var/obj/structure/spacevine/spawning_vine = master.spawn_spacevine_piece(stepturf, src) //Let's do a cool little animate - if(NSCOMPONENT(direction)) - spawning_vine.pixel_y = direction == NORTH ? -32 : 32 - animate(spawning_vine, pixel_y = 0, time = 1 SECONDS) - else - spawning_vine.pixel_x = direction == EAST ? -32 : 32 - animate(spawning_vine, pixel_x = 0, time = 1 SECONDS) + if(isspaceturf(stepturf) || isopenspaceturf(stepturf) || !stepturf.Enter(src)) + return + if(ischasm(stepturf) && !HAS_TRAIT(stepturf, TRAIT_CHASM_STOPPED)) + return + if(islava(stepturf) && !HAS_TRAIT(stepturf, TRAIT_LAVA_STOPPED)) + return + var/obj/structure/spacevine/spot_taken = locate() in stepturf + var/datum/spacevine_mutation/vine_eating/eating = locate() in mutations + if(!isnull(spot_taken)) //Proceed if there isn't a vine on the target turf, OR we have vine eater AND target vine is from our seed and doesn't. + if (isnull(eating)) + return + if (spot_taken.mutations?.Find(eating)) + return + for(var/datum/spacevine_mutation/mutation in mutations) + mutation.on_spread(src, stepturf) + stepturf = get_step(src, direction) + var/obj/structure/spacevine/spawning_vine = master.spawn_spacevine_piece(stepturf, src) + if(NSCOMPONENT(direction)) + spawning_vine.pixel_y = direction == NORTH ? -32 : 32 + animate(spawning_vine, pixel_y = 0, time = 1 SECONDS) + else + spawning_vine.pixel_x = direction == EAST ? -32 : 32 + animate(spawning_vine, pixel_x = 0, time = 1 SECONDS) /// Destroying an explosive vine sets off a chain reaction /obj/structure/spacevine/ex_act(severity, target) diff --git a/code/modules/events/wizard/blobies.dm b/code/modules/events/wizard/blobies.dm index 307d01ff7eb429..0a9c96d513545b 100644 --- a/code/modules/events/wizard/blobies.dm +++ b/code/modules/events/wizard/blobies.dm @@ -10,4 +10,4 @@ /datum/round_event/wizard/blobies/start() for(var/mob/living/carbon/human/H in GLOB.dead_mob_list) - new /mob/living/simple_animal/hostile/blob/blobspore(H.loc) + new /mob/living/basic/blob_minion/spore/minion(H.loc) // Creates zombies which ghosts can control diff --git a/code/modules/events/wizard/petsplosion.dm b/code/modules/events/wizard/petsplosion.dm index 33f7718f740baf..a9664d8dd47e29 100644 --- a/code/modules/events/wizard/petsplosion.dm +++ b/code/modules/events/wizard/petsplosion.dm @@ -5,6 +5,7 @@ GLOBAL_LIST_INIT(petsplosion_candidates, typecacheof(list( /mob/living/basic/carp/pet/cayenne, /mob/living/basic/chicken, /mob/living/basic/cow, + /mob/living/basic/goat, /mob/living/basic/lizard, /mob/living/basic/mothroach, /mob/living/basic/mouse/brown/tom, @@ -12,13 +13,12 @@ GLOBAL_LIST_INIT(petsplosion_candidates, typecacheof(list( /mob/living/basic/pig, /mob/living/basic/rabbit, /mob/living/basic/sheep, + /mob/living/basic/sloth, /mob/living/basic/snake, /mob/living/basic/spider/giant/sgt_araneus, - /mob/living/simple_animal/hostile/retaliate/goat, /mob/living/simple_animal/hostile/retaliate/goose/vomit, /mob/living/simple_animal/parrot, /mob/living/simple_animal/pet, - /mob/living/simple_animal/sloth, ))) /datum/round_event_control/wizard/petsplosion //the horror diff --git a/code/modules/experisci/destructive_scanner.dm b/code/modules/experisci/destructive_scanner.dm index 3591a31cd7b085..de0b03b0f09202 100644 --- a/code/modules/experisci/destructive_scanner.dm +++ b/code/modules/experisci/destructive_scanner.dm @@ -19,10 +19,17 @@ // Late load to ensure the component initialization occurs after the machines are initialized /obj/machinery/destructive_scanner/LateInitialize() . = ..() + + var/static/list/destructive_signals = list( + COMSIG_MACHINERY_DESTRUCTIVE_SCAN = TYPE_PROC_REF(/datum/component/experiment_handler, try_run_destructive_experiment), + ) + AddComponent(/datum/component/experiment_handler, \ allowed_experiments = list(/datum/experiment/scanning),\ config_mode = EXPERIMENT_CONFIG_CLICK, \ - start_experiment_callback = CALLBACK(src, PROC_REF(activate))) + start_experiment_callback = CALLBACK(src, PROC_REF(activate)), \ + experiment_signals = destructive_signals, \ + ) ///Activates the machine; checks if it can actually scan, then starts. /obj/machinery/destructive_scanner/proc/activate() @@ -82,7 +89,7 @@ if(isliving(movable_atom)) var/mob/living/fucked_up_thing = movable_atom fucked_up_thing.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) - fucked_up_thing.gib() + fucked_up_thing.gib(DROP_ALL_REMAINS) SEND_SIGNAL(src, COMSIG_MACHINERY_DESTRUCTIVE_SCAN, scanned_atoms) diff --git a/code/modules/experisci/experiment/experiments.dm b/code/modules/experisci/experiment/experiments.dm index 1959a849598a58..1259f56597d6da 100644 --- a/code/modules/experisci/experiment/experiments.dm +++ b/code/modules/experisci/experiment/experiments.dm @@ -291,7 +291,6 @@ /obj/machinery/rnd/experimentor = 1, /obj/machinery/medical_kiosk = 2, /obj/machinery/piratepad/civilian = 2, - /obj/machinery/rnd/bepis = 3 ) required_stock_part = /obj/item/stock_parts/scanning_module/adv @@ -332,7 +331,7 @@ ///Damage percent that each mech needs to be at for a scan to work. var/damage_percent -/datum/experiment/scanning/random/mecha_damage_scan/New() +/datum/experiment/scanning/random/mecha_damage_scan/New(datum/techweb/techweb) . = ..() damage_percent = rand(15, 95) //updating the description with the damage_percent var set diff --git a/code/modules/experisci/experiment/handlers/experiment_handler.dm b/code/modules/experisci/experiment/handlers/experiment_handler.dm index abc5d4ad1dd640..29e7da95391554 100644 --- a/code/modules/experisci/experiment/handlers/experiment_handler.dm +++ b/code/modules/experisci/experiment/handlers/experiment_handler.dm @@ -38,6 +38,7 @@ disallowed_traits = null, config_flags = null, datum/callback/start_experiment_callback = null, + list/experiment_signals ) . = ..() if(!ismovable(parent)) @@ -49,13 +50,8 @@ src.config_flags = config_flags src.start_experiment_callback = start_experiment_callback - if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(try_run_handheld_experiment)) - RegisterSignal(parent, COMSIG_ITEM_AFTERATTACK, PROC_REF(ignored_handheld_experiment_attempt)) - if(istype(parent, /obj/machinery/destructive_scanner)) - RegisterSignal(parent, COMSIG_MACHINERY_DESTRUCTIVE_SCAN, PROC_REF(try_run_destructive_experiment)) - if(istype(parent, /obj/machinery/computer/operating)) - RegisterSignal(parent, COMSIG_OPERATING_COMPUTER_AUTOPSY_COMPLETE, PROC_REF(try_run_autopsy_experiment)) + for(var/signal in experiment_signals) + RegisterSignal(parent, signal, experiment_signals[signal]) // Determine UI display mode switch(config_mode) @@ -85,9 +81,9 @@ */ /datum/component/experiment_handler/proc/try_run_handheld_experiment(datum/source, atom/target, mob/user, params) SIGNAL_HANDLER - if (!should_run_handheld_experiment(source, target, user, params)) + if (!should_run_handheld_experiment(source, target, user)) return - INVOKE_ASYNC(src, PROC_REF(try_run_handheld_experiment_async), source, target, user, params) + INVOKE_ASYNC(src, PROC_REF(try_run_handheld_experiment_async), source, target, user) return COMPONENT_CANCEL_ATTACK_CHAIN /** @@ -98,7 +94,7 @@ if (!proximity_flag) return . |= COMPONENT_AFTERATTACK_PROCESSED_ITEM - if (selected_experiment == null && !(config_flags & EXPERIMENT_CONFIG_ALWAYS_ACTIVE)) + if ((selected_experiment == null && !(config_flags & EXPERIMENT_CONFIG_ALWAYS_ACTIVE)) || config_flags & EXPERIMENT_CONFIG_SILENT_FAIL) return . playsound(user, 'sound/machines/buzz-sigh.ogg', 25) to_chat(user, span_notice("[target] is not related to your currently selected experiment.")) @@ -107,7 +103,7 @@ /** * Checks that an experiment can be run using the provided target, used for preventing the cancellation of the attack chain inappropriately */ -/datum/component/experiment_handler/proc/should_run_handheld_experiment(datum/source, atom/target, mob/user, params) +/datum/component/experiment_handler/proc/should_run_handheld_experiment(datum/source, atom/target, mob/user) // Check that there is actually an experiment selected if (selected_experiment == null && !(config_flags & EXPERIMENT_CONFIG_ALWAYS_ACTIVE)) return @@ -127,16 +123,17 @@ /** * This proc exists because Jared Fogle really likes async */ -/datum/component/experiment_handler/proc/try_run_handheld_experiment_async(datum/source, atom/target, mob/user, params) +/datum/component/experiment_handler/proc/try_run_handheld_experiment_async(datum/source, atom/target, mob/user) if (selected_experiment == null && !(config_flags & EXPERIMENT_CONFIG_ALWAYS_ACTIVE)) - to_chat(user, span_notice("You do not have an experiment selected!")) + if(!(config_flags & EXPERIMENT_CONFIG_SILENT_FAIL)) + to_chat(user, span_notice("You do not have an experiment selected!")) return - if(!do_after(user, 1 SECONDS, target = target)) + if(!(config_flags & EXPERIMENT_CONFIG_IMMEDIATE_ACTION) && !do_after(user, 1 SECONDS, target = target)) return if(action_experiment(source, target)) playsound(user, 'sound/machines/ping.ogg', 25) to_chat(user, span_notice("You scan [target].")) - else + else if(!(config_flags & EXPERIMENT_CONFIG_SILENT_FAIL)) playsound(user, 'sound/machines/buzz-sigh.ogg', 25) to_chat(user, span_notice("[target] is not related to your currently selected experiment.")) @@ -148,8 +145,9 @@ SIGNAL_HANDLER var/atom/movable/our_scanner = parent if (selected_experiment == null) - playsound(our_scanner, 'sound/machines/buzz-sigh.ogg', 25) - to_chat(our_scanner, span_notice("No experiment selected!")) + if(!(config_flags & EXPERIMENT_CONFIG_SILENT_FAIL)) + playsound(our_scanner, 'sound/machines/buzz-sigh.ogg', 25) + to_chat(our_scanner, span_notice("No experiment selected!")) return var/successful_scan for(var/scan_target in scanned_atoms) @@ -159,7 +157,7 @@ if(successful_scan) playsound(our_scanner, 'sound/machines/ping.ogg', 25) to_chat(our_scanner, span_notice("The scan succeeds.")) - else + else if(!(config_flags & EXPERIMENT_CONFIG_SILENT_FAIL)) playsound(src, 'sound/machines/buzz-sigh.ogg', 25) our_scanner.say("The scan did not result in anything.") @@ -261,6 +259,7 @@ /datum/component/experiment_handler/proc/link_techweb(datum/techweb/new_web) if (new_web == linked_web) return + selected_experiment?.on_unselected(src) selected_experiment = null linked_web = new_web @@ -268,6 +267,7 @@ * Unlinks this handler from the selected techweb */ /datum/component/experiment_handler/proc/unlink_techweb() + selected_experiment?.on_unselected(src) selected_experiment = null linked_web = null @@ -278,13 +278,15 @@ * * experiment - The experiment to attempt to link to */ /datum/component/experiment_handler/proc/link_experiment(datum/experiment/experiment) - if (experiment && can_select_experiment(experiment)) + if (can_select_experiment(experiment)) selected_experiment = experiment + selected_experiment.on_selected(src) /** * Unlinks this handler from the selected experiment */ /datum/component/experiment_handler/proc/unlink_experiment() + selected_experiment?.on_unselected(src) selected_experiment = null /** @@ -299,31 +301,19 @@ return FALSE // Check against the list of allowed experimentors - if (experiment.allowed_experimentors && experiment.allowed_experimentors.len) - var/matched = FALSE - for (var/experimentor in experiment.allowed_experimentors) - if (istype(parent, experimentor)) - matched = TRUE - break - if (!matched) - return FALSE + if (length(experiment.allowed_experimentors) && !is_type_in_list(parent, experiment.allowed_experimentors)) + return FALSE // Check that this experiment is visible currently - if (!linked_web || !(experiment in linked_web.available_experiments)) + if (!(experiment in linked_web?.available_experiments)) return FALSE // Check that this experiment type isn't blacklisted - for (var/badsci in blacklisted_experiments) - if (istype(experiment, badsci)) - return FALSE - - // Check against the allowed experiment types - for (var/goodsci in allowed_experiments) - if (istype(experiment, goodsci)) - return TRUE + if(is_type_in_list(experiment, blacklisted_experiments)) + return FALSE - // If we haven't returned yet then this shouldn't be allowed - return FALSE + // Finally, check against the allowed experiment types + return is_type_in_list(experiment, allowed_experiments) /datum/component/experiment_handler/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) @@ -355,12 +345,13 @@ .["techwebs"] += list(data) .["experiments"] = list() if (linked_web) - for (var/datum/experiment/experiment in linked_web.available_experiments) + for (var/datum/experiment/experiment as anything in linked_web.available_experiments) + if(!can_select_experiment(experiment)) + continue var/list/data = list( name = experiment.name, description = experiment.description, tag = experiment.exp_tag, - selectable = can_select_experiment(experiment), selected = selected_experiment == experiment, progress = experiment.check_progress(), performance_hint = experiment.performance_hint, diff --git a/code/modules/experisci/experiment/types/experiment.dm b/code/modules/experisci/experiment/types/experiment.dm index f760723f8db474..add015622f6219 100644 --- a/code/modules/experisci/experiment/types/experiment.dm +++ b/code/modules/experisci/experiment/types/experiment.dm @@ -22,11 +22,16 @@ /// A textual hint shown on the UI in a tooltip to help a user determine how to perform /// the experiment var/performance_hint + /** + * If set, these techweb points will be rewarded for completing the experiment. + * Useful for those loose ends not tied to any specific node discount or requirement. + */ + var/list/points_reward /** * Performs any necessary initialization of tags and other variables */ -/datum/experiment/New() +/datum/experiment/New(datum/techweb/techweb) if (traits & EXPERIMENT_TRAIT_DESTRUCTIVE) exp_tag = "Destructive [exp_tag]" @@ -60,6 +65,14 @@ /datum/experiment/proc/actionable(...) return !is_complete() +///Called when the experiment is selected by an experiment handler, for specific signals and the such. +/datum/experiment/proc/on_selected(datum/component/experiment_handler/experiment_handler) + return + +///Called when the opposite happens. +/datum/experiment/proc/on_unselected(datum/component/experiment_handler/experiment_handler) + return + /** * Proc that tries to perform the experiment, and then checks if its completed. */ diff --git a/code/modules/experisci/experiment/types/exploration.dm b/code/modules/experisci/experiment/types/exploration.dm index a6a5d2cd4cf4d8..821e69a103ac59 100644 --- a/code/modules/experisci/experiment/types/exploration.dm +++ b/code/modules/experisci/experiment/types/exploration.dm @@ -52,7 +52,7 @@ /// If not null the required_condition will be picked from this list var/list/possible_random_site_types -/datum/experiment/exploration_scan/random/New() +/datum/experiment/exploration_scan/random/New(datum/techweb/techweb) . = ..() if(length(possible_random_site_types)) required_site_type = pick(possible_random_site_types) diff --git a/code/modules/experisci/experiment/types/random_scanning.dm b/code/modules/experisci/experiment/types/random_scanning.dm index e80a80b5a0efab..c9d39bd47b4463 100644 --- a/code/modules/experisci/experiment/types/random_scanning.dm +++ b/code/modules/experisci/experiment/types/random_scanning.dm @@ -8,7 +8,7 @@ /// Max amount of a requirement per type var/max_requirement_per_type = 100 -/datum/experiment/scanning/random/New() +/datum/experiment/scanning/random/New(datum/techweb/techweb) // Generate random contents if (possible_types.len) var/picked = 0 diff --git a/code/modules/experisci/experiment/types/scanning.dm b/code/modules/experisci/experiment/types/scanning.dm index d9bbed88c8f375..54bd2ad637e660 100644 --- a/code/modules/experisci/experiment/types/scanning.dm +++ b/code/modules/experisci/experiment/types/scanning.dm @@ -17,16 +17,18 @@ var/list/required_atoms = list() /// The list of atoms with sub-lists of atom references for scanned atoms contributing to the experiment (Or a count of atoms destoryed for destructive expiriments) var/list/scanned = list() + /// If set, it'll be used in place of the generic "Scan samples of \a [initial(target.name)]" in serialize_progress_stage() + var/scan_message /** * Initializes the scanned atoms lists * * Initializes the internal scanned atoms list to keep track of which atoms have already been scanned */ -/datum/experiment/scanning/New() +/datum/experiment/scanning/New(datum/techweb/techweb) . = ..() for (var/req_atom in required_atoms) - scanned[req_atom] = traits & EXPERIMENT_TRAIT_DESTRUCTIVE ? 0 : list() + scanned[req_atom] = (traits & EXPERIMENT_TRAIT_DESTRUCTIVE && !(traits & EXPERIMENT_TRAIT_TYPECACHE)) ? 0 : list() /** * Checks if the scanning experiment is complete @@ -37,8 +39,12 @@ /datum/experiment/scanning/is_complete() . = TRUE var/destructive = traits & EXPERIMENT_TRAIT_DESTRUCTIVE + var/typecache = traits & EXPERIMENT_TRAIT_TYPECACHE for (var/req_atom in required_atoms) var/list/seen = scanned[req_atom] + ///typecache experiments work all the same whether it's destructive or not + if(typecache && length(seen) == required_atoms[req_atom]) + continue if (destructive && (!(req_atom in scanned) || scanned[req_atom] != required_atoms[req_atom])) return FALSE if (!destructive && (!seen || seen.len != required_atoms[req_atom])) @@ -65,8 +71,9 @@ * * seen_instances - The number of instances seen of this atom */ /datum/experiment/scanning/proc/serialize_progress_stage(atom/target, list/seen_instances) - var/scanned_total = traits & EXPERIMENT_TRAIT_DESTRUCTIVE ? scanned[target] : seen_instances.len - return EXPERIMENT_PROG_INT("Scan samples of \a [initial(target.name)]", scanned_total, required_atoms[target]) + var/scanned_total = (traits & EXPERIMENT_TRAIT_DESTRUCTIVE && !(traits & EXPERIMENT_TRAIT_TYPECACHE)) ? scanned[target] : seen_instances.len + var/message = scan_message || "Scan samples of \a [initial(target.name)]" + return EXPERIMENT_PROG_INT(message, scanned_total, required_atoms[target]) /** * Attempts to scan an atom towards the experiment's goal @@ -79,7 +86,10 @@ /datum/experiment/scanning/perform_experiment_actions(datum/component/experiment_handler/experiment_handler, atom/target) var/contributing_index_value = get_contributing_index(target) if (contributing_index_value) - scanned[contributing_index_value] += traits & EXPERIMENT_TRAIT_DESTRUCTIVE ? 1 : WEAKREF(target) + if(traits & EXPERIMENT_TRAIT_TYPECACHE) + scanned[contributing_index_value][target.type] = TRUE + else + scanned[contributing_index_value] += traits & EXPERIMENT_TRAIT_DESTRUCTIVE ? 1 : WEAKREF(target) if(traits & EXPERIMENT_TRAIT_DESTRUCTIVE && !isliving(target))//only qdel things when destructive scanning and they're not living (living things get gibbed) qdel(target) do_after_experiment(target, contributing_index_value) diff --git a/code/modules/experisci/experiment/types/scanning_fish.dm b/code/modules/experisci/experiment/types/scanning_fish.dm new file mode 100644 index 00000000000000..52e58c9104ccb9 --- /dev/null +++ b/code/modules/experisci/experiment/types/scanning_fish.dm @@ -0,0 +1,116 @@ +///a superlist containing typecaches shared between the several fish scanning experiments for each techweb. +GLOBAL_LIST_EMPTY(scanned_fish_by_techweb) + +/** + * A special scanning experiment that unlocks further settings for the fishing portal generator. + * Mainly as an inventive solution to many a fish source being limited to maps that have it, + * and to make the fishing portal generator a bit than just gubby and goldfish. + */ +/datum/experiment/scanning/fish + name = "Fish Scanning Experiment 1" + description = "An experiment requiring different fish species to be scanned to unlock the 'Beach' setting for the fishing portal generator." + performance_hint = "Scan fish. Examine scanner to review progress. Unlock new fishing portals." + allowed_experimentors = list(/obj/item/experi_scanner, /obj/machinery/destructive_scanner, /obj/item/fishing_rod/tech) + traits = EXPERIMENT_TRAIT_TYPECACHE + points_reward = list(TECHWEB_POINT_TYPE_GENERIC = 750) + required_atoms = list(/obj/item/fish = 4) + scan_message = "Scan different species of fish" + ///Further experiments added to the techweb when this one is completed. + var/list/next_experiments = list(/datum/experiment/scanning/fish/second) + ///Completing a experiment may also enable a fish source to be used for use for the portal generator. + var/fish_source_reward = /datum/fish_source/portal/beach + +/** + * We make sure the scanned list is shared between all fish scanning experiments for this techweb, + * since this is about scanning each species, and having to redo it for each species is a hassle. + */ +/datum/experiment/scanning/fish/New(datum/techweb/techweb) + . = ..() + if(isnull(techweb)) + return + var/techweb_ref = REF(techweb) + var/list/scanned_fish = GLOB.scanned_fish_by_techweb[techweb_ref] + if(isnull(scanned_fish)) + scanned_fish = list() + GLOB.scanned_fish_by_techweb[techweb_ref] = scanned_fish + for(var/atom_type in required_atoms) + LAZYINITLIST(scanned_fish[atom_type]) + scanned = scanned_fish + +/** + * Registers a couple signals to review the fish scanned so far. + * It'd be an hassle not having any way (beside memory) to know which fish species have been scanned already otherwise. + */ +/datum/experiment/scanning/fish/on_selected(datum/component/experiment_handler/experiment_handler) + RegisterSignal(experiment_handler.parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_handler_examine)) + RegisterSignal(experiment_handler.parent, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(on_handler_examine_more)) + +/datum/experiment/scanning/fish/on_unselected(datum/component/experiment_handler/experiment_handler) + UnregisterSignal(experiment_handler.parent, list(COMSIG_ATOM_EXAMINE, COMSIG_ATOM_EXAMINE_MORE)) + +/datum/experiment/scanning/fish/proc/on_handler_examine(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + examine_list += span_notice("Examine again to review all the species of fish scanned so far.") + +/datum/experiment/scanning/fish/proc/on_handler_examine_more(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + var/message = span_notice("Fish species scanned hitherto, if any:") + message += "" + for(var/atom_type in required_atoms) + for(var/obj/item/fish/fish_path as anything in scanned[atom_type]) + message += "\n[initial(fish_path.name)]" + message += "" + examine_list += message + +///Only scannable fish will contribute towards the experiment. +/datum/experiment/scanning/fish/final_contributing_index_checks(obj/item/fish/target, typepath) + return target.experisci_scannable + +/** + * After a fish scanning experiment is done, more may be unlocked. If so, add them to the techweb + * and automatically link the handler to the next experiment in the list as a bit of qol. + */ +/datum/experiment/scanning/fish/finish_experiment(datum/component/experiment_handler/experiment_handler, ...) + . = ..() + if(next_experiments) + experiment_handler.linked_web.add_experiments(next_experiments) + var/datum/experiment/next_in_line = locate(next_experiments[1]) in experiment_handler.linked_web.available_experiments + experiment_handler.link_experiment(next_in_line) + +/datum/experiment/scanning/fish/second + name = "Fish Scanning Experiment 2" + description = "An experiment requiring more fish species to be scanned to unlock the 'Chasm' setting for the fishing portal." + points_reward = list(TECHWEB_POINT_TYPE_GENERIC = 1500) + required_atoms = list(/obj/item/fish = 8) + next_experiments = list(/datum/experiment/scanning/fish/third) + fish_source_reward = /datum/fish_source/portal/chasm + +/datum/experiment/scanning/fish/third + name = "Fish Scanning Experiment 3" + description = "An experiment requiring even more fish species to be scanned to unlock the 'Ocean' setting for the fishing portal." + points_reward = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + required_atoms = list(/obj/item/fish = 14) + next_experiments = list(/datum/experiment/scanning/fish/fourth, /datum/experiment/scanning/fish/holographic) + fish_source_reward = /datum/fish_source/portal/ocean + +/datum/experiment/scanning/fish/holographic + name = "Holographic Fish Scanning Experiment" + description = "This one actually requires holographic fish to unlock the 'Randomizer' setting for the fishing portal." + performance_hint = "Load in the 'Beach' template at the Holodeck to fish some holo-fish." + points_reward = list(TECHWEB_POINT_TYPE_GENERIC = 500) + required_atoms = list(/obj/item/fish/holo = 4) + scan_message = "Scan different species of holographic fish" + next_experiments = null + fish_source_reward = /datum/fish_source/portal/random + +///holo fishes are normally unscannable, but this is an experiment for them, so we don't care for the experisci_scannable variable. +/datum/experiment/scanning/fish/holographic/final_contributing_index_checks(obj/item/fish/target, typepath) + return TRUE + +/datum/experiment/scanning/fish/fourth + name = "Fish Scanning Experiment 4" + description = "An experiment requiring lotsa fish species to unlock the 'Hyperspace' setting for the fishing portal." + points_reward = list(TECHWEB_POINT_TYPE_GENERIC = 3250) + required_atoms = list(/obj/item/fish = 21) + next_experiments = null + fish_source_reward = /datum/fish_source/portal/hyperspace diff --git a/code/modules/experisci/experiment/types/scanning_material.dm b/code/modules/experisci/experiment/types/scanning_material.dm index 714205289deac8..fb8a7ff354b3b6 100644 --- a/code/modules/experisci/experiment/types/scanning_material.dm +++ b/code/modules/experisci/experiment/types/scanning_material.dm @@ -9,7 +9,7 @@ ///List of materials actually required, indexed by the atom that is required. var/required_materials = list() -/datum/experiment/scanning/random/material/New() +/datum/experiment/scanning/random/material/New(datum/techweb/techweb) . = ..() for(var/req_atom in required_atoms) var/chosen_material = pick(possible_material_types) diff --git a/code/modules/experisci/experiment/types/scanning_plants.dm b/code/modules/experisci/experiment/types/scanning_plants.dm index c34822d6e7e74c..b92a4cc20b4667 100644 --- a/code/modules/experisci/experiment/types/scanning_plants.dm +++ b/code/modules/experisci/experiment/types/scanning_plants.dm @@ -10,7 +10,7 @@ ///List of plant genes actually required, indexed by the atom that is required. var/list/required_genes = list() -/datum/experiment/scanning/random/plants/New() +/datum/experiment/scanning/random/plants/New(datum/techweb/techweb) . = ..() if(possible_plant_genes.len) for(var/req_atom in required_atoms) diff --git a/code/modules/experisci/handheld_scanner.dm b/code/modules/experisci/handheld_scanner.dm index e0fd4d480d5a37..92031107ba51d1 100644 --- a/code/modules/experisci/handheld_scanner.dm +++ b/code/modules/experisci/handheld_scanner.dm @@ -19,9 +19,15 @@ // Late initialize to allow for the rnd servers to initialize first /obj/item/experi_scanner/LateInitialize() . = ..() + var/static/list/handheld_signals = list( + COMSIG_ITEM_PRE_ATTACK = TYPE_PROC_REF(/datum/component/experiment_handler, try_run_handheld_experiment), + COMSIG_ITEM_AFTERATTACK = TYPE_PROC_REF(/datum/component/experiment_handler, ignored_handheld_experiment_attempt), + ) AddComponent(/datum/component/experiment_handler, \ - allowed_experiments = list(/datum/experiment/scanning, /datum/experiment/physical),\ - disallowed_traits = EXPERIMENT_TRAIT_DESTRUCTIVE) + allowed_experiments = list(/datum/experiment/scanning, /datum/experiment/physical), \ + disallowed_traits = EXPERIMENT_TRAIT_DESTRUCTIVE, \ + experiment_signals = handheld_signals, \ + ) /obj/item/experi_scanner/suicide_act(mob/living/carbon/user) user.visible_message(span_suicide("[user] is giving in to the Great Toilet Beyond! It looks like [user.p_theyre()] trying to commit suicide!")) @@ -53,6 +59,6 @@ icon_state = "experiscanner" remove_atom_colour(ADMIN_COLOUR_PRIORITY, "#FF0000") - user.gib(FALSE, TRUE, TRUE) //we delete everything but the brain, as it's going to be moved to the cistern + user.gib(DROP_BRAIN) //we delete everything but the brain, as it's going to be moved to the cistern toilet_brain.forceMove(result_toilet) result_toilet.w_items += toilet_brain.w_class diff --git a/code/modules/explorer_drone/adventure.dm b/code/modules/explorer_drone/adventure.dm index 9718d6d5a49de4..56d83000f905c3 100644 --- a/code/modules/explorer_drone/adventure.dm +++ b/code/modules/explorer_drone/adventure.dm @@ -43,6 +43,7 @@ #define REQ_OPERATOR_FIELD "operator" #define CURRENT_ADVENTURE_VERSION 1 +#define ADVENTURE_LOOK_PATH "strings/exoadventures/" /// All possible adventures in raw form GLOBAL_LIST_EMPTY(explorer_drone_adventure_db_entries) @@ -50,34 +51,22 @@ GLOBAL_LIST_EMPTY(explorer_drone_adventure_db_entries) /// Loads all adventures from DB /proc/load_adventures() . = list() - if(!SSdbcore.Connect()) - GLOB.explorer_drone_adventure_db_entries = . - return - var/datum/db_query/Query = SSdbcore.NewQuery("SELECT id,adventure_data,uploader,timestamp,approved FROM [format_table_name("text_adventures")]") - if(!Query.Execute()) - qdel(Query) - return - while(Query.NextRow()) + for(var/filename in flist(ADVENTURE_LOOK_PATH)) + var/raw_json = file2text(ADVENTURE_LOOK_PATH + filename) + var/list/json_decoded = json_decode(raw_json) var/datum/adventure_db_entry/entry = new() - entry.id = Query.item[1] - entry.raw_json = Query.item[2] - entry.uploader = Query.item[3] - entry.timestamp = Query.item[4] - entry.approved = Query.item[5] + entry.filename = filename + entry.raw_json = raw_json + entry.uploader = json_decoded["author"] entry.extract_metadata() . += entry - qdel(Query) GLOB.explorer_drone_adventure_db_entries = . /datum/adventure_db_entry - /// db id or null for freshly created adventures - var/id + /// filename of the adventure + var/filename /// actual adventure json string var/raw_json - /// ckey of last change user. - var/uploader - /// Time of last change. - var/timestamp /// Unapproved adventures won't be used for exploration sites. var/approved = FALSE /// Was the adventure used for exploration site this round. @@ -85,6 +74,8 @@ GLOBAL_LIST_EMPTY(explorer_drone_adventure_db_entries) //Variables below are extracted from the JSON + /// whoever made the json + var/uploader /// json version var/version /// adventure name @@ -100,61 +91,13 @@ GLOBAL_LIST_EMPTY(explorer_drone_adventure_db_entries) return FALSE return TRUE -/// Updates this entry from db, if possible. -/datum/adventure_db_entry/proc/refresh() - if(id) - //Check if our timestamp is fresh, if not update local and stop - var/datum/db_query/SelectQuery = SSdbcore.NewQuery("SELECT adventure_data,uploader,timestamp,approved FROM [format_table_name("text_adventures")] WHERE id = :id",list("id" = id)) - if(!SelectQuery.warn_execute() || !SelectQuery.NextRow()) - qdel(SelectQuery) - return - raw_json = SelectQuery.item[1] - uploader = SelectQuery.item[2] - timestamp = SelectQuery.item[3] - approved = SelectQuery.item[4] - extract_metadata() - qdel(SelectQuery) - return - // No ID, nothing to be done. - -/// Pushes this entry changes to DB -/datum/adventure_db_entry/proc/save() - if(id) - //We're up to date, update db instead - var/datum/db_query/UpdateQuery = SSdbcore.NewQuery("UPDATE [format_table_name("text_adventures")] SET adventure_data = :adventure_data,uploader = :uploader,approved = :approved WHERE id = :id AND timestamp < NOW()", - list("id" = id, "adventure_data" = raw_json, "uploader" = usr.ckey, "approved" = approved)) - UpdateQuery.warn_execute() - qdel(UpdateQuery) - else - // Create new entry - var/datum/db_query/InsertQuery = SSdbcore.NewQuery("INSERT INTO [format_table_name("text_adventures")] (adventure_data, uploader) VALUES (:raw_json, :uploader)", list("raw_json" = raw_json, "uploader" = usr.ckey)) - if(!InsertQuery.warn_execute()) - qdel(InsertQuery) - return FALSE - id = InsertQuery.last_insert_id - qdel(InsertQuery) - refresh() - -/// Deletes the local AND db entry. -/datum/adventure_db_entry/proc/remove() - if(id) - var/datum/db_query/DelQuery = SSdbcore.NewQuery("DELETE FROM [format_table_name("text_adventures")] WHERE id = :id", list("id" = id)) - if(!DelQuery.warn_execute()) - qdel(DelQuery) - return FALSE - log_admin("[key_name(usr)] deleted text adventure with id : [id], name : [name]") - qdel(DelQuery) - GLOB.explorer_drone_adventure_db_entries -= src - qdel(src) - return TRUE - /// Extracts fields that are used by adventure browser / generation before instantiating /datum/adventure_db_entry/proc/extract_metadata() if(!raw_json) CRASH("Trying to extract metadata from empty adventure") var/list/json_data = json_decode(raw_json) if(!islist(json_data)) - CRASH("Invalid JSON for adventure with db id:[id]") + CRASH("Invalid JSON for adventure with at path:[filename]") version = json_data[ADVENTURE_VERSION_FIELD] || 0 name = json_data[ADVENTURE_NAME_FIELD] required_site_traits = json_data[ADVENTURE_REQUIRED_SITE_TRAITS_FIELD] @@ -169,13 +112,13 @@ GLOBAL_LIST_EMPTY(explorer_drone_adventure_db_entries) /datum/adventure_db_entry/proc/try_loading_adventure() var/list/json_data = json_decode(raw_json) if(!islist(json_data)) - CRASH("Invalid JSON in adventure with id:[id], name:[name]") + CRASH("Invalid JSON in adventure with path:[filename], name:[name]") //Basic validation of required fields, don't even bother loading if they are missing. var/static/list/required_fields = list(ADVENTURE_NAME_FIELD,ADVENTURE_STARTING_NODE_FIELD,ADVENTURE_NODES_FIELD) for(var/field in required_fields) if(!json_data[field]) - CRASH("Adventure id:[id], name:[name] missing [field] value") + CRASH("Adventure path:[filename], name:[name] missing [field] value") var/datum/adventure/loaded_adventure = new //load properties @@ -191,16 +134,16 @@ GLOBAL_LIST_EMPTY(explorer_drone_adventure_db_entries) var/datum/adventure_node/node = try_loading_node(node_data) if(node) if(loaded_adventure.nodes[node.id]) - CRASH("Duplicate [node.id] node in id:[id], name:[name] adventure") + CRASH("Duplicate [node.id] node in path:[filename], name:[name] adventure") loaded_adventure.nodes[node.id] = node loaded_adventure.triggers = json_data[ADVENTURE_TRIGGERS_FIELD] if(!loaded_adventure.validate()) - CRASH("Validation failed for id:[id], name:[name] adventure") + CRASH("Validation failed for path:[filename], name:[name] adventure") return loaded_adventure /datum/adventure_db_entry/proc/try_loading_node(node_data) if(!islist(node_data)) - CRASH("Invalid adventure node data in id:[id], name:[name] adventure.") + CRASH("Invalid adventure node data in path:[filename], name:[name] adventure.") var/datum/adventure_node/fresh_node = new fresh_node.id = node_data[NODE_NAME_FIELD] fresh_node.description = node_data[NODE_DESCRIPTION_FIELD] @@ -493,6 +436,7 @@ GLOBAL_LIST_EMPTY(explorer_drone_adventure_db_entries) if("exists") return qkey in qualities +#undef ADVENTURE_LOOK_PATH #undef ADVENTURE_VERSION_FIELD #undef CURRENT_ADVENTURE_VERSION diff --git a/code/modules/explorer_drone/example_adventures/a_model_earth.json b/code/modules/explorer_drone/example_adventures/a_model_earth.json deleted file mode 100644 index 908080b58343ce..00000000000000 --- a/code/modules/explorer_drone/example_adventures/a_model_earth.json +++ /dev/null @@ -1,570 +0,0 @@ -{ - "adventure_name": "A Model Earth", - "version": 1, - "author": "Armhulen", - "starting_node": "Planet Start", - "starting_qualities": { - "Long Range Scan Report": 0, - "UFOs Shot Down": 0 - }, - "required_site_traits": [ - "in space" - ], - "loot_categories": [ - "research" - ], - "scan_band_mods": {}, - "deep_scan_description": "", - "triggers": [], - "nodes": [ - { - "name": "Planet Start", - "description": "You come across a grey planet. It looks familiar, though you swore you've never come across this sector of space before.", - "choices": [ - { - "key": "choice 0", - "name": "Ignore the planet.", - "exit_node": "FAIL", - "delay": 0, - "delay_message": "Whatever, there's a lot of planets in space. Must be a hunch!" - }, - { - "key": "choice 1", - "name": "Begin Orbital Scan", - "exit_node": "Scanning from Orbit", - "requirements": [ - { - "quality": "Long Range Scan Report", - "operator": "==", - "value": 0 - } - ], - "delay": 30, - "delay_message": "Scanning planet..." - }, - { - "key": "choice 8", - "name": "Descend Into Orbit", - "exit_node": "Orbital Descent", - "delay": 30, - "delay_message": "Descending into Orbit..." - } - ], - "image": null, - "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAMAAAD0WI85AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAALlUExURQAAAAEBAQICAgMDAwQEBA8PDwUFBQcHBwkJCQwMDAoKCkRERNXV1cDAwNDQ0LGxsaioqJaWloyMjLOzs6WlpcLCwqSkpDc3Nw0NDeXl5b+/v5mZmZycnLKyssXFxXd3d6CgoODg4JeXl9PT08bGxsTExJiYmIqKiqGhoZqamoeHh5KSkvb29pOTk4ODg3FxcaOjo62trZ6enqKioqqqqq+vr4WFhcvLy729vb6+vqysrJGRkeTk5Jubm7q6uru7u6urq6amppWVlbe3t6enp9zc3GFhYYuLi93d3by8vH19fdHR0fn5+c/Pz8nJydnZ2XZ2dn9/f4mJibCwsNvb22pqauvr63x8fHV1dRUVFcPDw/Hx8c7Ozra2tp+fn1BQUFFRUYGBgV9fX4iIiHl5eQYGBqmpqbi4uLS0tMfHx83Nzbm5ubW1tV5eXmJiYpCQkHt7e+rq6kxMTFNTU2lpaXBwcG1tbXNzc4+Pj09PT52dnUhISEFBQUNDQ1JSUltbW1paWmVlZW9vb2traw4ODnR0dG5ubnh4eGxsbElJST8/P1ZWVnJycmdnZ2RkZHp6eoaGhmBgYEBAQEpKSlRUVGZmZmhoaMHBwdLS0oCAgDk5OWNjY11dXUZGRkJCQkdHR9jY2O/v75SUlDo6OlxcXFVVVVhYWD09PU5OTk1NTVlZWd7e3sjIyDMzMygoKH5+foKCgoSEhC4uLjs7OzU1NUVFRenp6TExMf7+/o6Ojtra2q6urt/f3/Dw8PLy8uPj4/z8/Pv7+/39/TIyMufn5+Li4srKyszMzFdXV+7u7tTU1Pr6+jAwMD4+Pu3t7SsrKyoqKuzs7NfX1zQ0NC0tLSwsLC8vLxAQEPPz89bW1ujo6Dw8PEtLS42NjfT09DY2NhwcHPX19RMTE/j4+Dg4OCkpKSEhIQgICCQkJCIiIiYmJhoaGiUlJRQUFOHh4ScnJ////xcXF+bm5vf39xkZGRERERgYGJOWJYYAAAAJcEhZcwAADsIAAA7CARUoSoAAABOjSURBVHhe7Vv3W5PZnidlog41VOlNuvQOUgJIVaqURTpITygJTQgEuJQQQu8JRSAQFEaqBFBBulyxULwjgWFnr3N37uyMc9e7uz/vOS/Zv+Gd51k+mrzJm/ec5/PtpyF2iUtc4hKXuMQlLnGJPygwAFgMFgsuONEX8MKDGzgAPAYHvuPBc1gc+AU8jsXixHDgDYMRQ36DP2PFsPA2ugD8AWVAEQ944jFYeAtcwBcsHogjBhjjIW0EOOw38AkgBLiPyIpoAIhxIS2KuCAI6UJ2YkC34AseUAa8gGiAHtA1oAuogrvwcSzyhoPyAPvAT0Bm8MhFf6gBEoNMAOULz4LsIGsCdCs8gXDlKuHqtavfXoGehsVCEZGHoCmghwFbwg/IPVQBnAeJCkAGIYf8RzhicVe+EZeQlJKWIcrKySvIK8opfXsFMIeGAKRhzCANkabwcVGPaAGhBdgAVhe+cyEPAXddWUVVTV1DRVNeS0tNVVtH94aevoHhNTwIKZHVQGNwgT1AZaAsCFAw9HKR5wM/AS8M7up1BSNjk5umhmbmFpZW1jaKtnb2ig6OThqKhs5GMBVAN0NcDeYy8A/GvqhHlADVCWRB3hHFAk8Ru3rL1sXM1c3G3l2S5K7o4Um00PFSv+1N9PF1tPXzM/WHaQy0QPIXBOJjBFGPaAGJ3gt7AFPAyL0SQDT1vXM3UMHJMchTXSY4xCBUi6QoE+YUei/c2SJC2iXSOQoGBrQE9EJgUtga5fQL1ArzDiIIoljsv8hFq9+PIfpJytx1dIy1CY2LT0hMVFQnOTl5eVjYmPgmkZJDU0JgIEEgfgmbgmBBFYiLIIygcbCYBxKpkmnpGZnpsVmOMtkkaxd3NS0yJSc3z8vWJi7OyzOfSisg5xYWmRddGAO2QSILdYtc+DliEyATPttT0UMtNs3EQ91DTi9W3Uu12MxYv4RKNJF+aGpTWlpGJ5dXUBmVVdVFlciIAJR9kUlQriOIGBDQNpg/yWTJu0p7uioouLnL2JCsZTxSamrD6wxy6osYdGY5ndngTWKR46nllEZ2kzlIW3Bsg1RILBblYEc4QGXC6L2mFRYrKRcdIxGtkOpl1FzcEtKY0tjqYWBHdCw1lMkpaGPQ2zsqNDuTqOS4dFpXOKiOF2kCifaLDtECLIAgbyF8rsloqad2G3W7yll7mBV1RTaHJ7GL6msNcnpcTEJ6Zaz6OFxZM1b/AGUwn1qrX+dB84YRDjMdHjYX9YgSoEPBFxhlEEhOWSoOXnoW+qFF1ZWcJnJnU9PQo85IUqPFcHpzpIm+Zl8yxXukfDSf3F7O0+nRL6SQRdEOQwxli4iGfLBA26rYuxqmKuoU1xR1UcZ4YxXkJEorkZNYL//QR95o2KQvqYQ3XsKfSHrMEK+n2eiF6XELWaAxDo7z8X+ArAXtAcI2NO2JtIVqS01jVxUnidHkWmU22VnRm+JGkoocDnVp0Wa0jeVPMdvyG8N59WQOtSNS0TIyt/M7JF8REO9EFYhPwAH8N26Szg+NzCPNnzZxyIHTmrJ1PqZ27GjH4ZleI7niAvrs3NR8WckEf4GRQB3VnBhgBbdakuvDE4AKwHwS/WAXQzKPGOZqaqrHcIpmldlDjy55Z78Z28LEEJrmM/en/MLYVtO7fFpCSe9i/chYTmU+ObJeINdJnWgiL3kXdvHhIB6oA0xnUAWMcnihWi/J1tQULdsM2UrJGzuvPH+hXl7OvfmSVRd7002H5zvIuK+T9dhsldi9dv9VBtV31Y/Nqu3oqK5tuobkXtTnI8g8SQxzxcmseSYuMaeI3VQV0+uto7Bqep/FpTqsSce1Dg05rZdQtdhUh0YX8sAac2OhRmNzK5itOsNht9K48chABQS9qEeUAHQJPBy/EhocrLkd6ZkznK27s+udm6dlm+5Gfb22tlfZe2MztzzhfsGfxUcqHHSzht+w+LXWrpKe0S+aqk2CW+srrwKjgiKPfh0BKRgYJLjIVI2t9sh/facwZ9g7oqh6uqPgqf7a2pDsE2NlO/OR/bVX7KG8t22euRvvlDqa3e3oxckZzUvlkR2loLDDgirqESXAfIPBvC+OWustZNcneXcK7D+8Iqkox5HvpL0Ij33KfnXgen+9p60oIbpgvazmsPZoYvY78f2KOX6ujL0nj8ny8WYRgAygkIh6RAmAAzCKtZlUc4hPa1drwbSzufqjHU9OXm3AaK9hzXpdqt/WQ82d3KUq1jK193DwePGN/LA+u9R6bmouOMfIoD2Y9fgjKIp/BNfCEP7i8X2Lnz6HMVpXQmlpb9dU//TUQ3bF0U/hdYidCXFdteVkKEZftjCDIWTOWbHexNfGx5/OhjQoOEsrhphVxu8jWQv9gigm1quQlVjF4SmeJtHOKP4luxkHtKHmHCM7NXl72810l1oj45pP/SnOngvife/GR+KPhOIVy8z9MemJSuuwQRYjXwxZEBL1iBZA7sR7ZUQvdblwGKWnFR5ljawmvpxGnR+xyy0odOWHMAm2Yt0jTXqtf6YdzS3gXHzxOGX/qO+wIUmmo6O/Pq0+l5zwr3B+hXZBBPH+7WqacdKB+Y+nEzPudJ0BpkmeAqVrKScgbP3Jq7fbkcVe3uNtTLlOmRd19HrGlHDqDb004bD95vfjTVE60vr17aw5WBLRXqDD4nH/phiVK93UWZI/sTBBPmHyK83WqJxgU//Ym8qCv+osVfFmyOOD3RRKaGFL4uTxsdLHzyzmwPh8/8Jc8GSWYjGfwYMrMWgvYoNaNq9mEFWxS/2z822ryW6/WjLfuLl62vmpx55GhP8LFwZb9nFl9T6XO3g43t45uEiVPWwbf1/200ZD/MfRRFq4eUq8EHSDdvqFC6SOduxQn44twXTXfcrp/j5zUPVpWp1qVl1i8QGls4Iyk6TVuCBMosTOMmbfr5fRS2TH//Z+nLW/MOcfH9/CKuHWx/87UAfK6RcvRhBLU60wz/b/8UyuulFIbxsUiiv4mzWemTxVtywI906K3R0da+kfSeKe/fz3Kepx2+nnhF82kuhtGxOc3dLBWiqVq2/+H7C0i3pEC6CYGdU2sogBMiW79NNBlnAmOtKycKkxMS7Z+GE1hUyrZXNoCe1KCa37v/76/tf5o3nSeVFfw/ynQaGQMlEvHt+cz6H8huySoAs8BpfTKKd/y/LLWM3uqyc5mRarasrsLP+Qs2KfmfqoyqZITc7uxOBC2/mRdXOb1uPZjxsOybUNIy4VG4f7pQ1lgxMJ5o+n4HK2qEO0AMqIUe9MJaOfUjAd1NM0QTZSeC2zpd01k+Mm+3DVgrXL6WK3ttPL+kJ/Lj/66fiX44HRqcq++e9mp5vaGgbmba3oCfHxU8jkClWAmR1uUs1qTKde2Hraf9o6zqT3L/Dzi16l2BFvVN1uTuAyCtScd8vzeRv7Skq/MxYX2tlzHpaLZwaU+aONNyOawtIx9ug+TH6iHtECmBOF1Yx6U3nJ3vw25sBgA71P3GefubK6qhP56UCu6vvRrl075tzhqNLI8bvjN+9/mp17MxAg0zgf7iycH8jnDjDKTxlvcGjv8wCPwIqptYyyC6lWkyyuf//axPxI6VwXmRH4yTS72OsggJbNJVfEM/sP90cazgd9j7qP2j4ezp0PnYZPt/PL2g7HO5jU3WMwG0C5IMJ1QotcMo89xqk3cF8OpQnP81vPywZZ9PQvm1Ivt9id0dE8XmFZw8bUhnD+543O38c3ZoU/HZ7fPKYJuz4u0U9p4tUVfwPDX1GHaAGupVsaRybNcAwqTIhSghc/HGwX9Q7MuN18GhvzSpDVWNnlb8kNL9Ueyd+fOp6aDx4fOacuvlsIb4ig8xemyuhzzp0c1m+gHKEd7ACVpsO2vg8L9M3bJYfsBE4ZRnsTvDF+0s31OJt1gWCP9GrtB4kT2b2Ss8WgI1JwVFKC0nxZwxvHwo2C895zJfFKGhmP/rYCmG5j/2SZumeaYbQbOj6u5J0m9YGSEt9ZMdA/ypp+cUcARBEI1tdud9EY9KN31ZTde+eSa4cj5/PHQbP8+ZziBdau+fhFrKEKuD53LWPGT9lGr0b4OfTO5yS9cGNqH6czl8eqTKpMvvOPm4L1dcErga7AiLR4PkBZMmPx3aO5i7XzY6OG5xtl/JDgsRFkiijqESVgcATMg7CHdfoHlqzPPPnAiCRdTjmZ+5FeoFlEi+CXnt0TCJ5AowhuRvicPz5cdJdtonqb9fWZjIzotgoblOg0dv4R3KhGWxAMDouXkzR8MvSJF+XLTPLypGoPHC7+MuftsqKYYU02Zar2rAH3WhfcTbR7SpkN1ow2s6R0938mFhbqEvv7Gug8FvM/4TxT1CFaAFMiMcJfvkau3nYgdtHt26PoA7c1eD+dv1NVK3DsurO735edhwgSlDbsN87LfctNXG1WXRLGM6La7OsW1BvmeE1CkDCATUQ9ogS4bIDDTFY/e7FF45U+0lIDThROO/39ffpEaHqgYNjt8Toix1v3peCRd2VVxu0DvTLLfq9bJitb3G2SS5TqExgNcKsI7fkITFs4fKq/6j8j1AqoGvnxE5X/XKPkvZvqPGoa3Vz/BxIer/56MHjn5GtZ226A8fLE/egwn2lJk3DrtJUVmrh5vPhvIPeinrVgvgFR8pQm+fpuSEmwSik5yF1qvUBQclotqbyWCDLW+vc/Puecve1dVmiVTSvTIRm8/XDgq/s8RifRzTNnxrgtfx7Zo0bdteCREixOq9f59cvH0bbFsr4r5muZgq3egKbMZ8pnaxFbsZ53R0nj3fvnI7IjL2X6MuOz1YcMg4PTonVv2OoP1zEnFpFNSLQtIoYlwANCD/xVt54nOw7Hdc+Yq8hWCVLTc5ZvBL5c3Qxc+5KpbRgXM1M75tnP6pglVUaahsfQwolxgd1+VfVVdhNTYHIIgh0EG6oAyoTDLYzXzj2FHdnNEm3vqPLOptUtqcagGxoKt5e/fHqux22ONniZ7h3V9rCX+7mtTJ/PORTuV0tbyFeMMhsH32PAJBMeeRL1iBLgXBuQwF4xkpoM285jfA2KumsUuva9sor2CnGjJ6On21KPk7m3dOaue7Yx+njVlK30hj1eOzJY3mw22p/AbxTikeSL+moQUCQ8t4AV44e6xgYElZq9dYsrTNl8oq2hntlTdK6ncPv1I6tdTnfc28jS/sdhFk3qvLa+8c+HNCtyF7+/g0L9L7g/DUY6qI+1EMciAKUq6ixFSewNW259eBQbm3fL0kzXZsDXMSjolqFRYoxCrOmms4rCgs5dGfOpo/d1BdTppSbxdg63DwgApv3oL6JAY8ARsBj2gXQoW3LS8yTww3JpbHfGfVt1Y6tgnR63WhvzG5LqPbm2mzqNz3eNUnILbbysLGQUNRb4EwVjcNMNSAHVIeoRJeDxkAUchj/4b6vCsbgKhc3RMxdvfyvHob2hneU8bbkbXtvLX3Xd8yRizkyydb18ZlSJ0k7u8h5LUR3c6v8BDZHTmqjXEcAD1hIgDBar5JfCLZFWubdiwcnu7CLdf7YV8fIL0Xx7Tzni7TOVbNtYLXbL3WxDV3XPuGk14llyZOUG0hD6FTzHjSrg8XFQSOBICYMrckrvdi3RuJduveN7K/3e5snbk4BntzbzTj6s6gZIbA75RQ9ZOctL54aRXIiyxilsIQFIAccGePSDBIggOgQHh0vNRu4rH7aDeuylvj6z/+qbemPoYGs1ImIzQOFr3qPV58/UJdKzYhzT5UgrsgbBnX1I4oaCwCvaGz2wmMEdfygLnnAeZ2qbHbB8sHrvIEb33pbyXs/ml1jlHyNOTk6+fvmi/akmzHFbJazl7GymqpUPhABJAjQE5iCgnX4BCeBZ0CZwcoTFXvdK17grEXRb+9PywXLy5smXtx8+RHw9UT450f6qPfRpp9vBU8M9n5scSRPCOQg8zAwkAS4mhrJFYF0G7gU3/KFSwbuPiruf/aT9ZOaTgJyI27fynj37+kz71vOh5b2dT9sK6bbp6bY6Z8HVf4cNAXuYu4EiUN96Q44owUIA+UB3x2B21c0MXR0CYwL2Apbvra6uPh8KWh7a0e3Zjgnc8bT0S1VsaakagyejLqwBvAtus6C99gtVikfMAidYwCSAEIGY2Oqqty2VGah7sHw7SEIiZifaflvjhkqsq4OXl0ViXesxeBz4JDwuCz7AtSBwFfWIEkD6BHzAoA8yQxhBxycY6Lj6ZU3qdTtmSu1k7NydlJTMckhLy071MvQwo8TDBlAEaI2L2IL5S9QjSgBk4J9bQDogRqCzYB9An3lAJGZl2TplOehFq0Rr+MllS2evyLsMy9qZ/wxMB10QqYXAqaB7wcSH+q4usACShC+SEHQSJB/jrlx/aEUikaRtw5ykV0hO1k4ePsmaVDjxgEkO+BOWAKshjC84QEF7XwH4E6CNA9aA3gIiBtY2KAvki7t6ne2ib+ShprMUatx7fIUA70I/hC4Im0EtwGHjhZuhCsgCVmbkAudY8Ab8gtAEqscTMAQCDAqodzASgaIgxGEb+Bn8iEgk6hAtAAaQGx64CxzFimatiBiAJGRIEBkA8T2kkP+fMUAzRBEYkO7ARdQjSgCcEPVDDwP0YHWAwY/IgvCHf5wI3QkwBz9B+kAYMBaAqQFKD4UAv18hoGwSRJWQPbgAftAMyPFZxMXgBSgaSAF8DD4FkxwQCNoBKSFAVKgJqA60Y+QSl7jEJS5xiUtc4hL/HyAm9r+XXnYR5dlv2QAAAABJRU5ErkJggg==" - }, - { - "name": "Scanning from Orbit", - "description": "You initiate a long range scan from orbit:\nThis planet has a smoggy cover that blocks any good look at the surface, yet it has a mostly survivable atmosphere.\nThis planet has zero life signs.\n", - "choices": [ - { - "key": "choice 9", - "name": "Stash that Report...", - "exit_node": "Planet Start", - "delay": 0 - } - ], - "image": null, - "on_enter_effects": [ - { - "effect_type": "Add", - "quality": "Long Range Scan Report", - "value": 1 - } - ], - "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkBAMAAAAxqGI4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAASUExURQAAAP///1lWUqwyMmlqakZHRwPX/kkAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAL5SURBVGje7ZldbqMwFIXtKnkvO4huyAYmG0CWea8i2P9Wxv/Y2MTYvjBVO4c8FET8+dxzDW5Ldqr73Hcf7fbemfwu+p1tkM+jILTbfeu2stNbDDSkklXnzNRbyUqUqbM/oVr5AFhOus5iUK3A/fmEW0BRHjCtwFPqj6NQS6GIVu5PTXEXnJUOjfLxXEOITYWitXECQk6BUOx6pSDkKAj4F6mrFxLEdNctAdl8gJVmBRBXy6tXcrScwwvXsufikXIP1qId5t2iz0D4osFClAga5MJDDbJaEUDJjF6eyZohxATjlhym9kkcMzhkIBQJ0g+pe2klJFWtG4DrgRSkeEUkjDDWA09TbPJdM6RXnySlDnLpYyO9/GhtQChthYhSMXeyup0aSFkoCYirVqJkdcnHEMaXakVeHIQUQYBPwSFdMB86IEBYolrAtyi1kF4asOIT40Ekq4JVQvS0R3UYI5G5GFLYwuKRO3l69dMEkxnc5MR8K6RCF9VL2sioe2tdLc6GRggROUDve5lcA9usXpw0So4Go5OwE0YySqutED33eZKH12TSyJJTK0RNFx6LFb4yMiI4uajJQmxlWT3tTsybEfxUnA0t9miGmNnCY54DMxNiJu7V6HLx89BO2iHLhIUXPxUleWVjf1SiZbvCHkEuLqX0brIM4hUfwkxERkKvdiPhxksGw3UuNpERmpuLeKGoBRM8k5WP/gsBsnrkAphUVGOJHeuIwPBDMcks6vmAUazkbtjXgAIhqVW+QHAYZHxnBIkRheKbGbAgJH6NIAcitWFlwmQQck28EzEDUdqwQnClrIxH+pA63od1EpgpHiP7i3ccSjEj/yd258SYqendLCR0UfcCyUK0B9KkbCYNBnZLRzIcC9HNdSzDODkYoraOB0eim+vgSIjcKM4HM06J5Hqak1Mi+d9ce3VGc5Ef01zXM5pLQN46oR0O5G0kKP+9nM+CfP1rSDqTwqTqmqvQX91SLINcvzGkLJPrCev9HMj8oyDk10MI+Qt3vM7Ve2h01AAAAABJRU5ErkJggg==" - }, - { - "name": "Orbital Descent", - "description": "As you descend into orbit, you see a flying object headed straight for you!\nA garbled voice begins to call out to your drone, but there's no time to decipher it!", - "choices": [ - { - "key": "choice 2", - "name": "Blast the damn UFO!", - "exit_node": "Tractor Beam", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "Tractor Beam Turns", - "value": 2 - }, - { - "effect_type": "Add", - "quality": "UFOs Shot Down", - "value": 1 - } - ], - "delay": 30, - "delay_message": "Blasting UFO!" - }, - { - "key": "choice 3", - "name": "Attempt Evasive Maneuvers!", - "exit_node": "UFO Evasion!", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "UFOs Violently Crashed Into", - "value": { - "value_type": "random", - "low": 0, - "high": 1 - } - } - ], - "delay": 30, - "delay_message": "You attempt to dodge the UFO..." - }, - { - "key": "choice 7", - "name": "Do NOTHING. Jesus take the wheel!", - "exit_node": "FAIL_DEATH", - "delay": 30, - "delay_message": "What? Why?!" - } - ], - "image": null, - "on_enter_effects": [ - { - "effect_type": "Add", - "quality": "Garbled Transmissions", - "value": 1 - } - ], - "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAKgklEQVR4Ae2dW5IbNwxFtZFswouI//ORqmwgNbHH9sayoyxGKcz4jiGIJAA+ukk2VKUCHwAJkveILXvGvv393/0e73324PfPn++ld5y176xvsWG+DZt9v0pwUN/s+c+WXwCy2Q0agPT9wAtANgJEgyNuED88AUgAEo9dBQ0EIIXNme15WMtHu0G0+Oh/vmECkAAkbpCCBgKQwuas9Imq3R7x/eP5drCcbwASgMQNUtBAAFLYHMsnzCw+2g0yS56r5RGAbACIBkc8XtU9XhHMAUgAEo9YBQ0kAblXvla7PnfJN26Q+htC08ADIJVcPIVpk0Z/vwO1wBGPWPX7/QbIk8IbGwKA+gPx7p0FEO+Y4f/r/G6NLCTDazc4ORhrrB1317h/vnx5+9F2aSU0u67/iHVNAQhjQC0esSmrzCFByNVXWc+MeZ4GiEpCwWHGjTwjJ3lz5Opn5LbLnIcDUtC9q2uXA6hdR+62kO2140fc+/eQQwBxKd/hfOVDJBByNwZvv/Ie9Vj7UEAcWq927bEJK44hb4pcfcW1zZTzEECq1V4ZONOGHpELvyG0m+SIfHaeYwtAiKudD0muLXdbpNpl7E712+12t75r170NIFeCxHqD1Ipiljir+D1+3rVtBcgVIEndErk2rxhm8U8J/v7b7W59p+J5m2ed2wGyOyQEw843CBcyL1vhkH58DF62QrIlIDtDkrstZLtVADP5cQHLshS+tS7H4XXL2rcFZEdIrDcH+VkOfyYfLtzacgoabSxtDwKQwi/LaJt3dH/p8Wr1G0QTsqefg6LFaWcYgCwCSAkOebNohz5bvyZiTz+Hg8parLYXAcgigEgISnXt0Gfr10Ts6Q9A6MuF4TWbCFryKcGQulla5jo61iN+zdcLB42nrXeqG4Qna2Ag68LH2aGcgiAHzWrr1URv6ZdgoG6J1fZrCkC0JKnf+rKMtZKPBw6CZqW1Ua4WEed8AELK5mJku7ZfpwKiJSf7U5BIn5nqXnH38J9p/ZZcpGC1egoG2aaNwfu1HE8DREtsxX76BNfePSDY5fGKzpiLVStLEGRdi0/1azo7BRAtqZX6c2I9o32lfUOuKdHm2iQQqOf8tXbkULIBSOUf82o3hbe/x81SOuhZ+zQR834AAcv7vGXrfhwOiDWxWf3OuBks8My6X1peXmH38s/lxccnnyH/cFzqyzTaconN3u69EXr5W+AAtLPvYSo/Lsijyqk80PaUAzog4NEW861iIb6V7Cp7S3k+CdLxW4I1sdrePI3JA0bDQePz+WYu97oBeo9juVFm3leZ25MgC4DguwesJ5Z85dy5+sO4KaeRoKTmm61NitoiyhlvmNn2NZXPgxgLcJAfwID1xKbmLrV9jF1yulqfBGOleg7iFc7wQ4yDAKndg7e8aoN3ivOCkBPjrO0rnJUFEtwcZC3+Pdb98P+D9BhwtTG8cKzmD2hXOBeL6C0+Pdd6WUBGCB1inNH2FM3osSwQ5Hx653ZJQEbAscKYvcUzerwcBKn2UblcDhD6dP/rzz/enmGlqKl95Pvsm2WUiFYcl0NWyv8ygECcJQAIGPjlLKBCv6yjXdrUvIg90pbEcKU+DgiVc2u/BCAQqxQptefeJFrEjbAyl9HzYfycEK7WLgFBXe7D9oCQuLkYa8WOT3nEoy4t+qWFn2ynOs8PfiOtFMFV64BCWr4fWwPChUdlEqP2JmFyH9RHW8zJc6a2EfNyAexU5kK3rovHyDKNsS0gXGiAo4fYaIzUG2JGH+otFmvAmL2sVTyr+aUEbl2DjP2oWwdYyQ/C4pbElRIrtaXac/68HYKtjU/FIR9usY6UP8/H07/SeVpz/RA1+5EVayz5peK3vUFIOBBWjYik+FFvtR4Ry7yxHrKteXiEs5JvSuTe/B/G8Aav4k8CgqBaRClFOqpOOfI8UU9ZrAuWx3nyW+UsvXk+CPznbeIdg/zfxqkJXCGGRAMBeUQjxUaxPd4YF2Oh3mr5GjG21a5wjrU5doOkNoHZ40gkEE+rCBEP4Vnr8GuxFMvjc3WslXLk/qX67GfYml8KEmrzjHuZ7yBWccPvKGsVs8UPkJC15u8Ry4q+rZBcAhCLuEhQVr+c+BCPftR7WBqDj1OqAxRLHiuK3ptzCySXAARC4RZi420jy/JTXc6Pei8rIcmtzSu2lf1ToGjr2RoQEgUJpVZ0EBXiUfdaKVaMN9piXrI8Zz6vJpDd+r2QbAsIHSyJQoqDC+WocimHUh/lBzEjV2+d4miO0jy7QaCtxwPJ1oDQRnFheMUl/SFSq6V4Lk6MB4s+1EdazMX3A+vQBLVjvxWS7QGBCM6yKUEil1IffGABj7UOP2kBCm/fEQDLmiyQbA8INooL4qhyCQDelxM/2mst1ol41CUk2KMrWg2SywBChw+BHGGlCPmcHA7efmSZ53BFMPiaS5BcChBsyhFC5AKU8+X65Cf9yDrlgDywL1e2OUguCQgJQYq2Z52LT44LUcr2M+qUy0vF/2to+adpV4QtBclpgPB/Je+szRwlyhwEufZReWjj1gBigYP7eM+Wx3rK3nly/k+Q5BxHtnM4UB45n2VsTUzW/hwE1J7rs47dy49uDXp7AfEIVvpqZyD9a+vaPJb+B0gsAb19AAW3veeoHa9FhDkIcu0tc9XGAo5fgHw1/XRrrWB5XOpMeH/vcmo+T9sbKJ6AXr4cDJR7jd1zHK8IczdErt07fqs/h+Ply9f7y1cbHLSnvV78fHqNWRqHz1dTPuU7CKDgtib5o2IswuS3hCxb4kf6PIJBj1cEx+v95fXVdHvQPvd89R5Py61FJwGI43+5LYkYUMDS9YxyKW5032xwaGIe0R+AOETeslkyFuIGCCkLnzPsIxzvj1TvN8c3881Ba97hJc/OWo8bpAGuFBCy7QwwaM4kHK+v95dv3+8v339cDhCC3AoF9wtABgIyDxzv3zdq4CCx7PLiwreWpwGEvrBbk57BT94Usp7K8Qhgnm+OX3CkcrK07QIIrcOyXu4TgGRuECl4T51vsKXcC5wUHJb5Sz47wbEMIHQg/I94ebl0WEf1AYZ/P326l97wk7ZHnl5oOByt8+8GhVyPZ39OuUEoQQ4FL3uSH+FLYi9BIftGwDFiXdqYUkQ717W94P2nAUJJcDB4mSd4ZNkLB2ABJEfm2jLXzuK3rM2zdwHIz+8gEDlE77UU79n4I3wtYrmij2fvTwWEEuU3B8qeBfTyrb09ANIMgFxR7N41e/VyOiASEu8CevmvDohXKFf19+plCkC8SY/wD0CugYxXOwEI+w6Cx6Uae/Yj1jXkXbdKLxTcPwDpAMjZcNCBxiu/A1zw3vI0gOALOlnvInr5k9C9j1qI6ZVD7Th5eURP7Z5S3BSAcDhQbllUayxEn4OF97fO1Ss+MEjvQOv+BiCZn8XCxnIYUEbfTDYtj2htPaMARAGkdYOPjN8VB+yhd32Ia7FTAEILwKPVmd9BWjZyhlivgFbwl/tqzVnG1danAaR2ARFX/h0Hq6Bm9JvhbAOQjR6xrILqBQPm6zWeHAfjn2kDkAsCMkJwUtwt9RH51Y4ZgAQgp/29U61oj4wLQAKQAKSggf8BsnyFPjzLbzcAAAAASUVORK5CYII=" - }, - { - "name": "UFO Evasion!", - "description": "Were you good enough at flying to avoid the UFO?", - "choices": [ - { - "key": "choice 4", - "name": "No, Back to flight school with you!", - "exit_node": "FAIL_DEATH", - "requirements": [ - { - "quality": "UFOs Violently Crashed Into", - "operator": "==", - "value": 1 - } - ], - "delay": 0 - }, - { - "key": "choice 5", - "name": "You barely avoided them! Nice!", - "exit_node": "Tractor Beam", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "Tractor Beam Turns", - "value": 2 - } - ], - "requirements": [ - { - "quality": "UFOs Violently Crashed Into", - "operator": "==", - "value": 0 - } - ], - "delay": 0 - } - ], - "image": "default" - }, - { - "name": "Tractor Beam", - "description": "Before you have time to think, your drone is captured by a Tractor beam! Now you've gone and done it.\n\nYou should have some time before you are pulled in.", - "choices": [ - { - "key": "choice 6", - "name": "Decipher Garbled Transmission", - "exit_node": "Deciphering Transmission", - "requirements": [ - { - "quality": "Garbled Transmissions", - "operator": "==", - "value": 1 - }, - { - "quality": "Tractor Beam Turns", - "operator": ">", - "value": 1 - } - ], - "delay": 30, - "delay_message": "Decipering..." - }, - { - "key": "choice 10", - "name": "Look at the surface of the planet", - "exit_node": "Looking at the Surface", - "requirements": [ - { - "quality": "Tractor Beam Turns", - "operator": ">", - "value": 1 - } - ], - "delay": 10, - "delay_message": "Looking out window..." - }, - { - "key": "choice 13", - "name": "Let the beam pull you in and dock you", - "exit_node": "Landed, Kinda", - "on_selection_effects": [ - { - "effect_type": "Set", - "quality": "Tractor Beam Turns", - "value": 0 - } - ], - "delay": 50, - "delay_message": "Getting captured..." - } - ], - "image": null, - "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAIOUlEQVR4Ae2dW5JcNwiGewdZQNbgbcTbyFM27ZXk6aTkmDJDIXSDIySYqi5dQQL+r0/PeGx//vnxPPnKHKQGeA18SmJqX5k0PmmZlzh5+dTgoPMpijiiyFr/rnU3IBSYMs5EZg5u18ASIAlNApKAcBRMzN2eyIzvzjcL9SfICDspqjtFdVNdtwKCYbopqRnLb/BxjXH/lBy5AQQnr/RPSWD0e9K69Y5PyZtbQHCie5KJ95d+j03uGc8TzfPs+JTcHwEILgJNLF5r9altjvsBaeV2dP2U3B8HyGgh6P5TCuPpnjSHGmNP8Ul3SUDyd9HEj6MaMHA+JFF6WktAEhAWEE7UmnOeIJDukoAkIF8A0YRA8iWJ0tNaOEBK0TwVwNNdJEFrr3mKW7pLApJPkJ9vGNoAtPxJovS0loAkIAmIoIEEREiOp3cy67u03vG9rFvngfoPBwhNQI7//57MCwAr97CoZQKST5AtH7FWQBixXYUmFCCrybrZfkR0J+8dreH1gIwmJOr+k0W/cvdWva8EpBV0rvN/FrQitNtsQSPXAAIBZcuLvycvt4lcIx7x38XSOMDKR0/Bc88YLFa1OtnvT0BASN4CgXtlOyb0lXx508Du+3wBBBL7xqXgrFPbv75/fyxfu/LyRu1POoMFBIpjGQiccVJrCUTL95t5sqz7ab5FQKAo2kGB31PalnjfXn8jb9o1P9VfFyC0ILPBUj/ex28Lf/Q86/zN1vkmuylArAuz2/+oUL3t18yfpdjLPb1/JSDod7G8CX31PhqgaAuY3knbv7a/BOQXIKti9GpPBTkzXhFdz3kr/q1tE5Afj/jj2m/fvj1Wr7eg6hFpa09LiC17ab3le+d6aEA4gVrB0OuXu5PGnCTQ3Ws7AWidHRYQKrpeAe/YR+86O94NgnR+S6i71sMBUhPXDuFrnlmLC89LAvWwtgsC6dxQgGCx4L6mUHf7wnFxfQ8g1O4gCXXXWhhAOLHsFrPl+Vy8Za4mTk/zu2Dgzr0eEE4olsL04puLG+Y8wdBzF064b81dDQgIgrZeRGx9Dxo3jHtE6XXPG2Dg2K8FBMRAW2tRevJPY8djLIIT+1qgtGK/EhAsBNr3JGDru9DY8bgljFPWR0CZiek6QLAIuL61KD355+KHuRmxRLS5ChAovtR6ErD1XaQ8RBT7TMzXACKJga5ZC9OLfxo3Hs+IJaLNFYDgwvf0vQjY8h6tPEQU+0zMIQEB8VgKdLdviLHWzoglos3xgNQE0Jp//vzjgZemmD+fz4Nfmr57fbViL+sRxT4Tc0hAAAzNFkPB9XvFvbKvBwzYMyOWiDZHAwLFHmk1ocC+OCjwHN5r1R/JQ0Sxz8QcChArYWIQpL7V+eA3AdH/FyjDAAIismglKPCaxdngM+HQh6M8cY4FZEQQICKrFkMg9a3OL35H8jHzUSOqTQKCfpo1K2AJCrw267/HLgHJJ8iXH02OCKJHYKt7MAhcf9W/ZD+Si6hPgtm48wmi8AQp4uWgwHOSwFfXEhCbp0eBKgQgRUCrIuy1x1CUfq/dyr4EJAH58vGqkD0iCrp3RYwebWl8tfHsx4zIdmGeIDXReBT86J1qsXHzkcU+E/uxgJRgOQFozI0KdOf+mXhnhBLVJgHp+K/UdgLQOnsGkGITVfCjcR8NSAl2ViBadi0BW66vxjAqloj7jwfEAyScUD2Dge8bUfQjMV8BiFdIsBChvwoO+NFsRwQTbe/RgPz79/Pgl6ZoovmKJvzeeI8EBEPB9aOJWzPeXuFE2XccIBwQdA6KpymcSL4gf9ke9qsmFARpTIsbSeCrsdLcRR4f8wSRYODWpKKuCiiCvZS/SGtHAMIB0JqDItJ9ME/bCKIfjZHmKOLYPSBU4FrjVrFHxXTr/laebl93DYgWDJyflcJ6gIHGZHmnlVydbusWECoAi7F28SxFCr5beYB92q12rk7x5xKQlgi01nuKRM/qsaF7tMRK78KNtc6ifmhMUcahASkCqxWaEx+eq9nReWwjnUft6Jj6kcZU3FpjeqcIY3eASIW3WKsVuXVWzQ7mV+3BT2lbvui6FhCcH3yvCH1XgNBCvzXGhR45E9vRfssP3c+NWz5q65ywNee4u946l4Cgj1k1wdXma6Ko7afzq/bUH4w1YeB8wf8LWLv/TfNuAIHi7mhLQWfO5YQw4ofaj9jW9nKCtpgDSHBL47lh7AKQWrG9z1MBjN4X24/a1vaDTwsosE8MRq0Pdzm53Q5IrdAnzEPhZ+9a7GdtOTu4D7RY0Bb9Ghi1ebjXSe1WQLginzRXCu3lvpzoilAtwACfNRB657k7e5tLQMjfSuwV/AlwgFBB0Not+NdqvcFR7rMNkF4h5j75KcWJihOsNhzgjztLY46La8fcFkBS9LLoe/LDiaUlTBC1Zts6U2udi/eNuQRk8iNWj4gt9tRE0SNETTDAV8+5WntqsVvOvw6IhWgi+JRE0CtAELVm23u2xj4pB1ZrrwISQcgWMUrFrwmP3gP2acJRfL35JeXBai0BcfwRSyp6TZgUDDo+DRApB2+svQYILVSO5W/Ua8WvgVHme3LqHZBa3LvmExCHTxAJgtpaDxywxyskuyCQzn0FEChMtvK7fE38rfnRvCYg9b8oR2ExB2S0eFH3tyCorc/kyyMgVJhexgnI5o9YNeH3zM/AUWy8AeIFBu4epoDMFvBtu5KYt88s5618zd63nKkNSPG38sUJ08tcaECgCLNiW7FbEdTquZ4AgRp4bcMCgguyIrhR2xUwiu3oeXg/nJ2AOPkmHRfHU/9EOFbzB3BA6wUSXAuP/f8AHPtbaN2iPfwAAAAASUVORK5CYII=" - }, - { - "name": "Deciphering Transmission", - "description": "You review the incoming transmissions your drone has gotten. These aren't in need of deciphering, just un-garbling it from the bad connection...\n\n\"You are in Space British Air Space! Identify yourself, Tally ho!\"\nWhat the fuck?", - "choices": [ - { - "key": "choice 11", - "name": "Whoops!", - "exit_node": "Tractor Beam", - "delay": 0, - "requirements": [ - { - "quality": "UFOs Shot Down", - "operator": "==", - "value": 1 - } - ] - }, - { - "key": "choice 12", - "name": "Good thing I didn't blast them, then.", - "exit_node": "Tractor Beam", - "delay": 0, - "requirements": [ - { - "quality": "UFOs Shot Down", - "operator": "==", - "value": 0 - } - ] - } - ], - "image": null, - "on_enter_effects": [ - { - "effect_type": "Add", - "quality": "Commercial Airliner Transmissions", - "value": 1 - } - ], - "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAALM0lEQVR4Ae1ddegGSxU9WBio2AjPFluxAwvEThDFVp74nt1iYHd3FyZ2Yj1FfehTEQPrmYiFYmF3Xjmw+1jnN3NndnZnv+/bPX987Lc7s3fuPffcuzGxAGD6CQNxIMmBZIECR8lDHFDmUIIQB1wOuIXKILqKbJ0DChBlUHHA4YDAccDZevaU/SKHEoQ44HLALVQG0TPI1jmgAFEGFQccDggcB5ytZ0/ZL3IoQYgDLgfcQmUQPYNsnQMKEGVQccDhgMBxwNl69pT9IocShDjgcsAtVAbRM8jWOaAAUQYVBxwOCBwHnK1nT9kvcihBiAMuB9xCZRA9g2ydAwoQZVBxwOGAwHHA2Xr2lP0ihxKEOOBywC1UBtEzyNY5oABRBhUHHA4IHAecrWdP2S9yKEGIAy4H3EJlED2DbJ0DChBlUHHA4cDhgnM6wI4B7MKAneUAMv0ZALtA9zvTAehL0pwdsEsBdj3AbnAgOjtkr7kaHkaAXAWwxwB2EmDfBex3gFnw+ztgPwXsU4A9BbAbAXbGHTn1OoA9FbDPAfZ9wP4Y6Erd/wLYTwD7aGfbdQE7dUN9T9MllCsDdnPA7gHYYwF7KWDvBuwzna5/juhKfT/YULeZSV0TCKlz9jdALgPYazvSh8EwZv91gF11AedeC7C3APabBMFKdP4XYC8E7JIV+l6sC0pi9iHAvgzYzwD7zwR9hjp/vkKnPSZ+KiDC4/sXIOcF7MUzOXXo4I8Axuw5t9MuAdgbG+j7dsAuOELfGzfQYYgfr4RzY3cA8vbL6EcC9o/Gjr73jI5+bmNdfwvYbQv15VVySOi5//++UI8DIP2YQN+fAHlBYwcPCcPbkKmO5O3UUGbL/88q0PeiC+gzFbMDPH86UeYw+m0LODck8PMLSBez7VyAfXIH+j48o+/ZFtAphsfKj+0+QD62gGPD4Oj3H5ohXej8MwN28g71vUNG396uVttTZdoP8VrB/m4D5GU7JFtPIr5eLXXke/dAX/b7pPTtbWq1PbfTdkqnAz+eBru1YQ/ZA7KRSB8udPqz90TfVzr61gQG+46eDtgjALsnYLfr+pCuBtjFAWNQsFO2NR/2VP5uDL/6npCtJ9RNMwS4zZ7pe9mEvn+o0PPbCVl7StilA3U3AfKeCkf2ZG6xZe+7R4gv7pm+b07o+4MKPRlUnu0bL1seHI7rmYvkqWERNfLPmiDK3WbUl/0aNbqF5/w8oeuXKuWfpxvTdjnArgkYbX4iYByF8LhEWxsJnOUD5IRKJ/Yk+R5gdwGMQyvoJA5U5P0ye577OjXbWyWI8M2Jcr/QjQ3re8XPAdh9AZuKw+Uj+nJcV43t3jlviLSzkeAgv5YNEGYqzxm5Mg5Y9HQmyf9d2UasX2Rq7/SbMvoeV6krcXpQRPZbJ8hLYf+BSDueD1ZW5hNubmPvOsGBHy901O0r2/h0RD5Hu6aIkztO8pfgx76YnKxYOcd/hfI5MjdWd8qxz0baCdtd8f5RkFsay4fLGmfx4XOMXiT72Ha+FWmDQ8DHymH93EN/aMuPK9qJvZ5+UoWcnH3fieAS6r/i/XHEmwoE5z/kHBIrf/JIJ3G4d0yOd+xXQRucP+HV98pKrx49ni+vaIvPNv35/Za3XZ5eNWUhLn1bG9keBbml4X+tdCDffI3R644V7fw3aIPD7msIxXMuFMjK6f7oirZiV9Upt7ApWzmfJKf/isuXM57jmFJOyB1nj+4YJ9y5sq3hDER2xuX0SpWP7Xmuedb5RQSTm03QOWULj4/BfmV1lzOeY4g8J3hl1x7ppIdVtPW3oI0p/TXnC2TlSFPzcB3rAb9Ghd0e7n1ZTv8Vly8XIJx51wM+dpt7vRs6iG+8xrbB6alDOVNm6LGfZigr95+z9cbqG3u7xCvtWDkl9cdeEXP2HlD5OEdOMYwrZJQ4I1aHnYOnLyQdR+fGZOSOcRj70L4rVsphOycGsoZyw/93qmwn1j9xzkpZOWz4PBbqvZH9ZQ3/5wQHvr7ASefvFivIOTxW/opAPpcUitUrPfbMQF6MUJwj/8vKdjg9OZTJ+Rql+o2pd+lIW2HbK90/CnJLQzm0eoxjwrpcnoaZPaYje9F5pQnPKd0P537ztqL03FQ9Tu29SEJfjnfiPO/UubnjqZVacufVlI99Boz550CPxcnWyph3TiDE0LGcD853/hyGzlek759BLsdIhXazr2HYbu1/Xv3uAxhnBD6h60islcXzvL6JKXJ5Lm3mMxyT0au7cWRXimATYrXS/aOkaGkoFyub6sAW5zPgYnZzAboW7U2V+YyEvrSBC9LVyI/Zr2MO0C3A4TNCjfNan5PKkFwhsXXbY+VzcTlv6mvtaIUW/l6BzHjmbGnY1GHeYwmVq5+6evQYcIxWTsaS5d7Vgzp/tVJfrorS26ztKVic8mcxcK5f6cAWJPyT8xDdk+TYPdKXAwe5CHavW2z7iUp9Uy8TYm1s6JgPdisg+A6/BeHHyizt0KvNymP1ydUvGZNW+yKEC4S38vcBy90NKFcAbM7psjlixco5grbUcVzUISZjyWOlownYn1OjF1fDL8VjWO/+gL0KMK628oACGeztfxpg7+oW2+aKkEN5sf8PBuw1gNE2vg2M1Wl0bNHG/s8w9lvUOHKOc0o6HUPA77VDfUuWHu31JflqMMotStfLH25jK2K+wyEwg5Bj3ob68TbXuzLydfOwPv+nFq0Y6jbT/90FCA24X8T4EIy598dcOUKQ+c2PufXJyePiCaEe3n7NQE3qwHnyntyw7HgHi1SWT73w+Fqi7Qc6bfDZMNSpwf4ijbiGzLlqSI5sz5sB1FoC5nSLlceGk+RIUPtSgUPuc7KH5bxSxHTmMS7rNKzL/7ytTtXn8dhwFn60J3XOQleRo4aEhi2xz6EMP3LASIFUepxDUGpuIVK233pCh1yJzuzNvkmEZCl9hsdrb11ji1YM5Yb/PfLyVX5Yn8sJebbHXhJ4i4THgjBsc4b9o4bMIPQIOCUyueIJB/ixI8wDcmxZq3WduOxQ7QNxygZ+Wq7kQdfDk1+6Ssn3jo9d3ufxTjuxKdIc28bP5MV04HNIzCbyIVafxx6VOCcmZ8KxuGITBEYNHSOvD5QfOuCkQOuPc30orhbiLfQ8Rievbh8onOHXtz9my2nI7+vezszRWcePbo5pv68bGz7v2c0yPjv05/fbcNrAUAafTfp6wy2HIA3r9f/5zUZ+k3JYl/+50mVfp/F2sYaqDOK3+vhFKN7vcqUQLuLG4eGcJ80Be18HjJ9P4BI4XFyatxe5jrSWgPI+m4tyk/BcEYWz/n7dOZirIX4FMH4KjisWcsHoGzZwNBMMX6EzwfBWjauf8OrwnG6B6rsDdgvAuD4yOwenfCGYBH5R13tP214C2GkzNt2y+4Yi/cigzK2LTH/yxco3uqkMY28FJ/p7vwNkonFVQak2xYkBBwTGAAwFVCb7bxArBcgGna5EUJ4IFCAKEHHA4YDAccBRpi3PtGvFSgGiABEHHA4IHAectWZF2VV+ZVSAKEDEAYcDAscBR5m2PNOuFSsFiAJEHHA4IHAccNaaFWVX+ZVRAaIAEQccDggcBxxl2vJMu1asFCAKEHHA4YDAccBZa1aUXeVXRgWIAkQccDggcBxwlGnLM+1asVKAKEDEAYcDAscBZ61ZUXaVXxkVIAoQccDhgMBxwFGmLc+0a8VKAaIAEQccDggcB5y1ZkXZVX5lVIAoQMQBhwMCxwFHmbY8064VKwWIAkQccDggcBxw1poVZVf5lVEBogARBxwOCBwHHGXa8ky7VqwUIAoQccDhgMBxwFlrVpRd5VdGBYgCRBxIceB/bK6VghmpUw0AAAAASUVORK5CYII=" - }, - { - "name": "Landed, Kinda", - "description": "You have been locked to the surface the beam. Robots are all around you, pointing at your drone with all sorts of old age weapons.\n\nOne of them angrily shouts at you, \"By God, Queen and Country, we've got you now!\"", - "choices": [ - { - "key": "choice 14", - "name": "Go out with a bang. Initiate self destruct!", - "exit_node": "FAIL", - "delay": 0 - }, - { - "key": "choice 15", - "name": "Surrender to the funny looking robot brits...", - "exit_node": "British Courtroom Start", - "delay": 50, - "delay_message": "You are being transported somewhere..." - } - ], - "image": null, - "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAIT0lEQVR4Ae2dvY5dNRSFzxsg0dKNBBLFKAiJApSKglREoqSDhqFAQihNChoKAiONlCISBUqRnlfhDXgRRGNkyI7W9dg+23/Hx/YqLO9jb/9tr+/Yc+9kst0+uzVMjAE14NfAxsD4A8O4MC5WAwSEJyhvEBENEJBIcHiK8BQhIASEJ0hEAwQkEhyeIDxBCAgB4QkS0cBygHzzlzHaxBOEJ8hSgGjBQD9CsjYkSwKiET0hWRsM0cgygOQIPqeNBPboHOfq2kfPZabxlgMkdfNQbKltW/vj3DR26/nM2D8BiXyCIRuO4pOy3jnOSWzfnKTO5r56lsWvkssBkisUEdoZBCVz0a5F/M8w99HmsAwgdmNEKFph4WaWtMV+Su3UeaT6l85vtvZLAWI3DwVj7ZQNlbYpbWr6yvjaeaf615zrLH0tB4jdOBSOVmxuux4CkHlrxhbflPVp+l3NZ0lAZJNRRGJLXSgXv6OFpx0X/Y6eYyhmI5cvDYjdOFdQ8hzbVI1PrH1O3d6YUo95zjhsc/mp1vKAoCBQXGijj7Wlzi1v9Szj2dwdA+vEdn34fCn6lHgQEM/3ICI0X26DK+UpgS7x9Y0nZZiXjMG2fogIiAcQFAsK0LXRr5WNY9ox8FnsVmOzX/6b9HtXlpgoRJCSx3xr1clYvrzWGOzHf3rYuHQ5QbjZ4Q1xxcpY6WPlxq7G8+GA+DbcLauxsFn6wNjMsqaR1tENEAwSigBt9KHd9026avxPAQgGHwGxNtbRJiRHa6AbIHviR1CODopmvM8ePTItk2YOLX0w/jG75RzO0PfhgNhFS8D3AiB+Nt/zPaK+JRB7fR+xPhkD4661pe1s+akBscHGDeoV/D3xHl3fKg4Ya2vvjYP+e76j1ncFRLMJNrC9NuJo4aeOV0t0GF+xtX2Lv821bUby6wKIDZAEdi9Y4of5XpvS+lShns0/df2lsZX2qeOO4N8dEBtcDJQEO5ajf037bEIvnY8mNhhnjb/rU9re7e9sz6cABIPss48IWqkYz9o+FjuMdczPV4dtre3zmaGsGyASPDfQPYJ9VnHXmpfEGnOMO5aLjfV7trSZMe8OSI+g1hLeSP1gnPcEr63HPme1lwJkJEG3mKuImADofyNhe/DhR2YvSWBHzVuIbcQ+Zf8EEHlmHgZmekBGFHLLOROGMAy+2BCQhN+pur6+NpJExPIcysXvLLlPBCwLQ7P9/uqV8aW9a1fN+lYbVFuUIQhKymvPUdNfq3jP2C8BSThBzDtvGZtKgNC21Qg912dGIbda07SA5IrH107AwFwr9Bp+vjmVlrUS1Gz9XgCC16bHj380kn55/tz40t2LF0aSr96W/fby5Zvku8rZMhw3ZKcEvlQ80h6B8Nk1xJ/ah8ytNE+J58q+0wFSKhwfCHtlqSKv4V+6zpVFn7L2qQDJFc0eACn1NcSv7SN3vbZdikhW9r34mFeuVDb//sl3b9JPn3xh9tLNzY3ZS9gnXr3QxisWjonlvg3LEUuK8HN9tWLP9ctZNwEJf6zramsKQFJFkiv2Fu1ywXDbpcbAFQKf/dAsB4hG5Nu2GUyaNkf5uGDIMwHxC7wU/AtA8BrT2r66es9ICo3157YZSeiDi9YKQyNghMJna/ro5aONg/hhDGmH4SIgr7/8s8L2QYFlvcSvGVeEr80JRRgKjM3QgGjFoBEYghCzNX318tHGw/qhCGiHYdmePv3DSJIrz3/525u5kgTXoTdltq6kHNr+endnJOFV6p+f3zWS/v74fSNJNlQrCI1gY1BgnaavXj7aeBCQMBCiLckJyOsrFkIQs3uJf29cwqEXvYhfkw8LSIog9sRl62NQYJ2mrx4+KfHQCIM+/wO3PXz4lZGEV6ZvH3xqJLUoxz7xWoW2fIJlcyy3m5ciCK1gEQSfre2nh19KPCh+/WlDQCb4FItw6AWf+nIgIACIvPnd00PKz5oTkIaA4FXnSPvLr38wknJ+FytFFNb3rOKuMa+UWKS+QVf3346EAscSOGx+BCAoohqiPFMfuLaYvbrYc9a/JCAoojMJPXcuuJ49O0ckK7fZLr74ky8G3S8B4Us9fPOX2PipFNo4Hyz3bdKeGHLrc4Xao13OGn2xZJn/5xgCovijDT2Erx0zBxDbhkD4gXDjMjQgdjG5AqnVTivkFn6la3DFwOf70AT/Nm/oqlOrHK9P2GfOJpUKpUX7FkBInzXnmxPvldpMAYjdsJqiadmXiDw3bzG3lQSfutZpABkJkhYiL+0zVTir+G+fX31gJIUWjVeg0NVIUx7yCY2bW14qlpXb58Z81nZTAiKbtbLQS9Yu8WN+a6YGBDe4RDCrtcW4rW4HfwaZOTCrCT5nvTPvf8ralgTEF6AcEc3exhen1coIyLP7Xw5ZEcwufu36VgPCXS8BCQDiBgqfteKaxQ/XvppNQDIACYlkFiB86witefZyAlIRkJBYfIIbrSy0ttnLCcgBgNQQ0RmAqrGO0fogIIMAIsLqDYrMY5WcgAwGCAqzFyw4h9ltAjIwICjOI2HBcWe3CcgkgIhQjwJFxps9JyCTAWIFewQks4Mh6yMgEwIim9saFBln5pyATAyIFW5LSGYGQ9ZGQCYHpCUkIqKZcwKyACCExP8LqRqwCcgigLSCRCOykX0ICAEp+jllZPFr5k5ACAgBiWiAgESCo3nDjOZT+1Ot0dafOl8CQkB4gkQ0QEAiwUl924zgzxMk7RMtArIYIBZiQqKHhIAQkGJgRjg5c+dIQAgIAYlogIBEgpP71jl7O16xeMXi/6AUAb82ILa/s78UcufHEyQipNygnr0dAeEJMu0brQZ8BISAEJCdk5GQ6CD5F0cJWniQ8Kf0AAAAAElFTkSuQmCC" - }, - { - "name": "British Courtroom Start", - "description": "Wow, that took forever. A one eye judge robot smacks their gavel, and points their hammer at you.\n\"I will now read out the crimes you are accused of!\"\nIs that how the judicial process works? You dunno.\n\"ONE ACCOUNT OF PLANETARY TRESSPASS!\"\nThis blows.", - "choices": [ - { - "key": "choice 16", - "name": "That's not that bad.", - "exit_node": "British Courtroom, Continued...", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "Crimes Committed", - "value": 1 - } - ], - "delay": 0 - } - ], - "image": null, - "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAJiElEQVR4Ae1cQbLduA18N8gBsppVVj6B9+MLzA1yn1z5pVBJu7owlAhQoARSUNUvkGADBJvop/dtz3z+8/PzrZ/ioHqg3QOfIqZNTPFSvEgPlEDqDVrfIE56oARyQk69ReotUgIpgdQb5KQHSiAn5NQbpN4gJRCHQL7Jn8/n85WfHZ+nPqy2EciOTeE9084C6XExS0DLCaRH1JvX3ywQ3Hu0UNILBAcv22cAAtn1a1afgW/4Hzg8IhDLQe/EoLF4z5aP1zOOUfMqAkG90VxGvkVuFUg0EVH5WhfV8kXtNyMP6oUd3QPxbM9yWXGcg2Mw5vWr4yUF4jk0SIP1xI5gsY9YefR8JOddMVwrjy37A89Y+NjyOo8ZgzGvt8bAadvCjvq2FYgmDfNRojxxvBePz3JYcbNyYP+Wbe0JnKxhLJYf+M8wwLewWGtZ4HlP+Fr4Ud9yArEeFGQxgdbYqzjeG+Nezhau5ZM88IvlB3749Bx+bYHjfOxjP2KxLnMeY73l7+GwD3CYc06MgcG8tR+vjY63F8goMVfjcIGwvXwtHPswblnkxpqei//s0XGChQ9Wx7Ofx4zTfszF8tPyw8c4HmO9ZRl3dVwCOWEQ5DMEPlhe4zHW2fK6HgMHP+Zi5eG59lligGlZzo119mE/rInV62eYVlzLxzmQn3E8xrq2jIkYLyUQz4FBXC8GOLH8WPw6huNlzDm8WI7VubCPxjCOx8AhrmWBObMcp3G8hjFjtA9zsVZcL4bXo8bbC4TJx5jJg08sHvaxX9Z5DfgjC+zROvuBbVngeE379JyxPAauZRmHseB4jDj4YOHXFuvaMo7X4G/5sCa2t87Y0XGkOCTX9L8H8RyUCdRjnYfXZY3nGCMGc7HRD3Ijr56LHz5tdQzWtR/zqxb5xfYexmLMMfDpXPAzlsdY13GMuTLeWiBCDAi0kAQsW87Bl8AYHlv28WCQW8fAD6vXs81Rp9jW01tvxcDHsTo/1oD12GhxTH+DeA4HrIcgYGF1jp5f1iMf7BedN7LGqFxXzsqxR2NvnTPEkVogEU0G8q1kj5KMfWBH84zGWc8XicNZr+ZEHraenKOcWeOm/Q7iOaTGgiztj55bSerhUK/YHvau9WiuMuW7i0PZZ4pA3krmnRc3ulemu7HWMnrWiLitBBJByFtzWJv1TlyGuwgXyEwCMxD2phpm3mUrd0ZuQwXSOrTVl5Gcs5r+/PXrO/PnbO9au+93vRQCWeXCZwqil3sVjnarM0wg1jcF41Yhs9e8d6+vwtsOdT4ikFWIu7vxvfutwuPKdYYIhN8KvfEKZHkbNRt+BY5XqfGyQHqC4PXspGRr9Kv1ZOd7hfpuEcgKRFxtxqzxK3CfucZLAuG3w9k4MwFSW9bmjqorO/+Z65sukIyHj2q8lfJkvIcVahoWyNkbQ9YyHn6lhp5Ra8Y7yV7TFIFkO/SMZlsxZ7Z7WaGeIYEcvT0yHnjFRp5Zc8Y7ylxTmECyHjKy2X78+PHFD/JifmSBy2Kz3lPWutwCab09sh4uuimPRHDFH12jJV/W+8pYl0sgK4lDyLY0iwdzRQjeWE9dXmzGRsxak1kgbxSHt6ln4b0CsOCzNmS2ukwC0eLIdghdj6VBLJhZDX8lr6VuC0ZzVvP2f2PiFkh2Ii3NcYb5/vMfX8vPlSaPiD07g2Ut+z1mqc8kkCzF9uqwNEYLYxFEDxPR9N4crbNYfT0ua/1/b5RtBGJtDMb1mj5i3dv0XjyfxzMuAbS/UmlethCIpzEEG9H4UTm8gjjCeznQjVDztmBeJxBLY/P/CE7Glpi7MCWQdiPPEvjyArF+cloaWAtDzy05nsJYeQBuVkPtlrcEQn9qpQWh5081v2VfNL7V7tbIs86ztECszWBpMC2Go7kl11MYKx+Cm9VQu+Utgfz/DXIkCO1/qvkt+5ZA4n8/KYFsIpASR7w45G24rEA8DWH59NVviqO5JdcTGA8fu30NmnmeEsgLf0mf2VC75S6BbCCQenvM+XolYi+BkEDw1Uh/vYI/qy2BbCSQf//r88XPldexpykEm7W5I+rycHGF8zfG3vIGgSC0/euPz1d+Roj3NIXGRjRlphz6fEfzEZ7fHjNdIFoUMocwYEcu4agJvP5MjT5ai+fMI1y/OWaqQFgcEMOZ9V6EpzE82NFGfSLOcy5gvTy/GT9NIF5xiHC8F4ELn22faHzrnqNn93L9Vny4QKTRR8TBbxbPZYw2SFSctZFn4K6ewcPzW7EhAmFB6DE3vnXsvYyrjTIjfoYgkDOyXi/Xb8NPE4hVDEc470VENs3MXGjyUTujNi/Xb8JfFshRg1/1j1zCjOZ5S84Rvt8Qk1YgIrDRC3hLU8845yjnu8ZtKRBc1owGekNO8Fc24N9iXf0qdRYfeUFvaOyoM0byvnquy28QIeCsya+szSI3qpF2zjOL+9XyhghkRZHoi9q52UfPpjl64zxMILNE8tSljDbVbnFP8Z9l3xLIT/+flu0mgt55sjTrE3WECgR/i37l945W7BPEjOzZa7SV10f42CFmikBEKK1GH/WtTvTKwkDtq9/BaP1hAkHzv/0tMnoRvTg06pO2V+OO6yECgTjEQiDRbxHJveMFeM/0pEBkb2+9q+MvCYSFwWOIhH1R49UJj6z/KbFEniF7LrdALM1vwYwKJjuhT9V3p1ieOuMT+04VyIyvWSKsJ4haZc+7hLIKH1frNAsEn/h4O/SaHzjERdurB985/g6R7Mwfn60rkFZjW5rfgmnl7vmQlw9R4/ZbdbZQ3sD7oUDOGhVNKvYIB8zRusePXGzfcDkRZ5wpkoj6suf4LRBuWDQi+/S4h8G6EKBjrXPk0FbisxObqb5ZIsl0xlm1fFrNioZsrcEHjFj42HLB7LeMOTfGHMe5a2z7sCiR2HjS/TQsEGnYVvOKX28ic27wszFywjK2lbd8bb5bvMwQSWufnXyhAukRw83eGkMUYmW9l6/WfRyVQHx8SX+dCgSN2mpm7bM0q47BnIUhY0uuwvh5KoH4OWsKRBoXTYsmPrPeZkUu7MHWm6vwvkuPFsnu/F8SyFVyShi+5r7Kt8SXQHycuwUScUmVw3dJkXyVQHzcHwoEX4PERl5Q5XqezxKJ/Q4OBVKNbCdxNa5KIPa7/ZtAVrvsqtd+2eCqBGLn7LdAQF5ZO3mrclUCsd/x73+LteplV932ywZX0QKRfMi9my2BDPx/sVZvghKI/UOlBFICCfm7kdU/NI7qL4G8UCDSDPUWsb1F/gs9r28akoDJcAAAAABJRU5ErkJggg==" - }, - { - "name": "British Courtroom, Continued...", - "description": "This big idiot they call a judge just keeps piling on crimes. With each one, some robot you'd like to drone-punch gasps in the back.", - "choices": [ - { - "key": "choice 17", - "name": "\"INTRUSIVE SCANNING ON OUR CITIZENS\"", - "exit_node": "British Courtroom, Continued...", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "Long Range Scan Report", - "value": -1 - }, - { - "effect_type": "Add", - "quality": "Crimes Committed", - "value": 1 - } - ], - "requirements": [ - { - "quality": "Long Range Scan Report", - "operator": ">", - "value": 0 - } - ], - "delay": 0 - }, - { - "key": "choice 18", - "name": "\"SHOOTING DOWN A COMMERCIAL AIRLINER\"", - "exit_node": "British Courtroom, Continued...", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "UFOs Shot Down", - "value": -1 - }, - { - "effect_type": "Add", - "quality": "Crimes Committed", - "value": 1 - } - ], - "requirements": [ - { - "quality": "UFOs Shot Down", - "operator": "==", - "value": 1 - } - ], - "delay": 0 - }, - { - "key": "choice 19", - "name": "\"AND WE HAVE PROOF YOU KNEW IT WAS JUST AN AIRLINER!\"", - "exit_node": "British Courtroom, Continued...", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "Commercial Airliner Transmissions", - "value": -1 - }, - { - "effect_type": "Add", - "quality": "Crimes Committed", - "value": 1 - } - ], - "requirements": [ - { - "quality": "Commercial Airliner Transmissions", - "operator": "==", - "value": 1 - } - ], - "delay": 0 - }, - { - "key": "choice 20", - "name": "\"THE TRANSMISSIONS WERE NOT LEGIBLE AND UNTRANSLATED. WE CANNOT PROVE MALICE!\"", - "exit_node": "British Courtroom, Continued...", - "on_selection_effects": [ - { - "effect_type": "Add", - "quality": "Garbled Transmissions", - "value": -1 - } - ], - "requirements": [ - { - "quality": "Garbled Transmissions", - "operator": "==", - "value": 1 - } - ], - "delay": 0 - }, - { - "key": "choice 24", - "name": "I think it's done listing crimes, thank god. Time to argue my case.", - "exit_node": "Verdict", - "requirements": [ - { - "quality": "Long Range Scan Report", - "operator": "==", - "value": 0 - }, - { - "group_type": "AND", - "requirements": [ - { - "quality": "Garbled Transmissions", - "operator": "==", - "value": 0 - }, - { - "quality": "Commercial Airliner Transmissions", - "operator": "!=", - "value": 1 - } - ] - }, - { - "quality": "UFOs Shot Down", - "operator": "!=", - "value": 1 - } - ], - "delay": 0 - } - ], - "image": null, - "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAJiElEQVR4Ae1cQbLduA18N8gBsppVVj6B9+MLzA1yn1z5pVBJu7owlAhQoARSUNUvkGADBJvop/dtz3z+8/PzrZ/ioHqg3QOfIqZNTPFSvEgPlEDqDVrfIE56oARyQk69ReotUgIpgdQb5KQHSiAn5NQbpN4gJRCHQL7Jn8/n85WfHZ+nPqy2EciOTeE9084C6XExS0DLCaRH1JvX3ywQ3Hu0UNILBAcv22cAAtn1a1afgW/4Hzg8IhDLQe/EoLF4z5aP1zOOUfMqAkG90VxGvkVuFUg0EVH5WhfV8kXtNyMP6oUd3QPxbM9yWXGcg2Mw5vWr4yUF4jk0SIP1xI5gsY9YefR8JOddMVwrjy37A89Y+NjyOo8ZgzGvt8bAadvCjvq2FYgmDfNRojxxvBePz3JYcbNyYP+Wbe0JnKxhLJYf+M8wwLewWGtZ4HlP+Fr4Ud9yArEeFGQxgdbYqzjeG+Nezhau5ZM88IvlB3749Bx+bYHjfOxjP2KxLnMeY73l7+GwD3CYc06MgcG8tR+vjY63F8goMVfjcIGwvXwtHPswblnkxpqei//s0XGChQ9Wx7Ofx4zTfszF8tPyw8c4HmO9ZRl3dVwCOWEQ5DMEPlhe4zHW2fK6HgMHP+Zi5eG59lligGlZzo119mE/rInV62eYVlzLxzmQn3E8xrq2jIkYLyUQz4FBXC8GOLH8WPw6huNlzDm8WI7VubCPxjCOx8AhrmWBObMcp3G8hjFjtA9zsVZcL4bXo8bbC4TJx5jJg08sHvaxX9Z5DfgjC+zROvuBbVngeE379JyxPAauZRmHseB4jDj4YOHXFuvaMo7X4G/5sCa2t87Y0XGkOCTX9L8H8RyUCdRjnYfXZY3nGCMGc7HRD3Ijr56LHz5tdQzWtR/zqxb5xfYexmLMMfDpXPAzlsdY13GMuTLeWiBCDAi0kAQsW87Bl8AYHlv28WCQW8fAD6vXs81Rp9jW01tvxcDHsTo/1oD12GhxTH+DeA4HrIcgYGF1jp5f1iMf7BedN7LGqFxXzsqxR2NvnTPEkVogEU0G8q1kj5KMfWBH84zGWc8XicNZr+ZEHraenKOcWeOm/Q7iOaTGgiztj55bSerhUK/YHvau9WiuMuW7i0PZZ4pA3krmnRc3ulemu7HWMnrWiLitBBJByFtzWJv1TlyGuwgXyEwCMxD2phpm3mUrd0ZuQwXSOrTVl5Gcs5r+/PXrO/PnbO9au+93vRQCWeXCZwqil3sVjnarM0wg1jcF41Yhs9e8d6+vwtsOdT4ikFWIu7vxvfutwuPKdYYIhN8KvfEKZHkbNRt+BY5XqfGyQHqC4PXspGRr9Kv1ZOd7hfpuEcgKRFxtxqzxK3CfucZLAuG3w9k4MwFSW9bmjqorO/+Z65sukIyHj2q8lfJkvIcVahoWyNkbQ9YyHn6lhp5Ra8Y7yV7TFIFkO/SMZlsxZ7Z7WaGeIYEcvT0yHnjFRp5Zc8Y7ylxTmECyHjKy2X78+PHFD/JifmSBy2Kz3lPWutwCab09sh4uuimPRHDFH12jJV/W+8pYl0sgK4lDyLY0iwdzRQjeWE9dXmzGRsxak1kgbxSHt6ln4b0CsOCzNmS2ukwC0eLIdghdj6VBLJhZDX8lr6VuC0ZzVvP2f2PiFkh2Ii3NcYb5/vMfX8vPlSaPiD07g2Ut+z1mqc8kkCzF9uqwNEYLYxFEDxPR9N4crbNYfT0ua/1/b5RtBGJtDMb1mj5i3dv0XjyfxzMuAbS/UmlethCIpzEEG9H4UTm8gjjCeznQjVDztmBeJxBLY/P/CE7Glpi7MCWQdiPPEvjyArF+cloaWAtDzy05nsJYeQBuVkPtlrcEQn9qpQWh5081v2VfNL7V7tbIs86ztECszWBpMC2Go7kl11MYKx+Cm9VQu+Utgfz/DXIkCO1/qvkt+5ZA4n8/KYFsIpASR7w45G24rEA8DWH59NVviqO5JdcTGA8fu30NmnmeEsgLf0mf2VC75S6BbCCQenvM+XolYi+BkEDw1Uh/vYI/qy2BbCSQf//r88XPldexpykEm7W5I+rycHGF8zfG3vIGgSC0/euPz1d+Roj3NIXGRjRlphz6fEfzEZ7fHjNdIFoUMocwYEcu4agJvP5MjT5ai+fMI1y/OWaqQFgcEMOZ9V6EpzE82NFGfSLOcy5gvTy/GT9NIF5xiHC8F4ELn22faHzrnqNn93L9Vny4QKTRR8TBbxbPZYw2SFSctZFn4K6ewcPzW7EhAmFB6DE3vnXsvYyrjTIjfoYgkDOyXi/Xb8NPE4hVDEc470VENs3MXGjyUTujNi/Xb8JfFshRg1/1j1zCjOZ5S84Rvt8Qk1YgIrDRC3hLU8845yjnu8ZtKRBc1owGekNO8Fc24N9iXf0qdRYfeUFvaOyoM0byvnquy28QIeCsya+szSI3qpF2zjOL+9XyhghkRZHoi9q52UfPpjl64zxMILNE8tSljDbVbnFP8Z9l3xLIT/+flu0mgt55sjTrE3WECgR/i37l945W7BPEjOzZa7SV10f42CFmikBEKK1GH/WtTvTKwkDtq9/BaP1hAkHzv/0tMnoRvTg06pO2V+OO6yECgTjEQiDRbxHJveMFeM/0pEBkb2+9q+MvCYSFwWOIhH1R49UJj6z/KbFEniF7LrdALM1vwYwKJjuhT9V3p1ieOuMT+04VyIyvWSKsJ4haZc+7hLIKH1frNAsEn/h4O/SaHzjERdurB985/g6R7Mwfn60rkFZjW5rfgmnl7vmQlw9R4/ZbdbZQ3sD7oUDOGhVNKvYIB8zRusePXGzfcDkRZ5wpkoj6suf4LRBuWDQi+/S4h8G6EKBjrXPk0FbisxObqb5ZIsl0xlm1fFrNioZsrcEHjFj42HLB7LeMOTfGHMe5a2z7sCiR2HjS/TQsEGnYVvOKX28ic27wszFywjK2lbd8bb5bvMwQSWufnXyhAukRw83eGkMUYmW9l6/WfRyVQHx8SX+dCgSN2mpm7bM0q47BnIUhY0uuwvh5KoH4OWsKRBoXTYsmPrPeZkUu7MHWm6vwvkuPFsnu/F8SyFVyShi+5r7Kt8SXQHycuwUScUmVw3dJkXyVQHzcHwoEX4PERl5Q5XqezxKJ/Q4OBVKNbCdxNa5KIPa7/ZtAVrvsqtd+2eCqBGLn7LdAQF5ZO3mrclUCsd/x73+LteplV932ywZX0QKRfMi9my2BDPx/sVZvghKI/UOlBFICCfm7kdU/NI7qL4G8UCDSDPUWsb1F/gs9r28akoDJcAAAAABJRU5ErkJggg==" - }, - { - "name": "Looking at the Surface", - "description": "The surface of this world looks exactly like a grey version of Earth! It seems to be an exact replica of some kind.\n\nYou see creatures moving around on the streets", - "choices": [ - { - "key": "choice 21", - "name": "Cool!", - "exit_node": "Tractor Beam", - "delay": 0 - }, - { - "key": "choice 22", - "name": "Scan the creatures.", - "exit_node": "Robo Brits!", - "delay": 30, - "delay_message": "Scanning..." - } - ], - "image": null, - "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAKCklEQVR4Ae2dW3IcNwxFtSYvIv7PR6qygZRiy8nGsiMvZlKQciMI4gMkAT660VVjNNkECIL3DGcSWX764+fjEa/r1OCXr18fpVfsddteP1HBclcUs62YO9SrBAc92yHHk3J4ysEh+09a1J1zDUBs39TUgEhgqH1nIe649hoccYK0a3YIkICmveCeYAUg9vthDkgKmjht7DcuBVoNkJRP9JX3ZhogKXBic8qb01qfAMS2nlT/pYBwaFrFEOM/iqEGBz1fUTO+x/x+RS49c24DCC8e3fcs5s4+qwCR+6Ztn7JX2wLCC60pJh9P9xqfK42pAWK1Vlnn3rZVPt5xjgCEb4IsCH9Wu5e+V2nX4LD4eFWrbevzU2p/HCCtGyHHn7IxLXl6AyJraNFuWd/KsQHIBX4WzRMQCxhSMVaKvmXuAORwQDRw9HzESonasq9FpCvHBiA3AKRFYJYQlGK15LRy7O0AoU1bWXDLuf/89u31R9ullaeKds6SoK2faXNaPS4AOfgEkSDk2hqRWQNQi6fJaYcxAcjBgMiTI9fWCK0maOvnmpx2GBOAHApI7rSQ/VqRWQPgFU+7HqtxtwPEqnCr4xAIuROD92vz9BL0zLjatbaMC0DiBHn9jxYzhTxzrhYYUmNvBUiqACf28ROidpJo1zdTtCvn0tYD4y4PCBZ6JSu/Z5Ta2nWvFO3KuWv1uSQgtUWf/lx7grSuc6VQd5sbtbsMIFjQ1W3ptJDPWmuxm0h3yKf4e7F2SDCXQ+vmX2U8QRAnSE4V9v2vgEA89uHHIiKvsO8/HiNPiVy7t2ZjO3Y97w+AoKgzlom5wr6Lv1YL7clB42qxcs9n7P1JcyQBQfE8F4I5wuoBKX28kifJSF099/202EVAUGTrRSFuWBs45MliUVfrPT81ngoQWfDexco40dYDIiEota3q2rvPV/LrAsRqAyKODpASDKmPXZZ19RQ75bn7FYAc8LNYKQhy0FjC4SFgmV8AcoAA5abt1G6Bg6DxyH1ExJp8RuJ7+8YJ4ghwq7gtxmsE2TOmJsSemPCpxV75PAAxBITewWsvCwhmfbyCgL3tSgBqcwcgg4DkxLqi31vInvFrQl31PADpBKR2UrQ+tzhZPAU8I/YqCErzBiCNgKw4GTTwzBCw9xwloa56FoAoAWk9EazGa+AAtN4CnhV/FQypeQOQCiAQ30l2lpBnzZMS7qy+ACQDiNUJYB1Hc6LMEu6KeWaAwdcVgCQAkaLWiHLHE4Zv9NXurUCp1SUAYYBIME5q5yCuCeD05y2g9Kw1APn5qP7PPQlKToy79vcII3zefpD09oBI8V+tDWhD8LqfnJZ1ui0gHiBAjDtaufHR1gFzS0A84DghZkChg4LX6XaA0Lv777/9+nh6evr03YP6PV+rTxa+8XGvg+U2gECcJQDoFMC4nMVJgeeyjX5pU/PCd6YNMHRgoE63AARilSKl/tyLRAs/Dytz8Z4P8bHxYXWgXB4QEjcXY6/Y8S4Pf7SlxXNpMU72U5vnh3GeNuDQwUF1ujQgXHh0T2KsvUiYfAza3hZz8pypz2PeACQA+fCuDDgsxEYxUi+IGc/QHrGABTGtbAByc0AgLG5JXCmxUl+qPzee90Owvf4pP+TDLdaRGs/zaXkekOgguexHLBIOhNUjIil+tEdti4hl3lgP2dE8ApAA5H9ARkQpRerVphx5nminLAeF7rlfS34BSR2Sy54gJBoIqUU0Umzka/FCXMRCe9TyNSK21gYgNwaERALxjIoQ/hCeto1xI5Z8uX+ujbVSjnx8qR2ABCCvkEDYXCzog5jQnm0xv4UFJGS16whIypBc9iMWCQSCsRAfxUOcnPjkc7QtLMXgcUptrBt5cj++DuoPQAKQ5LspRAMReVv5ri7nR9vKSkhy6wtAbgwIiYKE0is6iAr+aLdaKVbE87aYlyzPmc8bgGwOCP2dYq9NIlFIcXChzLov5VB6RvlBzMi1tU1+NEdpHq/6XyHu8u8gnoDQBnFhtIpLjodItZb8uTgRDxbP0Pa0mIvXA+u4gpC91mAGSK/Q+W+l8FgkRLDKpgSJXErPMAYW8GjbGCctQOH9HnW/SkxTQHog8QYEG8UFMeu+BAB/lhM/+nst1gl/tCUkqFHYzx/3bwMIbT4EMsNKEfI5ORy8f+Y9zyHA+AwGanIrQLDoGULkApTz5Z7Jd3rPNuWAPFCXsJ9BuSUgJAQpWss2F5+MC1HK/hVtyuXZ6d81vApsJoCMfI8Y8R3dBC9R5iDI9XvlUYsbgHw+MaSmzAEZ+aIuk5vZrolJ+zwHAfXnnmljW42jU4NeAcgkQEjIdNHvmqKrVdivTv/90eprPX5EhDkIcv0jc/X6Ao53QL4375d1zXeOZ3KC0ALl1bJo7tvi5z22VYS5EyLX3xp/dDyH4/nb98fz94CjpqEAhP3zB7liaYTJTwl5r/H3HPMRDPp4RXC8PJ5fXuL0qOy/GSAkLn7lxJbrH/HNxbTuL4kYUMDSx03cl/y8nwUc7R/5uW5MAaHA/OIT1e57/WpxPZ9D3AAhZTFmhf0Ix9tHqreT40ecHJWTA7rZEhCCBQnubFNAyL4VYNCcSTheXh7PP/56PP/19xH13WHvXQFpETo/QVr8VhZRwiDb+8Dx9n0j4Gh/4zUHhATLrxYB9/q1zGE1VsIg26l5ZgDz+eR4hyOVE+/j9dfcc9+r3rsDQoXWFk9uitbPY5wUfEu7NR8rcFJwaHKRde9ta+Y6bUwAkviyBhj++fLlUXphnLQWImiFhsOhnb8XBK2fNo+dx00BhAqqKUKq8Bo/yzEk9hIU8pkHHJbrQaxUbWf3IZeT7FaAUOFS16yCtsIBWADJrDy186RquVOfdh0rx7kAQgtKXZqF9vppYpfGQOQQfasl/1L82c9Sddy9b3aNNPNNBYQ2SJNUaiM1fiNjek8PgLQTIKn6ndY3speWvscAooWrtzhXAOQ0CFry7d3XUT83QCix3KVJesRXE1+OOR2QXL2u1C/3bEb7OECw4dbFORkQ1OTq1nrPNfFcAaEEcpcmuZwv79fE0YwZAYR8NXN4jOG1uPq9R/1qMd0BQQKpzcOznE35pPpy/q39JPRWUODTOtfo+FQdrtg3WqdR/2mAUKLy0iYv/VJtbSzNOIg+Bwt/XoqXylPbl4ur9T91XG7dq/qnAkKLlJd24dIv19bG047jMOBe45vLL/rzFdDUdfaY6YDQAuXVs2gZg7d74ln78HziXlcB6z2wiLcEEEpcXr2L4XHwW1WorzeelR/PK+7rFbCqu3WcZYDQQlLXyAKt41nnksov+ta/mZX2eSkgHpBgsVx46Jtl+dxxX6/ArH3pmWc5IJR07upZ0A4+ufVE/+cK7LBfpRy2AIQSTF2lxHd+llpL9KUrsPM+Um7bAELJ5K7diyjzy60j+j9XQNZut/a/8+89HVF1Xw8AAAAASUVORK5CYII=" - }, - { - "name": "Robo Brits!", - "description": "Wow, they're robotic humanoids that look and act exactly like the British! You see some robots laughing and chatting at a pub, and a Bobby walking down the street looking for crooks. Who created this earth replica? You only know Earth from the books, but you should be where London is!", - "choices": [ - { - "key": "choice 23", - "name": "Nice! Well, back to getting pulled in by a Tractor beam...", - "exit_node": "Tractor Beam", - "delay": 0 - } - ], - "image": null, - "on_enter_effects": [ - { - "effect_type": "Add", - "quality": "Long Range Scan Report", - "value": 1 - } - ], - "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAP2ElEQVR4Ae2dT8snRxHHnzcgYT3ksEgie1gXVkhIUFA0F1cPezAsHjzsKYR4URSvHj0IycmjvgLxIIigOYme9C1IZAUvCnkJXloqmyKfp5+u7qrp7pn5PduHpmqqv11VM/P9Ts/v+Xv14duvppHj6uoqjRiRnn70wR/TGuVr8OE77yRrjLhPVg6rZjRu5c/j0bxe/FWEiBY2b3bUsVWvFF8COZdAhANeElq4rTyy8m2Jdwtk60l415XEUIotgZxPIL0i8XKkhtsiCq7pEkitsVFzJTGUYksgSyAezpH8Hn8JJPv8kl/kMwov0mONBHmeGce1+rW5Gb3kOWv1dW4J5FOB5BePx2cRCXvKfatHvdElm+eYcVyq64nN6KWW0+rp9AKRkyq9UuUxiyCteO2ica6VZ9Y8e6j5Vn3rxku8lm/UXK1+bW5U/WievKerPEFOvNpxvnbWca0HnbMIUotH+q3lmTUX6Y9Y9pPfcB5zzSyf9bz+rF68ednnDYFIEiVdy3oL9uJafcg8SdHyt/bTyjtyfmuPuk574c3OfcXOsnk97/GsfqJ5pd+iQCSRh5TRgj34Vj9KiJbt6aGVW+Y9+UfladWSOjVSttb3zNfqWnM99SauLX/nu0VInZ/Y2DWyab2abRGvt9fR+Wv5enuV9S2BfPqEvHado3Utskfj0bo74pdAvBe7RmiZ8+YhzspJzFbfI5CISKKk9+K3nt9O65ZAvBfaIrPGvXmI07UlS1zU13xekh6Ji57bzvg+gcgrzx4N116tdE5JUbM9vdbyytyW3KNz5vmOJL639pbrtuOaF0sgOYFqx7wJNZzMEev1Wzl13sqn8zXrJeneOOucThhfAqkRzDu35cZ6c/fg9ia+p96Wa3XgmpsC0VcWr92jeW8vPWTqWRu9Bj21Ims9hN0TE71OJ8AvgUQIZ2GjN9LKMzq+J/k9taLX6Ui8nE/XNwr1qb7HSWgtjx1NMk++6DXw5OzFeAi7NyZ6nY7E31qBiIh6ybVlfeRmbskfXbM3+T31ItfoaGxVINKc52ktmNkn4u2DuCiZRuAj12FEvVYOD2H3xkSu0dHYpkCkQZKu5ntPhjk8a4iP+BZ53v/F+ykfFjYa95yPYqK5t+BnkV/PoWQ9NUvrzhgbKhAhb+0kI+Qehf3BP9MnYiC5cnGMPq5dA52Tfnrr8pws30PWKEbPoWY9OWvrzzLnEog0O4qwe+dRgfSSsWd9frN7crXW5kLxEDWCyc+ldjwrb63m6Dm3QKTw3uQeUa9FqNs4T5FESNrCbiFfKyfnt+SfvUb6M7/MWyo+grR75riNAvCeE8k3wi/xoRXbUreVc8/5JZDCB3YvAc+O20JOa81WUlr5PPGtNUeukz5DO4gU33MH6K11dhLP7M9DQg+mh3Ce/C1MT/2etdrXEsjaRab+Wq4Srdf2kH3LWu13CWQJxBTIFmKV1ijZRthS/tEx9rkE8gIL5M7nX05bR4SUJNwoP1I/imWP1/5wnCdR7+eCPdfPfMe/hNy80SV/qzhknYcrxJTqj4ixxiiffV0TiJC3VmRPcue9bK19CUSe1SNvdMm/DQLR86rxNjqnOcXeEEhOTE2+laD5Os2nNp+36gu+hG3FZpHvEvLyRqtPUXzhi6+l0vj9X/+WdJTmJcY8ei9rVuvPtrUevHPssSiQFul65q0mNac1r3HFee2ZiPy/dJVk7NUTb7T6JLZFfhWHWAvDPHpvalbr72VrvbTm2ONpBNJqWue9wlDcXmT01FkCsf8dHEk50lfeeG1ee3eBKHE9DQs2x+l6r/UQdy/MmQXCXePP//h30sE4d5Oz7yA3iO7835k31nmJNguXC6B2HO1hL+J76+wpkPxG6zGJTcJTCCoOsYwTzzy1e6ZzWv9Iq71YttTbYTsIyV5qWObzONfQz3GRYy+5R+CWQPZ/xSqSvrCblHASO4VASmLISU5B5H6OjRyPIP4Zc1g3nE9+a3fwxJmndb2tXi4hfhqBtESSi4LHrRtUmz8juUf1VCIgie0RAl+riGee2vUt9XBJsVMJpCYSCiLHvfTSS2nr4M0dRcyz5CkRkcQm4S0hWHHm4TWkX6p/abFdBMKLJn5O9tIx17Tmt4pD1rHOWYg9qg8lI8k829frqbUv3R4iEK9ISsLQmN4IsUsgN/9Si4hMyTlbFMyv90VrX7p1C0RPnFbJ2rJcQ7+1rjb/4MGDpOPRo0dJx+PHj5OOp0+fJh0aE6tYsZpD7Kgn95nyCEFJ4Nm+3t9LF4b27xKInnTJ1kjMudJajRHn9UlsEp5CUHGIZZx45jkTsUf2ojc7F8vf//SHpONXP/tpag3FiqXQ9D6qZb1L94cJRC+O2BLJOZ/7JXwrRmKT8BTCWQWy5/dDVGhKVBKbhG+JQ+aJZx7eT61zW2xVIDxx9YW46qu1YiS5YkuWuJpfWjsrpsSaYY8QiJyHkJbEJuF7BHJbxFA6D1MgFvEsMZTwJDvnGY/4zDHbnyEMzbm3QKKiSFdXSYclHIqL+Usku+RYSCAkMwmqccboy3x+rGsiljlm+0rmGXYJZOyPnJS4MEqULoHkJM4b4nw+Vzomfqv/21++n3TwaRb1NYfYGWIo5VwCGSeQEr80NkIkYYFocdqc5Jwr+Tl+yzGJHRUF8cxTIvOM2B4Cuf/6u0kHX4H+8rvfJB3W65MnrjnEMr/WFDuCoLUcJW7lsdp6z9w1geTJ9VgJrMe0OleyxKlfwm2JkdgkfNRnnhliKOVcAhmzgyinPNYjhhLGLZBSE15ic613TQvHJxhFwaffBz95PelgnHjmKZF5RmwJZH+BKAdLIqjFqgJRkmpyWp07ypLYJDyFoOIQyzjxzDNDDKWcewvklfvfTTr4OsRzj/rMo7nF7vWKRS5G/Zog8rmqQKzCR4mCdXlDSXgK4awCKYlmdIxEJYFJbF7DqM88zM+6OdlGHlvc9Ma9vVwTiBCwVYAkPdL3iOLr3/xe0uERy2iSHpmPRCWBSeyoKIhnHuZnXS8Jt+BaPPXOt2rfEEhNJEcKIq+9BPL8y9IkpOWTwJ97+VHSQZJHfc0hlvmtHhhvkbI17yW/F1er5xZITtCjj5dAlkC8AvDgLJEUBSLkLyU9QhSlPiTG7Z6fO+hbr1WMM49V68hXpVZtPpktn094PvmjuwbxzMP8Vg+MW2T0xq371BO3ai+B4Btn1gVukfTIeRLvy1/9cdLx8Gs/Tzq+8o13kw6dn2W1pljWYJ8WGb1x6z71xkv1TYHobsGiGpthWUd9qaN+bvnk565BnzuFFWeevIYeHymAVm0Sj4QkUVUcYomZ4bMu87PPEhEjMb0vo22ph5BApKFR4ug9ORK7x6eIrJ5aJD1ynsQjIUnUJZAr80HLez5EIL0iYUM9fo8ouPYSBWKJgnEKxPL/89FHSccbb3wntYZixVo5GWc/FC/jJVLWYj2caa0t1W3uIKXXnC27SKu56DxJ3uMvgTwXSUscMr8E8var5isUCRwVCNd6/G+99e2kI4rXdV7rEQhzHfk6pbX5BLaezHySWz4JvwRyVfzpY9cOEhUE8R6C5xgSMp8rHRMf9Y8UyNafyaJASH7G6RNj+RTLK6+8kXQwbq1lnHXpW5jSa00tVrr/o2KlulMFsrVxktyTg/iovwTy/MvBFIKKQyzjJLnlUxT0iWe8REor5uFCD6ZUd5pAoo2S2E+efD/puHPnTtJx//79pENjYj/++OPiuHfvXtJhYZhHc4tlXHsRyz71lWerXTtI7JeqopyK4EvikNgUgUQaUyyJR0KSqBaBLfKrOMRaGE9+9sM+twpD16lAxGrMY/kEfvPRr5MOxunz6f2v/z5JOnSdWGK4gzBOvOYQSwzr0udaxi1i5nHlySyb19PjJRDHDjVLICIGFYlHGIohwSziEUMCk9hcS8zZBDJLFJpXxVCywwWiRaP2vfd+mHSQkJ4nvLU7PHz4MOmwMJ787Ed7FKuE7bFLIO3fLoxyKYovCUNjSyDBHeTSBcJdw/K5m1gYxonnzkWfeMaViDUbJXwEX6src0sgJxFI5HMICWYRjxgSmHjL78GzLn3WYrxF0E9IWviXaRER1LCt+qcRCF9jrBO6e/duKg3inz17lnTo65VYjYklvpRPYsTwFYp9Mt7jR1+zSDCLeMT0EJ75LZ/5WZc+1zLeIuhMgbhq85t6I3wSK+KTeNY6D5kphCWQz/42Fkl5hL8E8umPqVjkbsWXQPxf6iXBLeIRcwbf6tPzFJ+xi7jrjtg1mKMlBGt+CWQJpEVaiztb4q1aOr8+gzg+1/DzBYXM+J4+dwTr/Z/9vPX6l1Jk9KxVYon19Em8x98ihnyNp45ilkCWQG6Ip0cgslbJNUMgkjsnfPRY+/PY4QKR161ow4Lnk9laf1s/pJOQHt9DPOaJ7B6C7V2rxPP0qdiItfjhiUfqCHYJ5MJ3EJLQ8vkaZvn8EE2MFSeGvtWDFY8SVvEeMeQYXRuxSyBLIJ/8sKElBCtOUdC3hGDFI2TNsbkAPMd5jtbxFIFsec3yvGJ5LgD/uSd/14NxTx5i+MrBPhnf07fIZsVJYMu3hGDFrTxWD1a8RdDWPO+T12/l5PwSiOPHGEj+MwiE/fAXmuiTkCSz56d5rbUUC/MwP9eyH/okYK/vFQVxkZqnFogQgSfm8blT3NYdZAnks58A9nAix1ykQF57+GbSwV9K4leudN5rR61lP6xNoh7l88lMn09yPuH55OeOQIy1lnjmsdayH/oRgnqwuQBax56cijnNDkLikZCjSM78Hp912Q/XHiUK1iXxGPeQ3CL2jDzsU8k30rZEwflI3WkCiX5QJ/FISBKVGI8/ai37YV0S6SifxGMPL5pASHqKIfeJ8/inFAhJaJGcpKU/ey3zk5BH+Usgn30eIeFzYcgx573+Egj+SB3JbwmTmBmiiP5uiNUDdxCPb+Vh3JOHGK5V30vMs+CWQE4qkMhvGCr5aElUj8+1lu/JQ4yV5yzk9/RxGoHw/5XTt57k/H4EfT7hR61lP/QtAvTGdRfpEQmJ6vE9PXvyEFPL6SHnGTBTBRL5oE7i0R9FcgqHgqJPDOuyH/o1AvTOqUh68+Treb70c1zpmHj6JawndgYBtHpYAsFfcVwCef5/Dy1yUxT0LXwr3iLnGeanC8S7i1hPZj7J6fMrV/SJsXzi6Vt43mirT2JG+C/CDiLX6QwiqPWwi0BEJJZQJC4XyiKeRVoSm76FZ5x4+sTQJ+GtPokZ4c8SCM+Xvqdn4ul71lqYGjnPMLerQFQotHrhLOKRqPR5g+gTY/nE07fw2qNYq09iRvgvikDkWp1BCFYPhwrEQySLtCQ2feKZn3Hi6RNDn3n28l8kgcg1tQh6dHwJBN8HoSjo7yUK1lGBiGV8i8+HAD9c0yeGNRgnnj4xXBv1jxZDqf7/AdVoY/i7GpcvAAAAAElFTkSuQmCC" - }, - { - "name": "Verdict", - "description": "Before even getting to defend your case, the judge says \"I've heard ENOUGH! It's time for a verdict!\"\nDang! You're definitely in kangaroo court!\n\"GUILTY! AND YOUR SENTENCE IS:\"", - "choices": [ - { - "key": "choice 25", - "name": "\"DEATH!\"", - "exit_node": "FAIL_DEATH", - "requirements": [ - { - "quality": "Crimes Committed", - "operator": ">=", - "value": 4 - } - ], - "delay": 0 - }, - { - "key": "choice 26", - "name": "\"SPACE JAIL!\"", - "exit_node": "Not Actually Space Jail, Just Normal Jail", - "requirements": [ - { - "quality": "Crimes Committed", - "operator": ">", - "value": 1 - } - ], - "delay": 20, - "delay_message": "You are being jailed..." - }, - { - "key": "choice 27", - "name": "\"FORGIVENESS! Just trespass? That's not that bad!\"", - "exit_node": "Sweet Sweet Freedom!", - "requirements": [ - { - "quality": "Crimes Committed", - "operator": "==", - "value": 1 - } - ], - "delay": 10, - "delay_message": "WOOP WOOP" - } - ], - "image": "default" - }, - { - "name": "Not Actually Space Jail, Just Normal Jail", - "description": "You'll have to wait out your crimes against the robo brits.", - "choices": [ - { - "key": "choice 28", - "name": "Sit out your sentence", - "exit_node": "Sweet Sweet Freedom!", - "delay": 1200, - "delay_message": "Sitting out your sentence..." - } - ], - "image": null, - "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAOkUlEQVR4Ae1caQ5etw30lYrcoblZgZzaBVsMMJlw1dNbnOiHwX04lMT3GUbaH3/854+fu//89q/ffnb+7O67E6/D33J29rwb61eaqcv17jv4cceldIe7o/cuzL/DDHoWv9JMXa6Wp3PutM+CBL+g3QvaeRl3Y/1qM32B71mQsyB/+evw3YvaxT8LEjzO7gHemfeFy9k936820xf4nl+QYEm/cDlnQd7/x56zIGdBzl+xgjdgH6izIMHhnF+Q/f/8P/1F/MIdnAU5C3J+QYI30P4F+fnjx0/9k30Nos1XDLYzPItxLvSq5kqcZ0A/lohf6aG1hq++nTY4q7S+7NvZU7EmMxonPnPVJ5y1VnlFdvoLoqCe7QEz8WpIxfTwzKd5kR3VT/08Q9RL/dMemg889a/YHhbPBB15sE1O+wGjquvmAce4oMaTytnLiXzoUclwQSJg9XsNmLjmd2wPs1OnOR5O13fHDFlv5p7ldWKMZTpqeCbTNQ9x5HekYkQ13Tyu9zgyDviyr6tzn0x3F+RqkyvE0VtJwz+VitO1MUN1SRmfbi8Po1vr5UV41UyIe5iRL+rF+Z0czmfdq4UPfGFPJPfI9L8sSLdJBnrlUaG/4sO/IhWrY+Pwr87S6RXN1Kn1ciI8zBTFzW85Hmbki7CQH8XNj5xMZvWdeVCf9chi7QXJQDRWPSoMhjoMoRJxkxozO/JHuYxX6eAYzRL5p729fPgqjl4ctavS5vJwPd9qD9R5mOxDXiS9O0K91sA/lX9aEAWF3QG1XOShzpM8FPJNerlZnGNRPWNqfmUzT8YxnWNXeiuuZ1c8Ne5hTH2KGdlTXC8/wja/l88+vQfG4jzTOTbRywXJwCIS6ofNA5nO2MhhmcU5Bp1rVUdOVzJXxeIY8DSHbeSo5BzTLe75tC6ytXbVjvDZv4qtdYypuuayzXegb8lwONd0xe7aSwuizWGjKWyV2VCaazbwTGqcY9A1h23kdCVzZRzTOQY8zWEbOSw5Dt3i0FlyXaZzzVU96xPxXO0Z9crw+A5M9zC03supfH+bBdHDULs6CI3zBSgWx6xO42ortlfDOVpvNscj3atb9UU94F/F9eqAqdLLhY/vAHpVr/GOvbQgBgyiLNGQfapjGJNVPuJeP8QU37ORO5HMUzERU79nez29vMrn4bCvql+JMz7rK1hVDeNDz2pwByxRB6n18E9kuSDWxAPU5pznxdiHoQyX/axzT/av6IzV1cFxpR/XaD+OTXXFYjvDsjwvbjN6fvgYn3XEPRn1ivzAYHzoiHkS98MSdZBaB/9E/mlBrFBBJzYaVwffwQTWLk6M19Fx8B2uUY7XJ8rt+qeYnM89MF91V1xvOmOozrkci/ycYzrnVb2YP/SqXuMde9uCcLPq0PVg1GYs0zXetRVnal+Zw+vV5Z3lTXE5H/PgQbGMenK96VGe+b1c9WUYnJv1sRhzh871Xh+Nd+y/LIgHXJHVwwHhTp3meKQ1p7I9jBWfzVH10njWR3NhT2s0HzgqNQ/34kmtZZtx2M8651Q616mOWvWr7c2AWkitgX8i3QUxAAWPbK8Zk4/qPL+HdZVLhNnx2xweT89X4Xk15lup45oI18Pme/F0xuIe0DmuOnK6kuu9Go6r7nE3XwfHy8l84YKgSMmxjRyV3gBcp7rWq635bGvuTtvm4F6qY85pT+B067r5yDPpYYNvR3r17Kt6ce6KzviqR/y9PlzrxStfuSAVgBePBlC/V/sln/KN7C9xzrhE/D1/hvN0zOPn+e7gdRYk+Z9bepfg+e64mDswPe6R747+q5gRR8+/2iOqOwvyD1oQewTeo/J80YN5w+/xi3y7+Z0FOQviLs3uh3YFL1oGz3+lj1f76oLYgB6pr/i8C4h8X+Fc8Yj4q7/CeTqu/CJ7N6+zIBt+Qeyydl/MXXjRw1L/Xf1XcZVfZK/iR3VnQc6CfP6vWPZ4o4VQf/TQV/23LMibA60eRFSnFxDZUf3X/BF/9R/e//9/ljwLkvyC2CPRhxPZX3tQEZ+Iv/qj+rf8yi+yd/M7C3IWxP0I7H5oV/GihVD/1T5afxbkLMhZkOQNnAVJDse+JvqFimz98nzVjvir/2v8lV9k7+Z9FuQsiPsR2P3QruJFC6H+q320/izIWZCzIMkbOAuSHI59TfQLFdn65fmqHfFX/9f4K7/I3s37LMimBbEL2305d+BFD0v9d/S+gqn8IvtKD6/2LMhZEPdX0nssb/qihVD/bo5nQc6CnAVJ3sBZkORw8DXSr1RkI//LMuKu/q/NoPwiezfvsyBnQc4vSPIGXl8Q+xLs3vrdeNHXSv27+67i/fv3339Gf5RzZK/2vqsu4qn+3f3PgiRfDxy2XkJkI/8tGS0F+yPu6ueat+bhvsovsrlmh34W5G+yIPygMz16WOrPMHY8vCmG8ovsKW6Vf9uCWONoCPVXJN+OK9/IfoNn9pC9WMRd/V6t+p6cV/lF9m5OZ0F+4V8QfbAdO3pY6u9gIWf3o/TwlF9me/Wrvs8tCA4dcnWwnXXZZXBsZ88OFs5oIplvpk8wLbfD90pOxlVjV/po7WcWpLoQJf6krRcQ2U9yqs4rikfc1R/VZ/4751d+mb2Tx1mQX/SvWNlDzWLZw+JYhlHFdj5QxmJ+mc41V/VPLEh14IhfHXa1PrsMjq3ir9ThTCbS+jDfTJ/gerkrM1U1GV+OVTiT+C+1IHYRk+F25fLhZ/qufh0c71FmPmBm/DmWYXVi6LdTMr9M39lz64J4B5cNgphXl/l2HkAHCzwr2cHalZOdj8a4ZzUD4lajOFOb++7Qwa2SO3oBY8uCZAdXDWPxrD6KYYAnZGcGy3mCC3pE56J+5ENOZ1G8qY2+O+SU+46elxakc1idoTo4mrNj+C5GZwbL6eLtyNPzmNideZjjBFtzGeeq3uG9+x6WF0QPIrK7Q0X1mf/qgXfruzN08XbkZecyiWWzKc8JLucqzqqdceXYKr5XdxbkH/bPvPxwWecHBt17MFzT1T2cFR94VXIFO6pZWpDuwVheNQziRnCCa7nRULv94NiRu3tHeNOzqvK92aLe5q/wNJ5hdWMeR8/XxevkfWJB9DC7dmfAHTneJUS+Hf26GN1z6ubpTBmPLibyMqxuTPlFdhevkzdeEAzcldEQ8HdxvLzOgDtywLUjd/TrYnhncsWn81U8pr0qvCqu/CK7wpnEb10QIxINAf/0kDl/MujVXPCt5NU+03o+j6u6ztbhMunZwctylF9kZxjT2GhBJodhuUYmGsL8UzzNnw57JT+bg2NXeqzW6rms2jyH6R0+014dzChH+UV2VL/iv21BQCYawvzTw+V84D8lszk49hQfrw+fz1TnGaB7PTzfpJdX3/WBVyW7eJ282xfESEQDTQ5WczvD7cyJZlD/zp6rWHpWHVvnMLvbv4OPnC6ml+dx9Hxe7arvlgVRMt4Q5sOhTaRiP2VHM6j/KT7TPtEZK3+2Jz0ifM8/weVc5pbpXHNVf3VBbEjvAD3f1UGv1mcXwrGrfZ6oZ76ZPuHi3Vnkm+BybsaVY1xzVf/8glwdcFc9X0Cm7+p3J07Gn2MTDtEyeP4JLucyt0znmqv66wuCQfUgrw62ux48K7m77x141QyIT3vrHUb2FBf54FVJ5O+Qn1kQDL1jqDswwK+Sd/TejVnNgPi0b7QQ6p/iIh+8Kon8HfIsSOM/VrSDri4F8R2XcjcGuFZyykMXIbKnuMiv+CKO/B3yLMhZkHD5pw8sWgj1T3GRjwWoJPJ3yEcWxIhWQyG+Y6g7MMCvknf03o1ZzYD4tK8uQmRPcZEPXpVE/g55FuT8goQfr+kDixZC/VNc5FeLgTjyd8jPLYgNuWOw3Rg4/Eru7nsHXjUD4tPeugiRPcVFPnhVEvk75FmQ8wtyfkGSN3DLgtiXQ7e32nqOa+0XbOaX6V/gWnHI+HOswuF49Gvh+bluojO3TJ9gVrmPLYgRyYbiWEX6jTjzq/Q3+E16Vvw53sX1FiHydTE1j3llutZdsW9bEDscJZYNxTGt+4LN/Cr9C3wzDhV/jmc4HIuWwfNz3URnXpk+waxyRwtiYN7AmY8JZENxjGu+ojO/Sv8K54hHxZ/jEYb6szfAMa2b2Mwr0yeYVe7tC2KHAxLZUBpDzZekcozsL3GOuETc1R/Vs58XoNK5bqort8ie4mb54wUxsOoQong0kOfPSL8V83h6vrf4Tfp6vD1fBzO6b8/fwYtyPH6eL6pf8T+6IHZg3kCeb2WYu2s8np7vbh478D3enq/q5S1B5qvwsrjHz/NlGNPY0oJYk+wQqpg3lPqmgzyRrxwj+wkuV3tE3NVf9anumuMVVhVXbpFd4UziryyIHVo0HPsngzyRy9wy/QkuV3tk/DmW9eHH39EzrE6MeWV6B6ubs7wg1qBzKFXOU4N2DyTLy7hyLMP4Soz5ZnrGt7pbjmc43VjGk2NdvE7epQWxBnwIqzoPx3pngCdzmFumP8lptVfGn2MR/vSuI5yJn3ll+gSzyr28INZgelhevjdwRf7puMfR8z3Na6Wfx9vzRdjeHUa+CGPq9/h5vilulr9lQaxBdDhTPw+cEX8jxtwy/Q1u054Zf455uNM79TBWfMwr01ewo5ptC4IG08Pz8nl44H5BMq9M/wLXikPGn2OK491X5tP6KzbzyvQrPbR2+4JYg+zAujEcgBJ+0wanjnyTZ6d3ZwbLUazu/SFP66/Yq5yv9LxlQYwQDuiqvDLc7truBXkPazeXq3jdWbjP9C65doe+wvlq39sWxIhNDzTLvzrojvruBZ0F+f1/d7/jzBmje/5cc1W/dUFALnv40xgw35JvXNIds07n+MI9TTnvOLdHFsSITg84y98x+CrGG5e0yjWrm86R3YcXy3qvxqacV/tw3WMLYk29g1z18RBP6m9c0h3zTeaY3tEdfA1zwnkXh0cXBKSnBx7lA+9J+cYl3THfZI7o/D3/HVyBOeGMmqvyv9va9kZwciKCAAAAAElFTkSuQmCC" - }, - { - "name": "Sweet Sweet Freedom!", - "description": "You're free! You spend a good while travelling around England (or at least the replica) and enjoying the cuisine, people and culture! Good society research is gained from this or something, but really you're just enjoying the sights and sounds.", - "choices": [ - { - "key": "choice 29", - "name": "Nice!", - "exit_node": "WIN", - "delay": 0 - } - ], - "image": null, - "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAQJklEQVR4Ae2deXBX1RXHY23/6DYdFBekilIInVrsTBUUEKWitf1Hp4467XQ6Y6frtLWtdpzWhaCCCQmJieKCKHWKY52xjgsg4AIo7s601NYlIoSdaEJIQgwgWU7nxB643Nz93fveu7/fy8ybu527vHu/n3ve/W2pgIB/B/v6ofHBV+H07y+Az319NlSMm1WS1+YdncpZ3HDpT2H9yNODXRsuuUrZ/5adnSU576inoydUwYSLmmDu3S/A/gN9ynlwKaxwqWRTZ2BgEHa17YW/PvYvGHN+fUkuVAFINhvf6Gl1sPCRN2F7azf0DwzYyNLYNjgg7EgOfNIH9Ytfhm9870747ITS8SgFIOkBcnRlFYy/sAluWbAWevd9wsorSDxVQPAO0KPs/KgbHnj0n3DKeaXhUQpA0gHkpKl1cM/Db8C2XV3BPAZPWWqALLzhGjC9YjurFICEA2TIY8xshNl3rIae3gO8foOngwNiCoXMLgZYCkDCADJqai3c/dAbsHVnF/T3hzlj6AjzDohM6D7y8wpLAYg/QD5TWQVfu6ARZjU+D909+3X6DV7uDIgPwSdtIy/AFID4AeTEKbWwYMnrsGVHZ2YegyduGCBJRZtV/SxhKQBxBwQ9xriZjXBjw3Owp3sfr8/M0xVZCTpkv2nDUgDiBgh6jDv+9lqmZwwdgdEDUltdq3x1LA1YCkDMATlq/Cw4bcbt8Jf5z8Luzl6dPjMvjx4QG0/02oqlgJdvaApAzADB9zEWLHkNWrbvgb6MXpWyJS53gKBHML1s4EBbAoRCX6AUgKgBOfX8BriudhW0dXxsq89M7QcHByFTQEioWYUFIGphJ52f48+eBw2LX4FN2+LxGEQkfrZryRPrwwGSleht+00qAqxfeJAjQRtzfgP8qWYlfNjeQ3qLIkSPsadrHzz+zDvw7Uvv+fRR3PYxRWZvK8y82BeAHCnuJPOBHqP+gZdh09aOaM4YRC56jIeXvgWTLlsIn//mrYfPqTLB2+bnRfC240giCKpb7h7klOn1cM1tK4Y+hEqCiyEc8hjd++CJ596FST+49zAU7PeWbEFQ2duKMy/2JHTXsFwBOW5yDdQtegk2bumAvr5sPivlCiJ6jEeW/wcmX7YQvjCR8RgsHBhXCd62LC+Ctx2HKxhUr9wAOXn6fPj9nKdhe2uXqz4zqYceo3Pvfnjq+ffgnMvvE3uMApBP3wthISKhu4blAsjIyTUw7751sGHz7ig9xqMr/gtnX36f2mMUgAwH5NQZDWa7CT95/0+XOiBfPXc+/O6W5bB1ZyfgLhzTX9fe/bBsTTNMvXKR2xrbPkbJ7NkdObY4vk5fv/gVOOGceU6TWKqAjJxUA9X3vjjkMfAHOGL6wzPGY6vegSlXLIIvnqE4Y0g2vUNPEzLB2+bHBgU7Xlx43Bnxq8DXVq8EfB3/0ATpJrAE3wfBH0P4zexlsHn7nug8RnfPAXh67fsw/UcPWK2hdL1tQRDZs2LTxUX1Q+XpxsKW0+6InxHauLUDahe9BPi6vnTiGHBKxYMce1Y1zLnrBXi/pR1i9BiPP/upx/jSGXOM1s1kbStIJElFSu2owqR92NZXjYUvI0AoRI+yrbUL/jD3ae2PS8QOyKipdfCrWU8NbQyxnTHQY6x8cQPM+PFif1Awm98hQEgwtiIke6qvCsk2rVA1Fr6MwOBDfH0fPUrNwnWAr/uLdp1YATnmrGq4+c410LwpTo/x5HPvwrQr7wevHoOFA+O8UDDtImBRO3yeS7tJ6/BjkKV5MPg07qz4C4VX37oc8H0AFpTYABk1pRZ+ceOTQ4fv2DxGz8cHYNW6D2DmTx4E/G4Juw5B4jLBYL6NOFXtUJlNe75sqW9fIXqUD7bsHvqpS3xfABclFkBGnHkbVDWthvc2tnk/Y3z34osh5IWvSi1d/R6c+8P74cvf8njG4D0Gn9YJx0Soujao3KQt3zbUt+8Qd1784g++2tPapv7Uata/zdva3gM/u/4JaG5p9/qqVEggdG0H8RY8HLJHLF5MOtHy9rK0rp0Q5bKx+MjHx7C+vn6t6LIGBGE+eNDf+xg68aZdHhQWG6HwArapi7Z8/TTStmN0sefPK3w6a0D48bim0xa+bX9BQHERhGudNIDg+3Adq009neBiB8RWqHmzTwSOjRCS2vLiTSOddMym9VWQxApI3oSedDxOoKBITUWQxC4pDBUVFUCXTVtJxmxTt9QASSrGvNa3hoTEZiMGF1vqxyUkMNjQtB2XsbrUKSVA8ipuX+NSrRVfNuwLUy7i0NUxFbPMjsDAcopjKLPn83Xj81HOTyybzvsjli/hxdQOuz6q+DBAUFw+BENt8GK1TYuAEOWp2qWxhAxVk5xXQGISdIixqtaMynINiAoEVZkMFhNA2Lom9mRDEyoK8wZICLHF2KZorfi8YICwQnONEwSy+lSOocwmST6J3zTkJ5fSeQIkRiGHHDOtkSxMDEgSAarqmorf1E7Vl6rMFA60k/2VKiAw+itAF4mY0rKQ7PISytaM8nMJiK3oyV4ldNcyG0B6//0OiK7mmVcG+x/p+P/Xm2deIeyXH4tvUcogSJLve4wm7fHzxKZzDYipqAkQDE3r2NjZQPLWmEnAX+uPnxgUEGyf71OUNhGLjU0SEGzr2ozL1lY0V5QnBATFYyoKG6GZ2LqKneqZ9GFrYzoXaIc7eh4vW9Go7G3F7dteNTbXMtma5QoQErmLJ0hSVwdM7IC4ioav51voPtrjx+iazj0gPgRObegE71JuColsorPKdxUM1fMh4jTaoPG6hrL1SexBUDgugmPrkLAxZPPzFI8REFexpCHoEH243i/Wyy0gMcCBoMYGiItYQog27TZd7jsKQNL0FgSlTZ8xAWIrkrRFnEZ/tnNg7UFsdk0bofG2LmLl27BJU38Y2tQrVUBMxMrOGcZN6mRtUzKA2IjUhy0ttm1bsQBiKgwTAdNcyUKTNrKyMZ0HssutB7EValJ7WmzbdgpADn9hjeYwK/Gb9EvCNw0LQBy/S0IgxQCIqRhMBEYQ6EKTtrKyMZ0PtCsAYQAh0duEBSDDPQjCk5X4TfotALnhGuODNrsT2oBBtgUgcQHiAw70KtI3ClEYpqIgEeU1TAqHzVzIXHXofBtBmOy+7Jyp4iZtZWFjMx+qtfEOCE1mXmCh8WCYZEymm4VqskOW2QjCVLDs3Inipu1kYWczH6p1CQaIaEKTitRU4KK+TevK7ApAhj9iZSF8kz59wYHgeAEExcMKSyTQLPPYsbnGyxEQEiO/dpSf19ArILy4WQGZikLVBtseP9Eh02y/PuKmc6Fy1yHLbESBtnkVt49x2cyFbk2O+Ac6vJBMRWEKCN9+TGnTudBNeKhyG1HwtjJRTpw4EUwvWRtZ5PP3J0ubrMURgJAIWOFSni5k65RiXHf/VE5f1WTDNL5yKxOBbb4pEKHsfABlc8/sOoniQkBosVHoFNeFpQgF3ZPu3tny3vVvA38F/9GGC64Y6tNGGDJbXvhox+flIS0DSXZfqnx+vdi0EhB24XVxElMphbp7FpXTz8WwYVo/+6MSgc+yPAAiGgNC43qf7Hqx8QIQwbvxIuGb5rGTS/G0AMH+XAXiq55IuGnlJb0HWi829AaIqYBK3Y6dXIqnCQj2mVQoIeqHhMTneGnNKCwAWbHU+JxlAjdNLBumDQj27VM0IdtKCk6IsbFrVwDiERB2Ytl4FoDEBEkIkSdtk9avAKSEAaFFTiqWcq5fAOIJEBKjKMzKg/BjKWehu957AUhCQEw+LpMXQFhgXAVTbvUqaqtrAS+TA2hhc/hAbwKGyMbk4w22NhsuuYrVvnW83ERvc7+HAClAOSx+1UYgEr1Lni0EKvukgIiIshFRKdtWyBZXJZJyLZPNlWu+SvQ2ZTpABgcH4WBfv4gD47xShkB1b1JAaNHLFQa6b/KsGNKc+AptIFDZ6gBpbe+Bn9/wJDS3tAPC4vtPJbDYy7SAkBhE5xRWPGnFaTylEqqEb1qmA2TLzk6oGDcLjjmzGmbfsXoIlKQexQSy2OHA8RsDgoJUQVAqgk37PkwhUNmZAoKQ4DVqah388qan4IMtu4N4FB08MYFjBUja4imH/lTCNy2zBYRAOeasarhlwVp4v6U98RlFB4Xv8rQgKwCpGP5jBGmCaQqBys4VEAJl9LQ6+HXVUti0rSMTj5IEntCgFIAUgAw9diEsx06qhrl3vwAbNu+OzqP0DwwE+YBm7gEZO3YsiC7ZLt/W1gbsJbPLS77KM5iWJfUg5EkoHD1tPvz25mWwecee6DxK1979sGxNszdYcguICApRHguDKp4XINhxmAKgs/MNCIEyclIN1CxcN3SY7+sbSPIklHpd9Cj/WPl2YlByAwgrbhEIujy2viheWVkJIS9W+Hx8xIgRwF5UrhO+aXkoQAiUk6fPh6tvXQ5bd3ZG6VGSnFMyB0QkZh0MonJRO3xeSECobRYEXdwUAJ1daEAIlJGTa6B20UuwcWsHxOhRXECxAoREkDSkHRTb4UUsEr9pHt8Wn046bpP6OijYcp3wTcvTAoRAOXl6Pfxx7grY0dqV+qNTkg7xUwS2kBgBYiIMFxtewJg2hUFkJ2qPzXMZo0sdFgJd3BQClV3agBAox02ugfn3vxydR7GBpAAkwNlEBwVbrhK+aVlWgBAoY86rh2urV8Kuj/Ym2eBTrWsKySFA2EXDOPsY5LKLmtRhd3eKizyDaR61IQtNxuTDhp9LVdoUApVd1oAQKMefPQ8aFr8CLdv2QF9//l/1MoGkQrV4WOZDMLI2REI2hUFkJ2qP8mRjCJGvm1O+XCV+k7K8AEKgnDqjAa6btwo+bO9J1SvYdlYAwrxpGAIEUZu8+E3SJhCobPIGCIFywjnzoPHBV6Flez49SpSA4I4v8g66PPIUolAk5FB5JkDwNirxm5TlFRAE5ajxs+C0GQ3w57pnoK3jY9tNPri9DhLtIxYuZigxYbsiQetgEJWL2sG8kGNn2+ZFb5M2gUBlk2dAyJtgeNLUOrjroddh845O6M/JGSVKQFDYIghkeTI4bESapa1K/CZlsQBCHmXsd26H6+ufhY7O3uAeQteBF0BIPOyO6TMuErgMBlG+qD6NOYbQBAKVTUyAsB7lxCm1sGDJ67BtV1emHkUFidEjlg+RqYASCRzzRDDI8tg2fIw37TZUAOjKYgUEYflMZRWMv7AJbmp8HvZ079Nt+EHKcwGITnCswCkug0GUT3Uw1PWVx3IdBKrymAFhPcqoKbVDZxT8UGSaZ5QoAEHRsiLHuAgEWR7VzaP4TcakAkBXViqAkEcZN7MRqppWQ3fP/iAeg280WkBsICkA4Zf9cJp+1YTdrWOI46te9zz8RvAzSjSAJPEiBSCHgeBjsQKCEB9dWQWVFzbBzXeugZ7eA/yteUmXDSAmjzJ5ttE9SsnKS+kRS+XZTppWBwv//iZsb+0C/Magr7+oAOG9iOzMweejB8mz+E3GJgNAl18ugJBHmXBRE8y5ay307j/oixHp90T+B7kri9Q1LZ2DAAAAAElFTkSuQmCC" - } - ] - } diff --git a/code/modules/explorer_drone/manager.dm b/code/modules/explorer_drone/manager.dm index 74a972216a41cb..9ca85ca4a20a59 100644 --- a/code/modules/explorer_drone/manager.dm +++ b/code/modules/explorer_drone/manager.dm @@ -24,27 +24,7 @@ if(.) return feedback_message = "" - var/mob/user = usr switch(action) - if("create") - var/datum/adventure_db_entry/new_entry = new - new_entry.name = "New Adventure" - new_entry.uploader = user.ckey - GLOB.explorer_drone_adventure_db_entries += new_entry - return TRUE - if("delete") - var/datum/adventure_db_entry/target = locate(params["ref"]) in GLOB.explorer_drone_adventure_db_entries - if(!target) - return - if(!target.remove()) - feedback_message = "Failed to remove adventure" - return TRUE - if("approve") - var/datum/adventure_db_entry/target = locate(params["ref"]) in GLOB.explorer_drone_adventure_db_entries - if(!target) - return - target.approved = !target.approved - return TRUE if("play") var/datum/adventure_db_entry/target = locate(params["ref"]) in GLOB.explorer_drone_adventure_db_entries if(!target) @@ -67,43 +47,6 @@ QDEL_NULL(temp_adventure) feedback_message = "Adventure stopped" return TRUE - if("refresh") - var/datum/adventure_db_entry/target = locate(params["ref"]) in GLOB.explorer_drone_adventure_db_entries - if(!target) - return - target.refresh() - return TRUE - if("save") - var/datum/adventure_db_entry/target = locate(params["ref"]) in GLOB.explorer_drone_adventure_db_entries - if(!target) - return - target.save() - return TRUE - if("download") - var/datum/adventure_db_entry/target = locate(params["ref"]) in GLOB.explorer_drone_adventure_db_entries - if(!target) - return - var/temp_file = file("data/AdventureDownloadTempFile") - fdel(temp_file) - WRITE_FILE(temp_file, target.raw_json) - user << ftp(temp_file,"[target.name].json") - return TRUE - if("upload") - var/datum/adventure_db_entry/target = locate(params["ref"]) in GLOB.explorer_drone_adventure_db_entries - if(!target) - return - var/source_json = input(user,"Select adventure JSON file.","Adventure Upload") as file|null - if(!source_json) - return - var/raw_json = file2text(source_json) - var/json = json_decode(raw_json) - if(!json) - feedback_message = "Decoding JSON failed." - return - //do basic validation here - target.raw_json = raw_json - target.extract_metadata() - return TRUE /datum/adventure_browser/ui_data(mob/user) . = ..() @@ -111,11 +54,10 @@ for(var/datum/adventure_db_entry/db_entry in GLOB.explorer_drone_adventure_db_entries) adventure_data += list(list( "ref" = ref(db_entry), - "id" = db_entry.id, + "filename" = db_entry.filename, "name" = db_entry.name, "version" = db_entry.version, "uploader" = db_entry.uploader, - "timestamp" = db_entry.timestamp, "approved" = db_entry.approved, "json_status" = db_entry.raw_json ? "Valid JSON" : "Empty" )) diff --git a/code/modules/fishing/aquarium/fish_analyzer.dm b/code/modules/fishing/aquarium/fish_analyzer.dm index c7feab860ca0b4..a83aa4296b6c91 100644 --- a/code/modules/fishing/aquarium/fish_analyzer.dm +++ b/code/modules/fishing/aquarium/fish_analyzer.dm @@ -33,6 +33,17 @@ case_color = rgb(rand(16, 255), rand(16, 255), rand(16, 255)) set_greyscale(colors = list(case_color)) . = ..() + + var/static/list/fishe_signals = list( + COMSIG_FISH_ANALYZER_ANALYZE_STATUS = TYPE_PROC_REF(/datum/component/experiment_handler, try_run_handheld_experiment), + ) + AddComponent(/datum/component/experiment_handler, \ + config_mode = EXPERIMENT_CONFIG_ALTCLICK, \ + allowed_experiments = list(/datum/experiment/scanning/fish), \ + config_flags = EXPERIMENT_CONFIG_SILENT_FAIL|EXPERIMENT_CONFIG_IMMEDIATE_ACTION, \ + experiment_signals = fishe_signals, \ + ) + register_item_context() update_appearance() @@ -42,6 +53,10 @@ radial_choices = null return ..() +/obj/item/fish_analyzer/examine(mob/user) + . = ..() + . += span_notice("Alt-Click to access the Experiment Configuration UI") + /obj/item/fish_analyzer/update_icon_state() . = ..() icon_state = base_icon_state @@ -190,21 +205,24 @@ if(fish.status != FISH_DEAD) render_list += "\n" - var/hunger = PERCENT(min((world.time - fish.last_feeding) / fish.feeding_frequency, 1)) - var/hunger_string = "[hunger]%" - switch(hunger) - if(0 to 60) - hunger_string = span_info(hunger_string) - if(60 to 90) - hunger_string = span_warning(hunger_string) - if(90 to 100) - hunger_string = span_alert(hunger_string) - render_list += "Hunger: [hunger_string]\n" + if(!HAS_TRAIT(fish, TRAIT_FISH_NO_HUNGER)) + var/hunger = PERCENT(min((world.time - fish.last_feeding) / fish.feeding_frequency, 1)) + var/hunger_string = "[hunger]%" + switch(hunger) + if(0 to 60) + hunger_string = span_info(hunger_string) + if(60 to 90) + hunger_string = span_warning(hunger_string) + if(90 to 100) + hunger_string = span_alert(hunger_string) + render_list += "Hunger: [hunger_string]\n" var/time_left = round(max(fish.breeding_wait - world.time, 0)/10) render_list += "Time until it can breed: [time_left] seconds" to_chat(user, examine_block(jointext(render_list, "")), type = MESSAGE_TYPE_INFO) + SEND_SIGNAL(src, COMSIG_FISH_ANALYZER_ANALYZE_STATUS, fish, user) + /** * Called when a fish or a menu choice is left-clicked. * This returns the fish's progenitors, traits and their inheritability. diff --git a/code/modules/fishing/fish/_fish.dm b/code/modules/fishing/fish/_fish.dm index 21585a075466f2..1275886141b52f 100644 --- a/code/modules/fishing/fish/_fish.dm +++ b/code/modules/fishing/fish/_fish.dm @@ -136,6 +136,9 @@ var/min_pressure = WARNING_LOW_PRESSURE var/max_pressure = HAZARD_HIGH_PRESSURE + /// If this fish type counts towards the Fish Species Scanning experiments + var/experisci_scannable = TRUE + /obj/item/fish/Initialize(mapload, apply_qualities = TRUE) . = ..() AddComponent(/datum/component/aquarium_content, PROC_REF(get_aquarium_animation), list(COMSIG_FISH_STATUS_CHANGED,COMSIG_FISH_STIRRED)) @@ -175,7 +178,7 @@ balloon_alert(user, "[src] is dead!") return TRUE feed(item.reagents) - balloon_alert(user, "you feed [src]") + balloon_alert(user, "fed [src]") return TRUE /obj/item/fish/examine(mob/user) @@ -185,14 +188,14 @@ . += span_notice("It weighs [weight] g.") ///Randomizes weight and size. -/obj/item/fish/proc/randomize_size_and_weight(avg_size = average_size, avg_weight = average_weight, deviation = 0.2, first_run = FALSE) - var/size_deviation = 0.2 * avg_size - var/new_size = round(max(1,gaussian(avg_size, size_deviation)), 1) +/obj/item/fish/proc/randomize_size_and_weight(base_size = average_size, base_weight = average_weight, deviation = 0.2) + var/size_deviation = 0.2 * base_size + var/new_size = round(clamp(gaussian(base_size, size_deviation), average_size * 1/MAX_FISH_DEVIATION_COEFF, average_size * MAX_FISH_DEVIATION_COEFF)) - var/weight_deviation = 0.2 * avg_weight - var/new_weight = round(max(1,gaussian(avg_weight, weight_deviation)), 1) + var/weight_deviation = 0.2 * base_weight + var/new_weight = round(clamp(gaussian(base_weight, weight_deviation), average_weight * 1/MAX_FISH_DEVIATION_COEFF, average_weight * MAX_FISH_DEVIATION_COEFF)) - update_size_and_weight(new_size, new_weight, first_run) + update_size_and_weight(new_size, new_weight) ///Updates weight and size, along with weight class, number of fillets you can get and grind results. /obj/item/fish/proc/update_size_and_weight(new_size = average_size, new_weight = average_weight) @@ -414,11 +417,14 @@ return FALSE return TRUE +/obj/item/fish/proc/is_hungry() + return !HAS_TRAIT(src, TRAIT_FISH_NO_HUNGER) && world.time - last_feeding >= feeding_frequency + /obj/item/fish/proc/process_health(seconds_per_tick) var/health_change_per_second = 0 if(!proper_environment()) health_change_per_second -= 3 //Dying here - if(world.time - last_feeding >= feeding_frequency) + if(is_hungry()) health_change_per_second -= 0.5 //Starving else health_change_per_second += 0.5 //Slowly healing @@ -541,10 +547,11 @@ #define FLOP_SINGLE_MOVE_TIME 1.5 #define JUMP_X_DISTANCE 5 #define JUMP_Y_DISTANCE 6 -/// This animation should be applied to actual parent atom instead of vc_object. -/proc/flop_animation(atom/movable/animation_target) + +/// This flopping animation played while the fish is alive. +/obj/item/fish/proc/flop_animation() var/pause_between = PAUSE_BETWEEN_PHASES + rand(1, 5) //randomized a bit so fish are not in sync - animate(animation_target, time = pause_between, loop = -1) + animate(src, time = pause_between, loop = -1) //move nose down and up for(var/_ in 1 to FLOP_COUNT) var/matrix/up_matrix = matrix() @@ -565,6 +572,7 @@ animate(time = up_time, pixel_y = JUMP_Y_DISTANCE , pixel_x=x_step, loop = -1, flags= ANIMATION_RELATIVE, easing = BOUNCE_EASING | EASE_IN) animate(time = up_time, pixel_y = -JUMP_Y_DISTANCE, pixel_x=x_step, loop = -1, flags= ANIMATION_RELATIVE, easing = BOUNCE_EASING | EASE_OUT) animate(time = PAUSE_BETWEEN_FLOPS, loop = -1) + #undef PAUSE_BETWEEN_PHASES #undef PAUSE_BETWEEN_FLOPS #undef FLOP_COUNT @@ -578,7 +586,7 @@ if(flopping) //Requires update_transform/animate_wrappers to be less restrictive. return flopping = TRUE - flop_animation(src) + flop_animation() /// Stops flopping animation /obj/item/fish/proc/stop_flopping() @@ -593,7 +601,7 @@ /obj/item/fish/proc/refresh_flopping() if(flopping) - flop_animation(src) + flop_animation() /// Returns random fish, using random_case_rarity probabilities. /proc/random_fish_type(required_fluid) diff --git a/code/modules/fishing/fish/fish_traits.dm b/code/modules/fishing/fish/fish_traits.dm index bec868ad24e77f..63de4cfdf1dced 100644 --- a/code/modules/fishing/fish/fish_traits.dm +++ b/code/modules/fishing/fish/fish_traits.dm @@ -12,6 +12,8 @@ GLOBAL_LIST_INIT(fish_traits, init_subtypes_w_path_keys(/datum/fish_trait, list( var/diff_traits_inheritability = 50 /// fishes of types within this list are granted to have this trait, no matter the probability var/list/guaranteed_inheritance_types + /// Depending on the value, fish with trait will be reported as more or less difficult in the catalog. + var/added_difficulty = 0 /// Difficulty modifier from this mod, needs to return a list with two values /datum/fish_trait/proc/difficulty_mod(obj/item/fishing_rod/rod, mob/fisherman) @@ -161,7 +163,7 @@ GLOBAL_LIST_INIT(fish_traits, init_subtypes_w_path_keys(/datum/fish_trait, list( /datum/fish_trait/necrophage name = "Necrophage" - catalog_description = "This fish will eat the carcasses of dead fishes when hungry." + catalog_description = "This fish will eat carcasses of dead fish when hungry." incompatible_traits = list(/datum/fish_trait/vegan) /datum/fish_trait/necrophage/apply_to_fish(obj/item/fish/fish) @@ -169,7 +171,7 @@ GLOBAL_LIST_INIT(fish_traits, init_subtypes_w_path_keys(/datum/fish_trait, list( /datum/fish_trait/necrophage/proc/eat_dead_fishes(obj/item/fish/source, seconds_per_tick) SIGNAL_HANDLER - if(world.time - source.last_feeding < source.feeding_frequency || !isaquarium(source.loc)) + if(!source.is_hungry() || !isaquarium(source.loc)) return for(var/obj/item/fish/victim in source.loc) if(victim.status != FISH_DEAD || victim == source || HAS_TRAIT(victim, TRAIT_YUCKY_FISH)) @@ -233,7 +235,7 @@ GLOBAL_LIST_INIT(fish_traits, init_subtypes_w_path_keys(/datum/fish_trait, list( /datum/fish_trait/predator/proc/eat_fishes(obj/item/fish/source, seconds_per_tick) SIGNAL_HANDLER - if(world.time - source.last_feeding < source.feeding_frequency || !isaquarium(source.loc)) + if(!source.is_hungry() || !isaquarium(source.loc)) return var/obj/structure/aquarium/aquarium = source.loc for(var/obj/item/fish/victim in aquarium.get_fishes(TRUE, source)) @@ -334,6 +336,7 @@ GLOBAL_LIST_INIT(fish_traits, init_subtypes_w_path_keys(/datum/fish_trait, list( diff_traits_inheritability = 45 guaranteed_inheritance_types = list(/obj/item/fish/clownfish/lube) catalog_description = "This fish exudes a viscous, slippery lubrificant. It's reccomended not to step on it." + added_difficulty = 5 /datum/fish_trait/lubed/apply_to_fish(obj/item/fish/fish) fish.AddComponent(/datum/component/slippery, 8 SECONDS, SLIDE|GALOSHES_DONT_HELP) @@ -352,3 +355,26 @@ GLOBAL_LIST_INIT(fish_traits, init_subtypes_w_path_keys(/datum/fish_trait, list( ADD_TRAIT(fish, TRAIT_FISH_AMPHIBIOUS, FISH_TRAIT_DATUM) if(fish.required_fluid_type == AQUARIUM_FLUID_AIR) fish.required_fluid_type = AQUARIUM_FLUID_FRESHWATER + +/datum/fish_trait/mixotroph + name = "Mixotroph" + inheritability = 75 + diff_traits_inheritability = 25 + catalog_description = "This fish is capable of substaining itself by producing its own sources of energy (food)." + incompatible_traits = list(/datum/fish_trait/predator, /datum/fish_trait/necrophage) + +/datum/fish_trait/antigrav/apply_to_fish(obj/item/fish/fish) + ADD_TRAIT(fish, TRAIT_FISH_NO_HUNGER, FISH_TRAIT_DATUM) + +/datum/fish_trait/antigrav + name = "Anti-Gravity" + inheritability = 75 + diff_traits_inheritability = 25 + catalog_description = "This fish will invert the gravity of the bait at random. May fall upward outside after being caught." + added_difficulty = 15 + +/datum/fish_trait/antigrav/minigame_mod(obj/item/fishing_rod/rod, mob/fisherman, datum/fishing_challenge/minigame) + minigame.special_effects |= FISHING_MINIGAME_RULE_ANTIGRAV + +/datum/fish_trait/antigrav/apply_to_fish(obj/item/fish/fish) + fish.AddElement(/datum/element/forced_gravity, NEGATIVE_GRAVITY) diff --git a/code/modules/fishing/fish/fish_types.dm b/code/modules/fishing/fish/fish_types.dm index 652b0aba8aa495..5ff62266ad9e66 100644 --- a/code/modules/fishing/fish/fish_types.dm +++ b/code/modules/fishing/fish/fish_types.dm @@ -341,7 +341,6 @@ icon_state = "sludgefish_purple" dedicated_in_aquarium_icon_state = "sludgefish_purple_small" random_case_rarity = FISH_RARITY_NOPE - random_case_rarity = FISH_RARITY_VERY_RARE fish_traits = list(/datum/fish_trait/parthenogenesis) /obj/item/fish/slimefish @@ -439,11 +438,13 @@ fillet_type = null death_text = "%SRC gently disappears." fish_traits = list(/datum/fish_trait/no_mating) //just to be sure, these shouldn't reproduce + experisci_scannable = FALSE /obj/item/fish/holo/Initialize(mapload) . = ..() var/area/station/holodeck/holo_area = get_area(src) if(!istype(holo_area)) + addtimer(CALLBACK(src, PROC_REF(set_status), FISH_DEAD), 1 MINUTES) return holo_area.linked.add_to_spawned(src) @@ -488,9 +489,9 @@ sprite_height = 5 /obj/item/fish/holo/checkered - name = "unrendered holographic fish" //it's a meta joke, buddy. + name = "unrendered holographic fish" desc = "A checkered silhoutte of searing purple and pitch black presents itself before your eyes, like a tear in fabric of reality. It hurts to watch." - icon_state = "checkered" + icon_state = "checkered" //it's a meta joke, buddy. dedicated_in_aquarium_icon_state = "checkered_small" sprite_width = 4 @@ -502,3 +503,37 @@ sprite_height = 4 sprite_width = 10 average_size = 50 + +/obj/item/fish/starfish + name = "cosmostarfish" + desc = "A peculiar, gravity-defying, echinoderm-looking critter from hyperspace." + icon_state = "starfish" + dedicated_in_aquarium_icon_state = "starfish_small" + icon_state_dead = "starfish_dead" + sprite_width = 4 + average_size = 30 + average_weight = 300 + stable_population = 3 + required_fluid_type = AQUARIUM_FLUID_AIR + random_case_rarity = FISH_RARITY_NOPE + required_temperature_min = 0 + required_temperature_max = INFINITY + safe_air_limits = null + min_pressure = 0 + max_pressure = INFINITY + grind_results = list(/datum/reagent/bluespace = 10, /datum/reagent/consumable/liquidgibs = 5) + fillet_type = null + fish_traits = list(/datum/fish_trait/antigrav, /datum/fish_trait/mixotroph) + +/obj/item/fish/starfish/Initialize(mapload) + . = ..() + update_appearance(UPDATE_OVERLAYS) + +/obj/item/fish/starfish/update_overlays() + . = ..() + if(status == FISH_ALIVE) + . += emissive_appearance(icon, "starfish_emissive", src) + +///It spins, and dimly glows in the dark. +/obj/item/fish/starfish/flop_animation() + DO_FLOATING_ANIM(src) diff --git a/code/modules/fishing/fish_catalog.dm b/code/modules/fishing/fish_catalog.dm index d41b4657e50a0f..a0f66c2227d0d3 100644 --- a/code/modules/fishing/fish_catalog.dm +++ b/code/modules/fishing/fish_catalog.dm @@ -68,14 +68,6 @@ if(source.catalog_description && (fish_type in source.fish_table)) spot_descriptions += source.catalog_description .["spots"] = english_list(spot_descriptions, nothing_text = "Unknown") - ///Difficulty descriptor - switch(initial(fishy.fishing_difficulty_modifier)) - if(-INFINITY to 10) - .["difficulty"] = "Easy" - if(20 to 30) - .["difficulty"] = "Medium" - else - .["difficulty"] = "Hard" var/list/fish_list_properties = collect_fish_properties() var/list/fav_bait = fish_list_properties[fishy][NAMEOF(fishy, favorite_bait)] var/list/disliked_bait = fish_list_properties[fishy][NAMEOF(fishy, disliked_bait)] @@ -91,12 +83,22 @@ // Fish traits description var/list/trait_descriptions = list() var/list/fish_traits = fish_list_properties[fishy][NAMEOF(fishy, fish_traits)] + var/fish_difficulty = initial(fishy.fishing_difficulty_modifier) for(var/fish_trait in fish_traits) var/datum/fish_trait/trait = GLOB.fish_traits[fish_trait] trait_descriptions += trait.catalog_description + fish_difficulty += trait.added_difficulty if(!length(trait_descriptions)) trait_descriptions += "This fish exhibits no special behavior." .["traits"] = trait_descriptions + ///Difficulty descriptor + switch(fish_difficulty) + if(-INFINITY to 9) + .["difficulty"] = "Easy" + if(10 to 19) + .["difficulty"] = "Medium" + else + .["difficulty"] = "Hard" return . /obj/item/book/fish_catalog/ui_assets(mob/user) diff --git a/code/modules/fishing/fishing_equipment.dm b/code/modules/fishing/fishing_equipment.dm index 6169b41fd88fce..3f34222ad87323 100644 --- a/code/modules/fishing/fishing_equipment.dm +++ b/code/modules/fishing/fishing_equipment.dm @@ -11,7 +11,8 @@ desc = "Simple fishing line." icon = 'icons/obj/fishing.dmi' icon_state = "reel_blue" - var/fishing_line_traits = NONE + ///A list of traits that this fishing line has, checked by fish traits and the minigame. + var/list/fishing_line_traits /// Color of the fishing line var/line_color = "#808080" @@ -59,7 +60,8 @@ icon_state = "hook" w_class = WEIGHT_CLASS_TINY - var/fishing_hook_traits = NONE + /// A list of traits that this fishing hook has, checked by fish traits and the minigame + var/list/fishing_hook_traits /// icon state added to main rod icon when this hook is equipped var/rod_overlay_icon_state = "hook_overlay" /// What subtype of `/obj/item/chasm_detritus` do we fish out of chasms? Defaults to `/obj/item/chasm_detritus`. @@ -175,7 +177,7 @@ name = "jawed hook" desc = "Despite hints of rust, this gritty beartrap-like hook hybrid manages to look even more threating than the real thing. May neptune have mercy of whatever gets caught in its jaws." icon_state = "jaws" - fishing_hook_traits = FISHING_HOOK_NO_ESCAPE|FISHING_HOOK_ENSNARE|FISHING_HOOK_KILL + fishing_hook_traits = FISHING_HOOK_NO_ESCAPE|FISHING_HOOK_NO_ESCAPE|FISHING_HOOK_KILL rod_overlay_icon_state = "hook_jaws_overlay" /obj/item/storage/toolbox/fishing diff --git a/code/modules/fishing/fishing_minigame.dm b/code/modules/fishing/fishing_minigame.dm index 478279749e406e..71617b4de07b34 100644 --- a/code/modules/fishing/fishing_minigame.dm +++ b/code/modules/fishing/fishing_minigame.dm @@ -43,8 +43,12 @@ var/fish_ai = FISH_AI_DUMB /// Rule modifiers (eg weighted bait) var/special_effects = NONE - /// Did the game get past the baiting phase, used to track if bait should be consumed afterwards - var/bait_taken = FALSE + /// A list of possible active minigame effects. If not empty, one will be picked from time to time. + var/list/active_effects + /// The cooldown between switching active effects + COOLDOWN_DECLARE(active_effect_cd) + /// The current active effect + var/current_active_effect /// Result path var/reward_path = FISHING_DUD /// Minigame difficulty @@ -61,6 +65,8 @@ var/obj/effect/fishing_lure/lure /// Background icon state from fishing_hud.dmi var/background = "background_default" + /// Fish icon state from fishing_hud.dmi + var/fish_icon = "fish" /// Fishing line visual var/datum/beam/fishing_line @@ -168,7 +174,10 @@ RegisterSignal(user, COMSIG_MOB_FISHING_REWARD_DISPENSED, PROC_REF(hurt_fish)) difficulty += comp.fish_source.calculate_difficulty(reward_path, rod, user, src) - difficulty = round(difficulty) + difficulty = clamp(round(difficulty), 1, 100) + + if(HAS_TRAIT(user, TRAIT_REVEAL_FISH) || (user.mind && HAS_TRAIT(user.mind, TRAIT_REVEAL_FISH))) + fish_icon = GLOB.specific_fish_icons[reward_path] || "fish" /** * If the chances are higher than 1% (100% at maximum difficulty), they'll scale @@ -194,6 +203,8 @@ if(!completed) complete(win = FALSE) if(fishing_line) + //Stops the line snapped message from appearing everytime the minigame is over. + UnregisterSignal(fishing_line, COMSIG_QDELETING) QDEL_NULL(fishing_line) if(lure) QDEL_NULL(lure) @@ -207,19 +218,21 @@ lure_turf?.balloon_alert(user, message) /datum/fishing_challenge/proc/on_spot_gone(datum/source) + SIGNAL_HANDLER send_alert("fishing spot gone!") - interrupt(balloon_alert = FALSE) + interrupt() /datum/fishing_challenge/proc/interrupt_challenge(datum/source, reason) if(reason) send_alert(reason) - interrupt(balloon_alert = FALSE) + interrupt() /datum/fishing_challenge/proc/start(mob/living/user) /// Create fishing line visuals fishing_line = used_rod.create_fishing_line(lure, target_py = 5) + active_effects = bitfield_to_list(special_effects & FISHING_MINIGAME_ACTIVE_EFFECTS) // If fishing line breaks los / rod gets dropped / deleted - RegisterSignal(fishing_line, COMSIG_FISHING_LINE_SNAPPED, PROC_REF(interrupt)) + RegisterSignal(fishing_line, COMSIG_QDELETING, PROC_REF(on_line_deleted)) RegisterSignal(used_rod, COMSIG_ITEM_ATTACK_SELF, PROC_REF(on_attack_self)) ADD_TRAIT(user, TRAIT_GONE_FISHING, REF(src)) user.add_mood_event("fishing", /datum/mood_event/fishing) @@ -228,6 +241,13 @@ to_chat(user, span_notice("You start fishing...")) playsound(lure, 'sound/effects/splash.ogg', 100) +/datum/fishing_challenge/proc/on_line_deleted(datum/source) + SIGNAL_HANDLER + fishing_line = null + ///The lure may be out of sight if the user has moed around a corner, so the message should be displayed over him instead. + user.balloon_alert(user.is_holding(used_rod) ? "line snapped" : "rod dropped") + interrupt() + /datum/fishing_challenge/proc/handle_click(mob/source, atom/target, modifiers) SIGNAL_HANDLER //You need to be holding the rod to use it. @@ -241,12 +261,9 @@ return COMSIG_MOB_CANCEL_CLICKON /// Challenge interrupted by something external -/datum/fishing_challenge/proc/interrupt(datum/source, balloon_alert = TRUE) - SIGNAL_HANDLER +/datum/fishing_challenge/proc/interrupt() if(!completed) experience_multiplier *= 0.5 - if(balloon_alert) - send_alert(user.is_holding(used_rod) ? "line snapped" : "tool dropped") complete(FALSE) /datum/fishing_challenge/proc/on_attack_self(obj/item/source, mob/user) @@ -278,7 +295,8 @@ if(reward_path != FISHING_DUD) playsound(lure, 'sound/effects/bigsplash.ogg', 100) SEND_SIGNAL(src, COMSIG_FISHING_CHALLENGE_COMPLETED, user, win) - qdel(src) + if(!QDELETED(src)) + qdel(src) /datum/fishing_challenge/proc/start_baiting_phase() deltimer(next_phase_timer) @@ -294,7 +312,30 @@ phase = BITING_PHASE // Trashing animation playsound(lure, 'sound/effects/fish_splash.ogg', 100) - send_alert("!!!") + if(HAS_TRAIT(user, TRAIT_REVEAL_FISH) || (user.mind && HAS_TRAIT(user.mind, TRAIT_REVEAL_FISH))) + switch(fish_icon) + if(FISH_ICON_DEF) + send_alert("fish!!!") + if(FISH_ICON_HOSTILE) + send_alert("hostile!!!") + if(FISH_ICON_STAR) + send_alert("starfish!!!") + if(FISH_ICON_CHUNKY) + send_alert("round fish!!!") + if(FISH_ICON_JELLYFISH) + send_alert("jellyfish!!!") + if(FISH_ICON_SLIME) + send_alert("slime!!!") + if(FISH_ICON_COIN) + send_alert("valuable!!!") + if(FISH_ICON_GEM) + send_alert("ore!!!") + if(FISH_ICON_CRAB) + send_alert("crustacean!!!") + if(FISH_ICON_BONE) + send_alert("bones!!!") + else + send_alert("!!!") animate(lure, pixel_y = 3, time = 5, loop = -1, flags = ANIMATION_RELATIVE) animate(pixel_y = -3, time = 5, flags = ANIMATION_RELATIVE) // Setup next phase @@ -307,7 +348,7 @@ ///The player is no longer around to play the minigame, so we interrupt it. /datum/fishing_challenge/proc/on_user_logout(datum/source) SIGNAL_HANDLER - interrupt(balloon_alert = FALSE) + interrupt() /datum/fishing_challenge/proc/win_anyway() if(!completed) @@ -345,6 +386,9 @@ RegisterSignal(user.client, COMSIG_CLIENT_MOUSEDOWN, PROC_REF(start_reeling)) RegisterSignal(user.client, COMSIG_CLIENT_MOUSEUP, PROC_REF(stop_reeling)) RegisterSignal(user, COMSIG_MOB_LOGOUT, PROC_REF(on_user_logout)) + if(length(active_effects)) + // Give the player a moment to prepare for active minigame effects + COOLDOWN_START(src, active_effect_cd, rand(5, 9) SECONDS) START_PROCESSING(SSfishing, src) ///Stop processing and remove references to the minigame hud @@ -369,11 +413,44 @@ ///Update the state of the fish, the bait and the hud /datum/fishing_challenge/process(seconds_per_tick) + if(length(active_effects) && COOLDOWN_FINISHED(src, active_effect_cd)) + select_active_effect() move_fish(seconds_per_tick) move_bait(seconds_per_tick) if(!QDELETED(fishing_hud)) update_visuals() +///The proc that handles fancy effects like flipping the hud or skewing movement +/datum/fishing_challenge/proc/select_active_effect() + ///bring forth an active effect + if(isnull(current_active_effect)) + current_active_effect = pick(active_effects) + switch(current_active_effect) + if(FISHING_MINIGAME_RULE_ANTIGRAV) + fishing_hud.icon_state = "background_antigrav" + SEND_SOUND(user, sound('sound/effects/arcade_jump.ogg', volume = 50)) + COOLDOWN_START(src, active_effect_cd, rand(6, 9) SECONDS) + if(FISHING_MINIGAME_RULE_FLIP) + fishing_hud.icon_state = "background_flip" + fishing_hud.transform = fishing_hud.transform.Scale(1, -1) + SEND_SOUND(user, sound('sound/effects/boing.ogg')) + COOLDOWN_START(src, active_effect_cd, rand(5, 6) SECONDS) + return + + ///go back to normal + switch(current_active_effect) + if(FISHING_MINIGAME_RULE_ANTIGRAV) + var/sound/inverted_sound = sound('sound/effects/arcade_jump.ogg', volume = 50) + inverted_sound.frequency = -1 + SEND_SOUND(user, inverted_sound) + COOLDOWN_START(src, active_effect_cd, rand(10, 13) SECONDS) + if(FISHING_MINIGAME_RULE_FLIP) + fishing_hud.transform = fishing_hud.transform.Scale(1, -1) + COOLDOWN_START(src, active_effect_cd, rand(8, 12) SECONDS) + + fishing_hud.icon_state = background + current_active_effect = null + ///The proc that moves the fish around, just like in the old TGUI, mostly. /datum/fishing_challenge/proc/move_fish(seconds_per_tick) var/long_chance = long_jump_chance * seconds_per_tick * 10 @@ -464,6 +541,9 @@ velocity_change = round(velocity_change) + if(current_active_effect == FISHING_MINIGAME_RULE_ANTIGRAV) + velocity_change = -velocity_change + /** * Pull the brake on the velocity if the current velocity and the acceleration * have different directions, making the bait less slippery, thus easier to control @@ -524,7 +604,7 @@ icon_state = challenge.background add_overlay("frame") hud_bait = new(null, null, challenge) - hud_fish = new + hud_fish = new(null, null, challenge) hud_completion = new(null, null, challenge) vis_contents += list(hud_bait, hud_fish, hud_completion) challenge.user.client.screen += src @@ -557,6 +637,11 @@ icon_state = "fish" vis_flags = VIS_INHERIT_ID +/atom/movable/screen/hud_fish/Initialize(mapload, datum/hud/hud_owner, datum/fishing_challenge/challenge) + . = ..() + if(challenge) + icon_state = challenge.fish_icon + /atom/movable/screen/hud_completion icon = 'icons/hud/fishing_hud.dmi' icon_state = "completion_0" diff --git a/code/modules/fishing/fishing_portal_machine.dm b/code/modules/fishing/fishing_portal_machine.dm index 3fc6b0eb938a6d..b156a37ba05503 100644 --- a/code/modules/fishing/fishing_portal_machine.dm +++ b/code/modules/fishing/fishing_portal_machine.dm @@ -1,40 +1,58 @@ /obj/machinery/fishing_portal_generator name = "fish-porter 3000" - desc = "fishing anywhere, anytime, anyway what was i talking about" - + desc = "Fishing anywhere, anytime... anyway what was I talking about?" icon = 'icons/obj/fishing.dmi' - icon_state = "portal_off" - + icon_state = "portal" idle_power_usage = 0 active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2 - anchored = FALSE density = TRUE + circuit = /obj/item/circuitboard/machine/fishing_portal_generator - var/fishing_source = /datum/fish_source/portal + ///The current fishing spot loaded in var/datum/component/fishing_spot/active +/obj/machinery/fishing_portal_generator/on_set_panel_open() + update_appearance() + return ..() + /obj/machinery/fishing_portal_generator/wrench_act(mob/living/user, obj/item/tool) . = ..() default_unfasten_wrench(user, tool) return TOOL_ACT_TOOLTYPE_SUCCESS +/obj/machinery/fishing_portal_generator/examine(mob/user) + . = ..() + . += span_notice("You can unlock further portal settings by completing fish scanning experiments.") + +/obj/machinery/fishing_portal_generator/emag_act(mob/user, obj/item/card/emag/emag_card) + if(obj_flags & EMAGGED) + return FALSE + obj_flags |= EMAGGED + balloon_alert(user, "syndicate setting loaded") + playsound(src, SFX_SPARKS, 25, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) + return TRUE + /obj/machinery/fishing_portal_generator/interact(mob/user, special_state) . = ..() if(active) deactivate() else - activate() + select_fish_source(user) -/obj/machinery/fishing_portal_generator/update_icon(updates) +/obj/machinery/fishing_portal_generator/update_overlays() . = ..() - if(active) - icon_state = "portal_on" - else - icon_state = "portal_off" + if(panel_open) + . += "portal_open" + if(!active) + return + . += "portal_on" + var/datum/fish_source/portal/portal = active.fish_source + . += portal.overlay_state + . += emissive_appearance(icon, "portal_emissive", src) -/obj/machinery/fishing_portal_generator/proc/activate() - active = AddComponent(/datum/component/fishing_spot, fishing_source) +/obj/machinery/fishing_portal_generator/proc/activate(datum/fish_source/selected_source) + active = AddComponent(/datum/component/fishing_spot, selected_source) use_power = ACTIVE_POWER_USE update_icon() @@ -46,3 +64,39 @@ /obj/machinery/fishing_portal_generator/on_set_is_operational(old_value) if(old_value) deactivate() + +///Create a radial menu from a list of available fish sources. If only the default is available, activate it right away. +/obj/machinery/fishing_portal_generator/proc/select_fish_source(mob/user) + var/datum/fish_source/portal/default = GLOB.preset_fish_sources[/datum/fish_source/portal] + var/list/available_fish_sources = list(default.radial_name = default) + if(obj_flags & EMAGGED) + var/datum/fish_source/portal/syndicate = GLOB.preset_fish_sources[/datum/fish_source/portal/syndicate] + available_fish_sources[syndicate.radial_name] = syndicate + for (var/datum/techweb/techweb as anything in SSresearch.techwebs) + var/get_fish_sources = FALSE + for(var/obj/machinery/rnd/server/server as anything in techweb.techweb_servers) + if(!is_valid_z_level(get_turf(server), get_turf(src))) + continue + get_fish_sources = TRUE + break + if(!get_fish_sources) + continue + for(var/experiment_type in typesof(/datum/experiment/scanning/fish)) + var/datum/experiment/scanning/fish/experiment = techweb.completed_experiments[experiment_type] + if(!experiment) + continue + var/datum/fish_source/portal/reward = GLOB.preset_fish_sources[experiment.fish_source_reward] + available_fish_sources[reward.radial_name] = reward + + if(length(available_fish_sources) == 1) + activate(default) + return + var/list/choices = list() + for(var/radial_name in available_fish_sources) + var/datum/fish_source/portal/source = available_fish_sources[radial_name] + choices[radial_name] = image(icon = 'icons/hud/radial_fishing.dmi', icon_state = source.radial_state) + + var/choice = show_radial_menu(user, src, choices, radius = 38, custom_check = CALLBACK(src, TYPE_PROC_REF(/atom, can_interact), user), tooltips = TRUE) + if(!choice || !can_interact(user)) + return + activate(available_fish_sources[choice]) diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm index 7e01f693dd5434..1abba8e414cb06 100644 --- a/code/modules/fishing/fishing_rod.dm +++ b/code/modules/fishing/fishing_rod.dm @@ -30,14 +30,11 @@ var/obj/item/currently_hooked_item /// Fishing line visual for the hooked item - var/datum/beam/hooked_item_fishing_line + var/datum/beam/fishing_line/fishing_line /// Are we currently casting var/casting = FALSE - /// List of fishing line beams - var/list/fishing_lines = list() - /// The default color for the reel overlay if no line is equipped. var/default_line_color = "gray" @@ -66,13 +63,10 @@ return NONE /obj/item/fishing_rod/Destroy(force) - . = ..() - //Remove any leftover fishing lines - QDEL_LIST(fishing_lines) + return ..() /obj/item/fishing_rod/examine(mob/user) . = ..() - . += "Right-Click in your active hand to access its slots UI" var/list/equipped_stuff = list() if(line) equipped_stuff += "[icon2html(line, user)] [line.name]" @@ -84,6 +78,7 @@ . += span_notice("\a [icon2html(bait, user)] [bait] is being used as bait.") else . += span_warning("It doesn't have any bait attached. Fishing will be more tedious!") + . += span_notice("Right-Click in your active hand to access its slots UI") /** * Catch weight modifier for the given fish_type (or FISHING_DUD) @@ -140,7 +135,7 @@ // Should probably respect and used force move later step_towards(currently_hooked_item, get_turf(src)) if(get_dist(currently_hooked_item,get_turf(src)) < 1) - clear_hooked_item() + QDEL_NULL(fishing_line) /obj/item/fishing_rod/attack_self_secondary(mob/user, modifiers) . = ..() @@ -159,30 +154,28 @@ var/mob/user = loc if(!istype(user)) return + if(fishing_line) + QDEL_NULL(fishing_line) var/beam_color = line?.line_color || default_line_color - var/datum/beam/fishing_line/fishing_line_beam = new(user, target, icon_state = "fishing_line", beam_color = beam_color, emissive = FALSE, override_target_pixel_y = target_py) - fishing_line_beam.lefthand = user.get_held_index_of_item(src) % 2 == 1 - RegisterSignal(fishing_line_beam, COMSIG_BEAM_BEFORE_DRAW, PROC_REF(check_los)) - RegisterSignal(fishing_line_beam, COMSIG_QDELETING, PROC_REF(clear_line)) - fishing_lines += fishing_line_beam - INVOKE_ASYNC(fishing_line_beam, TYPE_PROC_REF(/datum/beam/, Start)) + fishing_line = new(user, target, icon_state = "fishing_line", beam_color = beam_color, emissive = FALSE, override_target_pixel_y = target_py) + fishing_line.lefthand = user.get_held_index_of_item(src) % 2 == 1 + RegisterSignal(fishing_line, COMSIG_BEAM_BEFORE_DRAW, PROC_REF(check_los)) + RegisterSignal(fishing_line, COMSIG_QDELETING, PROC_REF(clear_line)) + INVOKE_ASYNC(fishing_line, TYPE_PROC_REF(/datum/beam/, Start)) user.update_held_items() - return fishing_line_beam + return fishing_line /obj/item/fishing_rod/proc/clear_line(datum/source) SIGNAL_HANDLER - fishing_lines -= source if(ismob(loc)) var/mob/user = loc user.update_held_items() + fishing_line = null + currently_hooked_item = null /obj/item/fishing_rod/dropped(mob/user, silent) . = ..() - if(currently_hooked_item) - clear_hooked_item() - for(var/datum/beam/fishing_line in fishing_lines) - SEND_SIGNAL(fishing_line, COMSIG_FISHING_LINE_SNAPPED) - QDEL_LIST(fishing_lines) + QDEL_NULL(fishing_line) /// Hooks the item /obj/item/fishing_rod/proc/hook_item(mob/user, atom/target_atom) @@ -191,28 +184,21 @@ if(!can_be_hooked(target_atom)) return currently_hooked_item = target_atom - hooked_item_fishing_line = create_fishing_line(target_atom) - RegisterSignal(hooked_item_fishing_line, COMSIG_FISHING_LINE_SNAPPED, PROC_REF(clear_hooked_item)) + create_fishing_line(target_atom) + SEND_SIGNAL(src, COMSIG_FISHING_ROD_HOOKED_ITEM, target_atom, user) /// Checks what can be hooked /obj/item/fishing_rod/proc/can_be_hooked(atom/movable/target) // Could be made dependent on actual hook, ie magnet to hook metallic items return isitem(target) -/obj/item/fishing_rod/proc/clear_hooked_item() - SIGNAL_HANDLER - - if(!QDELETED(hooked_item_fishing_line)) - QDEL_NULL(hooked_item_fishing_line) - currently_hooked_item = null - // Checks fishing line for interruptions and range /obj/item/fishing_rod/proc/check_los(datum/beam/source) SIGNAL_HANDLER . = NONE - if(!isturf(source.origin.loc) || !isturf(source.target.loc) || !CheckToolReach(src, source.target, cast_range)) - SEND_SIGNAL(source, COMSIG_FISHING_LINE_SNAPPED) //Stepped out of range or los interrupted + if(!CheckToolReach(src, source.target, cast_range)) + qdel(source) return BEAM_CANCEL_DRAW /obj/item/fishing_rod/afterattack(atom/target, mob/user, proximity_flag, click_parameters) @@ -300,7 +286,7 @@ reel_overlay.color = line_color . += reel_overlay /// if we don't have anything hooked show the dangling hook & line - if(isinhands && length(fishing_lines) == 0) + if(isinhands && !fishing_line) var/mutable_appearance/line_overlay = mutable_appearance(icon_file, "line_overlay") line_overlay.appearance_flags |= RESET_COLOR line_overlay.color = line_color @@ -507,8 +493,8 @@ balloon_alert(user, active ? "extended" : "collapsed") playsound(src, 'sound/weapons/batonextend.ogg', 50, TRUE) update_appearance(UPDATE_OVERLAYS) - if(currently_hooked_item) - clear_hooked_item() + if(fishing_line) + QDEL_NULL(fishing_line) return COMPONENT_NO_DEFAULT_MESSAGE /obj/item/fishing_rod/telescopic/master @@ -523,16 +509,34 @@ /obj/item/fishing_rod/tech name = "advanced fishing rod" desc = "An embedded universal constructor along with micro-fusion generator makes this marvel of technology never run out of bait. Interstellar treaties prevent using it outside of recreational fishing. And you can fish with this. " - ui_description = "This rod has an infinite supply of synthetic bait." + ui_description = "This rod has an infinite supply of synth-bait. Also doubles as an Experi-Scanner for fish." icon_state = "fishing_rod_science" reel_overlay = "reel_science" /obj/item/fishing_rod/tech/Initialize(mapload) . = ..() + + var/static/list/fishing_signals = list( + COMSIG_FISHING_ROD_HOOKED_ITEM = TYPE_PROC_REF(/datum/component/experiment_handler, try_run_handheld_experiment), + COMSIG_FISHING_ROD_CAUGHT_FISH = TYPE_PROC_REF(/datum/component/experiment_handler, try_run_handheld_experiment), + COMSIG_ITEM_PRE_ATTACK = TYPE_PROC_REF(/datum/component/experiment_handler, try_run_handheld_experiment), + COMSIG_ITEM_AFTERATTACK = TYPE_PROC_REF(/datum/component/experiment_handler, ignored_handheld_experiment_attempt), + ) + AddComponent(/datum/component/experiment_handler, \ + config_mode = EXPERIMENT_CONFIG_ALTCLICK, \ + allowed_experiments = list(/datum/experiment/scanning/fish), \ + config_flags = EXPERIMENT_CONFIG_SILENT_FAIL|EXPERIMENT_CONFIG_IMMEDIATE_ACTION, \ + experiment_signals = fishing_signals, \ + ) + var/obj/item/food/bait/doughball/synthetic/infinite_supply_of_bait = new(src) bait = infinite_supply_of_bait update_icon() +/obj/item/fishing_rod/tech/examine(mob/user) + . = ..() + . += span_notice("Alt-Click to access the Experiment Configuration UI") + /obj/item/fishing_rod/tech/consume_bait(atom/movable/reward) return diff --git a/code/modules/fishing/sources/_fish_source.dm b/code/modules/fishing/sources/_fish_source.dm index 5a34db9ce5fbeb..657b2f30968b74 100644 --- a/code/modules/fishing/sources/_fish_source.dm +++ b/code/modules/fishing/sources/_fish_source.dm @@ -1,11 +1,47 @@ GLOBAL_LIST_INIT(preset_fish_sources, init_subtypes_w_path_keys(/datum/fish_source, list())) +/** + * When adding new fishable rewards to a table/counts, you can specify an icon to show in place of the + * generic fish icon in the minigame UI should the user have the TRAIT_REVEAL_FISH trait, by adding it to + * this list. + * + * A lot of the icons here may be a tad inaccurate, but since we're limited to the free font awesome icons we + * have access to, we got to make do. + */ +GLOBAL_LIST_INIT(specific_fish_icons, zebra_typecacheof(list( + /mob/living/basic/carp = FISH_ICON_DEF, + /mob/living/basic/mining = FISH_ICON_HOSTILE, + /obj/effect/decal/remains = FISH_ICON_BONE, + /obj/effect/mob_spawn/corpse = FISH_ICON_BONE, + /obj/item/coin = FISH_ICON_COIN, + /obj/item/fish = FISH_ICON_DEF, + /obj/item/fish/armorfish = FISH_ICON_CRAB, + /obj/item/fish/boned = FISH_ICON_BONE, + /obj/item/fish/chasm_crab = FISH_ICON_CRAB, + /obj/item/fish/gunner_jellyfish = FISH_ICON_JELLYFISH, + /obj/item/fish/holo/crab = FISH_ICON_CRAB, + /obj/item/fish/holo/puffer = FISH_ICON_CHUNKY, + /obj/item/fish/mastodon = FISH_ICON_BONE, + /obj/item/fish/pufferfish = FISH_ICON_CHUNKY, + /obj/item/fish/slimefish = FISH_ICON_SLIME, + /obj/item/fish/sludgefish = FISH_ICON_SLIME, + /obj/item/fish/starfish = FISH_ICON_STAR, + /obj/item/storage/wallet = FISH_ICON_COIN, + /obj/item/stack/sheet/bone = FISH_ICON_BONE, + /obj/item/stack/sheet/mineral = FISH_ICON_GEM, + /obj/item/stack/ore = FISH_ICON_GEM, + /obj/structure/closet/crate = FISH_ICON_COIN, +))) + /** * Where the fish actually come from - every fishing spot has one assigned but multiple fishing holes * can share single source, ie single shared one for ocean/lavaland river */ /datum/fish_source - /// Fish catch weight table - these are relative weights + /** + * Fish catch weight table - these are relative weights + * + */ var/list/fish_table = list() /// If a key from fish_table is present here, that fish is availible in limited quantity and is reduced by one on successful fishing var/list/fish_counts = list() @@ -25,6 +61,10 @@ GLOBAL_LIST_INIT(preset_fish_sources, init_subtypes_w_path_keys(/datum/fish_sour if(!(path in fish_table)) stack_trace("path [path] found in the 'fish_counts' list but not in the fish_table one of [type]") +///Called when src is set as the fish source of a fishing spot component +/datum/fish_source/proc/on_fishing_spot_init(/datum/component/fishing_spot/spot) + return + /// Can we fish in this spot at all. Returns DENIAL_REASON or null if we're good to go /datum/fish_source/proc/reason_we_cant_fish(obj/item/fishing_rod/rod, mob/fisherman) return rod.reason_we_cant_fish(src) @@ -35,7 +75,7 @@ GLOBAL_LIST_INIT(preset_fish_sources, init_subtypes_w_path_keys(/datum/fish_sour * This includes the source's fishing difficulty, that of the fish, the rod, * favorite and disliked baits, fish traits and the fisherman skill. * - * For non-fish, it's just the source's fishing difficulty minus the fisherman skill, rod and settler modifiers. + * For non-fish, it's just the source's fishing difficulty minus the fisherman skill. */ /datum/fish_source/proc/calculate_difficulty(result, obj/item/fishing_rod/rod, mob/fisherman, datum/fishing_challenge/challenge) . = fishing_difficulty @@ -96,7 +136,7 @@ GLOBAL_LIST_INIT(preset_fish_sources, init_subtypes_w_path_keys(/datum/fish_sour * Used to register signals or add traits and the such right after conditions have been cleared * and before the minigame starts. */ -/datum/fish_source/proc/pre_challenge_started(obj/item/fishing_rod/rod, mob/user) +/datum/fish_source/proc/pre_challenge_started(obj/item/fishing_rod/rod, mob/user, datum/fishing_challenge/challenge) return ///Proc called when the challenge is interrupted within the fish source code. @@ -116,7 +156,9 @@ GLOBAL_LIST_INIT(preset_fish_sources, init_subtypes_w_path_keys(/datum/fish_sour user.add_mob_memory(/datum/memory/caught_fish, protagonist = user, deuteragonist = initial(caught.name)) var/turf/fishing_spot = get_turf(source.lure) var/atom/movable/reward = dispense_reward(source.reward_path, user, fishing_spot) - source.used_rod?.consume_bait(reward) + if(source.used_rod) + SEND_SIGNAL(source.used_rod, COMSIG_FISHING_ROD_CAUGHT_FISH, reward, user) + source.used_rod.consume_bait(reward) /// Gives out the reward if possible /datum/fish_source/proc/dispense_reward(reward_path, mob/fisherman, turf/fishing_spot) diff --git a/code/modules/fishing/sources/source_types.dm b/code/modules/fishing/sources/source_types.dm index ffb37753881d56..e2e5491dd1d3db 100644 --- a/code/modules/fishing/sources/source_types.dm +++ b/code/modules/fishing/sources/source_types.dm @@ -19,11 +19,168 @@ /datum/fish_source/portal fish_table = list( - FISHING_DUD = 5, + FISHING_DUD = 7, /obj/item/fish/goldfish = 10, /obj/item/fish/guppy = 10, + /obj/item/fish/angelfish = 10, + ) + catalog_description = "Aquarium dimension (Fishing portal generator)" + ///The name of this option shown in the radial menu on the fishing portal generator + var/radial_name = "Aquarium" + ///The icon state shown for this option in the radial menu + var/radial_state = "fish_tank" + ///The icon state of the overlay shown on the machine when active. + var/overlay_state = "portal_aquarium" + +/datum/fish_source/portal/beach + fish_table = list( + FISHING_DUD = 10, + /obj/item/fish/clownfish = 10, + /obj/item/fish/pufferfish = 10, + /obj/item/fish/cardinal = 10, + /obj/item/fish/greenchromis = 10, + ) + catalog_description = "Beach dimension (Fishing portal generator)" + radial_name = "Beach" + radial_state = "palm_beach" + +/datum/fish_source/portal/chasm + background = "background_lavaland" + fish_table = list( + FISHING_DUD = 5, + /obj/item/fish/chasm_crab = 10, + /obj/item/fish/boned = 5, + /obj/item/stack/sheet/bone = 5, + ) + catalog_description = "Chasm dimension (Fishing portal generator)" + fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 10 + radial_name = "Chasm" + overlay_state = "portal_chasm" + radial_state = "ground_hole" + +/datum/fish_source/portal/ocean + fish_table = list( + FISHING_DUD = 5, + /obj/item/fish/lanternfish = 5, + /obj/item/fish/firefish = 5, + /obj/item/fish/dwarf_moonfish = 5, + /obj/item/fish/gunner_jellyfish = 5, + /obj/item/fish/needlefish = 5, + /obj/item/fish/armorfish = 5, + ) + catalog_description = "Ocean dimension (Fishing portal generator)" + fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 10 + radial_name = "Ocean" + overlay_state = "portal_ocean" + radial_state = "seaboat" + +/datum/fish_source/portal/hyperspace + fish_table = list( + FISHING_DUD = 5, + /obj/item/fish/starfish = 6, + /obj/item/stack/ore/bluespace_crystal = 2, + /mob/living/basic/carp = 2, + ) + fish_counts = list( + /obj/item/stack/ore/bluespace_crystal = 10, ) - catalog_description = "Fish dimension (Fishing portal generator)" + catalog_description = "Hyperspace dimension (Fishing portal generator)" + fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 10 + radial_name = "Hyperspace" + overlay_state = "portal_hyperspace" + radial_state = "space_rocket" + +///Unlocked by emagging the fishing portal generator with an emag. +/datum/fish_source/portal/syndicate + background = "background_lavaland" + fish_table = list( + FISHING_DUD = 5, + /obj/item/fish/donkfish = 5, + /obj/item/fish/emulsijack = 5, + ) + catalog_description = "Syndicate dimension (Fishing portal generator)" + radial_name = "Syndicate" + fishing_difficulty = FISHING_DEFAULT_DIFFICULTY + 15 + overlay_state = "portal_syndicate" + radial_state = "syndi_snake" + +/** + * A special portal fish source which fish table is populated on init with the contents of all + * portal fish sources, except for FISHING_DUD, and a couple more caveats. + */ +/datum/fish_source/portal/random + fish_table = null //It's populated the first time the source is loaded on a fishing portal generator. + catalog_description = null // it'd make a bad entry in the catalog. + radial_name = "Randomizer" + overlay_state = "portal_randomizer" + var/static/list/all_portal_fish_sources_at_once + radial_state = "misaligned_question_mark" + +///Generate the fish table if we don't have one already. +/datum/fish_source/portal/random/on_fishing_spot_init(datum/component/fishing_spot/spot) + if(fish_table) + return + + ///rewards not found in other fishing portals + fish_table = list( + /obj/item/fish/holo/checkered = 1, + ) + + for(var/portal_type in GLOB.preset_fish_sources) + if(portal_type == type || !ispath(portal_type, /datum/fish_source/portal)) + continue + var/datum/fish_source/portal/preset_portal = GLOB.preset_fish_sources[portal_type] + fish_table |= preset_portal.fish_table + + ///We don't serve duds. + fish_table -= FISHING_DUD + + for(var/reward_path in fish_table) + fish_table[reward_path] = rand(1, 4) + +///Difficulty has to be calculated before the rest, because of how it influences jump chances +/datum/fish_source/portal/random/calculate_difficulty(result, obj/item/fishing_rod/rod, mob/fisherman, datum/fishing_challenge/challenge) + . = ..() + . += rand(-10, 15) + +///In the spirit of randomness, we skew a few values here and there +/datum/fish_source/portal/random/pre_challenge_started(obj/item/fishing_rod/rod, mob/user, datum/fishing_challenge/challenge) + challenge.bait_bounce_mult = clamp(challenge.bait_bounce_mult + (rand(-3, 3) * 0.1), 0.1, 1) + challenge.completion_loss = max(challenge.completion_loss + rand(-2, 2), 0) + challenge.completion_gain = max(challenge.completion_gain + rand(-1, 1), 2) + challenge.short_jump_velocity_limit += rand(-100, 100) + challenge.long_jump_velocity_limit += rand(-100, 100) + var/static/list/active_effects = bitfield_to_list(FISHING_MINIGAME_ACTIVE_EFFECTS) + for(var/effect in active_effects) + if(prob(30)) + challenge.special_effects |= effect + +///Cherry on top, fish caught from the randomizer portal also have (almost completely) random traits +/datum/fish_source/portal/random/spawn_reward(reward_path, mob/fisherman, turf/fishing_spot) + if(!ispath(reward_path, /obj/item/fish)) + return ..() + + var/static/list/weighted_traits + if(!weighted_traits) + weighted_traits = list() + for(var/trait_type as anything in GLOB.fish_traits) + var/datum/fish_trait/trait = GLOB.fish_traits[trait_type] + weighted_traits[trait.type] = round(trait.inheritability**2/100) + + var/obj/item/fish/caught_fish = new reward_path(get_turf(fisherman), FALSE) + var/list/fixed_traits = list() + for(var/trait_type in caught_fish.fish_traits) + var/datum/fish_trait/trait = GLOB.fish_traits[trait_type] + if(caught_fish.type in trait.guaranteed_inheritance_types) + fixed_traits += trait_type + var/list/new_traits = list() + for(var/iteration in rand(1, 4)) + new_traits |= pick_weight(weighted_traits) + caught_fish.inherit_traits(new_traits, fixed_traits = fixed_traits) + caught_fish.randomize_size_and_weight(deviation = 0.3) + caught_fish.progenitors = full_capitalize(caught_fish.name) + return caught_fish + /datum/fish_source/chasm catalog_description = "Chasm depths" @@ -99,7 +256,7 @@ fish_table = list( FISHING_DUD = 18, /obj/item/fish/sludgefish = 18, - /obj/item/fish/slimefish = 2, + /obj/item/fish/slimefish = 4, /obj/item/storage/wallet/money = 2, ) fish_counts = list( @@ -125,7 +282,7 @@ if(!istype(get_area(fisherman), /area/station/holodeck)) return "You need to be inside the Holodeck to catch holographic fish." -/datum/fish_source/holographic/pre_challenge_started(obj/item/fishing_rod/rod, mob/user) +/datum/fish_source/holographic/pre_challenge_started(obj/item/fishing_rod/rod, mob/user, datum/fishing_challenge/challenge) RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(check_area)) /datum/fish_source/holographic/proc/check_area(mob/user) diff --git a/code/modules/food_and_drinks/machinery/deep_fryer.dm b/code/modules/food_and_drinks/machinery/deep_fryer.dm index fc20112f08a89e..071cc18febc433 100644 --- a/code/modules/food_and_drinks/machinery/deep_fryer.dm +++ b/code/modules/food_and_drinks/machinery/deep_fryer.dm @@ -216,7 +216,7 @@ GLOBAL_LIST_INIT(oilfry_blacklisted_items, typecacheof(list( if(target_temp < TCMB + 10) // a tiny bit of leeway dunking_target.visible_message(span_userdanger("[dunking_target] explodes from the entropic difference! Holy fuck!")) dunking_target.investigate_log("has been gibbed by entropic difference (being dunked into [src]).", INVESTIGATE_DEATHS) - dunking_target.gib() + dunking_target.gib(DROP_ALL_REMAINS) log_combat(user, dunking_target, "blew up", null, "by dunking them into [src]") return diff --git a/code/modules/food_and_drinks/machinery/gibber.dm b/code/modules/food_and_drinks/machinery/gibber.dm index ebb2b85e2b931c..121acceb4c4976 100644 --- a/code/modules/food_and_drinks/machinery/gibber.dm +++ b/code/modules/food_and_drinks/machinery/gibber.dm @@ -198,6 +198,7 @@ occupant.reagents.trans_to(newmeat, occupant_volume / meat_produced, remove_blacklisted = TRUE) if(sourcejob) newmeat.subjectjob = sourcejob + allmeat[i] = newmeat if(typeofskin) @@ -221,12 +222,24 @@ skin.throw_at(pick(nearby_turfs),meat_produced,3) for (var/i=1 to meat_produced) var/obj/item/meatslab = allmeat[i] + + if(LAZYLEN(diseases)) + var/list/datum/disease/diseases_to_add = list() + for(var/datum/disease/disease as anything in diseases) + // admin or special viruses that should not be reproduced + if(disease.spread_flags & (DISEASE_SPREAD_SPECIAL | DISEASE_SPREAD_NON_CONTAGIOUS)) + continue + + diseases_to_add += disease + if(LAZYLEN(diseases_to_add)) + meatslab.AddComponent(/datum/component/infective, diseases_to_add) + meatslab.forceMove(loc) meatslab.throw_at(pick(nearby_turfs),i,3) for (var/turfs=1 to meat_produced) var/turf/gibturf = pick(nearby_turfs) if (!gibturf.density && (src in view(gibturf))) - new gibtype(gibturf,i,diseases) + new gibtype(gibturf, i, diseases) pixel_x = base_pixel_x //return to its spot after shaking operating = FALSE @@ -243,4 +256,4 @@ if(victim.loc == input) victim.forceMove(src) - victim.gib() + victim.gib(DROP_ALL_REMAINS) diff --git a/code/modules/food_and_drinks/machinery/microwave.dm b/code/modules/food_and_drinks/machinery/microwave.dm index 36d98c907a5a6d..d52e2213a5b281 100644 --- a/code/modules/food_and_drinks/machinery/microwave.dm +++ b/code/modules/food_and_drinks/machinery/microwave.dm @@ -14,11 +14,15 @@ /// The max amount of dirtiness a microwave can be #define MAX_MICROWAVE_DIRTINESS 100 -/obj/machinery/microwave//SKYRAT EDIT - ICON OVERRIDEN BY AESTHETICS - SEE MODULE +/// For the wireless version, and display fluff +#define TIER_1_CELL_CHARGE_RATE 250 + +/obj/machinery/microwave name = "microwave oven" desc = "Cooks and boils stuff." icon = 'icons/obj/machines/microwave.dmi' - icon_state = "map_icon" + base_icon_state = "" + icon_state = "mw_complete" appearance_flags = KEEP_TOGETHER | LONG_GLIDE | PIXEL_SCALE layer = BELOW_OBJ_LAYER density = TRUE @@ -27,30 +31,63 @@ light_color = LIGHT_COLOR_DIM_YELLOW light_power = 3 anchored_tabletop_offset = 6 - var/wire_disabled = FALSE // is its internal wire cut? + /// Is its function wire cut? + var/wire_disabled = FALSE + /// Wire cut to run mode backwards + var/wire_mode_swap = FALSE var/operating = FALSE /// How dirty is it? var/dirty = 0 var/dirty_anim_playing = FALSE /// How broken is it? NOT_BROKEN, KINDA_BROKEN, REALLY_BROKEN var/broken = NOT_BROKEN + /// Microwave door position var/open = FALSE + /// Microwave max capacity var/max_n_of_items = 10 + /// Microwave efficiency (power) based on the stock components var/efficiency = 0 + /// If we use a cell instead of powernet + var/cell_powered = FALSE + /// The cell we charge with + var/obj/item/stock_parts/cell/cell + /// The cell we're charging + var/obj/item/stock_parts/cell/vampire_cell + /// Capable of vampire charging PDAs + var/vampire_charging_capable = FALSE + /// Charge contents of microwave instead of cook + var/vampire_charging_enabled = FALSE var/datum/looping_sound/microwave/soundloop - var/list/ingredients = list() // may only contain /atom/movables - + /// May only contain /atom/movables + var/list/ingredients = list() + /// When this is the nth ingredient, whats its pixel_x? + var/list/ingredient_shifts_x = list( + -2, + 1, + -5, + 2, + -6, + 0, + -4, + ) + /// When this is the nth ingredient, whats its pixel_y? + var/list/ingredient_shifts_y = list( + -4, + -2, + -3, + ) var/static/radial_examine = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_examine") var/static/radial_eject = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_eject") - var/static/radial_use = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_use") + var/static/radial_cook = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_cook") + var/static/radial_charge = image(icon = 'icons/hud/radial.dmi', icon_state = "radial_charge") // we show the button even if the proc will not work - var/static/list/radial_options = list("eject" = radial_eject, "use" = radial_use) - var/static/list/ai_radial_options = list("eject" = radial_eject, "use" = radial_use, "examine" = radial_examine) + var/static/list/radial_options = list("eject" = radial_eject, "cook" = radial_cook, "charge" = radial_charge) + var/static/list/ai_radial_options = list("eject" = radial_eject, "cook" = radial_cook, "charge" = radial_charge, "examine" = radial_examine) /obj/machinery/microwave/Initialize(mapload) . = ..() - + register_context() set_wires(new /datum/wires/microwave(src)) create_reagents(100) soundloop = new(src, FALSE) @@ -66,7 +103,6 @@ itemized_ingredient.pixel_y = itemized_ingredient.base_pixel_y + rand(-5, 6) return ..() - /obj/machinery/microwave/on_deconstruction() eject() return ..() @@ -75,21 +111,70 @@ QDEL_LIST(ingredients) QDEL_NULL(wires) QDEL_NULL(soundloop) + if(!isnull(cell)) + QDEL_NULL(cell) return ..() +/obj/machinery/microwave/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + if(cell_powered) + if(!isnull(cell)) + context[SCREENTIP_CONTEXT_CTRL_LMB] = "Remove cell" + else if(held_item && istype(held_item, /obj/item/stock_parts/cell)) + context[SCREENTIP_CONTEXT_CTRL_LMB] = "Insert cell" + + if(!anchored && held_item?.tool_behaviour == TOOL_WRENCH) + context[SCREENTIP_CONTEXT_LMB] = "Install/Secure" + return CONTEXTUAL_SCREENTIP_SET + + if(broken > NOT_BROKEN) + if(broken == REALLY_BROKEN && held_item?.tool_behaviour == TOOL_WIRECUTTER) + context[SCREENTIP_CONTEXT_LMB] = "Repair" + return CONTEXTUAL_SCREENTIP_SET + + else if(broken == KINDA_BROKEN && held_item?.tool_behaviour == TOOL_WELDER) + context[SCREENTIP_CONTEXT_LMB] = "Repair" + return CONTEXTUAL_SCREENTIP_SET + + context[SCREENTIP_CONTEXT_LMB] = "Show menu" + + if(vampire_charging_capable) + context[SCREENTIP_CONTEXT_ALT_LMB] = "Change to [vampire_charging_enabled ? "cook" : "charge"]" + + if(length(ingredients) != 0) + context[SCREENTIP_CONTEXT_RMB] = "Start [vampire_charging_enabled ? "charging" : "cooking"]" + + return CONTEXTUAL_SCREENTIP_SET + /obj/machinery/microwave/RefreshParts() . = ..() efficiency = 0 + vampire_charging_capable = FALSE for(var/datum/stock_part/micro_laser/micro_laser in component_parts) efficiency += micro_laser.tier for(var/datum/stock_part/matter_bin/matter_bin in component_parts) max_n_of_items = 10 * matter_bin.tier break + for(var/datum/stock_part/capacitor/capacitor in component_parts) + if(capacitor.tier >= 2) + vampire_charging_capable = TRUE + visible_message(span_notice("The [EXAMINE_HINT("Charge Ready")] light on \the [src] flickers to life.")) + break /obj/machinery/microwave/examine(mob/user) . = ..() + if(vampire_charging_capable) + . += span_info("This model features Waveâ„¢: a Nanotrasen exclusive. Our latest and greatest, Waveâ„¢ allows your PDA to be charged wirelessly through microwave frequencies! You can Wave-charge your device by placing it inside and selecting the charge mode.") + . += span_info("Because nothing says 'future' like charging your PDA while overcooking your leftovers. Nanotrasen Waveâ„¢ - Multitasking, redefined.") + + if(cell_powered) + . += span_notice("This model is wireless, powered by portable cells. [isnull(cell) ? "The cell slot is empty." : "[EXAMINE_HINT("Ctrl-click")] to remove the power cell."]") + if(!operating) - . += span_notice("Right-click [src] to turn it on.") + if(!operating && vampire_charging_capable) + . += span_notice("[EXAMINE_HINT("Alt-click")] to change default mode.") + + . += span_notice("[EXAMINE_HINT("Right-click")] to start [vampire_charging_enabled ? "charging" : "cooking"] cycle.") if(!in_range(user, src) && !issilicon(user) && !isobserver(user)) . += span_warning("You're too far away to examine [src]'s contents and display!") @@ -106,46 +191,37 @@ var/list/items_counts = new for(var/i in ingredients) if(isstack(i)) - var/obj/item/stack/S = i - items_counts[S.name] += S.amount + var/obj/item/stack/item_stack = i + items_counts[item_stack.name] += item_stack.amount else - var/atom/movable/AM = i - items_counts[AM.name]++ - for(var/O in items_counts) - . += span_notice("- [items_counts[O]]x [O].") + var/atom/movable/single_item = i + items_counts[single_item.name]++ + for(var/item in items_counts) + . += span_notice("- [items_counts[item]]x [item].") else . += span_notice("\The [src] is empty.") if(!(machine_stat & (NOPOWER|BROKEN))) . += "[span_notice("The status display reads:")]\n"+\ + "[span_notice("- Mode: [vampire_charging_enabled ? "Charge" : "Cook"].")]\n"+\ "[span_notice("- Capacity: [max_n_of_items] items.")]\n"+\ - span_notice("- Cook time reduced by [(efficiency - 1) * 25]%.") + span_notice("- Power: [efficiency * TIER_1_CELL_CHARGE_RATE]W.") + + if(cell_powered) + . += span_notice("- Charge: [isnull(cell) ? "INSERT CELL" : "[round(cell.percent())]%"].") #define MICROWAVE_INGREDIENT_OVERLAY_SIZE 24 /obj/machinery/microwave/update_overlays() - // When this is the nth ingredient, whats its pixel_x? - var/static/list/ingredient_shifts = list( - // SKYRAT EDIT CHANGE START - All values offset by -3 from original - -3, - 0, - -6, - 1, - -7, - -1, - -5, - // SKYRAT EDIT CHANGE END - ) - . = ..() // All of these will use a full icon state instead - if (panel_open || dirty == MAX_MICROWAVE_DIRTINESS || broken || dirty_anim_playing) + if(panel_open || dirty == MAX_MICROWAVE_DIRTINESS || broken || dirty_anim_playing) return . var/ingredient_count = 0 - for (var/atom/movable/ingredient as anything in ingredients) + for(var/atom/movable/ingredient as anything in ingredients) var/image/ingredient_overlay = image(ingredient, src) var/list/icon_dimensions = get_icon_dimensions(ingredient.icon) @@ -154,11 +230,11 @@ MICROWAVE_INGREDIENT_OVERLAY_SIZE / icon_dimensions["height"], ) - ingredient_overlay.pixel_y = -4 + ingredient_overlay.pixel_x = ingredient_shifts_x[(ingredient_count % ingredient_shifts_x.len) + 1] + ingredient_overlay.pixel_y = ingredient_shifts_y[(ingredient_count % ingredient_shifts_y.len) + 1] ingredient_overlay.layer = FLOAT_LAYER ingredient_overlay.plane = FLOAT_PLANE ingredient_overlay.blend_mode = BLEND_INSET_OVERLAY - ingredient_overlay.pixel_x = ingredient_shifts[(ingredient_count % ingredient_shifts.len) + 1] ingredient_count += 1 @@ -167,46 +243,67 @@ var/border_icon_state var/door_icon_state - if (open) - door_icon_state = "door_open" - border_icon_state = "mwo" - else if (operating) - door_icon_state = "door_on" - border_icon_state = "mw1" + if(open) + door_icon_state = "[base_icon_state]door_open" + border_icon_state = "[base_icon_state]mwo" + else if(operating) + if(vampire_charging_enabled) + door_icon_state = "[base_icon_state]door_charge" + else + door_icon_state = "[base_icon_state]door_on" + border_icon_state = "[base_icon_state]mw1" else - door_icon_state = "door_off" - border_icon_state = "mw" + door_icon_state = "[base_icon_state]door_off" + border_icon_state = "[base_icon_state]mw" + . += mutable_appearance( icon, door_icon_state, - alpha = ingredients.len > 0 ? 128 : 255, ) . += border_icon_state - if (!open) - . += "door_handle" + if(!open) + . += "[base_icon_state]door_handle" + + if(!(machine_stat & NOPOWER) || cell_powered) + . += emissive_appearance(icon, "emissive_[border_icon_state]", src, alpha = src.alpha) + + if(cell_powered && !isnull(cell)) + switch(cell.percent()) + if(75 to 100) + . += mutable_appearance(icon, "[base_icon_state]cell_100") + . += emissive_appearance(icon, "[base_icon_state]cell_100", src, alpha = src.alpha) + if(50 to 75) + . += mutable_appearance(icon, "[base_icon_state]cell_75") + . += emissive_appearance(icon, "[base_icon_state]cell_75", src, alpha = src.alpha) + if(25 to 50) + . += mutable_appearance(icon, "[base_icon_state]cell_25") + . += emissive_appearance(icon, "[base_icon_state]cell_25", src, alpha = src.alpha) + else + . += mutable_appearance(icon, "[base_icon_state]cell_0") + . += emissive_appearance(icon, "[base_icon_state]cell_0", src, alpha = src.alpha) return . #undef MICROWAVE_INGREDIENT_OVERLAY_SIZE /obj/machinery/microwave/update_icon_state() - if (broken) - icon_state = "mwb" - else if (dirty_anim_playing) - icon_state = "mwbloody1" - else if (dirty == MAX_MICROWAVE_DIRTINESS) - icon_state = open ? "mwbloodyo" : "mwbloody" + if(broken) + icon_state = "[base_icon_state]mwb" + else if(dirty_anim_playing) + icon_state = "[base_icon_state]mwbloody1" + else if(dirty == MAX_MICROWAVE_DIRTINESS) + icon_state = open ? "[base_icon_state]mwbloodyo" : "[base_icon_state]mwbloody" else if(operating) - icon_state = "back_on" + icon_state = "[base_icon_state]back_on" else if(open) - icon_state = "back_open" + icon_state = "[base_icon_state]back_open" else if(panel_open) - icon_state = "mw-o" + icon_state = "[base_icon_state]mw-o" else - icon_state = "back_off" + icon_state = "[base_icon_state]back_off" return ..() @@ -234,23 +331,23 @@ update_appearance() return TOOL_ACT_TOOLTYPE_SUCCESS -/obj/machinery/microwave/attackby(obj/item/O, mob/living/user, params) +/obj/machinery/microwave/attackby(obj/item/item, mob/living/user, params) if(operating) return - if(panel_open && is_wire_tool(O)) + if(panel_open && is_wire_tool(item)) wires.interact(user) return TRUE if(broken > NOT_BROKEN) - if(broken == REALLY_BROKEN && O.tool_behaviour == TOOL_WIRECUTTER) // If it's broken and they're using a TOOL_WIRECUTTER + if(broken == REALLY_BROKEN && item.tool_behaviour == TOOL_WIRECUTTER) // If it's broken and they're using a TOOL_WIRECUTTER user.visible_message(span_notice("[user] starts to fix part of \the [src]."), span_notice("You start to fix part of \the [src]...")) - if(O.use_tool(src, user, 20)) + if(item.use_tool(src, user, 20)) user.visible_message(span_notice("[user] fixes part of \the [src]."), span_notice("You fix part of \the [src].")) broken = KINDA_BROKEN // Fix it a bit - else if(broken == KINDA_BROKEN && O.tool_behaviour == TOOL_WELDER) // If it's broken and they're doing the wrench + else if(broken == KINDA_BROKEN && item.tool_behaviour == TOOL_WELDER) // If it's broken and they're doing the wrench user.visible_message(span_notice("[user] starts to fix part of \the [src]."), span_notice("You start to fix part of \the [src]...")) - if(O.use_tool(src, user, 20)) + if(item.use_tool(src, user, 20)) user.visible_message(span_notice("[user] fixes \the [src]."), span_notice("You fix \the [src].")) broken = NOT_BROKEN update_appearance() @@ -260,8 +357,9 @@ return TRUE return - if(istype(O, /obj/item/reagent_containers/spray)) - var/obj/item/reagent_containers/spray/clean_spray = O + if(istype(item, /obj/item/reagent_containers/spray)) + var/obj/item/reagent_containers/spray/clean_spray = item + open(autoclose = 2 SECONDS) if(clean_spray.reagents.has_reagent(/datum/reagent/space_cleaner, clean_spray.amount_per_transfer_from_this)) clean_spray.reagents.remove_reagent(/datum/reagent/space_cleaner, clean_spray.amount_per_transfer_from_this,1) playsound(loc, 'sound/effects/spray3.ogg', 50, TRUE, -6) @@ -272,56 +370,83 @@ to_chat(user, span_warning("You need more space cleaner!")) return TRUE - if(istype(O, /obj/item/soap) || istype(O, /obj/item/reagent_containers/cup/rag)) + if(istype(item, /obj/item/soap) || istype(item, /obj/item/reagent_containers/cup/rag)) var/cleanspeed = 50 - if(istype(O, /obj/item/soap)) - var/obj/item/soap/used_soap = O + if(istype(item, /obj/item/soap)) + var/obj/item/soap/used_soap = item cleanspeed = used_soap.cleanspeed user.visible_message(span_notice("[user] starts to clean \the [src]."), span_notice("You start to clean \the [src]...")) + open(autoclose = cleanspeed + 1 SECONDS) if(do_after(user, cleanspeed, target = src)) user.visible_message(span_notice("[user] cleans \the [src]."), span_notice("You clean \the [src].")) dirty = 0 update_appearance() return TRUE + if(istype(item, /obj/item/stock_parts/cell) && cell_powered) + var/swapped = FALSE + if(!isnull(cell)) + cell.forceMove(drop_location()) + if(!issilicon(user) && Adjacent(user)) + user.put_in_hands(cell) + cell = null + swapped = TRUE + if(!user.transferItemToLoc(item, src)) + update_appearance() + return TRUE + cell = item + balloon_alert(user, "[swapped ? "swapped" : "inserted"] cell") + update_appearance() + return TRUE + + if(!anchored) + balloon_alert(user, "not secured!") + return ..() + if(dirty >= MAX_MICROWAVE_DIRTINESS) // The microwave is all dirty so can't be used! balloon_alert(user, "it's too dirty!") return TRUE - if(istype(O, /obj/item/storage)) - var/obj/item/storage/T = O + if(vampire_charging_capable && istype(item, /obj/item/modular_computer/pda) && ingredients.len > 0) + balloon_alert(user, "max 1 pda!") + return FALSE + + if(istype(item, /obj/item/storage)) + var/obj/item/storage/tray = item var/loaded = 0 - if(!istype(O, /obj/item/storage/bag/tray)) + if(!istype(item, /obj/item/storage/bag/tray)) // Non-tray dumping requires a do_after - to_chat(user, span_notice("You start dumping out the contents of [O] into [src]...")) - if(!do_after(user, 2 SECONDS, target = T)) + to_chat(user, span_notice("You start dumping out the contents of [item] into [src]...")) + if(!do_after(user, 2 SECONDS, target = tray)) return - for(var/obj/S in T.contents) - if(!IS_EDIBLE(S)) + for(var/obj/tray_item in tray.contents) + if(!IS_EDIBLE(tray_item)) continue if(ingredients.len >= max_n_of_items) balloon_alert(user, "it's full!") return TRUE - if(T.atom_storage.attempt_remove(S, src)) + if(tray.atom_storage.attempt_remove(tray_item, src)) loaded++ - ingredients += S + ingredients += tray_item if(loaded) + open(autoclose = 0.6 SECONDS) to_chat(user, span_notice("You insert [loaded] items into \the [src].")) update_appearance() return - if(O.w_class <= WEIGHT_CLASS_NORMAL && !istype(O, /obj/item/storage) && !user.combat_mode) + if(item.w_class <= WEIGHT_CLASS_NORMAL && !istype(item, /obj/item/storage) && !user.combat_mode) if(ingredients.len >= max_n_of_items) balloon_alert(user, "it's full!") return TRUE - if(!user.transferItemToLoc(O, src)) + if(!user.transferItemToLoc(item, src)) balloon_alert(user, "it's stuck to your hand!") return FALSE - ingredients += O - user.visible_message(span_notice("[user] adds \a [O] to \the [src]."), span_notice("You add [O] to \the [src].")) + ingredients += item + open(autoclose = 0.6 SECONDS) + user.visible_message(span_notice("[user] adds \a [item] to \the [src]."), span_notice("You add [item] to \the [src].")) update_appearance() return @@ -332,13 +457,34 @@ if(!length(ingredients)) balloon_alert(user, "it's empty!") return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN - cook(user) + + start_cycle(user) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN +/obj/machinery/microwave/AltClick(mob/user, list/modifiers) + if(user.can_perform_action(src, ALLOW_SILICON_REACH)) + if(!vampire_charging_capable) + return + + vampire_charging_enabled = !vampire_charging_enabled + balloon_alert(user, "set to [vampire_charging_enabled ? "charge" : "cook"]") + +/obj/machinery/microwave/CtrlClick(mob/user) + . = ..() + if(cell_powered && !isnull(cell) && anchored) + user.put_in_hands(cell) + balloon_alert(user, "removed cell") + cell = null + update_appearance() + /obj/machinery/microwave/ui_interact(mob/user) . = ..() - if(operating || panel_open || !anchored || !user.can_perform_action(src, ALLOW_SILICON_REACH)) + if(!anchored) + balloon_alert(user, "not secured!") + return + if(operating || panel_open || !user.can_perform_action(src, ALLOW_SILICON_REACH)) return if(isAI(user) && (machine_stat & NOPOWER)) return @@ -353,17 +499,21 @@ var/choice = show_radial_menu(user, src, isAI(user) ? ai_radial_options : radial_options, require_near = !issilicon(user)) // post choice verification - if(operating || panel_open || !anchored || !user.can_perform_action(src, ALLOW_SILICON_REACH)) + if(operating || panel_open || (!vampire_charging_capable && !anchored) || !user.can_perform_action(src, ALLOW_SILICON_REACH)) return if(isAI(user) && (machine_stat & NOPOWER)) return - usr.set_machine(src) + user.set_machine(src) switch(choice) if("eject") eject() - if("use") - cook(user) + if("cook") + vampire_charging_enabled = FALSE + start_cycle(user) + if("charge") + vampire_charging_enabled = TRUE + start_cycle(user) if("examine") examine(user) @@ -371,8 +521,20 @@ var/atom/drop_loc = drop_location() for(var/atom/movable/movable_ingredient as anything in ingredients) movable_ingredient.forceMove(drop_loc) - open() - playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) + open(autoclose = 1.4 SECONDS) + +/obj/machinery/microwave/proc/start_cycle(mob/user) + if(wire_mode_swap) + spark() + if(vampire_charging_enabled) + cook(user) + else + charge(user) + + else if(vampire_charging_enabled) + charge(user) + else + cook(user) /** * Begins the process of cooking the included ingredients. @@ -382,6 +544,7 @@ /obj/machinery/microwave/proc/cook(mob/cooker) if(machine_stat & (NOPOWER|BROKEN)) return + if(operating || broken > 0 || panel_open || !anchored || dirty >= MAX_MICROWAVE_DIRTINESS) return @@ -390,9 +553,15 @@ playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) return + if(cell_powered && cell?.charge < TIER_1_CELL_CHARGE_RATE * efficiency) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + balloon_alert(cooker, "replace cell!") + return + if(cooker && HAS_TRAIT(cooker, TRAIT_CURSED) && prob(7)) muck() return + if(prob(max((5 / efficiency) - 5, dirty * 5))) //a clean unupgraded microwave has no risk of failure muck() return @@ -413,16 +582,18 @@ /obj/machinery/microwave/proc/wzhzhzh() visible_message(span_notice("\The [src] turns on."), null, span_hear("You hear a microwave humming.")) operating = TRUE + if(cell_powered && !isnull(cell)) + cell.use(TIER_1_CELL_CHARGE_RATE * efficiency) - set_light(1.5) + set_light(l_range = 1.5, l_power = 1.2, l_on = TRUE) soundloop.start() update_appearance() /obj/machinery/microwave/proc/spark() visible_message(span_warning("Sparks fly around [src]!")) - var/datum/effect_system/spark_spread/s = new - s.set_up(2, 1, src) - s.start() + var/datum/effect_system/spark_spread/sparks = new + sparks.set_up(2, 1, src) + sparks.start() /** * The start of the cook loop @@ -431,7 +602,7 @@ */ /obj/machinery/microwave/proc/start(mob/cooker) wzhzhzh() - loop(MICROWAVE_NORMAL, 10, cooker = cooker) + cook_loop(type = MICROWAVE_NORMAL, cycles = 10, cooker = cooker) /** * The start of the cook loop, but can fail (result in a splat / dirty microwave) @@ -440,29 +611,29 @@ */ /obj/machinery/microwave/proc/start_can_fail(mob/cooker) wzhzhzh() - loop(MICROWAVE_PRE, 4, cooker = cooker) + cook_loop(type = MICROWAVE_PRE, cycles = 4, cooker = cooker) /obj/machinery/microwave/proc/muck() wzhzhzh() playsound(loc, 'sound/effects/splat.ogg', 50, TRUE) dirty_anim_playing = TRUE update_appearance() - loop(MICROWAVE_MUCK, 4) + cook_loop(type = MICROWAVE_MUCK, cycles = 4) /** * The actual cook loop started via [proc/start] or [proc/start_can_fail] * - * * type - the type of cooking, determined via how this iteration of loop is called, and determines the result + * * type - the type of cooking, determined via how this iteration of cook_loop is called, and determines the result * * time - how many loops are left, base case for recursion * * wait - deciseconds between loops * * cooker - The mob that initiated the cook cycle, can be null if no apparent mob triggered it (such as via emp) */ -/obj/machinery/microwave/proc/loop(type, time, wait = max(12 - 2 * efficiency, 2), mob/cooker) // standard wait is 10 +/obj/machinery/microwave/proc/cook_loop(type, cycles, wait = max(12 - 2 * efficiency, 2), mob/cooker) // standard wait is 10 if((machine_stat & BROKEN) && type == MICROWAVE_PRE) pre_fail() return - if(time <= 0 || !length(ingredients)) + if(cycles <= 0 || !length(ingredients)) switch(type) if(MICROWAVE_NORMAL) loop_finish(cooker) @@ -471,18 +642,21 @@ if(MICROWAVE_PRE) pre_success(cooker) return - time-- + cycles-- use_power(active_power_usage) - addtimer(CALLBACK(src, PROC_REF(loop), type, time, wait, cooker), wait) + addtimer(CALLBACK(src, PROC_REF(cook_loop), type, cycles, wait, cooker), wait) /obj/machinery/microwave/power_change() . = ..() + if(cell_powered) + return + if((machine_stat & NOPOWER) && operating) pre_fail() eject() /** - * Called when the loop is done successfully, no dirty mess or whatever + * Called when the cook_loop is done successfully, no dirty mess or whatever * * * cooker - The mob that initiated the cook cycle, can be null if no apparent mob triggered it (such as via emp) */ @@ -492,6 +666,11 @@ var/cursed_chef = cooker && HAS_TRAIT(cooker, TRAIT_CURSED) var/metal_amount = 0 for(var/obj/item/cooked_item in ingredients) + if(istype(cooked_item, /obj/item/modular_computer/pda) && prob(75)) + spark() + broken = REALLY_BROKEN + explosion(src, heavy_impact_range = 1, light_impact_range = 2, flame_range = 1) + var/sigreturn = cooked_item.microwave_act(src, cooker, randomize_pixel_offset = ingredients.len) if(sigreturn & COMPONENT_MICROWAVE_SUCCESS) if(isstack(cooked_item)) @@ -502,7 +681,7 @@ metal_amount += (cooked_item.custom_materials?[GET_MATERIAL_REF(/datum/material/iron)] || 0) - if(cursed_chef && prob(5)) + if(cursed_chef && (metal_amount || prob(5))) // If we're unlucky and have metal, we're guaranteed to explode spark() broken = REALLY_BROKEN explosion(src, light_impact_range = 2, flame_range = 1) @@ -510,10 +689,8 @@ if(metal_amount) spark() broken = REALLY_BROKEN - if(cursed_chef || prob(max(metal_amount / 2, 33))) // If we're unlucky and have metal, we're guaranteed to explode + if(prob(max(metal_amount / 2, 33))) explosion(src, heavy_impact_range = 1, light_impact_range = 2) - else - dump_inventory_contents() after_finish_loop() @@ -524,7 +701,7 @@ after_finish_loop() /obj/machinery/microwave/proc/pre_success(mob/cooker) - loop(MICROWAVE_NORMAL, 10, cooker = cooker) + cook_loop(type = MICROWAVE_NORMAL, cycles = 10, cooker = cooker) /obj/machinery/microwave/proc/muck_finish() visible_message(span_warning("\The [src] gets covered in muck!")) @@ -536,19 +713,121 @@ after_finish_loop() /obj/machinery/microwave/proc/after_finish_loop() - set_light(0) + set_light(l_on = FALSE) soundloop.stop() - open() + eject() + open(autoclose = 2 SECONDS) -/obj/machinery/microwave/proc/open() +/obj/machinery/microwave/proc/open(autoclose = 2 SECONDS) open = TRUE + playsound(loc, 'sound/machines/click.ogg', 15, TRUE, -3) update_appearance() - addtimer(CALLBACK(src, PROC_REF(close)), 0.8 SECONDS) + addtimer(CALLBACK(src, PROC_REF(close)), autoclose) /obj/machinery/microwave/proc/close() open = FALSE update_appearance() +/** + * The start of the charge loop + * + * * cooker - The mob that initiated the cook cycle, can be null if no apparent mob triggered it (such as via emp) + */ +/obj/machinery/microwave/proc/vampire(mob/cooker) + wzhzhzh() + var/obj/item/modular_computer/pda/vampire_pda = LAZYACCESS(ingredients, 1) + if(isnull(vampire_pda)) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + after_finish_loop() + return + + vampire_cell = vampire_pda.internal_cell + if(isnull(vampire_pda)) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + after_finish_loop() + return + + var/vampire_charge_amount = vampire_cell.maxcharge - vampire_cell.charge + charge_loop(vampire_charge_amount, cooker = cooker) + +/obj/machinery/microwave/proc/charge(mob/cooker) + if(!vampire_charging_capable) + balloon_alert(cooker, "needs upgrade!") + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + return + + if(operating || broken > 0 || panel_open || dirty >= MAX_MICROWAVE_DIRTINESS) + return + + if(wire_disabled) + audible_message("[src] buzzes.") + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + return + + // We should only be charging PDAs + for(var/atom/movable/potential_item as anything in ingredients) + if(!istype(potential_item, /obj/item/modular_computer/pda)) + balloon_alert(cooker, "pda only!") + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + eject() + return + + vampire(cooker) + +/** + * The actual cook loop started via [proc/start] or [proc/start_can_fail] + * + * * type - the type of charging, determined via how this iteration of cook_loop is called, and determines the result + * * time - how many loops are left, base case for recursion + * * wait - deciseconds between loops + * * cooker - The mob that initiated the cook cycle, can be null if no apparent mob triggered it (such as via emp) + */ +/obj/machinery/microwave/proc/charge_loop(vampire_charge_amount, wait = max(12 - 2 * efficiency, 2), mob/cooker) // standard wait is 10 + if(machine_stat & BROKEN) + pre_fail() + return + + if(!vampire_charge_amount || !length(ingredients) || (!isnull(cell) && !cell.charge) || vampire_charge_amount < 25) + vampire_cell = null + charge_loop_finish(cooker) + return + + var/charge_rate = vampire_cell.chargerate * (1 + ((efficiency - 1) * 0.25)) + if(charge_rate > vampire_charge_amount) + charge_rate = vampire_charge_amount + + if(cell_powered && !cell.use(charge_rate)) + charge_loop_finish(cooker) + + vampire_cell.give(charge_rate * (0.85 + (efficiency * 0.5))) // we lose a tiny bit of power in the transfer as heat + use_power(charge_rate) + + vampire_charge_amount = vampire_cell.maxcharge - vampire_cell.charge + + addtimer(CALLBACK(src, PROC_REF(charge_loop), vampire_charge_amount, wait, cooker), wait) + +/obj/machinery/microwave/power_change() + . = ..() + if((machine_stat & NOPOWER) && operating) + pre_fail() + eject() + +/** + * Called when the charge_loop is done successfully, no dirty mess or whatever + * + * * cooker - The mob that initiated the cook cycle, can be null if no apparent mob triggered it (such as via emp) + */ +/obj/machinery/microwave/proc/charge_loop_finish(mob/cooker) + operating = FALSE + var/cursed_chef = cooker && HAS_TRAIT(cooker, TRAIT_CURSED) + if(cursed_chef && prob(5)) + spark() + broken = REALLY_BROKEN + explosion(src, light_impact_range = 2, flame_range = 1) + + // playsound(src, 'sound/machines/chime.ogg', 50, FALSE) + after_finish_loop() + /// Type of microwave that automatically turns it self on erratically. Probably don't use this outside of the holodeck program "Microwave Paradise". /// You could also live your life with a microwave that will continously run in the background of everything while also not having any power draw. I think the former makes more sense. /obj/machinery/microwave/hell @@ -564,13 +843,48 @@ //The microwave should turn off asynchronously from any other microwaves that initialize at the same time. Keep in mind this will not turn off, since there is nothing to call the proc that ends this microwave's looping addtimer(CALLBACK(src, PROC_REF(wzhzhzh)), rand(0.5 SECONDS, 3 SECONDS)) +/obj/machinery/microwave/engineering + name = "wireless microwave oven" + desc = "For the hard-working tradesperson who's in the middle of nowhere and just wants to warm up their pastry-based savoury item from an overpriced vending machine." + base_icon_state = "engi_" + icon_state = "engi_mw_complete" + circuit = /obj/item/circuitboard/machine/microwave/engineering + light_color = LIGHT_COLOR_BABY_BLUE + // We don't use area power, we always use the cell + use_power = NO_POWER_USE + cell_powered = TRUE + vampire_charging_capable = TRUE + ingredient_shifts_x = list( + 0, + 5, + -5, + 3, + -3, + ) + ingredient_shifts_y = list( + 0, + 2, + -2, + ) + +/obj/machinery/microwave/engineering/Initialize(mapload) + . = ..() + if(mapload) + cell = new /obj/item/stock_parts/cell/upgraded/plus + update_appearance() + +/obj/machinery/microwave/engineering/cell_included/Initialize(mapload) + . = ..() + cell = new /obj/item/stock_parts/cell/upgraded/plus + update_appearance() + #undef MICROWAVE_NORMAL #undef MICROWAVE_MUCK #undef MICROWAVE_PRE - #undef NOT_BROKEN #undef KINDA_BROKEN #undef REALLY_BROKEN #undef MAX_MICROWAVE_DIRTINESS +#undef TIER_1_CELL_CHARGE_RATE diff --git a/code/modules/food_and_drinks/machinery/processor.dm b/code/modules/food_and_drinks/machinery/processor.dm index 2c1b0b9d3b3475..60679f8934567d 100644 --- a/code/modules/food_and_drinks/machinery/processor.dm +++ b/code/modules/food_and_drinks/machinery/processor.dm @@ -76,7 +76,7 @@ if(isliving(what)) var/mob/living/themob = what - themob.gib(TRUE,TRUE,TRUE) + themob.gib() else qdel(what) LAZYREMOVE(processor_contents, what) diff --git a/code/modules/food_and_drinks/machinery/smartfridge.dm b/code/modules/food_and_drinks/machinery/smartfridge.dm index 6d6645e3368dc0..dfe3987dfe2a14 100644 --- a/code/modules/food_and_drinks/machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/machinery/smartfridge.dm @@ -630,7 +630,7 @@ /obj/item/reagent_containers/cup/beaker, /obj/item/reagent_containers/spray, /obj/item/reagent_containers/medigel, - /obj/item/reagent_containers/cup/vial, //SKYRAT EDIT HYPOSPRAYS + /obj/item/reagent_containers/cup/vial, //SKYRAT EDIT ADDITION - HYPOSPRAYS /obj/item/reagent_containers/chem_pack )) diff --git a/code/modules/forensics/_forensics.dm b/code/modules/forensics/_forensics.dm index 76a051f1d727a6..5936ce4b5c4dee 100644 --- a/code/modules/forensics/_forensics.dm +++ b/code/modules/forensics/_forensics.dm @@ -232,6 +232,8 @@ /datum/forensics/proc/check_blood() if(!parent || !isitem(parent.resolve())) return + if(isorgan(parent.resolve())) // organs don't spawn with blood decals by default + return if(!length(blood_DNA)) return var/atom/parent_atom = parent.resolve() diff --git a/code/modules/hallucination/fake_sound.dm b/code/modules/hallucination/fake_sound.dm index 0a783df3adadf2..ec578f101d376f 100644 --- a/code/modules/hallucination/fake_sound.dm +++ b/code/modules/hallucination/fake_sound.dm @@ -167,7 +167,7 @@ sound_vary = FALSE no_source = TRUE sound_type = list( - 'sound/ambience/antag/bloodcult.ogg', + 'sound/ambience/antag/bloodcult/bloodcult_gain.ogg', 'sound/ambience/antag/clockcultalr.ogg', 'sound/ambience/antag/ecult_op.ogg', 'sound/ambience/antag/ling_alert.ogg', diff --git a/code/modules/hallucination/station_message.dm b/code/modules/hallucination/station_message.dm index 30b537afbc7e8d..fa51e103cca33b 100644 --- a/code/modules/hallucination/station_message.dm +++ b/code/modules/hallucination/station_message.dm @@ -78,7 +78,7 @@ to_chat(hallucinator, ALERT_BODY("Figments from an eldritch god are being summoned by [totally_real_cult_leader.real_name] \ into [fake_summon_area] from an unknown dimension. Disrupt the ritual at all costs!")) - SEND_SOUND(hallucinator, sound(SSstation.announcer.event_sounds[ANNOUNCER_SPANOMALIES])) + SEND_SOUND(hallucinator, 'sound/ambience/antag/bloodcult/bloodcult_scribe.ogg') return ..() /datum/hallucination/station_message/meteors diff --git a/code/modules/holodeck/holo_effect.dm b/code/modules/holodeck/holo_effect.dm index 02502c1e6fb5bc..a8d51c8772829f 100644 --- a/code/modules/holodeck/holo_effect.dm +++ b/code/modules/holodeck/holo_effect.dm @@ -61,6 +61,7 @@ mobtype = pick(mobtype) our_mob = new mobtype(loc) our_mob.flags_1 |= HOLOGRAM_1 + ADD_TRAIT(our_mob, TRAIT_PERMANENTLY_MORTAL, INNATE_TRAIT) // 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") & our_mob.vars) diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm index 80962a2d182992..f69f8a68317cb0 100644 --- a/code/modules/hydroponics/grown/melon.dm +++ b/code/modules/hydroponics/grown/melon.dm @@ -17,7 +17,7 @@ /obj/item/seeds/watermelon/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is swallowing [src]! It looks like [user.p_theyre()] trying to commit suicide!")) - user.gib() + user.gib(DROP_ALL_REMAINS) new product(drop_location()) qdel(src) return MANUAL_SUICIDE diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index 8c42dce397fb36..de8458cb3a94ae 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -247,11 +247,7 @@ // So we'll let it leak in, and move the water over. set_recipient_reagents_holder(nutri_reagents) reagents = nutri_reagents - process_request( - amount = MACHINE_REAGENT_TRANSFER, - reagent = null, - dir = dir - ) + process_request(dir = dir) // Move the leaked water from nutrients to... water var/leaking_water_amount = nutri_reagents.get_reagent_amount(/datum/reagent/water) diff --git a/code/modules/industrial_lift/industrial_lift.dm b/code/modules/industrial_lift/industrial_lift.dm index dd1b3f9604a5d1..0bcc2a49bc84a7 100644 --- a/code/modules/industrial_lift/industrial_lift.dm +++ b/code/modules/industrial_lift/industrial_lift.dm @@ -326,7 +326,7 @@ GLOBAL_LIST_INIT(all_radial_directions, list( if(violent_landing) // Violent landing = gibbed. But the nicest kind of gibbing, keeping everything intact. crushed.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) - crushed.gib(FALSE, FALSE, FALSE) + crushed.gib(DROP_ALL_REMAINS) else // Less violent landing simply crushes every bone in your body. crushed.Paralyze(30 SECONDS, ignore_canstun = TRUE) diff --git a/code/modules/industrial_lift/tram/tram_windows.dm b/code/modules/industrial_lift/tram/tram_windows.dm index 1a98a56a0ba673..55ec5aa283fcae 100644 --- a/code/modules/industrial_lift/tram/tram_windows.dm +++ b/code/modules/industrial_lift/tram/tram_windows.dm @@ -36,8 +36,9 @@ if(fulltile) return ..() smoothing_junction = new_junction - var/smooth_left = (smoothing_junction & turn(dir, 90)) - var/smooth_right = (smoothing_junction & turn(dir, -90)) + var/go_off = reverse_ndir(smoothing_junction) + var/smooth_left = (go_off & turn(dir, 90)) + var/smooth_right = (go_off & turn(dir, -90)) if(smooth_left && smooth_right) icon_state = "tram_mid" else if (smooth_left) diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index ce39b5a740563b..0d8e57f13eb030 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -178,6 +178,8 @@ for(var/i in roundstart_experience) spawned_human.mind.adjust_experience(i, roundstart_experience[i], TRUE) +/// Announce that this job as joined the round to all crew members. +/// Note the joining mob has no client at this point. /datum/job/proc/announce_job(mob/living/joining_mob, job_title) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - Original: /datum/job/proc/announce_job(mob/living/joining_mob) if(head_announce) announce_head(joining_mob, head_announce, job_title) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - Original: announce_head(joining_mob, head_announce) @@ -191,13 +193,27 @@ /mob/living/proc/on_job_equipping(datum/job/equipping) return -/mob/living/carbon/human/on_job_equipping(datum/job/equipping, datum/preferences/used_pref) //SKYRAT EDIT CHANGE +#define VERY_LATE_ARRIVAL_TOAST_PROB 20 + +/mob/living/carbon/human/on_job_equipping(datum/job/equipping, datum/preferences/used_pref, client/player_client) //SKYRAT EDIT CHANGE - ORIGINAL: /mob/living/carbon/human/on_job_equipping(datum/job/equipping) var/datum/bank_account/bank_account = new(real_name, equipping, dna.species.payday_modifier) bank_account.payday(STARTING_PAYCHECKS, TRUE) account_id = bank_account.account_id bank_account.replaceable = FALSE - dress_up_as_job(equipping, FALSE, used_pref) //SKYRAT EDIT CHANGE + add_mob_memory(/datum/memory/key/account, remembered_id = account_id) + + dress_up_as_job(equipping, FALSE, used_pref) //SKYRAT EDIT CHANGE - ORIGINAL: dress_up_as_job(equipping) + + if(EMERGENCY_PAST_POINT_OF_NO_RETURN && prob(VERY_LATE_ARRIVAL_TOAST_PROB)) + //equipping.equip_to_slot_or_del(new /obj/item/food/griddle_toast(equipping), ITEM_SLOT_MASK) // SKYRAT EDIT REMOVAL - See below + // SKYRAT EDIT ADDITION - Lizards + if(islizard(equipping)) + equip_to_slot_or_del(new /obj/item/food/breadslice/root(equipping), ITEM_SLOT_MASK) + else + equip_to_slot_or_del(new /obj/item/food/griddle_toast(equipping), ITEM_SLOT_MASK) + // SKYRAT EDIT ADDITION END - Lizards +#undef VERY_LATE_ARRIVAL_TOAST_PROB /mob/living/proc/dress_up_as_job(datum/job/equipping, visual_only = FALSE) return @@ -267,8 +283,43 @@ return TRUE -/datum/job/proc/radio_help_message(mob/M) - to_chat(M, "Prefix your message with :h to speak on your department's radio. To see other prefixes, look closely at your headset.") +/// Gets the message that shows up when spawning as this job +/datum/job/proc/get_spawn_message(alt_title) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: /datum/job/proc/get_spawn_message() + SHOULD_NOT_OVERRIDE(TRUE) + return examine_block(span_infoplain(jointext(get_spawn_message_information(alt_title), "\n• "))) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLED - ORIGINAL: return examine_block(span_infoplain(jointext(get_spawn_message_information(), "\n• "))) + +/// Returns a list of strings that correspond to chat messages sent to this mob when they join the round. +/datum/job/proc/get_spawn_message_information(alt_title = title) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: /datum/job/proc/get_spawn_message_information() + SHOULD_CALL_PARENT(TRUE) + var/list/info = list() + info += "You are the [alt_title].\n" // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: info += "You are the [title].\n" + var/related_policy = get_policy(title) + var/radio_info = get_radio_information() + if(related_policy) + info += related_policy + if(supervisors) + info += "As the [alt_title == title ? alt_title : "[alt_title] ([title])"] you answer directly to [supervisors]. Special circumstances may change this." // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: info += "As the [title] you answer directly to [supervisors]. Special circumstances may change this." + if(radio_info) + info += radio_info + if(req_admin_notify) + info += "You are playing a job that is important for Game Progression. \ + If you have to disconnect, please notify the admins via adminhelp." + if(CONFIG_GET(number/minimal_access_threshold)) + info += span_boldnotice("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.") + //SKYRAT EDIT ADDITION START - ALTERNATIVE_JOB_TITLES + if(alt_title != title) + info += span_warning("Remember that alternate titles are purely for flavor and roleplay.") + info += span_doyourjobidiot("Do not use your \"[alt_title]\" alt title as an excuse to forego your duties as a [title].") + //SKYRAT EDIT END + + return info + +/// Returns information pertaining to this job's radio. +/datum/job/proc/get_radio_information() + if(job_flags & JOB_CREW_MEMBER) + return "Prefix your message with :h to speak on your department's radio. To see other prefixes, look closely at your headset." /datum/outfit/job name = "Standard Gear" diff --git a/code/modules/jobs/job_types/ai.dm b/code/modules/jobs/job_types/ai.dm index f3f8b23837b276..0b38d6e081d39a 100644 --- a/code/modules/jobs/job_types/ai.dm +++ b/code/modules/jobs/job_types/ai.dm @@ -117,5 +117,5 @@ /datum/job/ai/config_check() return CONFIG_GET(flag/allow_ai) -/datum/job/ai/radio_help_message(mob/M) - to_chat(M, "Prefix your message with :b to speak with cyborgs and other AIs.") +/datum/job/ai/get_radio_information() + return "Prefix your message with :b to speak with cyborgs and other AIs." diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm index e788202b445190..d8ae6d335b3202 100755 --- a/code/modules/jobs/job_types/captain.dm +++ b/code/modules/jobs/job_types/captain.dm @@ -51,6 +51,9 @@ /datum/job/captain/get_captaincy_announcement(mob/living/captain) return "Captain [captain.real_name] on deck!" +/datum/job/captain/get_radio_information() + . = ..() + . += "\nYou have access to all radio channels, but they are not automatically tuned. Check your radio for more information." /datum/outfit/job/captain name = "Captain" diff --git a/code/modules/jobs/job_types/chaplain/chaplain.dm b/code/modules/jobs/job_types/chaplain/chaplain.dm index be4516a0db764c..58821ec5358760 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain.dm @@ -25,7 +25,6 @@ mail_goodies = list( /obj/item/reagent_containers/cup/glass/bottle/holywater = 30, - /obj/item/toy/plush/awakenedplushie = 10, /obj/item/grenade/chem_grenade/holy = 5, /obj/item/toy/plush/narplush = 2, /obj/item/toy/plush/ratplush = 1 diff --git a/code/modules/jobs/job_types/chaplain/chaplain_costumes.dm b/code/modules/jobs/job_types/chaplain/chaplain_costumes.dm index f2ab21c9c35261..637177adffbcd3 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain_costumes.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain_costumes.dm @@ -50,6 +50,14 @@ body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS flags_inv = HIDEJUMPSUIT +/obj/item/clothing/suit/chaplainsuit/habit + name = "religious tunic" + desc = "No nunsene clothing." + icon_state = "habit" + alternate_worn_layer = GLOVES_LAYER // since the sleeves cover a part of the hands, this way it looks better while retaining glove overlay correctly. + body_parts_covered = CHEST|GROIN|LEGS|ARMS|HANDS + flags_inv = HIDEJUMPSUIT + /obj/item/clothing/suit/chaplainsuit/bishoprobe name = "bishop's robes" desc = "Glad to see the tithes you collected were well spent." diff --git a/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm b/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm index a214eb48e0cc95..805c72a326749b 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain_nullrod.dm @@ -31,7 +31,7 @@ on_clear_callback = CALLBACK(src, PROC_REF(on_cult_rune_removed)), \ effects_we_clear = list(/obj/effect/rune, /obj/effect/heretic_rune, /obj/effect/cosmic_rune), \ ) - AddElement(/datum/element/bane, target_type = /mob/living/simple_animal/revenant, damage_multiplier = 0, added_damage = 25, requires_combat_mode = FALSE) + AddElement(/datum/element/bane, target_type = /mob/living/basic/revenant, damage_multiplier = 0, added_damage = 25, requires_combat_mode = FALSE) if(!GLOB.holy_weapon_type && type == /obj/item/nullrod) var/list/rods = list() diff --git a/code/modules/jobs/job_types/cook.dm b/code/modules/jobs/job_types/cook.dm index a3f03c2d9b13dd..e96bae827fa9b7 100644 --- a/code/modules/jobs/job_types/cook.dm +++ b/code/modules/jobs/job_types/cook.dm @@ -33,13 +33,14 @@ // Adds up to 100, don't mess it up mail_goodies = list( /obj/item/storage/box/ingredients/random = 40, - /obj/item/reagent_containers/cup/bottle/caramel = 8, - /obj/item/reagent_containers/condiment/flour = 8, - /obj/item/reagent_containers/condiment/rice = 8, - /obj/item/reagent_containers/condiment/ketchup = 8, - /obj/item/reagent_containers/condiment/enzyme = 8, - /obj/item/reagent_containers/condiment/soymilk = 8, + /obj/item/reagent_containers/cup/bottle/caramel = 7, + /obj/item/reagent_containers/condiment/flour = 7, + /obj/item/reagent_containers/condiment/rice = 7, + /obj/item/reagent_containers/condiment/ketchup = 7, + /obj/item/reagent_containers/condiment/enzyme = 7, + /obj/item/reagent_containers/condiment/soymilk = 7, /obj/item/kitchen/spoon/soup_ladle = 6, + /obj/item/kitchen/tongs = 6, /obj/item/knife/kitchen = 4, /obj/item/knife/butcher = 2, ) diff --git a/code/modules/jobs/job_types/cyborg.dm b/code/modules/jobs/job_types/cyborg.dm index ae6b7c142cc4ff..9209407303321a 100644 --- a/code/modules/jobs/job_types/cyborg.dm +++ b/code/modules/jobs/job_types/cyborg.dm @@ -4,7 +4,7 @@ auto_deadmin_role_flags = DEADMIN_POSITION_SILICON faction = FACTION_STATION total_positions = 3 // SKYRAT EDIT: Original value (0) - spawn_positions = 3 // SKYRAT EDIT: Original value (1) + spawn_positions = 3 supervisors = "your laws and the AI" //Nodrak spawn_type = /mob/living/silicon/robot minimal_player_age = 21 @@ -58,5 +58,5 @@ if(!robot_spawn.connected_ai) // Only log if there's no Master AI robot_spawn.log_current_laws() -/datum/job/cyborg/radio_help_message(mob/M) - to_chat(M, "Prefix your message with :b to speak with other cyborgs and AI.") +/datum/job/cyborg/get_radio_information() + return "Prefix your message with :b to speak with other cyborgs and AI." diff --git a/code/modules/jobs/job_types/paramedic.dm b/code/modules/jobs/job_types/paramedic.dm index 3dac90b4baf668..2fd4f3a93a6da0 100644 --- a/code/modules/jobs/job_types/paramedic.dm +++ b/code/modules/jobs/job_types/paramedic.dm @@ -32,7 +32,8 @@ /obj/item/reagent_containers/hypospray/medipen/salacid = 10, /obj/item/reagent_containers/hypospray/medipen/salbutamol = 10, /obj/item/reagent_containers/hypospray/medipen/penacid = 10, - /obj/item/reagent_containers/hypospray/medipen/survival/luxury = 5 + /obj/item/reagent_containers/hypospray/medipen/survival/luxury = 5, + /obj/item/storage/box/bandages = 5, ) rpg_title = "Corpse Runner" job_flags = STATION_JOB_FLAGS @@ -56,6 +57,7 @@ gloves = /obj/item/clothing/gloves/latex/nitrile shoes = /obj/item/clothing/shoes/sneakers/blue l_pocket = /obj/item/modular_computer/pda/medical/paramedic + r_pocket = /obj/item/storage/box/bandages backpack = /obj/item/storage/backpack/medic satchel = /obj/item/storage/backpack/satchel/med diff --git a/code/modules/library/bibles.dm b/code/modules/library/bibles.dm index 7a69fa2795764c..8a10a058341fe8 100644 --- a/code/modules/library/bibles.dm +++ b/code/modules/library/bibles.dm @@ -132,7 +132,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list( to_chat(user, span_userdanger("[deity_name] SMITE thee!")) add_memory_in_range(user, 7, /datum/memory/witnessed_gods_wrath, protagonist = user, deuteragonist = src, antagonist = deity_name) user.client?.give_award(/datum/award/achievement/misc/gods_wrath, user) - user.gib() + user.gib(DROP_ALL_REMAINS) else to_chat(user, span_userdanger("[deity_name] cast a curse upon thee!")) user.AddComponent(/datum/component/omen/bible) @@ -223,7 +223,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list( var/list/hurt_limbs = built_in_his_image.get_damaged_bodyparts(1, 1, BODYTYPE_ORGANIC) if(length(hurt_limbs)) for(var/obj/item/bodypart/affecting as anything in hurt_limbs) - if(affecting.heal_damage(heal_amt, heal_amt, BODYTYPE_ORGANIC)) + if(affecting.heal_damage(heal_amt, heal_amt, required_bodytype = BODYTYPE_ORGANIC)) built_in_his_image.update_damage_overlays() built_in_his_image.visible_message(span_notice("[user] heals [built_in_his_image] with the power of [deity_name]!")) to_chat(built_in_his_image, span_boldnotice("May the power of [deity_name] compel you to be healed!")) @@ -369,7 +369,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list( tip_text = "Clear rune", \ effects_we_clear = list(/obj/effect/rune, /obj/effect/heretic_rune, /obj/effect/cosmic_rune), \ ) - AddElement(/datum/element/bane, target_type = /mob/living/simple_animal/revenant, damage_multiplier = 0, added_damage = 25, requires_combat_mode = FALSE) + AddElement(/datum/element/bane, target_type = /mob/living/basic/revenant, damage_multiplier = 0, added_damage = 25, requires_combat_mode = FALSE) /obj/item/book/bible/syndicate/attack_self(mob/living/carbon/human/user, modifiers) if(!uses || !istype(user)) diff --git a/code/modules/library/skill_learning/skillchip.dm b/code/modules/library/skill_learning/skillchip.dm index f9fd629c1ed4dc..762e8e0162c528 100644 --- a/code/modules/library/skill_learning/skillchip.dm +++ b/code/modules/library/skill_learning/skillchip.dm @@ -489,4 +489,13 @@ activate_message = span_notice("You recall learning from your grandmother how they baked their cookies with love.") deactivate_message = span_notice("You forget all memories imparted upon you by your grandmother. Were they even your real grandma?") +/obj/item/skillchip/master_angler + name = "Mast-Angl-Er skillchip" + auto_traits = list(TRAIT_REVEAL_FISH) + skill_name = "Fisherman's Discernment" + skill_description = "While fishing, it'll make a smidge easier to guess whatever you're trying to catch." + skill_icon = "fish" + activate_message = span_notice("You feel the knowledge and passion of several sunbaked, seasoned fishermen burn within you.") + deactivate_message = span_notice("You no longer feel like casting a fishing rod by the sunny riverside.") + #undef SKILLCHIP_CATEGORY_GENERAL diff --git a/code/modules/mafia/controller.dm b/code/modules/mafia/controller.dm index 1916a65f7b17a2..f8d9db131064d3 100644 --- a/code/modules/mafia/controller.dm +++ b/code/modules/mafia/controller.dm @@ -578,7 +578,7 @@ GLOBAL_LIST_INIT(mafia_role_by_alignment, setup_mafia_role_by_alignment()) for(var/datum/mafia_role/role as anything in all_roles) var/mob/living/carbon/human/H = new(get_turf(role.assigned_landmark)) - H.add_traits(list(TRAIT_NOFIRE, TRAIT_NOBREATH, TRAIT_CANNOT_CRYSTALIZE), MAFIA_TRAIT) + H.add_traits(list(TRAIT_NOFIRE, TRAIT_NOBREATH, TRAIT_CANNOT_CRYSTALIZE, TRAIT_PERMANENTLY_MORTAL), MAFIA_TRAIT) H.equipOutfit(outfit_to_distribute) H.status_flags |= GODMODE RegisterSignal(H, COMSIG_ATOM_UPDATE_OVERLAYS, PROC_REF(display_votes)) diff --git a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm index 5e459758ee4054..aa201292f72a23 100644 --- a/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm +++ b/code/modules/mapfluff/ruins/lavalandruin_code/elephantgraveyard.dm @@ -60,6 +60,12 @@ if(prob(floor_variance)) icon_state = "[base_icon_state][rand(0,6)]" +/turf/open/misc/asteroid/basalt/wasteland/basin + icon_state = "wasteland_dug" + base_icon_state = "wasteland_dug" + floor_variance = 0 + dug = TRUE + /turf/closed/mineral/strong/wasteland name = "ancient dry rock" color = "#B5651D" diff --git a/code/modules/mapfluff/ruins/lavalandruin_code/watcher_grave.dm b/code/modules/mapfluff/ruins/lavalandruin_code/watcher_grave.dm new file mode 100644 index 00000000000000..75ac48c2467c4a --- /dev/null +++ b/code/modules/mapfluff/ruins/lavalandruin_code/watcher_grave.dm @@ -0,0 +1,263 @@ +/obj/effect/mob_spawn/corpse/goliath/pierced + corpse_description = "Seems to have been pierced through the heart by a Watcher spike." + naive_corpse_description = "It's got a pretty big boo-boo, might need one of the large plasters." + +/obj/effect/mob_spawn/corpse/watcher/goliath_chewed + corpse_description = "Prior to its death, it was badly mangled by the jaws of a Goliath." + naive_corpse_description = "It's all tuckered out after playing rough with a Goliath." + +/obj/effect/mob_spawn/corpse/watcher/crushed + corpse_description = "Crushed by a rockslide, it seemed to have been scraping frantically at the rocks even as it perished." + naive_corpse_description = "All of those rocks probably don't make a comfortable blanket." + + +#define WATCHER_EGG_LIVELY_MOD 0.75 +#define WATCHER_EGG_ACTIVE_MOD 0.5 + +/// Egg which hatches into a helpful pet. Or you can eat it if you want. +/obj/item/food/egg/watcher + name = "watcher egg" + desc = "A lonely egg still pulsing with life, somehow untouched by the corruption of the Necropolis." + icon_state = "egg_watcher" + chick_throw_prob = 100 + tastes = list("ocular fluid" = 6, "loneliness" = 1) + preserved_food = TRUE + /// How far have we moved? + var/steps_travelled = 0 + /// How far should we travel to hatch? + var/steps_to_hatch = 600 + /// Datum used to measure our steps + var/datum/movement_detector/pedometer + +/obj/item/food/egg/watcher/Initialize(mapload) + . = ..() + pedometer = new(src, CALLBACK(src, PROC_REF(on_stepped))) + +/obj/item/food/egg/watcher/Destroy(force) + . = ..() + QDEL_NULL(pedometer) + +/obj/item/food/egg/watcher/spawn_impact_chick(turf/spawn_turf) + new /obj/effect/spawner/random/lavaland_mob/watcher(spawn_turf) + +/obj/item/food/egg/watcher/examine(mob/user) + return ..() + span_notice("Watch it more closely to see how it is doing...") + +/obj/item/food/egg/watcher/examine_more(mob/user) + . = ..() + if (steps_travelled < (steps_to_hatch * WATCHER_EGG_ACTIVE_MOD)) + return . + span_notice("Something stirs listlessly inside.") + if (steps_travelled < steps_to_hatch * WATCHER_EGG_LIVELY_MOD) + return . + span_notice("Something is moving actively inside.") + return . + span_boldnotice("It's jiggling wildly, it's about to hatch!") + +/// Called when we are moved, whether inside an inventory or by ourself somehow +/obj/item/food/egg/watcher/proc/on_stepped(atom/movable/egg, atom/mover, atom/old_loc, direction) + var/new_loc = get_turf(egg) + if (isnull(new_loc) || new_loc == get_turf(old_loc)) + return // Didn't actually go anywhere + steps_travelled++ + if (steps_travelled == steps_to_hatch * WATCHER_EGG_ACTIVE_MOD) + jiggle() + return + if (steps_travelled < steps_to_hatch) + return + visible_message(span_boldnotice("[src] splits and unfurls into a baby Watcher!")) + playsound(new_loc, 'sound/effects/splat.ogg', 50, TRUE) + new /obj/effect/decal/cleanable/greenglow(new_loc) + new /obj/item/watcher_hatchling(new_loc) + qdel(src) + +/// Animate the egg +/obj/item/food/egg/watcher/proc/jiggle() + var/animation = isturf(loc) ? rand(1, 3) : 1 // Pixel_x/y animations don't work in an inventory + switch(animation) + if (1) + animate(src, transform = transform.Scale(1.3), time = 1 SECONDS, easing = BOUNCE_EASING) + animate(transform = matrix(), time = 0.5 SECONDS, easing = SINE_EASING | EASE_IN) + if (2) + animate(src, pixel_y = 8, time = 0.5 SECONDS, easing = SINE_EASING | EASE_OUT) + animate(pixel_y = 0, time = 0.5 SECONDS, easing = SINE_EASING | EASE_IN) + animate(pixel_y = 4, time = 0.5 SECONDS, easing = SINE_EASING | EASE_OUT) + animate(pixel_y = 0, time = 0.5 SECONDS, easing = BOUNCE_EASING | EASE_IN) + if (3) + Shake(pixelshiftx = 2, pixelshifty = 0, shake_interval = 0.3 SECONDS) + var/next_jiggle = rand(5 SECONDS, 10 SECONDS) / (steps_travelled >= steps_to_hatch * WATCHER_EGG_LIVELY_MOD ? 2 : 1) + addtimer(CALLBACK(src, PROC_REF(jiggle)), next_jiggle, TIMER_DELETE_ME) + +#undef WATCHER_EGG_LIVELY_MOD +#undef WATCHER_EGG_ACTIVE_MOD + + +/// A cute pet who will occasionally attack lavaland mobs for you +/obj/item/watcher_hatchling + name = "watcher hatchling" + desc = "A newly born watcher, apparently free of the Necropolis' corruption. Perhaps one of the last." + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "watcher_baby" + w_class = WEIGHT_CLASS_SMALL + /// The effect we create when out and about + var/obj/effect/watcher_orbiter/orbiter + /// Who are we orbiting? + var/mob/living/owner + +/obj/item/watcher_hatchling/attack_self(mob/user, modifiers) + . = ..() + if (!isnull(orbiter)) + watcher_return() + return + orbiter = new (get_turf(src)) + orbiter.follow(user) + owner = user + RegisterSignal(owner, COMSIG_QDELETING, PROC_REF(remove_owner)) + RegisterSignal(orbiter, COMSIG_QDELETING, PROC_REF(remove_orbiter)) + +/obj/item/watcher_hatchling/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) + . = ..() + if (isnull(orbiter)) + return + var/mob/holder = recursive_loc_check(src, /mob) + if (holder != owner) + watcher_return() + +/// If the guy we are orbiting is deleted but somehow we aren't +/obj/item/watcher_hatchling/proc/remove_owner() + SIGNAL_HANDLER + UnregisterSignal(owner, COMSIG_QDELETING) + owner = null + +/// In the more likely event that our orbiter is deleted, stop holding a reference to it +/obj/item/watcher_hatchling/proc/remove_orbiter() + SIGNAL_HANDLER + orbiter = null // No need to unregister signal because we only call this when it deletes + +/// Get back in your ball pikachu +/obj/item/watcher_hatchling/proc/watcher_return() + qdel(orbiter) + remove_owner() + + +/// Orbiting visual which shoots at mining mobs +/obj/effect/watcher_orbiter + name = "watcher hatchling" + icon = 'icons/mob/simple/lavaland/lavaland_monsters.dmi' + icon_state = "watcher_baby" + layer = EDGED_TURF_LAYER // Don't render under lightbulbs + plane = GAME_PLANE_UPPER + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + pixel_y = 22 + alpha = 0 + /// Who are we following? + var/atom/parent + /// Datum which keeps us hanging out with our parent + var/datum/movement_detector/tracker + /// Type of projectile we fire + var/projectile_type = /obj/projectile/baby_watcher_blast + /// Sound to make when we shoot + var/projectile_sound = 'sound/weapons/pierce.ogg' + /// Time between taking potshots at goliaths + var/fire_delay = 5 SECONDS + /// How much faster do we shoot when avenging our parent? + var/on_death_multiplier = 5 + /// Time taken between shots + COOLDOWN_DECLARE(shot_cooldown) + /// Types of mobs to attack + var/list/target_faction = list(FACTION_MINING) + +/obj/effect/watcher_orbiter/Initialize(mapload) + . = ..() + START_PROCESSING(SSobj, src) + +// Shuttle rotation fucks with our position, we just want to stick with our guy +/obj/effect/watcher_orbiter/shuttleRotate(rotation, params) + return + +/obj/effect/watcher_orbiter/Destroy(force) + STOP_PROCESSING(SSobj, src) + QDEL_NULL(tracker) + return ..() + +/obj/effect/watcher_orbiter/process(seconds_per_tick) + if (!COOLDOWN_FINISHED(src, shot_cooldown)) + return + for (var/mob/living/potential_target in oview(5, src)) + if (!ismining(potential_target) || potential_target.stat == DEAD) + continue + if (!faction_check(target_faction, potential_target.faction)) + continue + shoot_at(potential_target) + return + +/// Take a shot +/obj/effect/watcher_orbiter/proc/shoot_at(atom/target) + COOLDOWN_START(src, shot_cooldown, fire_delay) + fire_projectile(projectile_type, target, projectile_sound, ignore_targets = list(parent)) + +/// Set ourselves up to track and orbit around a guy +/obj/effect/watcher_orbiter/proc/follow(atom/movable/target) + parent = target + glide_size = target.glide_size + animate(src, pixel_y = 26, alpha = 255, time = 0.5 SECONDS) + addtimer(CALLBACK(src, PROC_REF(orbit_animation)), 0.5 SECONDS, TIMER_DELETE_ME) + tracker = new(target, CALLBACK(src, PROC_REF(on_parent_moved))) + RegisterSignal(target, COMSIG_MOVABLE_UPDATE_GLIDE_SIZE, PROC_REF(on_glide_size_changed)) + RegisterSignal(target, COMSIG_QDELETING, PROC_REF(on_parent_deleted)) + RegisterSignal(target, COMSIG_LIVING_DEATH, PROC_REF(on_parent_died)) + RegisterSignal(target, COMSIG_LIVING_REVIVE, PROC_REF(on_parent_revived)) + +/// Do our orbiting animation +/obj/effect/watcher_orbiter/proc/orbit_animation() + animate(src, pixel_y = 26, time = 1 SECONDS, loop = -1, easing = SINE_EASING, flags = ANIMATION_PARALLEL) + animate(pixel_y = 18, time = 1 SECONDS, easing = SINE_EASING) + animate(src, pixel_x = 20, time = 0.5 SECONDS, loop = -1, easing = SINE_EASING | EASE_OUT, flags = ANIMATION_PARALLEL) + animate(pixel_x = 0, time = 0.5 SECONDS, easing = SINE_EASING | EASE_IN) + animate(pixel_x = -20, time = 0.5 SECONDS, easing = SINE_EASING | EASE_OUT) + animate(pixel_x = 0, time = 0.5 SECONDS, easing = SINE_EASING | EASE_IN) + +/// Follow our parent +/obj/effect/watcher_orbiter/proc/on_parent_moved(atom/movable/parent, atom/mover, atom/old_loc, direction) + if(parent.loc == old_loc) + return + var/turf/new_turf = get_turf(parent) + if(isnull(new_turf)) + qdel(src) + return + if (loc != new_turf) + abstract_move(new_turf) + +/// Make sure we glide at the same speed as our parent +/obj/effect/watcher_orbiter/proc/on_glide_size_changed(atom/source, new_glide_size) + SIGNAL_HANDLER + glide_size = new_glide_size + +/// Called if the guy we're tracking is deleted somehow +/obj/effect/watcher_orbiter/proc/on_parent_deleted() + SIGNAL_HANDLER + parent = null + qdel(src) + +/// We must guard this corpse +/obj/effect/watcher_orbiter/proc/on_parent_died(mob/living/parent) + SIGNAL_HANDLER + visible_message(span_notice("[src] emits a piteous keening in mourning of [parent]!")) + fire_delay /= on_death_multiplier + +/// Exit hyperactive mode +/obj/effect/watcher_orbiter/proc/on_parent_revived(mob/living/parent) + SIGNAL_HANDLER + visible_message(span_notice("[src] chirps happily as [parent] suddenly gasps for breath!")) + fire_delay *= on_death_multiplier + + +/// Beam fired by a baby watcher, doesn't actually do less damage than its parent +/obj/projectile/baby_watcher_blast + name = "hatchling beam" + icon_state = "ice_2" + damage = 10 + damage_type = BRUTE // Mining mobs don't take a lot of burn damage so we'll pretend + speed = 1 + pixel_speed_multiplier = 0.5 + +/obj/projectile/baby_watcher_blast/Initialize(mapload) + . = ..() + transform = transform.Scale(0.5) diff --git a/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm index 505b6cd5d796e6..5775f0a20f2320 100644 --- a/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm +++ b/code/modules/mapfluff/ruins/objects_and_mobs/ash_walker_den.dm @@ -57,10 +57,10 @@ visible_message(span_notice("Serrated tendrils eagerly pull [H] apart, but find nothing of interest.")) return - if(H.mind?.has_antag_datum(/datum/antagonist/ashwalker) && (H.key || H.get_ghost(FALSE, TRUE))) //special interactions for dead lava lizards with ghosts attached + if(H.mind?.has_antag_datum(/datum/antagonist/ashwalker) && (H.ckey || H.get_ghost(FALSE, TRUE))) //special interactions for dead lava lizards with ghosts attached visible_message(span_warning("Serrated tendrils carefully pull [H] to [src], absorbing the body and creating it anew.")) var/datum/mind/deadmind - if(H.key) + if(H.ckey) deadmind = H else deadmind = H.get_ghost(FALSE, TRUE) @@ -77,14 +77,14 @@ meat_counter++ visible_message(span_warning("Serrated tendrils eagerly pull [H] to [src], tearing the body apart as its blood seeps over the eggs.")) playsound(get_turf(src),'sound/magic/demon_consume.ogg', 100, TRUE) - var/deliverykey = H.fingerprintslast //key of whoever brought the body - var/mob/living/deliverymob = get_mob_by_key(deliverykey) //mob of said key + var/deliverykey = H.fingerprintslast //ckey of whoever brought the body + var/mob/living/deliverymob = get_mob_by_key(deliverykey) //mob of said ckey //there is a 40% chance that the Lava Lizard unlocks their respawn with each sacrifice if(deliverymob && (deliverymob.mind?.has_antag_datum(/datum/antagonist/ashwalker)) && (deliverykey in ashies.players_spawned) && (prob(40))) to_chat(deliverymob, span_warning("The Necropolis is pleased with your sacrifice. You feel confident your existence after death is secure.")) ashies.players_spawned -= deliverykey H.investigate_log("has been gibbed by the necropolis tendril.", INVESTIGATE_DEATHS) - H.gib() + H.gib(DROP_ALL_REMAINS) atom_integrity = min(atom_integrity + max_integrity*0.05,max_integrity)//restores 5% hp of tendril for(var/mob/living/L in view(src, 5)) if(L.mind?.has_antag_datum(/datum/antagonist/ashwalker)) diff --git a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm index 424e1db299ec57..af316034f939bd 100644 --- a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm +++ b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm @@ -428,7 +428,7 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999)) if(unforeseen_consequences) to_chat(unforeseen_consequences, span_warning("\The [H] starts to resonate. Forcing it to enter itself induces a bluespace paradox, violently tearing your body apart.")) unforeseen_consequences.investigate_log("has been gibbed by using [H] while inside of it.", INVESTIGATE_DEATHS) - unforeseen_consequences.gib() + unforeseen_consequences.gib(DROP_ALL_REMAINS) var/turf/targetturf = find_safe_turf() if(!targetturf) diff --git a/code/modules/mapping/access_helpers.dm b/code/modules/mapping/access_helpers.dm index 16da29837fbd50..c208e2eea9ea9e 100644 --- a/code/modules/mapping/access_helpers.dm +++ b/code/modules/mapping/access_helpers.dm @@ -386,6 +386,11 @@ access_list += list(ACCESS_CARGO, ACCESS_MAINT_TUNNELS) return access_list +/obj/effect/mapping_helpers/airlock/access/any/supply/bit_den/get_access() + var/list/access_list = ..() + access_list += ACCESS_BIT_DEN + return access_list + // -------------------- Syndicate access helpers /obj/effect/mapping_helpers/airlock/access/any/syndicate icon_state = "access_helper_syn" diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm index 237ae9f2d52e4e..7917da4d542302 100644 --- a/code/modules/mapping/map_template.dm +++ b/code/modules/mapping/map_template.dm @@ -109,7 +109,6 @@ // need these two below? SSmachines.setup_template_powernets(cables) SSair.setup_template_machinery(atmos_machines) - SSshuttle.setup_shuttles(ports) //calculate all turfs inside the border var/list/template_and_bordering_turfs = block( diff --git a/code/modules/meteors/meteor_spawning.dm b/code/modules/meteors/meteor_spawning.dm index eac365bc2a83e9..97c359d03bfbae 100644 --- a/code/modules/meteors/meteor_spawning.dm +++ b/code/modules/meteors/meteor_spawning.dm @@ -109,7 +109,7 @@ new_changeling.log_message("was spawned as a midround space changeling by an event.", LOG_GAME) var/datum/antagonist/changeling/changeling_datum = locate() in player_mind.antag_datums - changeling_datum.give_power(/datum/action/changeling/suit/organic_space_suit) + changeling_datum.give_power(/datum/action/changeling/void_adaption) changeling_datum.give_power(/datum/action/changeling/weapon/arm_blade) new_changeling.equipOutfit(/datum/outfit/changeling_space) diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index a656aa467d65d5..c9fdb9747e5bdc 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -188,7 +188,9 @@ new /obj/item/clothing/suit/costume/wellworn_shirt/graphic/ian(src) new /obj/item/clothing/suit/hooded/ian_costume(src) if(67 to 68) - new /obj/item/toy/plush/awakenedplushie(src) + var/obj/item/gibtonite/free_bomb = new /obj/item/gibtonite(src) + free_bomb.quality = rand(1, 3) + free_bomb.GibtoniteReaction(null, "A secure loot closet has spawned a live") if(69 to 70) new /obj/item/stack/ore/bluespace_crystal(src, 5) if(71 to 72) diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index caee1bbac8d2bb..4ceddb09854cad 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -437,3 +437,36 @@ chaser.monster_damage_boost = FALSE // Weaker cuz no cooldown chaser.damage = 20 log_combat(user, target, "fired a chaser at", src) + +/obj/item/crusher_trophy/ice_demon_cube + name = "demonic cube" + desc = "A stone cold cube dropped from an ice demon." + icon_state = "ice_demon_cube" + denied_type = /obj/item/crusher_trophy/ice_demon_cube + ///how many will we summon? + var/summon_amount = 2 + ///cooldown to summon demons upon the target + COOLDOWN_DECLARE(summon_cooldown) + +/obj/item/crusher_trophy/ice_demon_cube/effect_desc() + return "mark detonation to unleash demonic ice clones upon the target" + +/obj/item/crusher_trophy/ice_demon_cube/on_mark_detonation(mob/living/target, mob/living/user) + if(isnull(target) || !COOLDOWN_FINISHED(src, summon_cooldown)) + return + for(var/i in 1 to summon_amount) + var/turf/drop_off = find_dropoff_turf(target, user) + var/mob/living/basic/mining/demon_afterimage/crusher/friend = new(drop_off) + friend.faction = list(FACTION_NEUTRAL) + friend.befriend(user) + friend.ai_controller?.set_blackboard_key(BB_BASIC_MOB_CURRENT_TARGET, target) + COOLDOWN_START(src, summon_cooldown, 30 SECONDS) + +///try to make them spawn all around the target to surround him +/obj/item/crusher_trophy/ice_demon_cube/proc/find_dropoff_turf(mob/living/target, mob/living/user) + var/list/turfs_list = get_adjacent_open_turfs(target) + for(var/turf/possible_turf in turfs_list) + if(possible_turf.is_blocked_turf()) + continue + return possible_turf + return get_turf(user) diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index e9c652fd7bdf48..b01b537ec80d94 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -267,7 +267,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ return if(I.tool_behaviour == TOOL_MINING || istype(I, /obj/item/resonator) || I.force >= 10) - GibtoniteReaction(user) + GibtoniteReaction(user, "A resonator has primed for detonation a") return if(istype(I, /obj/item/mining_scanner) || istype(I, /obj/item/t_scanner/adv_mining_scanner) || I.tool_behaviour == TOOL_MULTITOOL) @@ -294,14 +294,14 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ return ..() /obj/item/gibtonite/bullet_act(obj/projectile/P) - GibtoniteReaction(P.firer) + GibtoniteReaction(P.firer, "A projectile has primed for detonation a") return ..() /obj/item/gibtonite/ex_act() - GibtoniteReaction(null, 1) + GibtoniteReaction(null, "An explosion has primed for detonation a") return TRUE -/obj/item/gibtonite/proc/GibtoniteReaction(mob/user, triggered_by = 0) +/obj/item/gibtonite/proc/GibtoniteReaction(mob/user, triggered_by) if(primed) return primed = TRUE @@ -311,18 +311,16 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ if(!is_mining_level(z))//Only annoy the admins ingame if we're triggered off the mining zlevel notify_admins = TRUE - if(triggered_by == 1) - log_bomber(null, "An explosion has primed a", src, "for detonation", notify_admins) - else if(triggered_by == 2) - var/turf/bombturf = get_turf(src) - if(notify_admins) - message_admins("A signal has triggered a [name] to detonate at [ADMIN_VERBOSEJMP(bombturf)]. Igniter attacher: [ADMIN_LOOKUPFLW(attacher)]") - var/bomb_message = "A signal has primed a [name] for detonation at [AREACOORD(bombturf)]. Igniter attacher: [key_name(attacher)]." - log_game(bomb_message) - GLOB.bombers += bomb_message - else + if(user) user.visible_message(span_warning("[user] strikes \the [src], causing a chain reaction!"), span_danger("You strike \the [src], causing a chain reaction.")) - log_bomber(user, "has primed a", src, "for detonation", notify_admins) + + var/attacher_text = attacher ? "Igniter attacher: [ADMIN_LOOKUPFLW(attacher)]" : null + + if(triggered_by) + log_bomber(user, triggered_by, src, attacher_text, notify_admins) + else + log_bomber(user, "Something has primed a", src, "for detonation.[attacher_text ? " " : ""][attacher_text]", notify_admins) + det_timer = addtimer(CALLBACK(src, PROC_REF(detonate), notify_admins), det_time, TIMER_STOPPABLE) /obj/item/gibtonite/proc/detonate(notify_admins) diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index a38fe1711742ec..5c07c8c8fd405e 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -176,6 +176,12 @@ /mob/dead/new_player/proc/AttemptLateSpawn(rank) + // Check that they're picking someone new for new character respawning + if(CONFIG_GET(flag/allow_respawn) == RESPAWN_FLAG_NEW_CHARACTER) + if("[client.prefs.default_slot]" in client.player_details.joined_as_slots) + tgui_alert(usr, "You already have played this character in this round!") + return FALSE + var/error = IsJobUnavailable(rank) if(error != JOB_AVAILABLE) tgui_alert(usr, get_job_unavailable_error_message(error, rank)) @@ -305,6 +311,8 @@ preserved_mind.original_character_slot_index = client.prefs.default_slot preserved_mind.transfer_to(spawning_mob) //won't transfer key since the mind is not active preserved_mind.set_original_character(spawning_mob) + + LAZYADD(client.player_details.joined_as_slots, "[client.prefs.default_slot]") client.init_verbs() . = spawning_mob new_character = . diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 7e288ebcee560c..4660a1b0546510 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -286,6 +286,10 @@ I.dropped(src) return FALSE +/// Returns true if a mob is holding something +/mob/proc/is_holding_items() + return !!locate(/obj/item) in held_items + /mob/proc/drop_all_held_items() . = FALSE for(var/obj/item/I in held_items) diff --git a/code/modules/mob/living/basic/basic.dm b/code/modules/mob/living/basic/basic.dm index aebb54770d7028..4802ef347a02d0 100644 --- a/code/modules/mob/living/basic/basic.dm +++ b/code/modules/mob/living/basic/basic.dm @@ -117,13 +117,23 @@ if(speak_emote) speak_emote = string_list(speak_emote) - if(unsuitable_atmos_damage != 0) - //String assoc list returns a cached list, so this is like a static list to pass into the element below. - habitable_atmos = string_assoc_list(habitable_atmos) - AddElement(/datum/element/atmos_requirements, habitable_atmos, unsuitable_atmos_damage) + apply_atmos_requirements() + apply_temperature_requirements() + +/// Ensures this mob can take atmospheric damage if it's supposed to +/mob/living/basic/proc/apply_atmos_requirements() + if(unsuitable_atmos_damage == 0) + return + //String assoc list returns a cached list, so this is like a static list to pass into the element below. + habitable_atmos = string_assoc_list(habitable_atmos) + AddElement(/datum/element/atmos_requirements, habitable_atmos, unsuitable_atmos_damage) + +/// Ensures this mob can take temperature damage if it's supposed to +/mob/living/basic/proc/apply_temperature_requirements() + if(unsuitable_cold_damage == 0 && unsuitable_heat_damage == 0) + return + AddElement(/datum/element/basic_body_temp_sensitive, minimum_survivable_temperature, maximum_survivable_temperature, unsuitable_cold_damage, unsuitable_heat_damage) - if(unsuitable_cold_damage != 0 && unsuitable_heat_damage != 0) - AddElement(/datum/element/basic_body_temp_sensitive, minimum_survivable_temperature, maximum_survivable_temperature, unsuitable_cold_damage, unsuitable_heat_damage) /mob/living/basic/Life(seconds_per_tick = SSMOBS_DT, times_fired) . = ..() @@ -191,7 +201,7 @@ . = ..() if(stat != DEAD) return - . += span_deadsay("Upon closer examination, [p_they()] appear[p_s()] to be [HAS_TRAIT(user.mind, TRAIT_NAIVE) ? "asleep" : "dead"].") + . += span_deadsay("Upon closer examination, [p_they()] appear[p_s()] to be [HAS_MIND_TRAIT(user, TRAIT_NAIVE) ? "asleep" : "dead"].") /mob/living/basic/proc/melee_attack(atom/target, list/modifiers, ignore_cooldown = FALSE) face_atom(target) @@ -207,10 +217,24 @@ melee_attack(attack_target, modifiers) /mob/living/basic/vv_edit_var(vname, vval) + switch(vname) + if(NAMEOF(src, habitable_atmos), NAMEOF(src, unsuitable_atmos_damage)) + RemoveElement(/datum/element/atmos_requirements, habitable_atmos, unsuitable_atmos_damage) + . = TRUE + if(NAMEOF(src, minimum_survivable_temperature), NAMEOF(src, maximum_survivable_temperature), NAMEOF(src, unsuitable_cold_damage), NAMEOF(src, unsuitable_heat_damage)) + RemoveElement(/datum/element/basic_body_temp_sensitive, minimum_survivable_temperature, maximum_survivable_temperature, unsuitable_cold_damage, unsuitable_heat_damage) + . = TRUE + . = ..() - if(vname == NAMEOF(src, speed)) - datum_flags |= DF_VAR_EDITED - set_varspeed(vval) + + switch(vname) + if(NAMEOF(src, habitable_atmos), NAMEOF(src, unsuitable_atmos_damage)) + apply_atmos_requirements() + if(NAMEOF(src, minimum_survivable_temperature), NAMEOF(src, maximum_survivable_temperature), NAMEOF(src, unsuitable_cold_damage), NAMEOF(src, unsuitable_heat_damage)) + apply_temperature_requirements() + if(NAMEOF(src, speed)) + datum_flags |= DF_VAR_EDITED + set_varspeed(vval) /mob/living/basic/proc/set_varspeed(var_value) speed = var_value @@ -260,3 +284,25 @@ else if(on_fire && !isnull(last_icon_state)) return last_icon_state return null + +/mob/living/basic/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE, ignore_animation = TRUE) + . = ..() + if (.) + update_held_items() + +/mob/living/basic/update_held_items() + . = ..() + if(isnull(client) || isnull(hud_used) || hud_used.hud_version == HUD_STYLE_NOHUD) + return + var/turf/our_turf = get_turf(src) + for(var/obj/item/held in held_items) + var/index = get_held_index_of_item(held) + SET_PLANE(held, ABOVE_HUD_PLANE, our_turf) + held.screen_loc = ui_hand_position(index) + client.screen |= held + +/mob/living/basic/get_body_temp_heat_damage_limit() + return maximum_survivable_temperature + +/mob/living/basic/get_body_temp_cold_damage_limit() + return minimum_survivable_temperature diff --git a/code/modules/mob/living/basic/basic_defense.dm b/code/modules/mob/living/basic/basic_defense.dm index cc128a9f5e9e75..87fe6f8fed1bb6 100644 --- a/code/modules/mob/living/basic/basic_defense.dm +++ b/code/modules/mob/living/basic/basic_defense.dm @@ -148,7 +148,7 @@ apply_damage(500, damagetype = BRUTE) else investigate_log("has been gibbed by an explosion.", INVESTIGATE_DEATHS) - gib() + gib(DROP_ALL_REMAINS) if (EXPLODE_HEAVY) var/bloss = 60 @@ -165,6 +165,9 @@ return TRUE /mob/living/basic/blob_act(obj/structure/blob/attacking_blob) + . = ..() + if (!.) + return apply_damage(20, damagetype = BRUTE) /mob/living/basic/do_attack_animation(atom/attacked_atom, visual_effect_icon, used_item, no_effect) diff --git a/code/modules/mob/living/basic/blob_minions/blob_ai.dm b/code/modules/mob/living/basic/blob_minions/blob_ai.dm new file mode 100644 index 00000000000000..6168b7ca83be72 --- /dev/null +++ b/code/modules/mob/living/basic/blob_minions/blob_ai.dm @@ -0,0 +1,51 @@ +/** + * Extremely simple AI, this isn't a very smart boy + * Only notable quirk is that it uses JPS movement, simple avoidance would fail to realise it can path through blobs + */ +/datum/ai_controller/basic_controller/blobbernaut + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/attack_until_dead, + ) + + ai_movement = /datum/ai_movement/jps + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/** + * Move to a point designated by the overmind, otherwise just slap people nearby + */ +/datum/ai_controller/basic_controller/blob_zombie + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/attack_until_dead, + ) + + ai_movement = /datum/ai_movement/jps + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/travel_to_point/and_clear_target, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/** + * As blob zombie but will prioritise attacking corpses to zombify them + */ +/datum/ai_controller/basic_controller/blob_spore + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/attack_until_dead, + ) + + ai_movement = /datum/ai_movement/jps + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/find_and_hunt_target/corpses, + /datum/ai_planning_subtree/travel_to_point/and_clear_target, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) diff --git a/code/modules/mob/living/basic/blob_minions/blob_mob.dm b/code/modules/mob/living/basic/blob_minions/blob_mob.dm new file mode 100644 index 00000000000000..35e41f09058456 --- /dev/null +++ b/code/modules/mob/living/basic/blob_minions/blob_mob.dm @@ -0,0 +1,37 @@ +/// Root of shared behaviour for mobs spawned by blobs, is abstract and should not be spawned +/mob/living/basic/blob_minion + name = "Blob Error" + desc = "A nonfunctional fungal creature created by bad code or celestial mistake. Point and laugh." + icon = 'icons/mob/nonhuman-player/blob.dmi' + icon_state = "blob_head" + unique_name = TRUE + pass_flags = PASSBLOB + faction = list(ROLE_BLOB) + combat_mode = TRUE + bubble_icon = "blob" + speak_emote = null + habitable_atmos = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + minimum_survivable_temperature = 0 + maximum_survivable_temperature = INFINITY + lighting_cutoff_red = 20 + lighting_cutoff_green = 40 + lighting_cutoff_blue = 30 + initial_language_holder = /datum/language_holder/empty + +/mob/living/basic/blob_minion/Initialize(mapload) + . = ..() + add_traits(list(TRAIT_BLOB_ALLY, TRAIT_MUTE), INNATE_TRAIT) + AddComponent(/datum/component/blob_minion, on_strain_changed = CALLBACK(src, PROC_REF(on_strain_updated))) + +/// Called when our blob overmind changes their variant, update some of our mob properties +/mob/living/basic/blob_minion/proc/on_strain_updated(mob/camera/blob/overmind, datum/blobstrain/new_strain) + return + +/// Associates this mob with a specific blob factory node +/mob/living/basic/blob_minion/proc/link_to_factory(obj/structure/blob/special/factory/factory) + RegisterSignal(factory, COMSIG_QDELETING, PROC_REF(on_factory_destroyed)) + +/// Called when our factory is destroyed +/mob/living/basic/blob_minion/proc/on_factory_destroyed() + SIGNAL_HANDLER + to_chat(src, span_userdanger("Your factory was destroyed! You feel yourself dying!")) diff --git a/code/modules/mob/living/basic/blob_minions/blob_spore.dm b/code/modules/mob/living/basic/blob_minions/blob_spore.dm new file mode 100644 index 00000000000000..e8c3acc8b97f0f --- /dev/null +++ b/code/modules/mob/living/basic/blob_minions/blob_spore.dm @@ -0,0 +1,123 @@ +/** + * A floating fungus which turns people into zombies and explodes into reagent clouds upon death. + */ +/mob/living/basic/blob_minion/spore + name = "blob spore" + desc = "A floating, fragile spore." + icon = 'icons/mob/nonhuman-player/blob.dmi' + icon_state = "blobpod" + icon_living = "blobpod" + health_doll_icon = "blobpod" + health = BLOBMOB_SPORE_HEALTH + maxHealth = BLOBMOB_SPORE_HEALTH + verb_say = "psychically pulses" + verb_ask = "psychically probes" + verb_exclaim = "psychically yells" + verb_yell = "psychically screams" + melee_damage_lower = BLOBMOB_SPORE_DMG_LOWER + melee_damage_upper = BLOBMOB_SPORE_DMG_UPPER + obj_damage = 0 + attack_verb_continuous = "batters" + attack_verb_simple = "batter" + attack_sound = 'sound/weapons/genhit1.ogg' + death_message = "explodes into a cloud of gas!" + gold_core_spawnable = HOSTILE_SPAWN + basic_mob_flags = DEL_ON_DEATH + ai_controller = /datum/ai_controller/basic_controller/blob_spore + /// Size of cloud produced from a dying spore + var/death_cloud_size = 1 + /// Type of mob to create + var/mob/living/zombie_type = /mob/living/basic/blob_minion/zombie + +/mob/living/basic/blob_minion/spore/Initialize(mapload) + . = ..() + AddElement(/datum/element/simple_flying) + AddElement(/datum/element/swabable, CELL_LINE_TABLE_BLOBSPORE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) + +/mob/living/basic/blob_minion/spore/death(gibbed) + . = ..() + death_burst() + +/mob/living/basic/blob_minion/spore/on_factory_destroyed() + death() + +/// Create an explosion of spores on death +/mob/living/basic/blob_minion/spore/proc/death_burst() + do_chem_smoke(range = death_cloud_size, holder = src, location = get_turf(src), reagent_type = /datum/reagent/toxin/spore) + + +/mob/living/basic/blob_minion/spore/melee_attack(mob/living/carbon/human/target, list/modifiers, ignore_cooldown) + . = ..() + if (!ishuman(target) || target.stat != DEAD) + return + zombify(target) + +/// Become a zombie +/mob/living/basic/blob_minion/spore/proc/zombify(mob/living/carbon/human/target) + visible_message(span_warning("The corpse of [target.name] suddenly rises!")) + var/mob/living/basic/blob_minion/zombie/blombie = change_mob_type(zombie_type, loc, new_name = initial(zombie_type.name)) + blombie.set_name() + if (istype(blombie)) // In case of badmin + blombie.consume_corpse(target) + SEND_SIGNAL(src, COMSIG_BLOB_ZOMBIFIED, blombie) + qdel(src) + +/// Variant of the blob spore which is actually spawned by blob factories +/mob/living/basic/blob_minion/spore/minion + gold_core_spawnable = NO_SPAWN + zombie_type = /mob/living/basic/blob_minion/zombie/controlled + /// We die if we leave the same turf as this z level + var/turf/z_turf + +/mob/living/basic/blob_minion/spore/minion/Initialize(mapload) + . = ..() + RegisterSignal(src, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(on_z_changed)) + +/// When we z-move check that we're on the same z level as our factory was +/mob/living/basic/blob_minion/spore/minion/proc/on_z_changed() + SIGNAL_HANDLER + if (isnull(z_turf)) + return + if (!is_valid_z_level(get_turf(src), z_turf)) + death() + +/// Mark the turf we need to track from our factory +/mob/living/basic/blob_minion/spore/minion/link_to_factory(obj/structure/blob/special/factory/factory) + . = ..() + z_turf = get_turf(factory) + +/// If the blob changes to distributed neurons then you can control the spores +/mob/living/basic/blob_minion/spore/minion/on_strain_updated(mob/camera/blob/overmind, datum/blobstrain/new_strain) + if (isnull(overmind)) + REMOVE_TRAIT(src, TRAIT_PERMANENTLY_MORTAL, INNATE_TRAIT) + else + ADD_TRAIT(src, TRAIT_PERMANENTLY_MORTAL, INNATE_TRAIT) + + if (istype(new_strain, /datum/blobstrain/reagent/distributed_neurons)) + AddComponent(\ + /datum/component/ghost_direct_control,\ + ban_type = ROLE_BLOB_INFECTION,\ + poll_candidates = TRUE,\ + poll_ignore_key = POLL_IGNORE_BLOB,\ + ) + else + qdel(GetComponent(/datum/component/ghost_direct_control)) + +/mob/living/basic/blob_minion/spore/minion/death_burst() + return // This behaviour is superceded by the overmind's intervention + + +/// Weakened spore spawned by distributed neurons, can't zombify people and makes a teeny explosion +/mob/living/basic/blob_minion/spore/minion/weak + name = "fragile blob spore" + health = 15 + maxHealth = 15 + melee_damage_lower = 1 + melee_damage_upper = 2 + death_cloud_size = 0 + +/mob/living/basic/blob_minion/spore/minion/weak/zombify() + return + +/mob/living/basic/blob_minion/spore/minion/weak/on_strain_updated() + return diff --git a/code/modules/mob/living/basic/blob_minions/blob_zombie.dm b/code/modules/mob/living/basic/blob_minions/blob_zombie.dm new file mode 100644 index 00000000000000..c9bf3b7346a989 --- /dev/null +++ b/code/modules/mob/living/basic/blob_minions/blob_zombie.dm @@ -0,0 +1,99 @@ +/// A shambling mob made out of a crew member +/mob/living/basic/blob_minion/zombie + name = "blob zombie" + desc = "A shambling corpse animated by the blob." + icon_state = "zombie" + icon_living = "zombie" + health_doll_icon = "blobpod" + mob_biotypes = MOB_ORGANIC | MOB_HUMANOID + health = 70 + maxHealth = 70 + verb_say = "gurgles" + verb_ask = "demands" + verb_exclaim = "roars" + verb_yell = "bellows" + melee_damage_lower = 10 + melee_damage_upper = 15 + melee_attack_cooldown = CLICK_CD_MELEE + obj_damage = 20 + attack_verb_continuous = "punches" + attack_verb_simple = "punch" + attack_sound = 'sound/weapons/genhit1.ogg' + death_message = "collapses to the ground!" + gold_core_spawnable = NO_SPAWN + basic_mob_flags = DEL_ON_DEATH + ai_controller = /datum/ai_controller/basic_controller/blob_zombie + /// The dead body we have inside + var/mob/living/carbon/human/corpse + +/mob/living/basic/blob_minion/zombie/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_PERMANENTLY_MORTAL, INNATE_TRAIT) // This mob doesn't function visually without a corpse and wouldn't respawn with one + AddElement(/datum/element/swabable, CELL_LINE_TABLE_BLOBSPORE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) + +/mob/living/basic/blob_minion/zombie/death(gibbed) + corpse?.forceMove(loc) + death_burst() + return ..() + +/mob/living/basic/blob_minion/zombie/Exited(atom/movable/gone, direction) + . = ..() + if (gone != corpse) + return + corpse = null + death() + +/mob/living/basic/blob_minion/zombie/Destroy() + QDEL_NULL(corpse) + return ..() + +/mob/living/basic/blob_minion/zombie/on_factory_destroyed() + . = ..() + death() + +/mob/living/basic/blob_minion/zombie/update_overlays() + . = ..() + copy_overlays(corpse, TRUE) + var/mutable_appearance/blob_head_overlay = mutable_appearance('icons/mob/nonhuman-player/blob.dmi', "blob_head") + blob_head_overlay.color = LAZYACCESS(atom_colours, FIXED_COLOUR_PRIORITY) || COLOR_WHITE + color = initial(color) // reversing what our component did lol, but we needed the value for the overlay + . += blob_head_overlay + +/// Create an explosion of spores on death +/mob/living/basic/blob_minion/zombie/proc/death_burst() + do_chem_smoke(range = 0, holder = src, location = get_turf(src), reagent_type = /datum/reagent/toxin/spore) + +/// Store a body so that we can drop it on death +/mob/living/basic/blob_minion/zombie/proc/consume_corpse(mob/living/carbon/human/new_corpse) + if(new_corpse.wear_suit) + maxHealth += new_corpse.get_armor_rating(MELEE) + health = maxHealth + new_corpse.set_facial_hairstyle("Shaved", update = FALSE) + new_corpse.set_hairstyle("Bald", update = TRUE) + new_corpse.forceMove(src) + corpse = new_corpse + update_appearance(UPDATE_ICON) + RegisterSignal(corpse, COMSIG_LIVING_REVIVE, PROC_REF(on_corpse_revived)) + +/// Dynamic changeling reentry +/mob/living/basic/blob_minion/zombie/proc/on_corpse_revived() + SIGNAL_HANDLER + visible_message(span_boldwarning("[src] bursts from the inside!")) + death() + +/// Blob-created zombies will ping for player control when they make a zombie +/mob/living/basic/blob_minion/zombie/controlled + +/mob/living/basic/blob_minion/zombie/controlled/consume_corpse(mob/living/carbon/human/new_corpse) + . = ..() + if (!isnull(client)) + return + AddComponent(\ + /datum/component/ghost_direct_control,\ + ban_type = ROLE_BLOB_INFECTION,\ + poll_candidates = TRUE,\ + poll_ignore_key = POLL_IGNORE_BLOB,\ + ) + +/mob/living/basic/blob_minion/zombie/controlled/death_burst() + return diff --git a/code/modules/mob/living/basic/blob_minions/blobbernaut.dm b/code/modules/mob/living/basic/blob_minions/blobbernaut.dm new file mode 100644 index 00000000000000..b483641993a7e0 --- /dev/null +++ b/code/modules/mob/living/basic/blob_minions/blobbernaut.dm @@ -0,0 +1,109 @@ +/** + * Player-piloted brute mob. Mostly just a "move and click" kind of guy. + * Has a variant which takes damage when away from blob tiles + */ +/mob/living/basic/blob_minion/blobbernaut + name = "blobbernaut" + desc = "A hulking, mobile chunk of blobmass." + icon_state = "blobbernaut" + icon_living = "blobbernaut" + icon_dead = "blobbernaut_dead" + health = BLOBMOB_BLOBBERNAUT_HEALTH + maxHealth = BLOBMOB_BLOBBERNAUT_HEALTH + damage_coeff = list(BRUTE = 0.5, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) + melee_damage_lower = BLOBMOB_BLOBBERNAUT_DMG_SOLO_LOWER + melee_damage_upper = BLOBMOB_BLOBBERNAUT_DMG_SOLO_UPPER + melee_attack_cooldown = CLICK_CD_MELEE + obj_damage = BLOBMOB_BLOBBERNAUT_DMG_OBJ + attack_verb_continuous = "slams" + attack_verb_simple = "slam" + attack_sound = 'sound/effects/blobattack.ogg' + verb_say = "gurgles" + verb_ask = "demands" + verb_exclaim = "roars" + verb_yell = "bellows" + force_threshold = 10 + pressure_resistance = 50 + mob_size = MOB_SIZE_LARGE + hud_type = /datum/hud/living/blobbernaut + gold_core_spawnable = HOSTILE_SPAWN + ai_controller = /datum/ai_controller/basic_controller/blobbernaut + +/mob/living/basic/blob_minion/blobbernaut/Initialize(mapload) + . = ..() + AddElement(/datum/element/swabable, CELL_LINE_TABLE_BLOBBERNAUT, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) + +/mob/living/basic/blob_minion/blobbernaut/death(gibbed) + flick("blobbernaut_death", src) + return ..() + +/// This variant is the one actually spawned by blob factories, takes damage when away from blob tiles +/mob/living/basic/blob_minion/blobbernaut/minion + gold_core_spawnable = NO_SPAWN + /// Is our factory dead? + var/orphaned = FALSE + +/mob/living/basic/blob_minion/blobbernaut/minion/Life(seconds_per_tick, times_fired) + . = ..() + if (!.) + return FALSE + var/damage_sources = 0 + var/list/blobs_in_area = range(2, src) + + if (!(locate(/obj/structure/blob) in blobs_in_area)) + damage_sources++ + + if (orphaned) + damage_sources++ + else + var/particle_colour = atom_colours[FIXED_COLOUR_PRIORITY] || COLOR_BLACK + if (locate(/obj/structure/blob/special/core) in blobs_in_area) + heal_overall_damage(maxHealth * BLOBMOB_BLOBBERNAUT_HEALING_CORE * seconds_per_tick) + var/obj/effect/temp_visual/heal/heal_effect = new /obj/effect/temp_visual/heal(get_turf(src)) + heal_effect.color = particle_colour + + if (locate(/obj/structure/blob/special/node) in blobs_in_area) + heal_overall_damage(maxHealth * BLOBMOB_BLOBBERNAUT_HEALING_NODE * seconds_per_tick) + var/obj/effect/temp_visual/heal/heal_effect = new /obj/effect/temp_visual/heal(get_turf(src)) + heal_effect.color = particle_colour + + if (damage_sources == 0) + return FALSE + + // take 2.5% of max health as damage when not near the blob or if the naut has no factory, 5% if both + apply_damage(maxHealth * BLOBMOB_BLOBBERNAUT_HEALTH_DECAY * damage_sources * seconds_per_tick, damagetype = TOX) // We reduce brute damage + var/mutable_appearance/harming = mutable_appearance('icons/mob/nonhuman-player/blob.dmi', "nautdamage", MOB_LAYER + 0.01) + harming.appearance_flags = RESET_COLOR + harming.color = atom_colours[FIXED_COLOUR_PRIORITY] || COLOR_WHITE + harming.dir = dir + flick_overlay_view(harming, 0.8 SECONDS) + return TRUE + +/// Called by the blob creation power to give us a mind and a basic task orientation +/mob/living/basic/blob_minion/blobbernaut/minion/proc/assign_key(ckey, datum/blobstrain/blobstrain) + key = ckey + flick("blobbernaut_produce", src) + health = maxHealth / 2 // Start out injured to encourage not beelining away from the blob + SEND_SOUND(src, sound('sound/effects/blobattack.ogg')) + SEND_SOUND(src, sound('sound/effects/attackblob.ogg')) + to_chat(src, span_infoplain("You are powerful, hard to kill, and slowly regenerate near nodes and cores, [span_cultlarge("but will slowly die if not near the blob")] or if the factory that made you is killed.")) + to_chat(src, span_infoplain("You can communicate with other blobbernauts and overminds telepathically by attempting to speak normally")) + to_chat(src, span_infoplain("Your overmind's blob reagent is: [blobstrain.name]!")) + to_chat(src, span_infoplain("The [blobstrain.name] reagent [blobstrain.shortdesc ? "[blobstrain.shortdesc]" : "[blobstrain.description]"]")) + +/// Set our attack damage based on blob's properties +/mob/living/basic/blob_minion/blobbernaut/minion/on_strain_updated(mob/camera/blob/overmind, datum/blobstrain/new_strain) + if (isnull(overmind)) + melee_damage_lower = initial(melee_damage_lower) + melee_damage_upper = initial(melee_damage_upper) + attack_verb_continuous = initial(attack_verb_continuous) + return + melee_damage_lower = BLOBMOB_BLOBBERNAUT_DMG_LOWER + melee_damage_upper = BLOBMOB_BLOBBERNAUT_DMG_UPPER + attack_verb_continuous = new_strain.blobbernaut_message + +/// Called by our factory to inform us that it's not going to support us financially any more +/mob/living/basic/blob_minion/blobbernaut/minion/on_factory_destroyed() + . = ..() + orphaned = TRUE + throw_alert("nofactory", /atom/movable/screen/alert/nofactory) diff --git a/code/modules/mob/living/basic/clown/clown.dm b/code/modules/mob/living/basic/clown/clown.dm index 78715361356083..5682edf933907e 100644 --- a/code/modules/mob/living/basic/clown/clown.dm +++ b/code/modules/mob/living/basic/clown/clown.dm @@ -37,7 +37,7 @@ BB_EMOTE_SAY = list("HONK", "Honk!", "Welcome to clown planet!"), BB_EMOTE_HEAR = list("honks", "squeaks"), BB_EMOTE_SOUND = list('sound/items/bikehorn.ogg'), //WE LOVE TO PARTY - BB_EMOTE_CHANCE = 5, + BB_SPEAK_CHANCE = 5, ) ///do we waddle (honk) var/waddles = TRUE @@ -150,9 +150,9 @@ ), BB_EMOTE_HEAR = list("honks", "contemplates its existence"), BB_EMOTE_SEE = list("sweats", "jiggles"), - BB_EMOTE_CHANCE = 5, + BB_SPEAK_CHANCE = 5, ) - + /mob/living/basic/clown/fleshclown/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS, INNATE_TRAIT) @@ -185,7 +185,7 @@ emotes = list( BB_EMOTE_SAY = list("YA-HONK!!!"), BB_EMOTE_HEAR = list("honks", "squeaks"), - BB_EMOTE_CHANCE = 60, + BB_SPEAK_CHANCE = 60, ) /mob/living/basic/clown/clownhulk @@ -221,7 +221,7 @@ BB_EMOTE_SAY = list("HONK", "Honk!", "HAUAUANK!!!", "GUUURRRRAAAHHH!!!"), BB_EMOTE_HEAR = list("honks", "grunts"), BB_EMOTE_SEE = list("sweats"), - BB_EMOTE_CHANCE = 5, + BB_SPEAK_CHANCE = 5, ) /mob/living/basic/clown/clownhulk/chlown @@ -252,7 +252,7 @@ emotes = list( BB_EMOTE_SAY = list("HONK", "Honk!", "Bruh", "cheeaaaahhh?"), BB_EMOTE_SEE = list("asserts his dominance", "emasculates everyone implicitly"), - BB_EMOTE_CHANCE = 5, + BB_SPEAK_CHANCE = 5, ) /mob/living/basic/clown/clownhulk/honkmunculus @@ -318,7 +318,7 @@ BB_EMOTE_SAY = list("HONK!!!", "The Honkmother is merciful, so I must act out her wrath.", "parce mihi ad beatus honkmother placet mihi ut peccata committere,", "DIE!!!"), BB_EMOTE_HEAR = list("honks", "grunts"), BB_EMOTE_SEE = list("sweats"), - BB_EMOTE_CHANCE = 5, + BB_SPEAK_CHANCE = 5, ) /mob/living/basic/clown/mutant @@ -354,7 +354,7 @@ emotes = list( BB_EMOTE_SAY = list("aaaaaahhhhuuhhhuhhhaaaaa", "AAAaaauuuaaAAAaauuhhh", "huuuuuh... hhhhuuuooooonnnnkk", "HuaUAAAnKKKK"), BB_EMOTE_SEE = list("squirms", "writhes", "pulsates", "froths", "oozes"), - BB_EMOTE_CHANCE = 10, + BB_SPEAK_CHANCE = 10, ) /mob/living/basic/clown/mutant/slow diff --git a/code/modules/mob/living/basic/constructs/_construct.dm b/code/modules/mob/living/basic/constructs/_construct.dm new file mode 100644 index 00000000000000..f2e55cceb86b3b --- /dev/null +++ b/code/modules/mob/living/basic/constructs/_construct.dm @@ -0,0 +1,156 @@ +/mob/living/basic/construct + icon = 'icons/mob/nonhuman-player/cult.dmi' + gender = NEUTER + basic_mob_flags = DEL_ON_DEATH + combat_mode = TRUE + mob_biotypes = MOB_MINERAL | MOB_SPECIAL + faction = list(FACTION_CULT) + unsuitable_atmos_damage = 0 + minimum_survivable_temperature = 0 + maximum_survivable_temperature = INFINITY + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) + pressure_resistance = 100 + speed = 0 + unique_name = TRUE + initial_language_holder = /datum/language_holder/construct + death_message = "collapses in a shattered heap." + + speak_emote = list("hisses") + response_help_continuous = "thinks better of touching" + response_help_simple = "think better of touching" + response_disarm_continuous = "flails at" + response_disarm_simple = "flail at" + response_harm_continuous = "punches" + response_harm_simple = "punch" + + // Vivid red, cause cult theme + lighting_cutoff_red = 30 + lighting_cutoff_green = 5 + lighting_cutoff_blue = 20 + + /// List of spells that this construct can cast + var/list/construct_spells = list() + /// Flavor text shown to players when they spawn as this construct + var/playstyle_string = "You are a generic construct. Your job is to not exist, and you should probably adminhelp this." + /// The construct's master + var/master = null + /// Whether this construct is currently seeking nar nar + var/seeking = FALSE + /// Whether this construct can repair other constructs or cult buildings. Gets the healing_touch component if so. + var/can_repair = FALSE + /// Whether this construct can repair itself. Works independently of can_repair. + var/can_repair_self = FALSE + /// Theme controls color. THEME_CULT is red THEME_WIZARD is purple and THEME_HOLY is blue + var/theme = THEME_CULT + /// What flavor of gunk does this construct drop on death? + var/static/list/remains = list(/obj/item/ectoplasm/construct) + /// Can this construct smash walls? Gets the wall_smasher element if so. + var/smashes_walls = FALSE + +/mob/living/basic/construct/Initialize(mapload) + . = ..() + AddElement(/datum/element/simple_flying) + if(length(remains)) + AddElement(/datum/element/death_drops, remains) + if(smashes_walls) + AddElement(/datum/element/wall_smasher, strength_flag = ENVIRONMENT_SMASH_WALLS) + if(can_repair) + AddComponent(\ + /datum/component/healing_touch,\ + heal_brute = 5,\ + heal_burn = 0,\ + heal_time = 0,\ + valid_targets_typecache = typecacheof(list(/mob/living/basic/construct, /mob/living/simple_animal/hostile/construct, /mob/living/simple_animal/shade)),\ + self_targetting = can_repair_self ? HEALING_TOUCH_ANYONE : HEALING_TOUCH_NOT_SELF,\ + action_text = "%SOURCE% begins repairing %TARGET%'s dents.",\ + complete_text = "%TARGET%'s dents are repaired.",\ + show_health = TRUE,\ + heal_color = COLOR_CULT_RED,\ + ) + var/static/list/structure_types = typecacheof(list(/obj/structure/destructible/cult)) + AddElement(\ + /datum/element/structure_repair,\ + structure_types_typecache = structure_types,\ + ) + add_traits(list(TRAIT_HEALS_FROM_CULT_PYLONS, TRAIT_SPACEWALK), INNATE_TRAIT) + for(var/spell in construct_spells) + var/datum/action/new_spell = new spell(src) + new_spell.Grant(src) + + var/spell_count = 1 + for(var/datum/action/spell as anything in actions) + if(!(spell.type in construct_spells)) + continue + + var/pos = 2 + spell_count * 31 + if(construct_spells.len >= 4) + pos -= 31 * (construct_spells.len - 4) + spell.default_button_position = "6:[pos],4:-2" // Set the default position to this random position + spell_count++ + update_action_buttons() + + if(icon_state) + add_overlay("glow_[icon_state]_[theme]") + +/mob/living/basic/construct/Login() + . = ..() + if(!. || !client) + return FALSE + to_chat(src, span_bold(playstyle_string)) + +/mob/living/basic/construct/examine(mob/user) + var/text_span + switch(theme) + if(THEME_CULT) + text_span = "cult" + if(THEME_WIZARD) + text_span = "purple" + if(THEME_HOLY) + text_span = "blue" + . = list("This is [icon2html(src, user)] \a [src]!\n[desc]") + if(health < maxHealth) + if(health >= maxHealth/2) + . += span_warning("[p_They()] look[p_s()] slightly dented.") + else + . += span_warning(span_bold("[p_They()] look[p_s()] severely dented!")) + . += "" + return . + +/mob/living/basic/construct/narsie_act() + return + +/mob/living/basic/construct/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE) + return FALSE + +// Allows simple constructs to repair basic constructs. +/mob/living/basic/construct/attack_animal(mob/living/simple_animal/user, list/modifiers) + if(!isconstruct(user)) + if(src != user) + return ..() + return + + if(src == user) //basic constructs use the healing hands component instead + return + + var/mob/living/simple_animal/hostile/construct/doll = user + if(!doll.can_repair || (doll == src && !doll.can_repair_self)) + return ..() + if(theme != doll.theme) + return ..() + + if(health >= maxHealth) + to_chat(user, span_cult("You cannot repair [src]'s dents, as [p_they()] [p_have()] none!")) + return + + heal_overall_damage(brute = 5) + + Beam(user, icon_state = "sendbeam", time = 4) + user.visible_message( + span_danger("[user] repairs some of \the [src]'s dents."), + span_cult("You repair some of [src]'s dents, leaving [src] at [health]/[maxHealth] health."), + ) + +/// Construct ectoplasm. Largely a placeholder, since the death drop element needs a unique list. +/obj/item/ectoplasm/construct + name = "blood-red ectoplasm" + desc = "Has a pungent metallic smell." diff --git a/code/modules/mob/living/simple_animal/hostile/constructs/harvester.dm b/code/modules/mob/living/basic/constructs/harvester.dm similarity index 69% rename from code/modules/mob/living/simple_animal/hostile/constructs/harvester.dm rename to code/modules/mob/living/basic/constructs/harvester.dm index 8c5fc8eae37b3b..30b3099487282d 100644 --- a/code/modules/mob/living/simple_animal/hostile/constructs/harvester.dm +++ b/code/modules/mob/living/basic/constructs/harvester.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/hostile/construct/harvester +/mob/living/basic/construct/harvester name = "Harvester" real_name = "Harvester" desc = "A long, thin construct built to herald Nar'Sie's rise. It'll be all over soon." @@ -24,58 +24,33 @@ can_repair = TRUE slowed_by_drag = FALSE - -/mob/living/simple_animal/hostile/construct/harvester/Bump(atom/thing) +/mob/living/basic/construct/harvester/Initialize(mapload) . = ..() - if(!istype(thing, /turf/closed/wall/mineral/cult) || thing == loc) - return // we can go through cult walls - var/atom/movable/stored_pulling = pulling - - if(stored_pulling) - stored_pulling.setDir(get_dir(stored_pulling.loc, loc)) - stored_pulling.forceMove(loc) - forceMove(thing) - - if(stored_pulling) - start_pulling(stored_pulling, supress_message = TRUE) //drag anything we're pulling through the wall with us by magic + AddElement(\ + /datum/element/amputating_limbs,\ + surgery_time = 0,\ + surgery_verb = "slicing",\ + minimum_stat = CONSCIOUS,\ + ) + AddElement(/datum/element/wall_walker, /turf/closed/wall/mineral/cult) + var/datum/action/innate/seek_prey/seek = new(src) + seek.Grant(src) + seek.Activate() -/mob/living/simple_animal/hostile/construct/harvester/AttackingTarget() - if(!iscarbon(target)) +/// If the attack is a limbless carbon, abort the attack, paralyze them, and get a special message from Nar'Sie. +/mob/living/basic/construct/harvester/resolve_unarmed_attack(atom/attack_target, list/modifiers) + if(!iscarbon(attack_target)) return ..() + var/mob/living/carbon/carbon_target = attack_target - var/mob/living/carbon/victim = target - if(HAS_TRAIT(victim, TRAIT_NODISMEMBER)) - return ..() //ATTACK! - - var/list/parts = list() - var/strong_limbs = 0 - - for(var/obj/item/bodypart/limb as anything in victim.bodyparts) + for(var/obj/item/bodypart/limb as anything in carbon_target.bodyparts) if(limb.body_part == HEAD || limb.body_part == CHEST) continue - if(!(limb.bodypart_flags & BODYPART_UNREMOVABLE)) - parts += limb - else - strong_limbs++ - - if(!LAZYLEN(parts)) - if(strong_limbs) // they have limbs we can't remove, and no parts we can, attack! - return ..() - victim.Paralyze(60) - visible_message(span_danger("[src] knocks [victim] down!")) - to_chat(src, span_cultlarge("\"Bring [victim.p_them()] to me.\"")) - return FALSE - - do_attack_animation(victim) - var/obj/item/bodypart/limb = pick(parts) - limb.dismember() - return FALSE - -/mob/living/simple_animal/hostile/construct/harvester/Initialize(mapload) - . = ..() - var/datum/action/innate/seek_prey/seek = new() - seek.Grant(src) - seek.Activate() + return ..() //if any arms or legs exist, attack + + carbon_target.Paralyze(6 SECONDS) + visible_message(span_danger("[src] knocks [carbon_target] down!")) + to_chat(src, span_cultlarge("\"Bring [carbon_target.p_them()] to me.\"")) /datum/action/innate/seek_master name = "Seek your Master" @@ -89,7 +64,7 @@ /// Where is nar nar? Are we even looking? var/tracking = FALSE /// The construct we're attached to - var/mob/living/simple_animal/hostile/construct/the_construct + var/mob/living/basic/construct/the_construct /datum/action/innate/seek_master/Grant(mob/living/player) the_construct = player @@ -132,7 +107,7 @@ /datum/action/innate/seek_prey/Activate() if(GLOB.cult_narsie == null) return - var/mob/living/simple_animal/hostile/construct/harvester/the_construct = owner + var/mob/living/basic/construct/harvester/the_construct = owner if(the_construct.seeking) desc = "None can hide from Nar'Sie, activate to track a survivor attempting to flee the red harvest!" diff --git a/code/modules/mob/living/basic/farm_animals/deer.dm b/code/modules/mob/living/basic/farm_animals/deer.dm index 445ad831e59518..a948ec4d7a6e3d 100644 --- a/code/modules/mob/living/basic/farm_animals/deer.dm +++ b/code/modules/mob/living/basic/farm_animals/deer.dm @@ -34,7 +34,6 @@ /datum/ai_controller/basic_controller/deer blackboard = list( - BB_BASIC_MOB_FLEEING = TRUE, BB_STATIONARY_MOVE_TO_TARGET = TRUE, BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/ignore_faction, ) diff --git a/code/modules/mob/living/basic/farm_animals/goat/_goat.dm b/code/modules/mob/living/basic/farm_animals/goat/_goat.dm new file mode 100644 index 00000000000000..f698e5015e8c70 --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/goat/_goat.dm @@ -0,0 +1,135 @@ +/// The Greatest (animal) Of All Time. Cud chewing, shin-kicking, kitchen-dwelling nuisance. +/mob/living/basic/goat + name = "goat" + desc = "Not known for their pleasant disposition." + icon_state = "goat" + icon_living = "goat" + icon_dead = "goat_dead" + + speak_emote = list("brays") + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" + attack_verb_continuous = "kicks" + attack_verb_simple = "kick" + attack_sound = 'sound/weapons/punch1.ogg' + attack_vis_effect = ATTACK_EFFECT_KICK + + butcher_results = list(/obj/item/food/meat/slab/grassfed = 4) + + faction = list(FACTION_NEUTRAL) + mob_biotypes = MOB_ORGANIC | MOB_BEAST + + health = 40 + maxHealth = 40 + melee_damage_lower = 1 + melee_damage_upper = 2 + environment_smash = ENVIRONMENT_SMASH_NONE + + minimum_survivable_temperature = COLD_ROOM_TEMP - 75 // enough so that they can survive the cold room spawn with plenty of room for comfort + + blood_volume = BLOOD_VOLUME_NORMAL + + ai_controller = /datum/ai_controller/basic_controller/goat + + /// List of stuff (flora) that we want to eat + var/static/list/edibles = list( + /obj/structure/alien/resin/flower_bud, + /obj/structure/glowshroom, + /obj/structure/spacevine, + ) + +/mob/living/basic/goat/Initialize(mapload) + . = ..() + add_udder() + AddElement(/datum/element/cliff_walking) //we walk the cliff + AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_SHOE) + AddElement(/datum/element/ai_retaliate) + + RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(on_pre_attack)) + RegisterSignal(src, COMSIG_ATOM_WAS_ATTACKED, PROC_REF(on_attacked)) + RegisterSignal(src, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_move)) + + ai_controller.set_blackboard_key(BB_BASIC_FOODS, edibles) + +/// Called when we attack something in order to piece together the intent of the AI/user and provide desired behavior. The element might be okay here but I'd rather the fluff. +/// Goats are really good at beating up plants by taking bites out of them, but we use the default attack for everything else +/mob/living/basic/goat/proc/on_pre_attack(datum/source, atom/target) + if(is_type_in_list(target, edibles)) + eat_plant(list(target)) + return COMPONENT_HOSTILE_NO_ATTACK + + if(!isliving(target)) + return + + var/mob/living/living_target = target + if(!(living_target.mob_biotypes & MOB_PLANT)) + return + + living_target.adjustBruteLoss(20) + playsound(src, 'sound/items/eatfood.ogg', rand(30, 50), TRUE) + var/obj/item/bodypart/edible_bodypart + + if(ishuman(living_target)) + var/mob/living/carbon/human/plant_man = target + edible_bodypart = pick(plant_man.bodyparts) + edible_bodypart.dismember() + + living_target.visible_message( + span_warning("[src] takes a big chomp out of [living_target]!"), + span_userdanger("[src] takes a big chomp out of your [edible_bodypart || "body"]!"), + ) + + return COMPONENT_HOSTILE_NO_ATTACK + +/// If we are being attacked by someone who we are already retaliating against, give a nice fluff message. +/mob/living/basic/goat/proc/on_attacked(datum/source, atom/attacker, attack_flags) + var/is_attacker_shitlisted = locate(attacker) in ai_controller.blackboard[BB_BASIC_MOB_RETALIATE_LIST] + if(!is_attacker_shitlisted) + return + + visible_message( + span_danger("[src] gets an evil-looking gleam in [p_their()] eye."), + ) + +/// Handles automagically eating a plant when we move into a turf that has one. +/mob/living/basic/goat/proc/on_move(datum/source, atom/entering_loc) + SIGNAL_HANDLER + if(!isturf(entering_loc)) + return + + var/list/edible_plants = list() + for(var/obj/target in entering_loc) + if(is_type_in_list(target, edibles)) + edible_plants += target + + INVOKE_ASYNC(src, PROC_REF(eat_plant), edible_plants) + +/// When invoked, adds an udder. Overridden on subtypes +/mob/living/basic/goat/proc/add_udder() + AddComponent(/datum/component/udder) + +/// Proc that handles dealing with the various types of plants we might eat. Assumes that a valid list of type(s) will be passed in. +/mob/living/basic/goat/proc/eat_plant(list/plants) + var/eaten = FALSE + + for(var/atom/target as anything in plants) + if(istype(target, /obj/structure/spacevine)) + var/obj/structure/spacevine/vine = target + vine.eat(src) + eaten = TRUE + + if(istype(target, /obj/structure/alien/resin/flower_bud)) + target.take_damage(rand(30, 50), BRUTE, 0) + eaten = TRUE + + if(istype(target, /obj/structure/glowshroom)) + qdel(target) + eaten = TRUE + + if(eaten && prob(10)) + say("Nom") // bon appetit + playsound(src, 'sound/items/eatfood.ogg', rand(30, 50), TRUE) diff --git a/code/modules/mob/living/basic/farm_animals/goat/goat_ai.dm b/code/modules/mob/living/basic/farm_animals/goat/goat_ai.dm new file mode 100644 index 00000000000000..41fc448a3b6ac6 --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/goat/goat_ai.dm @@ -0,0 +1,22 @@ +/// Goats are normally content to sorta hang around and crunch any plant in sight, but they will go ape on someone who attacks them. +/datum/ai_controller/basic_controller/goat + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, + ) + + ai_traits = STOP_MOVING_WHEN_PULLED + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + + planning_subtrees = list( + /datum/ai_planning_subtree/target_retaliate, + /datum/ai_planning_subtree/find_food, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + /datum/ai_planning_subtree/random_speech/goat, + ) + +/datum/ai_planning_subtree/random_speech/goat + speech_chance = 3 + emote_hear = list("brays.") + emote_see = list("shakes their head.", "stamps a foot.", "glares around.") + speak = list("EHEHEHEHEH", "eh?") diff --git a/code/modules/mob/living/basic/farm_animals/goat/goat_subtypes.dm b/code/modules/mob/living/basic/farm_animals/goat/goat_subtypes.dm new file mode 100644 index 00000000000000..19d50fb38097ad --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/goat/goat_subtypes.dm @@ -0,0 +1,12 @@ +/mob/living/basic/goat/pete // Pete! + name = "Pete" + gender = MALE + +/mob/living/basic/goat/pete/examine() + . = ..() + var/area/goat_area = get_area(src) + if((bodytemperature < T20C) || istype(goat_area, /area/station/service/kitchen/coldroom)) + . += span_notice("[p_They()] [p_do()]n't seem to be too bothered about the cold.") // special for pete + +/mob/living/basic/goat/pete/add_udder() + return //no thank you diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm new file mode 100644 index 00000000000000..b0926b41811a1a --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla.dm @@ -0,0 +1,181 @@ +/// Where do we draw gorilla held overlays? +#define GORILLA_HANDS_LAYER 1 + +/** + * Like a bigger monkey + * They make a lot of noise and punch limbs off unconscious folks + */ +/mob/living/basic/gorilla + name = "Gorilla" + desc = "A ground-dwelling, predominantly herbivorous ape which usually inhabits the forests of central Africa but today is quite far away from there." + icon = 'icons/mob/simple/gorilla.dmi' + icon_state = "crawling" + icon_living = "crawling" + icon_dead = "dead" + health_doll_icon = "crawling" + mob_biotypes = MOB_ORGANIC|MOB_HUMANOID + maxHealth = 220 + health = 220 + response_help_continuous = "prods" + response_help_simple = "prod" + response_disarm_continuous = "challenges" + response_disarm_simple = "challenge" + response_harm_continuous = "thumps" + response_harm_simple = "thump" + speed = 0.5 + melee_damage_lower = 15 + melee_damage_upper = 18 + damage_coeff = list(BRUTE = 1, BURN = 1.5, TOX = 1.5, CLONE = 0, STAMINA = 0, OXY = 1.5) + obj_damage = 20 + attack_verb_continuous = "pummels" + attack_verb_simple = "pummel" + attack_sound = 'sound/weapons/punch1.ogg' + unique_name = TRUE + ai_controller = /datum/ai_controller/basic_controller/gorilla + faction = list(FACTION_MONKEY, FACTION_JUNGLE) + butcher_results = list(/obj/item/food/meat/slab/gorilla = 4, /obj/effect/gibspawner/generic/animal = 1) + /// How likely our meaty fist is to stun someone + var/paralyze_chance = 20 + /// A counter for when we can scream again + var/oogas = 0 + /// Types of things we want to find and eat + var/static/list/gorilla_food = list( + /obj/item/food/bread/banana, + /obj/item/food/breadslice/banana, + /obj/item/food/cnds/banana_honk, + /obj/item/food/grown/banana, + /obj/item/food/popsicle/topsicle/banana, + /obj/item/food/salad/fruit, + /obj/item/food/salad/jungle, + /obj/item/food/sundae, + ) + +/mob/living/basic/gorilla/Initialize(mapload) + . = ..() + add_traits(list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP), ROUNDSTART_TRAIT) + AddElement(/datum/element/wall_smasher) + AddElement(/datum/element/dextrous) + AddElement(/datum/element/footstep, FOOTSTEP_MOB_BAREFOOT) + AddElement(/datum/element/basic_eating, heal_amt = 10, food_types = gorilla_food) + AddElement( + /datum/element/amputating_limbs, \ + surgery_time = 0 SECONDS, \ + surgery_verb = "punches",\ + ) + AddComponent(/datum/component/personal_crafting) + AddComponent(/datum/component/basic_inhands, y_offset = -1) + ai_controller?.set_blackboard_key(BB_BASIC_FOODS, gorilla_food) + +/mob/living/basic/gorilla/update_overlays() + . = ..() + if (is_holding_items()) + . += "standing_overlay" + +/mob/living/basic/gorilla/update_icon_state() + . = ..() + if (stat == DEAD) + return + icon_state = is_holding_items() ? "standing" : "crawling" + +/mob/living/basic/gorilla/update_held_items() + . = ..() + update_appearance(UPDATE_ICON) + if (is_holding_items()) + add_movespeed_modifier(/datum/movespeed_modifier/gorilla_standing) + else + remove_movespeed_modifier(/datum/movespeed_modifier/gorilla_standing) + +/mob/living/basic/gorilla/melee_attack(mob/living/target, list/modifiers, ignore_cooldown) + . = ..() + if (!. || !isliving(target)) + return + ooga_ooga() + if (prob(paralyze_chance)) + target.Paralyze(2 SECONDS) + visible_message(span_danger("[src] knocks [target] down!")) + else + target.throw_at(get_edge_target_turf(target, dir), range = rand(1, 2), speed = 7, thrower = src) + +/mob/living/basic/gorilla/gib(drop_bitflags = DROP_BRAIN) + if(!(drop_bitflags & DROP_BRAIN)) + return ..() + var/mob/living/brain/gorilla_brain = new(drop_location()) + gorilla_brain.name = real_name + gorilla_brain.real_name = real_name + mind?.transfer_to(gorilla_brain) + return ..() + +/mob/living/basic/gorilla/can_use_guns(obj/item/gun) + to_chat(src, span_warning("Your meaty finger is much too large for the trigger guard!")) + return FALSE + +/// Assert your dominance with audio cues +/mob/living/basic/gorilla/proc/ooga_ooga() + if (isnull(client)) + return // Sorry NPCs + oogas -= 1 + if(oogas > 0) + return + oogas = rand(2,6) + emote("ooga") + +/// Gorillas are slower when carrying something +/datum/movespeed_modifier/gorilla_standing + blacklisted_movetypes = (FLYING|FLOATING) + multiplicative_slowdown = 0.5 + +/// A smaller gorilla summoned via magic +/mob/living/basic/gorilla/lesser + name = "lesser Gorilla" + desc = "An adolescent Gorilla. It may not be fully grown but, much like a banana, that just means it's sturdier and harder to chew!" + maxHealth = 120 + health = 120 + speed = 0.35 + melee_damage_lower = 10 + melee_damage_upper = 15 + obj_damage = 15 + ai_controller = /datum/ai_controller/basic_controller/gorilla/lesser + butcher_results = list(/obj/item/food/meat/slab/gorilla = 2) + +/mob/living/basic/gorilla/lesser/Initialize(mapload) + . = ..() + transform *= 0.75 + +/// Cargo's wonderful mascot, the tranquil box-carrying ape +/mob/living/basic/gorilla/cargorilla + name = "Cargorilla" // Overriden, normally + icon = 'icons/mob/simple/cargorillia.dmi' + desc = "Cargo's pet gorilla. They seem to have an 'I love Mom' tattoo." + maxHealth = 200 + health = 200 + faction = list(FACTION_NEUTRAL, FACTION_MONKEY, FACTION_JUNGLE) + unique_name = FALSE + ai_controller = null + +/mob/living/basic/gorilla/cargorilla/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_PACIFISM, INNATE_TRAIT) + AddComponent(/datum/component/crate_carrier) + +/** + * Poll ghosts for control of the gorilla. Not added in init because we only want to poll when the round starts. + * Preferably in future we can replace this with a popup on the lobby to queue to become a gorilla. + */ +/mob/living/basic/gorilla/cargorilla/proc/poll_for_gorilla() + AddComponent(\ + /datum/component/ghost_direct_control,\ + poll_candidates = TRUE,\ + poll_length = 30 SECONDS,\ + role_name = "Cargorilla",\ + assumed_control_message = "You are Cargorilla, a pacifist friend of the station and carrier of freight.",\ + poll_ignore_key = POLL_IGNORE_CARGORILLA,\ + after_assumed_control = CALLBACK(src, PROC_REF(became_player_controlled)),\ + ) + +/// Called once a ghost assumes control +/mob/living/basic/gorilla/cargorilla/proc/became_player_controlled() + mind.set_assigned_role(SSjob.GetJobType(/datum/job/cargo_technician)) + mind.special_role = "Cargorilla" + to_chat(src, span_notice("You can pick up crates by clicking on them, and drop them by clicking on the ground.")) + +#undef GORILLA_HANDS_LAYER diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_accessories.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_accessories.dm new file mode 100644 index 00000000000000..814e56487bf54d --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_accessories.dm @@ -0,0 +1,5 @@ +/// Cargorilla's ID card +/obj/item/card/id/advanced/cargo_gorilla + name = "cargorilla ID" + desc = "A card used to provide ID and determine access across the station. A gorilla-sized ID for a gorilla-sized cargo technician." + trim = /datum/id_trim/job/cargo_technician diff --git a/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_ai.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_ai.dm new file mode 100644 index 00000000000000..c62307542777d3 --- /dev/null +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_ai.dm @@ -0,0 +1,35 @@ +/// Pretty basic, just click people to death. Also hunt and eat bananas. +/datum/ai_controller/basic_controller/gorilla + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/allow_items/gorilla, + BB_EMOTE_KEY = "ooga", + BB_EMOTE_CHANCE = 40, + ) + + ai_traits = STOP_MOVING_WHEN_PULLED + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + + planning_subtrees = list( + /datum/ai_planning_subtree/run_emote, + /datum/ai_planning_subtree/find_food, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/attack_obstacle_in_path/gorilla, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/datum/targetting_datum/basic/allow_items/gorilla + stat_attack = UNCONSCIOUS + +/datum/ai_planning_subtree/attack_obstacle_in_path/gorilla + attack_behaviour = /datum/ai_behavior/attack_obstructions/gorilla + +/datum/ai_behavior/attack_obstructions/gorilla + can_attack_turfs = TRUE + +/datum/ai_controller/basic_controller/gorilla/lesser + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/allow_items, + BB_EMOTE_KEY = "ooga", + BB_EMOTE_CHANCE = 60, + ) diff --git a/code/modules/mob/living/simple_animal/hostile/gorilla/emotes.dm b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_emotes.dm similarity index 78% rename from code/modules/mob/living/simple_animal/hostile/gorilla/emotes.dm rename to code/modules/mob/living/basic/farm_animals/gorilla/gorilla_emotes.dm index 20166d81391910..94133336c4d495 100644 --- a/code/modules/mob/living/simple_animal/hostile/gorilla/emotes.dm +++ b/code/modules/mob/living/basic/farm_animals/gorilla/gorilla_emotes.dm @@ -1,5 +1,5 @@ /datum/emote/gorilla - mob_type_allowed_typecache = /mob/living/simple_animal/hostile/gorilla + mob_type_allowed_typecache = /mob/living/basic/gorilla mob_type_blacklist_typecache = list() /datum/emote/gorilla/ooga @@ -9,4 +9,3 @@ message_param = "oogas at %t." emote_type = EMOTE_AUDIBLE | EMOTE_VISIBLE sound = 'sound/creatures/gorilla.ogg' - diff --git a/code/modules/mob/living/basic/farm_animals/pony.dm b/code/modules/mob/living/basic/farm_animals/pony.dm index 4bc09391cb7183..7649068458d1cf 100644 --- a/code/modules/mob/living/basic/farm_animals/pony.dm +++ b/code/modules/mob/living/basic/farm_animals/pony.dm @@ -24,15 +24,24 @@ gold_core_spawnable = FRIENDLY_SPAWN blood_volume = BLOOD_VOLUME_NORMAL ai_controller = /datum/ai_controller/basic_controller/pony + /// Do we register a unique rider? + var/unique_tamer = FALSE + /// The person we've been tamed by + var/datum/weakref/my_owner + + greyscale_config = /datum/greyscale_config/pony + /// Greyscale color config; 1st color is body, 2nd is mane + var/list/ponycolors = list("#cc8c5d", "#cc8c5d") /mob/living/basic/pony/Initialize(mapload) . = ..() + apply_colour() AddElement(/datum/element/pet_bonus, "whickers.") AddElement(/datum/element/ai_retaliate) AddElement(/datum/element/ai_flee_while_injured) AddElement(/datum/element/waddling) - AddComponent(/datum/component/tameable, food_types = list(/obj/item/food/grown/apple), tame_chance = 25, bonus_tame_chance = 15, after_tame = CALLBACK(src, PROC_REF(tamed))) + AddComponent(/datum/component/tameable, food_types = list(/obj/item/food/grown/apple), tame_chance = 25, bonus_tame_chance = 15, after_tame = CALLBACK(src, PROC_REF(tamed)), unique = unique_tamer) /mob/living/basic/pony/proc/tamed(mob/living/tamer) can_buckle = TRUE @@ -40,6 +49,7 @@ playsound(src, 'sound/creatures/pony/snort.ogg', 50) AddElement(/datum/element/ridable, /datum/component/riding/creature/pony) visible_message(span_notice("[src] snorts happily.")) + new /obj/effect/temp_visual/heart(loc) ai_controller.replace_planning_subtrees(list( /datum/ai_planning_subtree/find_nearest_thing_which_attacked_me_to_flee, @@ -47,6 +57,30 @@ /datum/ai_planning_subtree/random_speech/pony/tamed )) + if(unique_tamer) + my_owner = WEAKREF(tamer) + RegisterSignal(src, COMSIG_MOVABLE_PREBUCKLE, PROC_REF(on_prebuckle)) + +/mob/living/basic/pony/Destroy() + UnregisterSignal(src, COMSIG_MOVABLE_PREBUCKLE) + my_owner = null + return ..() + +/// Only let us get ridden if the buckler is our owner, if we have a unique owner. +/mob/living/basic/pony/proc/on_prebuckle(mob/source, mob/living/buckler, force, buckle_mob_flags) + SIGNAL_HANDLER + var/mob/living/tamer = my_owner?.resolve() + if(!unique_tamer || (isnull(tamer) && unique_tamer)) + return + if(buckler != tamer) + whinny_angrily() + return COMPONENT_BLOCK_BUCKLE + +/mob/living/basic/pony/proc/apply_colour() + if(!greyscale_config) + return + set_greyscale(colors = ponycolors) + /mob/living/basic/pony/proc/whinny_angrily() manual_emote("whinnies ANGRILY!") @@ -86,3 +120,35 @@ /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/random_speech/pony ) + +// A stronger horse is required for our strongest cowboys. +/mob/living/basic/pony/syndicate + health = 300 + maxHealth = 300 + desc = "A special breed of horse engineered by the syndicate to be capable of surviving in the deep reaches of space. A modern outlaw's best friend." + faction = list(ROLE_SYNDICATE) + ponycolors = list("#5d566f", COLOR_RED) + pressure_resistance = 200 + habitable_atmos = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + minimum_survivable_temperature = 0 + maximum_survivable_temperature = 1500 + unique_tamer = TRUE + +/mob/living/basic/pony/syndicate/Initialize(mapload) + . = ..() + // Help discern your horse from your allies + var/mane_colors = list( + COLOR_RED=6, + COLOR_BLUE=6, + COLOR_PINK=3, + COLOR_GREEN=3, + COLOR_BLACK=3, + COLOR_YELLOW=2, + COLOR_ORANGE=1, + COLOR_WHITE=1, + COLOR_DARK_BROWN=1, + ) + ponycolors = list("#5d566f", pick_weight(mane_colors)) + name = pick("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday") + // Only one person can tame these fellas, and they only need one apple + AddComponent(/datum/component/tameable, food_types = list(/obj/item/food/grown/apple), tame_chance = 100, bonus_tame_chance = 15, after_tame = CALLBACK(src, PROC_REF(tamed)), unique = unique_tamer) diff --git a/code/modules/mob/living/basic/farm_animals/rabbit.dm b/code/modules/mob/living/basic/farm_animals/rabbit.dm index 92d40e0228e2d1..e837fc3bf8325b 100644 --- a/code/modules/mob/living/basic/farm_animals/rabbit.dm +++ b/code/modules/mob/living/basic/farm_animals/rabbit.dm @@ -49,7 +49,6 @@ /datum/ai_controller/basic_controller/rabbit blackboard = list( - BB_BASIC_MOB_FLEEING = TRUE, BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/ignore_faction(), ) ai_traits = STOP_MOVING_WHEN_PULLED diff --git a/code/modules/mob/living/basic/farm_animals/sheep.dm b/code/modules/mob/living/basic/farm_animals/sheep.dm index 691f1db14e3ce4..4452c5ae77cbae 100644 --- a/code/modules/mob/living/basic/farm_animals/sheep.dm +++ b/code/modules/mob/living/basic/farm_animals/sheep.dm @@ -81,7 +81,6 @@ /datum/ai_controller/basic_controller/sheep blackboard = list( - BB_BASIC_MOB_FLEEING = TRUE, BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/ignore_faction(), ) ai_traits = STOP_MOVING_WHEN_PULLED diff --git a/code/modules/mob/living/basic/health_adjustment.dm b/code/modules/mob/living/basic/health_adjustment.dm index 6355f809cf470e..9644a1a6299057 100644 --- a/code/modules/mob/living/basic/health_adjustment.dm +++ b/code/modules/mob/living/basic/health_adjustment.dm @@ -1,57 +1,70 @@ /** - * Adjusts the health of a simple mob by a set amount and wakes AI if its idle to react + * Adjusts the health of a simple mob by a set amount * * Arguments: * * amount The amount that will be used to adjust the mob's health * * updating_health If the mob's health should be immediately updated to the new value * * forced If we should force update the adjustment of the mob's health no matter the restrictions, like GODMODE + * returns the net change in bruteloss after applying the damage amount */ /mob/living/basic/proc/adjust_health(amount, updating_health = TRUE, forced = FALSE) . = FALSE - if(forced || !(status_flags & GODMODE)) - bruteloss = round(clamp(bruteloss + amount, 0, maxHealth * 2), DAMAGE_PRECISION) - if(updating_health) - updatehealth() - . = amount - if(ckey || stat) - return - //if(AIStatus == AI_IDLE) - // toggle_ai(AI_ON) + if(!forced && (status_flags & GODMODE)) + return 0 + . = bruteloss // bruteloss value before applying damage + bruteloss = round(clamp(bruteloss + amount, 0, maxHealth * 2), DAMAGE_PRECISION) + if(updating_health) + updatehealth() + return . - bruteloss /mob/living/basic/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) + if(!can_adjust_brute_loss(amount, forced, required_bodytype)) + return 0 if(forced) . = adjust_health(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[BRUTE]) . = adjust_health(amount * damage_coeff[BRUTE] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/basic/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) + if(!can_adjust_fire_loss(amount, forced, required_bodytype)) + return 0 if(forced) . = adjust_health(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[BURN]) . = adjust_health(amount * damage_coeff[BURN] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/basic/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype, required_respiration_type) + if(!can_adjust_oxy_loss(amount, forced, required_biotype, required_respiration_type)) + return 0 if(forced) . = adjust_health(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[OXY]) . = adjust_health(amount * damage_coeff[OXY] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/basic/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) + if(!can_adjust_tox_loss(amount, forced, required_biotype)) + return 0 if(forced) . = adjust_health(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[TOX]) . = adjust_health(amount * damage_coeff[TOX] * CONFIG_GET(number/damage_multiplier), updating_health, forced) -/mob/living/basic/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE) +/mob/living/basic/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) + if(!can_adjust_clone_loss(amount, forced, required_biotype)) + return 0 if(forced) . = adjust_health(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[CLONE]) . = adjust_health(amount * damage_coeff[CLONE] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/basic/adjustStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype) + if(!can_adjust_stamina_loss(amount, forced, required_biotype)) + return 0 + . = staminaloss if(forced) staminaloss = max(0, min(BASIC_MOB_MAX_STAMINALOSS, staminaloss + amount)) else staminaloss = max(0, min(BASIC_MOB_MAX_STAMINALOSS, staminaloss + (amount * damage_coeff[STAMINA]))) if(updating_stamina) update_stamina() + . -= staminaloss diff --git a/code/modules/mob/living/basic/heretic/ash_spirit.dm b/code/modules/mob/living/basic/heretic/ash_spirit.dm new file mode 100644 index 00000000000000..b2d4d8b4d29473 --- /dev/null +++ b/code/modules/mob/living/basic/heretic/ash_spirit.dm @@ -0,0 +1,25 @@ +/** + * Player-only mob which is fast, can jaunt a short distance, and is dangerous at close range + */ +/mob/living/basic/heretic_summon/ash_spirit + name = "Ash Spirit" + real_name = "Ashy" + desc = "A manifestation of ash, trailing a perpetual cloud of short-lived cinders." + icon_state = "ash_walker" + icon_living = "ash_walker" + maxHealth = 75 + health = 75 + melee_damage_lower = 15 + melee_damage_upper = 20 + sight = SEE_TURFS + +/mob/living/basic/heretic_summon/ash_spirit/Initialize(mapload) + . = ..() + var/static/list/actions_to_add = list( + /datum/action/cooldown/spell/fire_sworn, + /datum/action/cooldown/spell/jaunt/ethereal_jaunt/ash, + /datum/action/cooldown/spell/pointed/cleave, + ) + for (var/action in actions_to_add) + var/datum/action/cooldown/new_action = new action(src) + new_action.Grant(src) diff --git a/code/modules/mob/living/basic/heretic/flesh_stalker.dm b/code/modules/mob/living/basic/heretic/flesh_stalker.dm new file mode 100644 index 00000000000000..6f31b3ce7c523a --- /dev/null +++ b/code/modules/mob/living/basic/heretic/flesh_stalker.dm @@ -0,0 +1,46 @@ +/// Durable ambush mob with an EMP ability +/mob/living/basic/heretic_summon/stalker + name = "Flesh Stalker" + real_name = "Flesh Stalker" + desc = "An abomination cobbled together from varied remains. Its appearance changes slightly every time you blink." + icon_state = "stalker" + icon_living = "stalker" + maxHealth = 150 + health = 150 + melee_damage_lower = 15 + melee_damage_upper = 20 + sight = SEE_MOBS + ai_controller = /datum/ai_controller/basic_controller/stalker + /// Associative list of action types we would like to have, and what blackboard key (if any) to put it in + var/static/list/actions_to_add = list( + /datum/action/cooldown/spell/emp/eldritch = BB_GENERIC_ACTION, + /datum/action/cooldown/spell/jaunt/ethereal_jaunt/ash = null, + /datum/action/cooldown/spell/shapeshift/eldritch = BB_SHAPESHIFT_ACTION, + ) + +/mob/living/basic/heretic_summon/stalker/Initialize(mapload) + . = ..() + AddComponent(/datum/component/ai_target_timer) + for (var/action_type in actions_to_add) + var/datum/action/new_action = new action_type(src) + new_action.Grant(src) + var/blackboard_key = actions_to_add[action_type] + if (!isnull(blackboard_key)) + ai_controller?.set_blackboard_key(blackboard_key, new_action) + +/// Changes shape and lies in wait when it has no target, uses EMP and attacks once it does +/datum/ai_controller/basic_controller/stalker + ai_traits = CAN_ACT_IN_STASIS + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/shapechange_ambush, + /datum/ai_planning_subtree/use_mob_ability, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) diff --git a/code/modules/mob/living/basic/heretic/flesh_worm.dm b/code/modules/mob/living/basic/heretic/flesh_worm.dm new file mode 100644 index 00000000000000..3c60a9b653c32a --- /dev/null +++ b/code/modules/mob/living/basic/heretic/flesh_worm.dm @@ -0,0 +1,137 @@ +/// Armsy starts to look a bit funky if he's shorter than this +#define MINIMUM_ARMSY_LENGTH 2 + +// What if we took a linked list... But made it a mob? +/// The "Terror of the Night" / Armsy, a large worm made of multiple bodyparts that occupies multiple tiles +/mob/living/basic/heretic_summon/armsy + name = "Lord of the Night" + real_name = "Master of Decay" + desc = "An abomination made from dozens and dozens of severed and malformed limbs grasping onto each other." + icon_state = "armsy_start" + icon_living = "armsy_start" + base_icon_state = "armsy" + maxHealth = 400 + health = 400 + melee_damage_lower = 30 + melee_damage_upper = 50 + obj_damage = 200 + move_force = MOVE_FORCE_OVERPOWERING + move_resist = MOVE_FORCE_OVERPOWERING + pull_force = MOVE_FORCE_OVERPOWERING + mob_size = MOB_SIZE_HUGE + sentience_type = SENTIENCE_BOSS + mob_biotypes = MOB_ORGANIC|MOB_SPECIAL + ///Previous segment in the chain, we hold onto this purely to keep track of how long we currently are and to attach new growth to the back + var/mob/living/basic/heretic_summon/armsy/back + ///How many arms do we have to eat to expand? + var/stacks_to_grow = 5 + ///Currently eaten arms + var/current_stacks = 0 +/* + * Arguments + * * spawn_bodyparts - whether we spawn additional armsy bodies until we reach length. + * * worm_length - the length of the worm we're creating. Below 2 doesn't work very well. + */ +/mob/living/basic/heretic_summon/armsy/Initialize(mapload, spawn_bodyparts = TRUE, worm_length = 6) + . = ..() + AddElement(/datum/element/wall_smasher, ENVIRONMENT_SMASH_RWALLS) + AddElement(\ + /datum/element/amputating_limbs,\ + surgery_time = 0 SECONDS,\ + surgery_verb = "tears",\ + minimum_stat = CONSCIOUS,\ + snip_chance = 10,\ + target_zones = GLOB.arm_zones,\ + ) + AddComponent(\ + /datum/component/blood_walk, \ + blood_type = /obj/effect/decal/cleanable/blood/tracks, \ + target_dir_change = TRUE,\ + ) + + if(spawn_bodyparts) + build_tail(worm_length) + +// We are a vessel of otherworldly destruction, we bring our gravity with us +/mob/living/basic/heretic_summon/armsy/has_gravity(turf/gravity_turf) + return TRUE + +/mob/living/basic/heretic_summon/armsy/can_be_pulled() + return FALSE // The component does this but not on the head. We don't want the head to be pulled either. + +/mob/living/basic/heretic_summon/armsy/proc/build_tail(worm_length) + worm_length = max(worm_length, MINIMUM_ARMSY_LENGTH) + // Sets the hp of the head to be exactly the (length * hp), so the head is de facto the hardest to destroy. + maxHealth = worm_length * maxHealth + health = maxHealth + + AddComponent(/datum/component/mob_chain, vary_icon_state = TRUE) // We're the front + + var/mob/living/basic/heretic_summon/armsy/prev = src + for(var/i in 1 to worm_length) + prev = new_segment(behind = prev) + update_appearance(UPDATE_ICON_STATE) + +/// Grows a new segment behind the passed mob +/mob/living/basic/heretic_summon/armsy/proc/new_segment(mob/living/basic/heretic_summon/armsy/behind) + var/mob/living/segment = new type(drop_location(), FALSE) + ADD_TRAIT(segment, TRAIT_PERMANENTLY_MORTAL, INNATE_TRAIT) + segment.AddComponent(/datum/component/mob_chain, front = behind, vary_icon_state = TRUE) + behind.register_behind(segment) + return segment + +/// Record that we got another guy on our ass +/mob/living/basic/heretic_summon/armsy/proc/register_behind(mob/living/tail) + if(!isnull(back)) // Shouldn't happen but just in case + UnregisterSignal(back, COMSIG_QDELETING) + back = tail + update_appearance(UPDATE_ICON_STATE) + if(!isnull(back)) + RegisterSignal(back, COMSIG_QDELETING, PROC_REF(tail_deleted)) + +/// When our tail is gone stop holding a reference to it +/mob/living/basic/heretic_summon/armsy/proc/tail_deleted() + SIGNAL_HANDLER + register_behind(null) + +/mob/living/basic/heretic_summon/armsy/melee_attack(atom/target, list/modifiers, ignore_cooldown) + if(!istype(target, /obj/item/bodypart/arm)) + return ..() + visible_message(span_warning("[src] devours [target]!")) + playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) + qdel(target) + on_arm_eaten() + +/* + * Handle healing our chain. + * Eating arms off the ground heals us, and if we eat enough arms while above a certain health threshold we get longer! + */ +/mob/living/basic/heretic_summon/armsy/proc/on_arm_eaten() + if(!isnull(back)) + back.on_arm_eaten() + return + + adjustBruteLoss(-maxHealth * 0.5, FALSE) + adjustFireLoss(-maxHealth * 0.5, FALSE) + + if(health < maxHealth * 0.8) + return + + current_stacks++ + if(current_stacks < stacks_to_grow) + return + + visible_message(span_boldwarning("[src] flexes and expands!")) + current_stacks = 0 + new_segment(behind = src) + +/* + * Recursively get the length of our chain. + */ +/mob/living/basic/heretic_summon/armsy/proc/get_length() + . = 1 + if(isnull(back)) + return + . += back.get_length() + +#undef MINIMUM_ARMSY_LENGTH diff --git a/code/modules/mob/living/basic/heretic/heretic_summon.dm b/code/modules/mob/living/basic/heretic/heretic_summon.dm index 0f7d63f903cc5c..cf1bcf80aad830 100644 --- a/code/modules/mob/living/basic/heretic/heretic_summon.dm +++ b/code/modules/mob/living/basic/heretic/heretic_summon.dm @@ -1,26 +1,25 @@ /mob/living/basic/heretic_summon name = "Eldritch Demon" real_name = "Eldritch Demon" - desc = "A horror from beyond this realm." + desc = "A horror from beyond this realm, summoned by bad code." icon = 'icons/mob/nonhuman-player/eldritch_mobs.dmi' faction = list(FACTION_HERETIC) basic_mob_flags = DEL_ON_DEATH gender = NEUTER mob_biotypes = NONE - unsuitable_atmos_damage = 0 - unsuitable_cold_damage = 0 - unsuitable_heat_damage = 0 + habitable_atmos = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) speed = 0 + melee_attack_cooldown = CLICK_CD_MELEE attack_sound = 'sound/weapons/punch1.ogg' response_help_continuous = "thinks better of touching" response_help_simple = "think better of touching" response_disarm_continuous = "flails at" response_disarm_simple = "flail at" - response_harm_continuous = "reaps" - response_harm_simple = "tears" + response_harm_continuous = "rips" + response_harm_simple = "tear" death_message = "implodes into itself." combat_mode = TRUE diff --git a/code/modules/antagonists/heretic/mobs/maid_in_mirror.dm b/code/modules/mob/living/basic/heretic/maid_in_the_mirror.dm similarity index 60% rename from code/modules/antagonists/heretic/mobs/maid_in_mirror.dm rename to code/modules/mob/living/basic/heretic/maid_in_the_mirror.dm index b53bbe147d3df9..edc5148b3ccce3 100644 --- a/code/modules/antagonists/heretic/mobs/maid_in_mirror.dm +++ b/code/modules/mob/living/basic/heretic/maid_in_the_mirror.dm @@ -1,11 +1,11 @@ -// A summon which floats around the station incorporeally, and can appear in any mirror -/mob/living/simple_animal/hostile/heretic_summon/maid_in_the_mirror +/// Scout and assassin who can appear and disappear from glass surfaces. Damaged by being examined. +/mob/living/basic/heretic_summon/maid_in_the_mirror name = "Maid in the Mirror" real_name = "Maid in the Mirror" desc = "A floating and flowing wisp of chilled air. Glancing at it causes it to shimmer slightly." icon = 'icons/mob/simple/mob.dmi' icon_state = "stand" - icon_living = "stand" // Placeholder sprite + icon_living = "stand" // Placeholder sprite... still speak_emote = list("whispers") movement_type = FLOATING status_flags = CANSTUN | CANPUSH @@ -16,36 +16,34 @@ melee_damage_upper = 16 sight = SEE_MOBS | SEE_OBJS | SEE_TURFS death_message = "shatters and vanishes, releasing a gust of cold air." - loot = list( - /obj/item/shard, + /// Whether we take damage when someone looks at us + var/harmed_by_examine = TRUE + /// How often being examined by a specific mob can hurt us + var/recent_examine_damage_cooldown = 10 SECONDS + /// A list of REFs to people who recently examined us + var/list/recent_examiner_refs = list() + +/mob/living/basic/heretic_summon/Initialize(mapload) + . = ..() + var/static/list/loot = list( /obj/effect/decal/cleanable/ash, /obj/item/clothing/suit/armor/vest, /obj/item/organ/internal/lungs, + /obj/item/shard, ) - actions_to_add = list(/datum/action/cooldown/spell/jaunt/mirror_walk) + AddElement(/datum/element/death_drops, loot) + var/datum/action/cooldown/spell/jaunt/mirror_walk/jaunt = new (src) + jaunt.Grant(src) - /// Whether we take damage when we're examined - var/weak_on_examine = TRUE - /// The cooldown after being examined that the same mob cannot trigger it again - var/recent_examine_damage_cooldown = 10 SECONDS - /// A list of REFs to people who recently examined us - var/list/recent_examiner_refs = list() - -/mob/living/simple_animal/hostile/heretic_summon/maid_in_the_mirror/death(gibbed) +/mob/living/basic/heretic_summon/maid_in_the_mirror/death(gibbed) var/turf/death_turf = get_turf(src) - death_turf.TakeTemperature(-40) + death_turf.TakeTemperature(-40) // Spooky return ..() // Examining them will harm them, on a cooldown. -/mob/living/simple_animal/hostile/heretic_summon/maid_in_the_mirror/examine(mob/user) +/mob/living/basic/heretic_summon/maid_in_the_mirror/examine(mob/user) . = ..() - if(!weak_on_examine) - return - - if(!isliving(user) || user.stat == DEAD) - return - - if(IS_HERETIC_OR_MONSTER(user) || user == src) + if(!harmed_by_examine || user == src || user.stat == DEAD || !isliving(user) || IS_HERETIC_OR_MONSTER(user)) return var/user_ref = REF(user) @@ -62,7 +60,9 @@ recent_examiner_refs += user_ref apply_damage(maxHealth * 0.1) // We take 10% of our health as damage upon being examined playsound(src, 'sound/effects/ghost2.ogg', 40, TRUE) - addtimer(CALLBACK(src, PROC_REF(clear_recent_examiner), user_ref), recent_examine_damage_cooldown) + addtimer(CALLBACK(src, PROC_REF(clear_recent_examiner), user_ref), recent_examine_damage_cooldown, TIMER_DELETE_ME) + animate(src, alpha = 120, time = 0.5 SECONDS, easing = ELASTIC_EASING, loop = 2, flags = ANIMATION_PARALLEL) + animate(alpha = 255, time = 0.5 SECONDS, easing = ELASTIC_EASING) // If we're examined on low enough health we die straight up else @@ -73,7 +73,7 @@ death() -/mob/living/simple_animal/hostile/heretic_summon/maid_in_the_mirror/proc/clear_recent_examiner(mob_ref) +/mob/living/basic/heretic_summon/maid_in_the_mirror/proc/clear_recent_examiner(mob_ref) if(!(mob_ref in recent_examiner_refs)) return diff --git a/code/modules/mob/living/basic/heretic/raw_prophet.dm b/code/modules/mob/living/basic/heretic/raw_prophet.dm new file mode 100644 index 00000000000000..1a3b2d1aa923a2 --- /dev/null +++ b/code/modules/mob/living/basic/heretic/raw_prophet.dm @@ -0,0 +1,96 @@ +/** + * A funny little rolling guy who is great at scouting. + * It can see through walls, jaunt, and create a psychic network to report its findings. + * It can blind people to make a getaway, but also get stronger if it attacks the same target consecutively. + */ +/mob/living/basic/heretic_summon/raw_prophet + name = "Raw Prophet" + real_name = "Raw Prophet" + desc = "An abomination stitched together from a few severed arms and one swollen, orphaned eye." + icon_state = "raw_prophet" + icon_living = "raw_prophet" + status_flags = CANPUSH + melee_damage_lower = 5 + melee_damage_upper = 10 + maxHealth = 65 + health = 65 + sight = SEE_MOBS|SEE_OBJS|SEE_TURFS + /// Some ability we use to make people go blind + var/blind_action_type = /datum/action/cooldown/spell/pointed/blind/eldritch + +/mob/living/basic/heretic_summon/raw_prophet/Initialize(mapload) + . = ..() + AddElement(/datum/element/wheel) + var/static/list/body_parts = list(/obj/effect/gibspawner/human, /obj/item/bodypart/arm/left, /obj/item/organ/internal/eyes) + AddElement(/datum/element/death_drops, body_parts) + AddComponent(/datum/component/focused_attacker) + var/on_link_message = "You feel something new enter your sphere of mind... \ + You hear whispers of people far away, screeches of horror and a huming of welcome to [src]'s Mansus Link." + var/on_unlink_message = "Your mind shatters as [src]'s Mansus Link leaves your mind." + AddComponent( \ + /datum/component/mind_linker/active_linking, \ + network_name = "Mansus Link", \ + chat_color = "#568b00", \ + post_unlink_callback = CALLBACK(src, PROC_REF(after_unlink)), \ + speech_action_background_icon_state = "bg_heretic", \ + speech_action_overlay_state = "bg_heretic_border", \ + linker_action_path = /datum/action/cooldown/spell/pointed/manse_link, \ + link_message = on_link_message, \ + unlink_message = on_unlink_message, \ + ) + + // We don't use these for AI so we can just repeat the same adding process + var/static/list/add_abilities = list( + /datum/action/cooldown/spell/jaunt/ethereal_jaunt/ash/long, + /datum/action/cooldown/spell/list_target/telepathy/eldritch, + /datum/action/innate/expand_sight, + ) + for (var/ability_type in add_abilities) + var/datum/action/new_action = new ability_type(src) + new_action.Grant(src) + + var/datum/action/cooldown/blind = new blind_action_type(src) + blind.Grant(src) + ai_controller?.set_blackboard_key(BB_TARGETTED_ACTION, blind) + +/* + * Callback for the mind_linker component. + * Stuns people who are ejected from the network. + */ +/mob/living/basic/heretic_summon/raw_prophet/proc/after_unlink(mob/living/unlinked_mob) + if(QDELETED(unlinked_mob) || unlinked_mob.stat == DEAD) + return + + INVOKE_ASYNC(unlinked_mob, TYPE_PROC_REF(/mob, emote), "scream") + unlinked_mob.AdjustParalyzed(0.5 SECONDS) //micro stun + +/mob/living/basic/heretic_summon/raw_prophet/melee_attack(atom/target, list/modifiers, ignore_cooldown) + SpinAnimation(speed = 5, loops = 1) + if (target == src) + return + return ..() + +/// Variant raw prophet used by eldritch transformation with more base attack power +/mob/living/basic/heretic_summon/raw_prophet/ascended + melee_damage_lower = 15 + melee_damage_upper = 20 + +/// NPC variant with a less bullshit ability +/mob/living/basic/heretic_summon/raw_prophet/ruins + ai_controller = /datum/ai_controller/basic_controller/raw_prophet + blind_action_type = /datum/action/cooldown/mob_cooldown/watcher_gaze + +/// Walk and attack people, blind them when we can +/datum/ai_controller/basic_controller/raw_prophet + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/targeted_mob_ability, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) diff --git a/code/modules/mob/living/basic/heretic/rust_walker.dm b/code/modules/mob/living/basic/heretic/rust_walker.dm new file mode 100644 index 00000000000000..070326c0281aeb --- /dev/null +++ b/code/modules/mob/living/basic/heretic/rust_walker.dm @@ -0,0 +1,87 @@ +/// Pretty simple mob which creates areas of rust and has a rust-creating projectile spell +/mob/living/basic/heretic_summon/rust_walker + name = "Rust Walker" + real_name = "Rusty" + desc = "A grinding, clanking construct which leaches life from its surroundings with every armoured step." + icon_state = "rust_walker_s" + base_icon_state = "rust_walker" + icon_living = "rust_walker_s" + maxHealth = 75 + health = 75 + melee_damage_lower = 15 + melee_damage_upper = 20 + sight = SEE_TURFS + speed = 1 + ai_controller = /datum/ai_controller/basic_controller/rust_walker + +/mob/living/basic/heretic_summon/rust_walker/Initialize(mapload) + . = ..() + AddElement(/datum/element/footstep, FOOTSTEP_MOB_RUST) + var/datum/action/cooldown/spell/aoe/rust_conversion/small/conversion = new(src) + conversion.Grant(src) + ai_controller?.set_blackboard_key(BB_GENERIC_ACTION, conversion) + + var/datum/action/cooldown/spell/basic_projectile/rust_wave/short/wave = new(src) + wave.Grant(src) + ai_controller?.set_blackboard_key(BB_TARGETTED_ACTION, wave) + +/mob/living/basic/heretic_summon/rust_walker/setDir(newdir) + . = ..() + update_appearance(UPDATE_ICON_STATE) + +/mob/living/basic/heretic_summon/rust_walker/update_icon_state() + . = ..() + if(stat == DEAD) // We usually delete on death but just in case + return + if(dir & NORTH) + icon_state = "[base_icon_state]_n" + else if(dir & SOUTH) + icon_state = "[base_icon_state]_s" + icon_living = icon_state + +/mob/living/basic/heretic_summon/rust_walker/Life(seconds_per_tick = SSMOBS_DT, times_fired) + if(stat == DEAD) + return ..() + var/turf/our_turf = get_turf(src) + if(HAS_TRAIT(our_turf, TRAIT_RUSTY)) + adjustBruteLoss(-3 * seconds_per_tick) + + return ..() + +/// Converts unconverted terrain, sprays pocket sand around +/datum/ai_controller/basic_controller/rust_walker + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk/rust + planning_subtrees = list( + /datum/ai_planning_subtree/use_mob_ability/rust_walker, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/targeted_mob_ability, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/// Moves a lot if healthy and on rust (to find more tiles to rust) or unhealthy and not on rust (to find healing rust) +/// Still moving in random directions though we're not really seeking it out +/datum/idle_behavior/idle_random_walk/rust + +/datum/idle_behavior/idle_random_walk/rust/perform_idle_behavior(seconds_per_tick, datum/ai_controller/controller) + var/mob/living/our_mob = controller.pawn + var/turf/our_turf = get_turf(our_mob) + if (HAS_TRAIT(our_turf, TRAIT_RUSTY)) + walk_chance = (our_mob.health < our_mob.maxHealth) ? 10 : 50 + else + walk_chance = (our_mob.health < our_mob.maxHealth) ? 50 : 10 + return ..() + +/// Use if we're not stood on rust right now +/datum/ai_planning_subtree/use_mob_ability/rust_walker + +/datum/ai_planning_subtree/use_mob_ability/rust_walker/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/turf/our_turf = get_turf(controller.pawn) + if (HAS_TRAIT(our_turf, TRAIT_RUSTY)) + return + return ..() diff --git a/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon.dm b/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon.dm new file mode 100644 index 00000000000000..960f875365bfa4 --- /dev/null +++ b/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon.dm @@ -0,0 +1,89 @@ +/mob/living/basic/mining/ice_demon + name = "demonic watcher" + desc = "A creature formed entirely out of ice, bluespace energy emanates from inside of it." + icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi' + icon_state = "ice_demon" + icon_living = "ice_demon" + icon_gib = "syndicate_gib" + mob_biotypes = MOB_ORGANIC|MOB_BEAST + mouse_opacity = MOUSE_OPACITY_ICON + basic_mob_flags = DEL_ON_DEATH + speed = 2 + maxHealth = 150 + health = 150 + obj_damage = 40 + melee_damage_lower = 15 + melee_damage_upper = 15 + attack_verb_continuous = "slices" + attack_verb_simple = "slice" + attack_sound = 'sound/weapons/bladeslice.ogg' + attack_vis_effect = ATTACK_EFFECT_SLASH + move_force = MOVE_FORCE_VERY_STRONG + move_resist = MOVE_FORCE_VERY_STRONG + pull_force = MOVE_FORCE_VERY_STRONG + crusher_loot = /obj/item/crusher_trophy/ice_demon_cube + ai_controller = /datum/ai_controller/basic_controller/ice_demon + death_message = "fades as the energies that tied it to this world dissipate." + death_sound = 'sound/magic/demon_dies.ogg' + +/mob/living/basic/mining/ice_demon/Initialize(mapload) + . = ..() + var/datum/action/cooldown/mob_cooldown/slippery_ice_floors/ice_floor = new(src) + ice_floor.Grant(src) + ai_controller.set_blackboard_key(BB_DEMON_SLIP_ABILITY, ice_floor) + var/datum/action/cooldown/mob_cooldown/ice_demon_teleport/demon_teleport = new(src) + demon_teleport.Grant(src) + ai_controller.set_blackboard_key(BB_DEMON_TELEPORT_ABILITY, demon_teleport) + var/datum/action/cooldown/spell/conjure/create_afterimages/afterimage = new(src) + afterimage.Grant(src) + ai_controller.set_blackboard_key(BB_DEMON_CLONE_ABILITY, afterimage) + AddComponent(\ + /datum/component/ranged_attacks,\ + projectile_type = /obj/projectile/temp/ice_demon,\ + projectile_sound = 'sound/weapons/pierce.ogg',\ + ) + var/static/list/death_loot = list(/obj/item/stack/ore/bluespace_crystal = 3) + AddElement(/datum/element/death_drops, death_loot) + AddElement(/datum/element/simple_flying) + +/mob/living/basic/mining/ice_demon/death(gibbed) + if(prob(5)) + new /obj/item/raw_anomaly_core/bluespace(loc) + return ..() + +/mob/living/basic/mining/demon_afterimage + name = "afterimage demonic watcher" + desc = "Is this some sort of illusion?" + icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi' + icon_state = "ice_demon" + icon_living = "ice_demon" + icon_gib = "syndicate_gib" + mob_biotypes = MOB_ORGANIC|MOB_BEAST + mouse_opacity = MOUSE_OPACITY_ICON + basic_mob_flags = DEL_ON_DEATH + speed = 5 + maxHealth = 20 + health = 20 + melee_damage_lower = 5 + melee_damage_upper = 5 + attack_verb_continuous = "slices" + attack_verb_simple = "slice" + attack_sound = 'sound/weapons/bladeslice.ogg' + alpha = 80 + ai_controller = /datum/ai_controller/basic_controller/ice_demon/afterimage + ///how long do we exist for + var/existence_period = 15 SECONDS + +/mob/living/basic/mining/demon_afterimage/Initialize(mapload) + . = ..() + AddElement(/datum/element/simple_flying) + AddElement(/datum/element/temporary_atom, life_time = existence_period) + +///afterimage subtypes summoned by the crusher +/mob/living/basic/mining/demon_afterimage/crusher + speed = 2 + health = 60 + maxHealth = 60 + melee_damage_lower = 10 + melee_damage_upper = 10 + existence_period = 7 SECONDS diff --git a/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon_abilities.dm b/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon_abilities.dm new file mode 100644 index 00000000000000..79c9ee9bd583eb --- /dev/null +++ b/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon_abilities.dm @@ -0,0 +1,117 @@ +/obj/projectile/temp/ice_demon + name = "ice blast" + icon_state = "ice_2" + damage = 5 + damage_type = BURN + armor_flag = ENERGY + speed = 1 + pixel_speed_multiplier = 0.25 + temperature = -75 + +/datum/action/cooldown/mob_cooldown/ice_demon_teleport + name = "Bluespace Teleport" + desc = "Teleport towards a destination target!" + button_icon = 'icons/obj/ore.dmi' + button_icon_state = "bluespace_crystal" + cooldown_time = 3 SECONDS + melee_cooldown_time = 0 SECONDS + ///time delay before teleport + var/time_delay = 0.5 SECONDS + +/datum/action/cooldown/mob_cooldown/ice_demon_teleport/Activate(atom/target_atom) + if(isclosedturf(get_turf(target_atom))) + owner.balloon_alert(owner, "blocked!") + return FALSE + animate(owner, transform = matrix().Scale(0.8), time = time_delay, easing = SINE_EASING) + addtimer(CALLBACK(src, PROC_REF(teleport_to_turf), target_atom), time_delay) + StartCooldown() + return TRUE + +/datum/action/cooldown/mob_cooldown/ice_demon_teleport/proc/teleport_to_turf(atom/target) + animate(owner, transform = matrix(), time = 0.5 SECONDS, easing = SINE_EASING) + do_teleport(teleatom = owner, destination = target, channel = TELEPORT_CHANNEL_BLUESPACE, forced = TRUE) + +/datum/action/cooldown/mob_cooldown/slippery_ice_floors + name = "Iced Floors" + desc = "Summon slippery ice floors all around!" + button_icon = 'icons/turf/floors/ice_turf.dmi' + button_icon_state = "ice_turf-6" + cooldown_time = 2 SECONDS + click_to_activate = FALSE + melee_cooldown_time = 0 SECONDS + ///perimeter we will spawn the iced floors on + var/radius = 1 + ///intervals we will spawn the ice floors in + var/spread_duration = 0.2 SECONDS + +/datum/action/cooldown/mob_cooldown/slippery_ice_floors/Activate(atom/target_atom) + for(var/i in 0 to radius) + var/list/list_of_turfs = border_diamond_range_turfs(owner, i) + addtimer(CALLBACK(src, PROC_REF(spawn_icy_floors), list_of_turfs), i * spread_duration) + StartCooldown() + return TRUE + +/datum/action/cooldown/mob_cooldown/slippery_ice_floors/proc/spawn_icy_floors(list/list_of_turfs) + if(!length(list_of_turfs)) + return + for(var/turf/location in list_of_turfs) + if(isnull(location)) + continue + if(isclosedturf(location) || isspaceturf(location)) + continue + new /obj/effect/temp_visual/slippery_ice(location) + +/obj/effect/temp_visual/slippery_ice + name = "slippery acid" + icon = 'icons/turf/floors/ice_turf.dmi' + icon_state = "ice_turf-6" + layer = BELOW_MOB_LAYER + plane = GAME_PLANE + anchored = TRUE + duration = 3 SECONDS + alpha = 100 + /// how long does it take for the effect to phase in + var/phase_in_period = 2 SECONDS + +/obj/effect/temp_visual/slippery_ice/Initialize(mapload) + . = ..() + animate(src, alpha = 160, time = phase_in_period) + animate(alpha = 0, time = duration - phase_in_period) /// slowly fade out of existence + addtimer(CALLBACK(src, PROC_REF(add_slippery_component), phase_in_period)) //only become slippery after we phased in + +/obj/effect/temp_visual/slippery_ice/proc/add_slippery_component() + AddComponent(/datum/component/slippery, 2 SECONDS) + +/datum/action/cooldown/spell/conjure/create_afterimages + name = "Create After Images" + button_icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi' + button_icon_state = "ice_demon" + spell_requirements = NONE + cooldown_time = 1 MINUTES + summon_type = list(/mob/living/basic/mining/demon_afterimage) + summon_radius = 1 + summon_amount = 2 + ///max number of after images + var/max_afterimages = 2 + ///How many clones do we have summoned + var/number_of_afterimages = 0 + +/datum/action/cooldown/spell/conjure/create_afterimages/can_cast_spell(feedback = TRUE) + . = ..() + if(!.) + return FALSE + if(number_of_afterimages >= max_afterimages) + return FALSE + return TRUE + +/datum/action/cooldown/spell/conjure/create_afterimages/post_summon(atom/summoned_object, atom/cast_on) + var/mob/living/basic/created_copy = summoned_object + created_copy.AddComponent(/datum/component/joint_damage, overlord_mob = owner) + RegisterSignals(created_copy, list(COMSIG_QDELETING, COMSIG_LIVING_DEATH), PROC_REF(delete_copy)) + number_of_afterimages++ + +/datum/action/cooldown/spell/conjure/create_afterimages/proc/delete_copy(mob/source) + SIGNAL_HANDLER + + UnregisterSignal(source, list(COMSIG_QDELETING, COMSIG_LIVING_DEATH)) + number_of_afterimages-- diff --git a/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon_ai.dm b/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon_ai.dm new file mode 100644 index 00000000000000..b17d5c1a30dd8b --- /dev/null +++ b/code/modules/mob/living/basic/icemoon/ice_demon/ice_demon_ai.dm @@ -0,0 +1,118 @@ +/datum/ai_controller/basic_controller/ice_demon + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, + BB_LIST_SCARY_ITEMS = list( + /obj/item/weldingtool, + /obj/item/flashlight/flare, + ), + BB_BASIC_MOB_FLEEING = TRUE, + BB_MINIMUM_DISTANCE_RANGE = 3, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/flee_target/ice_demon, + /datum/ai_planning_subtree/ranged_skirmish/ice_demon, + /datum/ai_planning_subtree/maintain_distance/cover_minimum_distance/ice_demon, + /datum/ai_planning_subtree/teleport_away_from_target, + /datum/ai_planning_subtree/find_and_hunt_target/teleport_destination, + /datum/ai_planning_subtree/targeted_mob_ability/summon_afterimages, + ) + + +/datum/ai_planning_subtree/maintain_distance/cover_minimum_distance/ice_demon + maximum_distance = 7 + +/datum/ai_planning_subtree/teleport_away_from_target + ability_key = BB_DEMON_TELEPORT_ABILITY + +/datum/ai_planning_subtree/find_and_hunt_target/teleport_destination + target_key = BB_TELEPORT_DESTINATION + hunting_behavior = /datum/ai_behavior/hunt_target/use_ability_on_target/demon_teleport + finding_behavior = /datum/ai_behavior/find_valid_teleport_location + hunt_targets = list(/turf/open) + hunt_range = 3 + finish_planning = FALSE + +/datum/ai_planning_subtree/find_and_hunt_target/teleport_destination/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if(!controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET)) + return + if(controller.blackboard_key_exists(BB_ESCAPE_DESTINATION)) + controller.clear_blackboard_key(BB_TELEPORT_DESTINATION) + return + var/datum/action/cooldown/ability = controller.blackboard[BB_DEMON_TELEPORT_ABILITY] + if(!ability?.IsAvailable()) + return + return ..() + +/datum/ai_behavior/find_valid_teleport_location + +/datum/ai_behavior/find_valid_teleport_location/perform(seconds_per_tick, datum/ai_controller/controller, hunting_target_key, types_to_hunt, hunt_range) + . = ..() + var/mob/living/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] + var/list/possible_turfs = list() + + if(QDELETED(target)) + finish_action(controller, FALSE) + return + + for(var/turf/open/potential_turf in oview(hunt_range, target)) //we check for turfs around the target + if(potential_turf.is_blocked_turf()) + continue + if(!can_see(target, potential_turf, hunt_range)) + continue + possible_turfs += potential_turf + + if(!length(possible_turfs)) + finish_action(controller, FALSE) + return + + controller.set_blackboard_key(hunting_target_key, pick(possible_turfs)) + finish_action(controller, TRUE) + +/datum/ai_behavior/hunt_target/use_ability_on_target/demon_teleport + hunt_cooldown = 2 SECONDS + ability_key = BB_DEMON_TELEPORT_ABILITY + behavior_flags = NONE + +/datum/ai_planning_subtree/targeted_mob_ability/summon_afterimages + ability_key = BB_DEMON_CLONE_ABILITY + +/datum/ai_planning_subtree/targeted_mob_ability/summon_afterimages/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/mob/living/living_pawn = controller.pawn + if(living_pawn.health / living_pawn.maxHealth > 0.5) //only use this ability when under half health + return + return ..() + +/datum/ai_planning_subtree/flee_target/ice_demon + +/datum/ai_planning_subtree/flee_target/ice_demon/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/atom/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] + if(QDELETED(target)) + return + if(!iscarbon(target)) + return + var/mob/living/carbon/human_target = target + + for(var/obj/held_item in human_target.held_items) + if(!is_type_in_list(held_item, controller.blackboard[BB_LIST_SCARY_ITEMS])) + continue + if(!held_item.light_on) + continue + var/datum/action/cooldown/slip_ability = controller.blackboard[BB_DEMON_SLIP_ABILITY] + if(slip_ability?.IsAvailable()) + controller.queue_behavior(/datum/ai_behavior/use_mob_ability, BB_DEMON_SLIP_ABILITY) + return ..() + +/datum/ai_planning_subtree/ranged_skirmish/ice_demon + min_range = 0 + +/datum/ai_controller/basic_controller/ice_demon/afterimage + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/flee_target/ice_demon, //even the afterimages are afraid of flames! + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + diff --git a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm index 292766be07bf90..f89009cc2d9a5c 100644 --- a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm +++ b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp.dm @@ -87,5 +87,5 @@ balloon_alert(src, "devouring...") if(!do_after(src, 5 SECONDS, target)) return - target.gib() + target.gib(DROP_ALL_REMAINS) adjustBruteLoss(-1 * heal_on_cannibalize) diff --git a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm index 5951bd6b7feb8e..47280af4281698 100644 --- a/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm +++ b/code/modules/mob/living/basic/icemoon/ice_whelp/ice_whelp_ai.dm @@ -13,53 +13,33 @@ /datum/ai_planning_subtree/attack_obstacle_in_path, /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/sculpt_statues, - /datum/ai_planning_subtree/find_and_hunt_target/cannibalize, + /datum/ai_planning_subtree/find_and_hunt_target/corpses/ice_whelp, /datum/ai_planning_subtree/burn_trees, ) - -/datum/ai_planning_subtree/find_and_hunt_target/cannibalize +/datum/ai_planning_subtree/find_and_hunt_target/corpses/ice_whelp target_key = BB_TARGET_CANNIBAL - hunting_behavior = /datum/ai_behavior/cannibalize - finding_behavior = /datum/ai_behavior/find_hunt_target/dragon_corpse + finding_behavior = /datum/ai_behavior/find_hunt_target/corpses/dragon_corpse + hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/dragon_cannibalise hunt_targets = list(/mob/living/basic/mining/ice_whelp) hunt_range = 10 -/datum/ai_behavior/find_hunt_target/dragon_corpse +/datum/ai_behavior/find_hunt_target/corpses/dragon_corpse -/datum/ai_behavior/find_hunt_target/dragon_corpse/valid_dinner(mob/living/source, mob/living/dinner, radius) - if(dinner.stat != DEAD) - return FALSE +/datum/ai_behavior/find_hunt_target/corpses/dragon_corpse/valid_dinner(mob/living/source, mob/living/dinner, radius) if(dinner.pulledby) //someone already got him before us return FALSE + return ..() - return can_see(source, dinner, radius) - -/datum/ai_behavior/cannibalize +/datum/ai_behavior/hunt_target/unarmed_attack_target/dragon_cannibalise behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION -/datum/ai_behavior/cannibalize/setup(datum/ai_controller/controller, target_key) - . = ..() - var/atom/target = controller.blackboard[target_key] - if(QDELETED(target)) - return FALSE - set_movement_target(controller, target) - -/datum/ai_behavior/cannibalize/perform(seconds_per_tick, datum/ai_controller/controller, target_key, attack_key) - . = ..() - var/mob/living/basic/living_pawn = controller.pawn +/datum/ai_behavior/hunt_target/unarmed_attack_target/dragon_cannibalise/perform(seconds_per_tick, datum/ai_controller/controller, target_key, attack_key) var/mob/living/target = controller.blackboard[target_key] - - if(QDELETED(target)) + if(QDELETED(target) || target.stat != DEAD || target.pulledby) //we were too slow finish_action(controller, FALSE) return - - if(target.stat != DEAD || target.pulledby) //we were too slow - finish_action(controller, FALSE) - return - - living_pawn.melee_attack(target) - finish_action(controller, TRUE) + return ..() /datum/ai_behavior/cannibalize/finish_action(datum/ai_controller/controller, succeeded, target_key) . = ..() diff --git a/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm b/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm index c88178135dc54c..8964ebf837ec18 100644 --- a/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm +++ b/code/modules/mob/living/basic/jungle/mega_arachnid/mega_arachnid_ai.dm @@ -1,7 +1,6 @@ /datum/ai_controller/basic_controller/mega_arachnid blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, - BB_BASIC_MOB_FLEEING = TRUE, BB_BASIC_MOB_FLEE_DISTANCE = 5, ) @@ -37,7 +36,7 @@ flee_behaviour = /datum/ai_behavior/run_away_from_target/mega_arachnid /datum/ai_planning_subtree/flee_target/mega_arachnid/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) - if(!controller.blackboard[BB_BASIC_MOB_FLEEING]) + if(controller.blackboard[BB_BASIC_MOB_STOP_FLEEING]) return var/datum/action/cooldown/slip_acid = controller.blackboard[BB_ARACHNID_SLIP] diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/basic/jungle/venus_human_trap.dm similarity index 62% rename from code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm rename to code/modules/mob/living/basic/jungle/venus_human_trap.dm index c489d6c888d4aa..a997a8d266b1a0 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/basic/jungle/venus_human_trap.dm @@ -120,13 +120,14 @@ * The result of a kudzu flower bud, these enemies use vines to drag prey close to them for attack. * * A carnivorious plant which uses vines to catch and ensnare prey. Spawns from kudzu flower buds. - * Each one has a maximum of four vines, which can be attached to a variety of things. Carbons are stunned when a vine is attached to them, and movable entities are pulled closer over time. + * Each one can attach up to two temporary vines to objects or mobs and drag them around with it. * Attempting to attach a vine to something with a vine already attached to it will pull all movable targets closer on command. * Once the prey is in melee range, melee attacks from the venus human trap heals itself for 10% of its max health, assuming the target is alive. * Akin to certain spiders, venus human traps can also be possessed and controlled by ghosts. * */ -/mob/living/simple_animal/hostile/venus_human_trap + +/mob/living/basic/venus_human_trap name = "venus human trap" desc = "Now you know how the fly feels." icon = 'icons/mob/spacevines.dmi' @@ -135,24 +136,21 @@ mob_biotypes = MOB_ORGANIC | MOB_PLANT layer = SPACEVINE_MOB_LAYER plane = GAME_PLANE_UPPER_FOV_HIDDEN - health = 50 - maxHealth = 50 - ranged = TRUE - harm_intent_damage = 5 + health = 100 + maxHealth = 100 obj_damage = 60 - melee_damage_lower = 20 + melee_damage_lower = 10 melee_damage_upper = 20 - minbodytemp = 100 + minimum_survivable_temperature = 100 combat_mode = TRUE - ranged_cooldown_time = 4 SECONDS - del_on_death = TRUE + basic_mob_flags = DEL_ON_DEATH death_message = "collapses into bits of plant matter." attacked_sound = 'sound/creatures/venus_trap_hurt.ogg' death_sound = 'sound/creatures/venus_trap_death.ogg' attack_sound = 'sound/creatures/venus_trap_hit.ogg' unsuitable_heat_damage = 5 // heat damage is different from cold damage since coldmos is significantly more common than plasmafires unsuitable_cold_damage = 2 // they now do take cold damage, but this should be sufficiently small that it does not cause major issues - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + habitable_atmos = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 0 /// copied over from the code from eyeballs (the mob) to make it easier for venus human traps to see in kudzu that doesn't have the transparency mutation sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS @@ -163,74 +161,82 @@ faction = list(FACTION_HOSTILE,FACTION_VINES,FACTION_PLANTS) initial_language_holder = /datum/language_holder/venus unique_name = TRUE - /// A list of all the plant's vines - var/list/vines = list() - /// The maximum amount of vines a plant can have at one time - var/max_vines = 4 - /// How far away a plant can attach a vine to something - var/vine_grab_distance = 5 - /// Whether or not this plant is ghost possessable - var/playable_plant = TRUE + speed = 1.2 + melee_attack_cooldown = 1.2 SECONDS + ai_controller = /datum/ai_controller/basic_controller/human_trap + ///how much damage we take out of weeds + var/no_weed_damage = 20 + ///how much do we heal in weeds + var/weed_heal = 10 + ///if the balloon alert was shown atleast once, reset after healing in weeds + var/alert_shown = FALSE -/mob/living/simple_animal/hostile/venus_human_trap/Life(seconds_per_tick = SSMOBS_DT, times_fired) +/mob/living/basic/venus_human_trap/Initialize(mapload) . = ..() - pull_vines() + AddElement(/datum/element/lifesteal, 5) + var/datum/action/cooldown/vine_tangle/tangle = new(src) + tangle.Grant(src) + ai_controller.set_blackboard_key(BB_TARGETTED_ACTION, tangle) -/mob/living/simple_animal/hostile/venus_human_trap/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) - . = ..() - pixel_x = base_pixel_x + (dir & (NORTH|WEST) ? 2 : -2) +/mob/living/basic/venus_human_trap/RangedAttack(atom/victim) + if(!combat_mode) + return + var/datum/action/cooldown/mob_cooldown/tangle_ability = ai_controller.blackboard[BB_TARGETTED_ACTION] + if(!istype(tangle_ability)) + return + tangle_ability.Trigger(target = victim) -/mob/living/simple_animal/hostile/venus_human_trap/AttackingTarget() +/mob/living/basic/venus_human_trap/Life(seconds_per_tick = SSMOBS_DT, times_fired) . = ..() - if(isliving(target)) - var/mob/living/L = target - if(L.stat != DEAD) - adjustHealth(-maxHealth * 0.1) - -/mob/living/simple_animal/hostile/venus_human_trap/OpenFire(atom/the_target) - for(var/datum/beam/B in vines) - if(B.target == the_target) - pull_vines() - ranged_cooldown = world.time + (ranged_cooldown_time * 0.5) - return - if(get_dist(src,the_target) > vine_grab_distance || vines.len >= max_vines) + if(!.) + return FALSE + + var/vines_in_range = locate(/obj/structure/spacevine) in range(2, src) + if(!vines_in_range && !alert_shown) + alert_shown = TRUE + balloon_alert(src, "do not leave vines!") + else if(vines_in_range) + alert_shown = FALSE + + apply_damage(vines_in_range ? weed_heal : no_weed_damage, BRUTE) //every life tick take 20 brute if not near vines or heal 10 if near vines, 5 times out of weeds = u ded + +/datum/action/cooldown/vine_tangle + name = "Tangle" + button_icon = 'icons/mob/spacevines.dmi' + button_icon_state = "Light1" + desc = "Grabs a target with a sticky vine, allowing you to pull it alongside you." + cooldown_time = 8 SECONDS + ///how many vines can we handle + var/max_vines = 2 + /// An assoc list of all the plant's vines (beam = leash) + var/list/datum/beam/vines = list() + /// How far away a plant can attach a vine to something + var/vine_grab_distance = 4 + /// how long does a vine attached to something last (and its leash) (lasts twice as long on nonliving things) + var/vine_duration = 2 SECONDS + +/datum/action/cooldown/vine_tangle/Remove(mob/remove_from) + QDEL_LIST(vines) + return ..() + +/datum/action/cooldown/vine_tangle/Activate(atom/target_atom) + if(isturf(target_atom) || istype(target_atom, /obj/structure/spacevine)) + return + if(length(vines) >= max_vines || get_dist(owner, target_atom) > vine_grab_distance) return - for(var/turf/T in get_line(src,target)) - if (T.density) + for(var/turf/blockage in get_line(owner, target_atom)) + if(blockage.is_blocked_turf(exclude_mobs = TRUE)) return - for(var/obj/O in T) - if(O.density) - return - - var/datum/beam/newVine = Beam(the_target, icon_state = "vine", maxdistance = vine_grab_distance, beam_type=/obj/effect/ebeam/vine, emissive = FALSE) - RegisterSignal(newVine, COMSIG_QDELETING, PROC_REF(remove_vine), newVine) - vines += newVine - if(isliving(the_target)) - var/mob/living/L = the_target - L.apply_damage(85, STAMINA, BODY_ZONE_CHEST) - L.Knockdown(1 SECONDS) - ranged_cooldown = world.time + ranged_cooldown_time - -/mob/living/simple_animal/hostile/venus_human_trap/Destroy() - for(var/datum/beam/vine as anything in vines) - qdel(vine) // reference is automatically deleted by remove_vine - return ..() -/** - * Manages how the vines should affect the things they're attached to. - * - * Pulls all movable targets of the vines closer to the plant - * If the target is on the same tile as the plant, destroy the vine - * Removes any QDELETED vines from the vines list. - */ -/mob/living/simple_animal/hostile/venus_human_trap/proc/pull_vines() - for(var/datum/beam/B in vines) - if(istype(B.target, /atom/movable)) - var/atom/movable/AM = B.target - if(!AM.anchored) - step(AM, get_dir(AM, src)) - if(get_dist(src, B.target) == 0) - qdel(B) + var/datum/beam/new_vine = owner.Beam(target_atom, icon_state = "vine", time = vine_duration * (ismob(target_atom) ? 1 : 2), beam_type = /obj/effect/ebeam/vine, emissive = FALSE) + var/component = target_atom.AddComponent(/datum/component/leash, owner, vine_grab_distance) + RegisterSignal(new_vine, COMSIG_QDELETING, PROC_REF(remove_vine), new_vine) + vines[new_vine] = component + if(isliving(target_atom)) + var/mob/living/victim = target_atom + victim.Knockdown(2 SECONDS) + StartCooldown() + return TRUE /** * Removes a vine from the list. @@ -240,9 +246,24 @@ * Arguments: * * datum/beam/vine - The vine to be removed from the list. */ -/mob/living/simple_animal/hostile/venus_human_trap/proc/remove_vine(datum/beam/vine) +/datum/action/cooldown/vine_tangle/proc/remove_vine(datum/beam/vine) SIGNAL_HANDLER + qdel(vines[vine]) vines -= vine +/datum/ai_controller/basic_controller/human_trap + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/targeted_mob_ability/continue_planning, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + #undef FINAL_BUD_GROWTH_ICON diff --git a/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_ai.dm b/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_ai.dm index 58efaf1f81b46f..fe1c4150315b04 100644 --- a/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_ai.dm +++ b/code/modules/mob/living/basic/lavaland/goldgrub/goldgrub_ai.dm @@ -3,7 +3,6 @@ BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends, BB_ORE_IGNORE_TYPES = list(/obj/item/stack/ore/iron, /obj/item/stack/ore/glass), - BB_BASIC_MOB_FLEEING = TRUE, BB_STORM_APPROACHING = FALSE, ) @@ -14,9 +13,9 @@ /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/dig_away_from_danger, /datum/ai_planning_subtree/flee_target, - /datum/ai_planning_subtree/find_and_hunt_target/consume_ores, + /datum/ai_planning_subtree/find_and_hunt_target/hunt_ores, /datum/ai_planning_subtree/find_and_hunt_target/baby_egg, - /datum/ai_planning_subtree/grub_mine, + /datum/ai_planning_subtree/mine_walls, ) /datum/ai_controller/basic_controller/babygrub @@ -25,7 +24,6 @@ BB_ORE_IGNORE_TYPES = list(/obj/item/stack/ore/glass), BB_FIND_MOM_TYPES = list(/mob/living/basic/mining/goldgrub), BB_IGNORE_MOM_TYPES = list(/mob/living/basic/mining/goldgrub/baby), - BB_BASIC_MOB_FLEEING = TRUE, BB_STORM_APPROACHING = FALSE, ) @@ -34,29 +32,29 @@ planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/dig_away_from_danger, - /datum/ai_planning_subtree/find_and_hunt_target/consume_ores, + /datum/ai_planning_subtree/find_and_hunt_target/hunt_ores, /datum/ai_planning_subtree/flee_target, /datum/ai_planning_subtree/look_for_adult, ) ///consume food! -/datum/ai_planning_subtree/find_and_hunt_target/consume_ores +/datum/ai_planning_subtree/find_and_hunt_target/hunt_ores target_key = BB_ORE_TARGET - hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/consume_ores - finding_behavior = /datum/ai_behavior/find_hunt_target/consume_ores + hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/hunt_ores + finding_behavior = /datum/ai_behavior/find_hunt_target/hunt_ores hunt_targets = list(/obj/item/stack/ore) hunt_chance = 75 hunt_range = 9 -/datum/ai_behavior/find_hunt_target/consume_ores +/datum/ai_behavior/find_hunt_target/hunt_ores -/datum/ai_behavior/find_hunt_target/consume_ores/valid_dinner(mob/living/basic/source, obj/item/stack/ore/target, radius) +/datum/ai_behavior/find_hunt_target/hunt_ores/valid_dinner(mob/living/basic/source, obj/item/stack/ore/target, radius) var/list/forbidden_ore = source.ai_controller.blackboard[BB_ORE_IGNORE_TYPES] if(is_type_in_list(target, forbidden_ore)) return FALSE - if(target in source) + if(!isturf(target.loc)) return FALSE var/obj/item/pet_target = source.ai_controller.blackboard[BB_CURRENT_PET_TARGET] @@ -65,7 +63,7 @@ return can_see(source, target, radius) -/datum/ai_behavior/hunt_target/unarmed_attack_target/consume_ores +/datum/ai_behavior/hunt_target/unarmed_attack_target/hunt_ores always_reset_target = TRUE ///find our child's egg and pull it! @@ -123,45 +121,6 @@ /datum/ai_behavior/use_mob_ability/burrow behavior_flags = AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION -///mine walls to look for food! -/datum/ai_planning_subtree/grub_mine - -/datum/ai_planning_subtree/grub_mine/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) - if(controller.blackboard_key_exists(BB_TARGET_MINERAL_WALL)) - controller.queue_behavior(/datum/ai_behavior/mine_wall, BB_TARGET_MINERAL_WALL) - return SUBTREE_RETURN_FINISH_PLANNING - controller.queue_behavior(/datum/ai_behavior/find_mineral_wall, BB_TARGET_MINERAL_WALL) - -/datum/ai_behavior/mine_wall - behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_REQUIRE_REACH | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION - action_cooldown = 15 SECONDS - -/datum/ai_behavior/mine_wall/setup(datum/ai_controller/controller, target_key) - . = ..() - var/turf/target = controller.blackboard[target_key] - if(isnull(target)) - return FALSE - set_movement_target(controller, target) - -/datum/ai_behavior/mine_wall/perform(seconds_per_tick, datum/ai_controller/controller, target_key) - . = ..() - var/mob/living/basic/living_pawn = controller.pawn - var/turf/closed/mineral/target = controller.blackboard[target_key] - var/is_gibtonite_turf = istype(target, /turf/closed/mineral/gibtonite) - if(QDELETED(target)) - finish_action(controller, FALSE, target_key) - return - living_pawn.melee_attack(target) - if(is_gibtonite_turf) - living_pawn.manual_emote("sighs...") //accept whats about to happen to us - - finish_action(controller, TRUE, target_key) - return - -/datum/ai_behavior/mine_wall/finish_action(datum/ai_controller/controller, success, target_key) - . = ..() - controller.clear_blackboard_key(target_key) - /datum/pet_command/grub_spit command_name = "Spit" command_desc = "Ask your grub pet to spit out its ores." diff --git a/code/modules/mob/living/basic/lavaland/hivelord/hivelord.dm b/code/modules/mob/living/basic/lavaland/hivelord/hivelord.dm index 256ab1fbd8f861..11043e58d11ead 100644 --- a/code/modules/mob/living/basic/lavaland/hivelord/hivelord.dm +++ b/code/modules/mob/living/basic/lavaland/hivelord/hivelord.dm @@ -102,7 +102,7 @@ /mob/living/basic/hivelord_brood/Initialize(mapload) . = ..() - add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE), INNATE_TRAIT) + add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE, TRAIT_PERMANENTLY_MORTAL), INNATE_TRAIT) AddElement(/datum/element/simple_flying) AddComponent(/datum/component/swarming) AddComponent(/datum/component/clickbox, icon_state = "hivelord", max_scale = INFINITY) diff --git a/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm b/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm index 6b3525cb32ab68..cbadd709047a31 100644 --- a/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm +++ b/code/modules/mob/living/basic/lavaland/legion/legion_ai.dm @@ -2,7 +2,6 @@ /datum/ai_controller/basic_controller/legion blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/attack_until_dead/legion, - BB_BASIC_MOB_FLEEING = TRUE, BB_AGGRO_RANGE = 5, // Unobservant BB_BASIC_MOB_FLEE_DISTANCE = 6, ) diff --git a/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm b/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm index bc21bd0e506c90..962d232c5ef842 100644 --- a/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm +++ b/code/modules/mob/living/basic/lavaland/legion/legion_brood.dm @@ -34,7 +34,7 @@ /mob/living/basic/legion_brood/Initialize(mapload) . = ..() - add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE), INNATE_TRAIT) + add_traits(list(TRAIT_LAVA_IMMUNE, TRAIT_ASHSTORM_IMMUNE, TRAIT_PERMANENTLY_MORTAL), INNATE_TRAIT) AddElement(/datum/element/simple_flying) AddComponent(/datum/component/swarming) AddComponent(/datum/component/clickbox, icon_state = "sphere", max_scale = 2) diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm index 18cd73219362e9..a048fe77ab146a 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity.dm @@ -28,8 +28,6 @@ ai_controller = /datum/ai_controller/basic_controller/lobstrosity /// Charging ability var/datum/action/cooldown/mob_cooldown/charge/basic_charge/lobster/charge - /// Limbs we will cut off an unconscious man - var/static/list/target_limbs = list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM) /// Things we will eat if we see them (arms, chiefly) var/static/list/target_foods = list(/obj/item/bodypart/arm) @@ -41,8 +39,8 @@ AddElement(/datum/element/basic_eating, food_types = target_foods) AddElement(\ /datum/element/amputating_limbs,\ - surgery_verb = "snipping",\ - target_zones = target_limbs,\ + surgery_verb = "begins snipping",\ + target_zones = GLOB.arm_zones,\ ) charge = new(src) charge.Grant(src) @@ -76,7 +74,7 @@ var/mob/living/basic/basic_source = source var/mob/living/living_target = target basic_source.melee_attack(living_target, ignore_cooldown = TRUE) - basic_source.ai_controller?.set_blackboard_key(BB_BASIC_MOB_FLEEING, FALSE) + basic_source.ai_controller?.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, TRUE) basic_source.start_pulling(living_target) /datum/action/cooldown/mob_cooldown/charge/basic_charge/lobster/do_charge(atom/movable/charger, atom/target_atom, delay, past) diff --git a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm index 8e4dfe9e29463f..7b6926fca04e7f 100644 --- a/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm +++ b/code/modules/mob/living/basic/lavaland/lobstrosity/lobstrosity_ai.dm @@ -2,7 +2,6 @@ blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/lobster, BB_LOBSTROSITY_EXPLOIT_TRAITS = list(TRAIT_INCAPACITATED, TRAIT_FLOORED, TRAIT_IMMOBILIZED, TRAIT_KNOCKEDOUT), - BB_BASIC_MOB_FLEEING = TRUE, BB_LOBSTROSITY_FINGER_LUST = 0 ) @@ -26,7 +25,7 @@ melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/lobster /datum/ai_planning_subtree/basic_melee_attack_subtree/lobster/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) - if (controller.blackboard[BB_BASIC_MOB_FLEEING]) + if (!controller.blackboard[BB_BASIC_MOB_STOP_FLEEING]) return if (!isnull(controller.blackboard[BB_LOBSTROSITY_TARGET_LIMB])) return @@ -48,8 +47,8 @@ is_vulnerable = TRUE break if (!is_vulnerable) - controller.set_blackboard_key(BB_BASIC_MOB_FLEEING, TRUE) - if (controller.blackboard[BB_BASIC_MOB_FLEEING]) + controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, FALSE) + if (!controller.blackboard[BB_BASIC_MOB_STOP_FLEEING]) finish_action(controller = controller, succeeded = TRUE, target_key = target_key) // We don't want to clear our target return return ..() @@ -57,6 +56,12 @@ /datum/ai_planning_subtree/flee_target/lobster flee_behaviour = /datum/ai_behavior/run_away_from_target/lobster +/datum/ai_planning_subtree/flee_target/lobster/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/datum/action/cooldown/using_action = controller.blackboard[BB_TARGETTED_ACTION] + if (using_action?.IsAvailable()) + return + return ..() + /datum/ai_behavior/run_away_from_target/lobster clear_failed_targets = FALSE @@ -64,10 +69,11 @@ var/atom/target = controller.blackboard[target_key] if(isnull(target)) return ..() + for (var/trait in controller.blackboard[BB_LOBSTROSITY_EXPLOIT_TRAITS]) if (!HAS_TRAIT(target, trait)) continue - controller.set_blackboard_key(BB_BASIC_MOB_FLEEING, FALSE) + controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, TRUE) finish_action(controller, succeeded = FALSE) return diff --git a/code/modules/mob/living/basic/lavaland/mook/mook.dm b/code/modules/mob/living/basic/lavaland/mook/mook.dm new file mode 100644 index 00000000000000..da833437715c64 --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/mook/mook.dm @@ -0,0 +1,273 @@ +//Fragile but highly aggressive wanderers that pose a large threat in numbers. +//They'll attempt to leap at their target from afar using their hatchets. +/mob/living/basic/mining/mook + name = "wanderer" + desc = "This unhealthy looking primitive seems to be talented at administiring health care." + icon = 'icons/mob/simple/jungle/mook.dmi' + icon_state = "mook" + icon_living = "mook" + icon_dead = "mook_dead" + mob_biotypes = MOB_ORGANIC|MOB_HUMANOID + gender = FEMALE + maxHealth = 150 + faction = list(FACTION_MINING, FACTION_NEUTRAL) + health = 150 + move_resist = MOVE_FORCE_OVERPOWERING + melee_damage_lower = 8 + melee_damage_upper = 8 + pass_flags_self = LETPASSTHROW + attack_sound = 'sound/weapons/rapierhit.ogg' + attack_vis_effect = ATTACK_EFFECT_SLASH + death_sound = 'sound/voice/mook_death.ogg' + ai_controller = /datum/ai_controller/basic_controller/mook/support + speed = 5 + + pixel_x = -16 + base_pixel_x = -16 + pixel_y = -16 + base_pixel_y = -16 + + ///the state of combat we are in + var/attack_state = MOOK_ATTACK_NEUTRAL + ///are we a healer? + var/is_healer = TRUE + ///the ore we are holding if any + var/obj/held_ore + ///overlay for neutral stance + var/mutable_appearance/neutral_stance + ///overlay for attacking stance + var/mutable_appearance/attack_stance + ///overlay when we hold an ore + var/mutable_appearance/ore_overlay + ///commands we obey + var/list/pet_commands = list( + /datum/pet_command/idle, + /datum/pet_command/free, + /datum/pet_command/point_targetting/attack, + /datum/pet_command/point_targetting/fetch, + ) + +/mob/living/basic/mining/mook/Initialize(mapload) + . = ..() + AddComponent(/datum/component/ai_retaliate_advanced, CALLBACK(src, PROC_REF(attack_intruder))) + var/datum/action/cooldown/mob_cooldown/mook_ability/mook_jump/jump = new(src) + jump.Grant(src) + ai_controller.set_blackboard_key(BB_MOOK_JUMP_ABILITY, jump) + + ore_overlay = mutable_appearance(icon, "mook_ore_overlay") + + AddComponent(/datum/component/ai_listen_to_weather) + AddElement(/datum/element/wall_smasher) + RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(pre_attack)) + RegisterSignal(src, COMSIG_KB_MOB_DROPITEM_DOWN, PROC_REF(drop_ore)) + + if(is_healer) + grant_healer_abilities() + + AddComponent(/datum/component/obeys_commands, pet_commands) + +/mob/living/basic/mining/mook/proc/grant_healer_abilities() + AddComponent(\ + /datum/component/healing_touch,\ + heal_brute = melee_damage_upper,\ + heal_burn = melee_damage_upper,\ + heal_time = 0,\ + valid_targets_typecache = typecacheof(list(/mob/living/basic/mining/mook)),\ + ) + +/mob/living/basic/mining/mook/Entered(atom/movable/mover) + if(istype(mover, /obj/item/stack/ore)) + held_ore = mover + update_appearance(UPDATE_OVERLAYS) + + return ..() + +/mob/living/basic/mining/mook/Exited(atom/movable/mover) + . = ..() + if(held_ore != mover) + return + held_ore = null + update_appearance(UPDATE_OVERLAYS) + +/mob/living/basic/mining/mook/proc/pre_attack(mob/living/attacker, atom/target) + SIGNAL_HANDLER + + return attack_sequence(target) + +/mob/living/basic/mining/mook/proc/attack_sequence(atom/target) + if(istype(target, /obj/item/stack/ore) && isnull(held_ore)) + var/obj/item/ore_target = target + ore_target.forceMove(src) + return COMPONENT_HOSTILE_NO_ATTACK + + if(istype(target, /obj/structure/material_stand)) + if(held_ore) + held_ore.forceMove(target) + return COMPONENT_HOSTILE_NO_ATTACK + + if(istype(target, /obj/structure/bonfire)) + var/obj/structure/bonfire/fire_target = target + if(!fire_target.burning) + fire_target.start_burning() + return COMPONENT_HOSTILE_NO_ATTACK + +/mob/living/basic/mining/mook/proc/change_combatant_state(state) + attack_state = state + update_appearance() + +/mob/living/basic/mining/mook/Destroy() + QDEL_NULL(held_ore) + return ..() + +/mob/living/basic/mining/mook/update_icon_state() + . = ..() + if(stat == DEAD) + return + switch(attack_state) + if(MOOK_ATTACK_NEUTRAL) + icon_state = "mook" + if(MOOK_ATTACK_WARMUP) + icon_state = "mook_warmup" + if(MOOK_ATTACK_ACTIVE) + icon_state = "mook_leap" + if(MOOK_ATTACK_STRIKE) + icon_state = "mook_strike" + +/mob/living/basic/mining/mook/update_overlays() + . = ..() + if(stat == DEAD) + return + + if(attack_state != MOOK_ATTACK_NEUTRAL || isnull(held_ore)) + return + + . += ore_overlay + +/mob/living/basic/mining/mook/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback, force, gentle = FALSE, quickstart = TRUE) + change_combatant_state(state = MOOK_ATTACK_ACTIVE) + return ..() + +/mob/living/basic/mining/mook/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + . = ..() + change_combatant_state(state = MOOK_ATTACK_NEUTRAL) + +/mob/living/basic/mining/mook/CanAllowThrough(atom/movable/mover, border_dir) + . = ..() + + if(!istype(mover, /mob/living/basic/mining/mook)) + return FALSE + + var/mob/living/basic/mining/mook/mook_moover = mover + if(mook_moover.attack_state == MOOK_ATTACK_ACTIVE) + return TRUE + +/mob/living/basic/mining/mook/proc/drop_ore(mob/living/user) + SIGNAL_HANDLER + + if(isnull(held_ore)) + return + dropItemToGround(held_ore) + return COMSIG_KB_ACTIVATED + +/mob/living/basic/mining/mook/death() + desc = "A deceased primitive. Upon closer inspection, it was suffering from severe cellular degeneration and its garments are machine made..." //Can you guess the twist + return ..() + +/mob/living/basic/mining/mook/proc/attack_intruder(mob/living/intruder) + if(istype(intruder, /mob/living/basic/mining/mook)) + return + for(var/mob/living/basic/mining/mook/villager in oview(src, 9)) + villager.ai_controller?.insert_blackboard_key_lazylist(BB_BASIC_MOB_RETALIATE_LIST, intruder) + + +/mob/living/basic/mining/mook/worker + desc = "This unhealthy looking primitive is wielding a rudimentary hatchet, swinging it with wild abandon. One isn't much of a threat, but in numbers they can quickly overwhelm a superior opponent." + gender = MALE + melee_damage_lower = 15 + melee_damage_upper = 15 + ai_controller = /datum/ai_controller/basic_controller/mook + is_healer = FALSE + +/mob/living/basic/mining/mook/worker/Initialize(mapload) + . = ..() + neutral_stance = mutable_appearance(icon, "mook_axe_overlay") + attack_stance = mutable_appearance(icon, "axe_strike_overlay") + update_appearance() + var/datum/action/cooldown/mob_cooldown/mook_ability/mook_leap/leap = new(src) + leap.Grant(src) + ai_controller.set_blackboard_key(BB_MOOK_LEAP_ABILITY, leap) + +/mob/living/basic/mining/mook/worker/attack_sequence(atom/target) + . = ..() + if(. & COMPONENT_HOSTILE_NO_ATTACK) + return + + if(attack_state == MOOK_ATTACK_STRIKE) + return COMPONENT_HOSTILE_NO_ATTACK + + change_combatant_state(state = MOOK_ATTACK_STRIKE) + addtimer(CALLBACK(src, PROC_REF(change_combatant_state), MOOK_ATTACK_NEUTRAL), 0.3 SECONDS) + +/mob/living/basic/mining/mook/worker/update_overlays() + . = ..() + if(stat == DEAD) + return + + switch(attack_state) + if(MOOK_ATTACK_STRIKE) + . += attack_stance + if(MOOK_ATTACK_NEUTRAL) + . += neutral_stance + +/mob/living/basic/mining/mook/worker/bard + desc = "It's holding a guitar?" + melee_damage_lower = 10 + melee_damage_upper = 10 + gender = MALE + attack_sound = 'sound/weapons/stringsmash.ogg' + death_sound = 'sound/voice/mook_death.ogg' + ai_controller = /datum/ai_controller/basic_controller/mook/bard + ///our guitar + var/obj/item/instrument/guitar/held_guitar + +/mob/living/basic/mining/mook/worker/bard/Initialize(mapload) + . = ..() + neutral_stance = mutable_appearance(icon, "bard_overlay") + attack_stance = mutable_appearance(icon, "bard_strike") + held_guitar = new(src) + ai_controller.set_blackboard_key(BB_SONG_INSTRUMENT, held_guitar) + update_appearance() + +/mob/living/basic/mining/mook/worker/tribal_chief + name = "tribal chief" + desc = "Acknowledge him!" + gender = MALE + melee_damage_lower = 20 + melee_damage_upper = 20 + ai_controller = /datum/ai_controller/basic_controller/mook/tribal_chief + ///overlay in our neutral state + var/static/mutable_appearance/chief_neutral = mutable_appearance('icons/mob/simple/jungle/mook.dmi', "mook_chief") + ///overlay in our striking state + var/static/mutable_appearance/chief_strike = mutable_appearance('icons/mob/simple/jungle/mook.dmi', "mook_chief_strike") + ///overlay in our active state + var/static/mutable_appearance/chief_active = mutable_appearance('icons/mob/simple/jungle/mook.dmi', "mook_chief_leap") + ///overlay in our warmup state + var/static/mutable_appearance/chief_warmup = mutable_appearance('icons/mob/simple/jungle/mook.dmi', "mook_chief_warmup") + +/mob/living/basic/mining/mook/worker/tribal_chief/Initialize(mapload) + . = ..() + update_appearance() + +/mob/living/basic/mining/mook/worker/tribal_chief/update_overlays() + . = ..() + if(stat == DEAD) + return + switch(attack_state) + if(MOOK_ATTACK_NEUTRAL) + . += chief_neutral + if(MOOK_ATTACK_WARMUP) + . += chief_warmup + if(MOOK_ATTACK_ACTIVE) + . += chief_active + if(MOOK_ATTACK_STRIKE) + . += chief_strike diff --git a/code/modules/mob/living/basic/lavaland/mook/mook_abilities.dm b/code/modules/mob/living/basic/lavaland/mook/mook_abilities.dm new file mode 100644 index 00000000000000..cfc359bd54fccb --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/mook/mook_abilities.dm @@ -0,0 +1,140 @@ +/datum/action/cooldown/mob_cooldown/mook_ability + ///are we a mook? + var/is_mook = FALSE + +/datum/action/cooldown/mob_cooldown/mook_ability/Grant(mob/grant_to) + . = ..() + if(isnull(owner)) + return + is_mook = istype(owner, /mob/living/basic/mining/mook) + +/datum/action/cooldown/mob_cooldown/mook_ability/IsAvailable(feedback) + . = ..() + + if(!.) + return FALSE + + if(!is_mook) + return TRUE + + var/mob/living/basic/mining/mook/mook_owner = owner + if(mook_owner.attack_state != MOOK_ATTACK_NEUTRAL) + if(feedback) + mook_owner.balloon_alert(mook_owner, "still recovering!") + return FALSE + return TRUE + +/datum/action/cooldown/mob_cooldown/mook_ability/mook_leap + name = "Mook leap" + desc = "Leap towards the enemy!" + cooldown_time = 7 SECONDS + shared_cooldown = NONE + melee_cooldown_time = 0 SECONDS + ///telegraph time before jumping + var/wind_up_time = 2 SECONDS + ///intervals between each of our attacks + var/attack_interval = 0.4 SECONDS + ///how many times do we attack if we reach the target? + var/times_to_attack = 4 + +/datum/action/cooldown/mob_cooldown/mook_ability/mook_leap/Activate(atom/target) + if(owner.CanReach(target)) + attack_combo(target) + StartCooldown() + return TRUE + + if(is_mook) + var/mob/living/basic/mining/mook/mook_owner = owner + mook_owner.change_combatant_state(state = MOOK_ATTACK_WARMUP) + + addtimer(CALLBACK(src, PROC_REF(launch_towards_target), target), wind_up_time) + StartCooldown() + return TRUE + +/datum/action/cooldown/mob_cooldown/mook_ability/mook_leap/proc/launch_towards_target(atom/target) + new /obj/effect/temp_visual/mook_dust(get_turf(owner)) + playsound(get_turf(owner), 'sound/weapons/thudswoosh.ogg', 25, TRUE) + playsound(owner, 'sound/voice/mook_leap_yell.ogg', 100, TRUE) + var/turf/target_turf = get_turf(target) + + if(!target_turf.is_blocked_turf()) + owner.throw_at(target = target_turf, range = 7, speed = 1, spin = FALSE, callback = CALLBACK(src, PROC_REF(attack_combo), target)) + return + + var/list/open_turfs = list() + + for(var/turf/possible_turf in get_adjacent_open_turfs(target)) + if(possible_turf.is_blocked_turf()) + continue + open_turfs += possible_turf + + if(!length(open_turfs)) + return + + var/turf/final_turf = get_closest_atom(/turf, open_turfs, owner) + owner.throw_at(target = final_turf, range = 7, speed = 1, spin = FALSE, callback = CALLBACK(src, PROC_REF(attack_combo), target)) + +/datum/action/cooldown/mob_cooldown/mook_ability/mook_leap/proc/attack_combo(atom/target) + if(!owner.CanReach(target)) + return FALSE + + for(var/i in 0 to (times_to_attack - 1)) + addtimer(CALLBACK(src, PROC_REF(attack_target), target), i * attack_interval) + +/datum/action/cooldown/mob_cooldown/mook_ability/mook_leap/proc/attack_target(atom/target) + if(!owner.CanReach(target) || owner.stat == DEAD) + return + var/mob/living/basic/basic_owner = owner + basic_owner.melee_attack(target, ignore_cooldown = TRUE) + +/datum/action/cooldown/mob_cooldown/mook_ability/mook_jump + name = "Mook Jump" + desc = "Soar high in the air!" + cooldown_time = 14 SECONDS + shared_cooldown = NONE + melee_cooldown_time = 0 SECONDS + click_to_activate = FALSE + +/datum/action/cooldown/mob_cooldown/mook_ability/mook_jump/Activate(atom/target) + var/obj/effect/landmark/drop_zone = locate(/obj/effect/landmark/mook_village) in GLOB.landmarks_list + if(drop_zone?.z == owner.z) + var/turf/jump_destination = get_turf(drop_zone) + jump_to_turf(jump_destination) + StartCooldown() + return TRUE + var/list/potential_turfs = list() + for(var/turf/open_turf in oview(9, owner)) + if(!open_turf.is_blocked_turf()) + potential_turfs += open_turf + if(!length(potential_turfs)) + return FALSE + jump_to_turf(pick(potential_turfs)) + StartCooldown() + return TRUE + +/datum/action/cooldown/mob_cooldown/mook_ability/mook_jump/proc/jump_to_turf(turf/target) + if(is_mook) + var/mob/living/basic/mining/mook/mook_owner = owner + mook_owner.change_combatant_state(state = MOOK_ATTACK_ACTIVE) + new /obj/effect/temp_visual/mook_dust(get_turf(owner)) + playsound(get_turf(owner), 'sound/weapons/thudswoosh.ogg', 50, TRUE) + animate(owner, pixel_y = owner.base_pixel_y + 146, time = 0.5 SECONDS) + addtimer(CALLBACK(src, PROC_REF(land_on_turf), target), 0.5 SECONDS) + +/datum/action/cooldown/mob_cooldown/mook_ability/mook_jump/proc/land_on_turf(turf/target) + do_teleport(owner, target, precision = 3, no_effects = TRUE) + animate(owner, pixel_y = owner.base_pixel_y, time = 0.5 SECONDS) + new /obj/effect/temp_visual/mook_dust(get_turf(owner)) + if(is_mook) + addtimer(CALLBACK(owner, TYPE_PROC_REF(/mob/living/basic/mining/mook, change_combatant_state), MOOK_ATTACK_NEUTRAL), 0.5 SECONDS) + +/obj/effect/temp_visual/mook_dust + name = "dust" + desc = "It's just a dust cloud!" + icon = 'icons/mob/simple/jungle/mook.dmi' + icon_state = "mook_leap_cloud" + layer = BELOW_MOB_LAYER + plane = GAME_PLANE + base_pixel_y = -16 + base_pixel_x = -16 + duration = 1 SECONDS diff --git a/code/modules/mob/living/basic/lavaland/mook/mook_ai.dm b/code/modules/mob/living/basic/lavaland/mook/mook_ai.dm new file mode 100644 index 00000000000000..14ed9eb2982936 --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/mook/mook_ai.dm @@ -0,0 +1,426 @@ +///commands the chief can pick from +GLOBAL_LIST_INIT(mook_commands, list( + new /datum/pet_command/point_targetting/attack, + new /datum/pet_command/point_targetting/fetch, +)) + +/datum/ai_controller/basic_controller/mook + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/mook, + BB_BLACKLIST_MINERAL_TURFS = list(/turf/closed/mineral/gibtonite, /turf/closed/mineral/strong), + BB_MAXIMUM_DISTANCE_TO_VILLAGE = 7, + BB_STORM_APPROACHING = FALSE, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + planning_subtrees = list( + /datum/ai_planning_subtree/target_retaliate, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/look_for_village, + /datum/ai_planning_subtree/targeted_mob_ability/leap, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + /datum/ai_planning_subtree/find_and_hunt_target/material_stand, + /datum/ai_planning_subtree/use_mob_ability/mook_jump, + /datum/ai_planning_subtree/find_and_hunt_target/hunt_ores/mook, + /datum/ai_planning_subtree/mine_walls/mook, + /datum/ai_planning_subtree/wander_away_from_village, + ) + +///check for faction if not a ash walker, otherwise just attack +/datum/targetting_datum/basic/mook/faction_check(mob/living/living_mob, mob/living/the_target) + if(FACTION_ASHWALKER in living_mob.faction) + return FALSE + + return ..() + +/datum/ai_planning_subtree/targeted_mob_ability/leap + ability_key = BB_MOOK_LEAP_ABILITY + +/datum/ai_planning_subtree/use_mob_ability/mook_jump + ability_key = BB_MOOK_JUMP_ABILITY + +///jump towards the village when we have found ore or there is a storm coming +/datum/ai_planning_subtree/use_mob_ability/mook_jump/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/storm_approaching = controller.blackboard[BB_STORM_APPROACHING] + var/mob/living/living_pawn = controller.pawn + var/obj/effect/home = controller.blackboard[BB_HOME_VILLAGE] + if(QDELETED(home)) + return + if(get_dist(living_pawn, home) < controller.blackboard[BB_MAXIMUM_DISTANCE_TO_VILLAGE]) + return + if(home.z != living_pawn.z) + return + if(!storm_approaching && !(locate(/obj/item/stack/ore) in living_pawn)) + return + + controller.clear_blackboard_key(BB_TARGET_MINERAL_WALL) + return ..() + +///hunt ores that we will haul off back to the village +/datum/ai_planning_subtree/find_and_hunt_target/hunt_ores/mook + +/datum/ai_planning_subtree/find_and_hunt_target/hunt_ores/mook/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/mob/living/living_pawn = controller.pawn + if(locate(/obj/item/stack/ore) in living_pawn) + return + return ..() + +///deposit ores into the stand! +/datum/ai_planning_subtree/find_and_hunt_target/material_stand + target_key = BB_MATERIAL_STAND_TARGET + hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/material_stand + finding_behavior = /datum/ai_behavior/find_hunt_target + hunt_targets = list(/obj/structure/material_stand) + hunt_range = 9 + +/datum/ai_planning_subtree/find_and_hunt_target/material_stand/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/mob/living/living_pawn = controller.pawn + if(!locate(/obj/item/stack/ore) in living_pawn) + return + return ..() + +/datum/ai_behavior/hunt_target/unarmed_attack_target/material_stand + required_distance = 0 + always_reset_target = TRUE + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT + +///try to face the counter when depositing ores +/datum/ai_behavior/hunt_target/unarmed_attack_target/material_stand/setup(datum/ai_controller/controller, hunting_target_key, hunting_cooldown_key) + . = ..() + var/atom/hunt_target = controller.blackboard[hunting_target_key] + if (QDELETED(hunt_target)) + return FALSE + var/list/possible_turfs = list() + var/list/directions = list(SOUTH, SOUTHEAST) + + for(var/direction in directions) + var/turf/bottom_turf = get_step(hunt_target, direction) + if(!bottom_turf.is_blocked_turf()) + possible_turfs += bottom_turf + + if(!length(possible_turfs)) + return FALSE + set_movement_target(controller, pick(possible_turfs)) + +///look for our village +/datum/ai_planning_subtree/look_for_village + +/datum/ai_planning_subtree/look_for_village/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if(controller.blackboard_key_exists(BB_HOME_VILLAGE)) + return + + controller.queue_behavior(/datum/ai_behavior/find_village, BB_HOME_VILLAGE) + +/datum/ai_behavior/find_village + +/datum/ai_behavior/find_village/perform(seconds_per_tick, datum/ai_controller/controller, village_key) + . = ..() + + var/obj/effect/landmark/home_marker = locate(/obj/effect/landmark/mook_village) in GLOB.landmarks_list + if(isnull(home_marker)) + finish_action(controller, FALSE) + return + + controller.set_blackboard_key(village_key, home_marker) + finish_action(controller, TRUE) + +///explore the lands away from the village to look for ore +/datum/ai_planning_subtree/wander_away_from_village + +/datum/ai_planning_subtree/wander_away_from_village/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/mob/living/living_pawn = controller.pawn + var/storm_approaching = controller.blackboard[BB_STORM_APPROACHING] + ///if we have ores to deposit or a storm is approaching, dont wander away + if(storm_approaching || (locate(/obj/item/stack/ore) in living_pawn)) + return + + if(controller.blackboard_key_exists(BB_HOME_VILLAGE)) + controller.queue_behavior(/datum/ai_behavior/wander, BB_HOME_VILLAGE) + +/datum/ai_behavior/wander + behavior_flags = AI_BEHAVIOR_REQUIRE_MOVEMENT | AI_BEHAVIOR_CAN_PLAN_DURING_EXECUTION + required_distance = 0 + /// distance we will wander away from the village + var/wander_distance = 9 + +/datum/ai_behavior/wander/setup(datum/ai_controller/controller, village_key) + . = ..() + var/mob/living/living_pawn = controller.pawn + var/obj/effect/target = controller.blackboard[village_key] + if(QDELETED(target)) + return FALSE + + if(target.z != living_pawn.z) + return FALSE + + var/list/angle_directions = list() + for(var/direction in GLOB.alldirs) + angle_directions += dir2angle(direction) + + var/angle_to_home = get_angle(living_pawn, target) + angle_directions -= angle_to_home + angle_directions -= (angle_to_home + 45) + angle_directions -= (angle_to_home - 45) + shuffle_inplace(angle_directions) + + var/turf/wander_destination = get_turf(living_pawn) + for(var/angle in angle_directions) + var/turf/test_turf = get_furthest_turf(living_pawn, angle, target) + if(isnull(test_turf)) + continue + var/distance_from_target = get_dist(target, test_turf) + if(distance_from_target <= get_dist(target, wander_destination)) + continue + wander_destination = test_turf + if(distance_from_target == wander_distance) + break + + set_movement_target(controller, wander_destination) + +/datum/ai_behavior/wander/proc/get_furthest_turf(atom/source, angle, atom/target) + var/turf/return_turf + for(var/i in 1 to wander_distance) + var/turf/test_destination = get_ranged_target_turf_direct(source, target, range = i, offset = angle) + if(test_destination.is_blocked_turf(source_atom = source)) + break + return_turf = test_destination + return return_turf + +/datum/ai_behavior/wander/perform(seconds_per_tick, datum/ai_controller/controller, target_key, hiding_location_key) + . = ..() + finish_action(controller, TRUE) + +/datum/ai_planning_subtree/mine_walls/mook + find_wall_behavior = /datum/ai_behavior/find_mineral_wall/mook + +/datum/ai_planning_subtree/mine_walls/mook/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/mob/living/living_pawn = controller.pawn + var/storm_approaching = controller.blackboard[BB_STORM_APPROACHING] + if(storm_approaching || locate(/obj/item/stack/ore) in living_pawn) + return + return ..() + +/datum/ai_behavior/find_mineral_wall/mook + +/datum/ai_behavior/find_mineral_wall/mook/check_if_mineable(datum/ai_controller/controller, turf/target_wall) + var/list/forbidden_turfs = controller.blackboard[BB_BLACKLIST_MINERAL_TURFS] + if(is_type_in_list(target_wall, forbidden_turfs)) + return FALSE + return ..() + +///bard mook plays nice music for the village +/datum/ai_controller/basic_controller/mook/bard + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/mook, + BB_MAXIMUM_DISTANCE_TO_VILLAGE = 10, + BB_STORM_APPROACHING = FALSE, + BB_SONG_LINES = MOOK_SONG, + ) + idle_behavior = /datum/idle_behavior/walk_near_target/mook_village + planning_subtrees = list( + /datum/ai_planning_subtree/target_retaliate, + /datum/ai_planning_subtree/look_for_village, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + /datum/ai_planning_subtree/play_music_for_visitor, + /datum/ai_planning_subtree/use_mob_ability/mook_jump, + /datum/ai_planning_subtree/generic_play_instrument, + ) + + +///find an audience to follow and play music for! +/datum/ai_planning_subtree/play_music_for_visitor + +/datum/ai_planning_subtree/play_music_for_visitor/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if(!controller.blackboard_key_exists(BB_MOOK_MUSIC_AUDIENCE)) + controller.queue_behavior(/datum/ai_behavior/find_and_set/music_audience, BB_MOOK_MUSIC_AUDIENCE, /mob/living/carbon/human) + return + var/atom/home = controller.blackboard[BB_HOME_VILLAGE] + if(isnull(home)) + return + + var/atom/human_target = controller.blackboard[BB_MOOK_MUSIC_AUDIENCE] + if(get_dist(human_target, home) > controller.blackboard[BB_MAXIMUM_DISTANCE_TO_VILLAGE] || controller.blackboard[BB_STORM_APPROACHING]) + controller.clear_blackboard_key(BB_MOOK_MUSIC_AUDIENCE) + return + + controller.queue_behavior(/datum/ai_behavior/travel_towards, BB_MOOK_MUSIC_AUDIENCE) + +/datum/ai_behavior/find_and_set/music_audience + +/datum/ai_behavior/find_and_set/music_audience/search_tactic(datum/ai_controller/controller, locate_path, search_range) + var/atom/home = controller.blackboard[BB_HOME_VILLAGE] + for(var/mob/living/carbon/human/target in oview(search_range, controller.pawn)) + if(target.stat > UNCONSCIOUS || !target.mind) + continue + if(isnull(home) || get_dist(target, home) > controller.blackboard[BB_MAXIMUM_DISTANCE_TO_VILLAGE]) + continue + return target + +/datum/idle_behavior/walk_near_target/mook_village + target_key = BB_HOME_VILLAGE + +///healer mooks guard the village from intruders and heal the miner mooks when they come home +/datum/ai_controller/basic_controller/mook/support + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/mook, + BB_MAXIMUM_DISTANCE_TO_VILLAGE = 10, + BB_STORM_APPROACHING = FALSE, + BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends, + ) + idle_behavior = /datum/idle_behavior/walk_near_target/mook_village + planning_subtrees = list( + /datum/ai_planning_subtree/target_retaliate, + /datum/ai_planning_subtree/look_for_village, + /datum/ai_planning_subtree/acknowledge_chief, + /datum/ai_planning_subtree/pet_planning, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/use_mob_ability/mook_jump, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + /datum/ai_planning_subtree/find_and_hunt_target/injured_mooks, + ) + +///tree to find and register our leader +/datum/ai_planning_subtree/acknowledge_chief/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if(controller.blackboard_key_exists(BB_MOOK_TRIBAL_CHIEF)) + return + controller.queue_behavior(/datum/ai_behavior/find_and_set/find_chief, BB_MOOK_TRIBAL_CHIEF, /mob/living/basic/mining/mook/worker/tribal_chief) + +/datum/ai_behavior/find_and_set/find_chief/search_tactic(datum/ai_controller/controller, locate_path, search_range) + var/mob/living/chief = locate(locate_path) in oview(search_range, controller.pawn) + if(isnull(chief)) + return null + var/mob/living/living_pawn = controller.pawn + living_pawn.befriend(chief) + return chief + +///find injured miner mooks after they come home from a long day of work +/datum/ai_planning_subtree/find_and_hunt_target/injured_mooks + target_key = BB_INJURED_MOOK + hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/injured_mooks + finding_behavior = /datum/ai_behavior/find_hunt_target/injured_mooks + hunt_targets = list(/mob/living/basic/mining/mook/worker) + hunt_range = 9 + +///we only heal when the mooks are home during a storm +/datum/ai_planning_subtree/find_and_hunt_target/injured_mooks/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if(controller.blackboard[BB_STORM_APPROACHING]) + return ..() + + +/datum/ai_behavior/find_hunt_target/injured_mooks + +/datum/ai_behavior/find_hunt_target/injured_mooks/valid_dinner(mob/living/source, mob/living/injured_mook) + return (injured_mook.health < injured_mook.maxHealth) + +/datum/ai_behavior/hunt_target/unarmed_attack_target/injured_mooks + +/datum/ai_behavior/hunt_target/unarmed_attack_target/injured_mooks + always_reset_target = TRUE + hunt_cooldown = 10 SECONDS + + +///the chief would rather command his mooks to attack people than attack them himself +/datum/ai_controller/basic_controller/mook/tribal_chief + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/mook, + BB_STORM_APPROACHING = FALSE, + ) + idle_behavior = /datum/idle_behavior/walk_near_target/mook_village + planning_subtrees = list( + /datum/ai_planning_subtree/target_retaliate, + /datum/ai_planning_subtree/look_for_village, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/targeted_mob_ability/leap, + /datum/ai_planning_subtree/issue_commands, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + /datum/ai_planning_subtree/find_and_hunt_target/material_stand, + /datum/ai_planning_subtree/use_mob_ability/mook_jump, + /datum/ai_planning_subtree/find_and_hunt_target/bonfire, + /datum/ai_planning_subtree/find_and_hunt_target/hunt_ores/tribal_chief, + ) + +/datum/ai_planning_subtree/issue_commands + ///how far we look for a mook to command + var/command_distance = 5 + +/datum/ai_planning_subtree/issue_commands/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + if(!locate(/mob/living/basic/mining/mook) in oview(command_distance, controller.pawn)) + return + if(controller.blackboard_key_exists(BB_BASIC_MOB_CURRENT_TARGET)) + controller.queue_behavior(/datum/ai_behavior/issue_commands, BB_BASIC_MOB_CURRENT_TARGET, /datum/pet_command/point_targetting/attack) + return + + var/atom/ore_target = controller.blackboard[BB_ORE_TARGET] + var/mob/living/living_pawn = controller.pawn + if(isnull(ore_target)) + return + if(get_dist(ore_target, living_pawn) <= 1) + return + + controller.queue_behavior(/datum/ai_behavior/issue_commands, BB_ORE_TARGET, /datum/pet_command/point_targetting/fetch) + +/datum/ai_behavior/issue_commands + action_cooldown = 5 SECONDS + +/datum/ai_behavior/issue_commands/perform(seconds_per_tick, datum/ai_controller/controller, target_key, command_path) + . = ..() + var/mob/living/basic/living_pawn = controller.pawn + var/atom/target = controller.blackboard[target_key] + + if(isnull(target)) + finish_action(controller, FALSE) + return + + var/datum/pet_command/to_command = locate(command_path) in GLOB.mook_commands + if(isnull(to_command)) + finish_action(controller, FALSE) + return + + var/issue_command = pick(to_command.speech_commands) + living_pawn.say(issue_command, forced = "controller") + living_pawn._pointed(target) + finish_action(controller, TRUE) + + +///find an ore, only pick it up when a mook brings it close to us +/datum/ai_planning_subtree/find_and_hunt_target/hunt_ores/tribal_chief + +/datum/ai_planning_subtree/find_and_hunt_target/hunt_ores/tribal_chief/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) + var/mob/living/living_pawn = controller.pawn + if(locate(/obj/item/stack/ore) in living_pawn) + return + + var/atom/target_ore = controller.blackboard[BB_ORE_TARGET] + + if(isnull(target_ore)) + return ..() + + if(!isturf(target_ore.loc)) //picked up by someone else + controller.clear_blackboard_key(BB_ORE_TARGET) + return + + if(get_dist(target_ore, living_pawn) > 1) + return + + return ..() + +/datum/ai_planning_subtree/find_and_hunt_target/bonfire + target_key = BB_MOOK_BONFIRE_TARGET + finding_behavior = /datum/ai_behavior/find_hunt_target/bonfire + hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/bonfire + hunt_targets = list(/obj/structure/bonfire) + hunt_range = 9 + + +/datum/ai_behavior/find_hunt_target/bonfire + +/datum/ai_behavior/find_hunt_target/bonfire/valid_dinner(mob/living/source, obj/structure/bonfire/fire, radius) + if(fire.burning) + return FALSE + + return can_see(source, fire, radius) + +/datum/ai_behavior/hunt_target/unarmed_attack_target/bonfire + always_reset_target = TRUE diff --git a/code/modules/mob/living/basic/lavaland/mook/mook_village.dm b/code/modules/mob/living/basic/lavaland/mook/mook_village.dm new file mode 100644 index 00000000000000..e3a091f6f0e49f --- /dev/null +++ b/code/modules/mob/living/basic/lavaland/mook/mook_village.dm @@ -0,0 +1,85 @@ +///unique items that spawn at the mook village +/obj/structure/material_stand + name = "material stand" + desc = "Is everyone free to use this thing?" + icon = 'icons/mob/simple/jungle/mook.dmi' + icon_state = "material_stand" + density = TRUE + anchored = TRUE + resistance_flags = INDESTRUCTIBLE + bound_width = 64 + bound_height = 64 + +/obj/structure/material_stand/attackby(obj/item/ore, mob/living/carbon/human/user, list/modifiers) + if(istype(ore, /obj/item/stack/ore)) + ore.forceMove(src) + return + return ..() + +/obj/structure/material_stand/Entered(atom/movable/mover) + . = ..() + update_appearance(UPDATE_OVERLAYS) + +/obj/structure/material_stand/Exited(atom/movable/mover) + . = ..() + update_appearance(UPDATE_OVERLAYS) + +///put ore icons on the counter! +/obj/structure/material_stand/update_overlays() + . = ..() + for(var/obj/item/stack/ore/ore_item in contents) + var/image/ore_icon = image(icon = initial(ore_item.icon), icon_state = initial(ore_item.icon_state), layer = LOW_ITEM_LAYER) + ore_icon.transform = ore_icon.transform.Scale(0.6, 0.6) + ore_icon.pixel_x = rand(9, 17) + ore_icon.pixel_y = rand(2, 4) + . += ore_icon + +/obj/structure/material_stand/ui_interact(mob/user, datum/tgui/ui) + . = ..() + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "MaterialStand") + ui.open() + +/obj/structure/material_stand/ui_data(mob/user) + var/list/data = list() + data["ores"] = list() + for(var/obj/item/stack/ore/ore_item in contents) + data["ores"] += list(list( + "id" = REF(ore_item), + "name" = ore_item.name, + "amount" = ore_item.amount, + )) + return data + +/obj/structure/material_stand/ui_static_data(mob/user) + var/list/data = list() + data["ore_images"] = list() + for(var/obj/item/stack/ore_item as anything in subtypesof(/obj/item/stack/ore)) + data["ore_images"] += list(list( + "name" = initial(ore_item.name), + "icon" = icon2base64(getFlatIcon(image(icon = initial(ore_item.icon), icon_state = initial(ore_item.icon_state)), no_anim=TRUE)) + )) + return data + +/obj/structure/material_stand/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + + if(. || !isliving(usr)) + return TRUE + + var/mob/living/customer = usr + var/obj/item/stack_to_move + switch(action) + if("withdraw") + if(isnull(params["reference"])) + return TRUE + stack_to_move = locate(params["reference"]) in contents + if(isnull(stack_to_move)) + return TRUE + stack_to_move.forceMove(get_turf(customer)) + return TRUE + +/obj/effect/landmark/mook_village + name = "mook village landmark" + icon_state = "x" diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm index a25234817f31e6..348bbcfcaa7d00 100644 --- a/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm +++ b/code/modules/mob/living/basic/lavaland/watcher/watcher_ai.dm @@ -27,13 +27,10 @@ return ..() /datum/ai_planning_subtree/ranged_skirmish/watcher - attack_behavior = /datum/ai_behavior/ranged_skirmish/watcher + min_range = 0 /datum/ai_planning_subtree/ranged_skirmish/watcher/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) var/mob/living/target = controller.blackboard[BB_BASIC_MOB_CURRENT_TARGET] if (QDELETED(target) || HAS_TRAIT(target, TRAIT_OVERWATCHED)) return // Don't bully people who are playing red light green light return ..() - -/datum/ai_behavior/ranged_skirmish/watcher - min_range = 0 diff --git a/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm b/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm index 9426db41cca60d..4b322c220ed3ec 100644 --- a/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm +++ b/code/modules/mob/living/basic/lavaland/watcher/watcher_gaze.dm @@ -12,6 +12,7 @@ check_flags = AB_CHECK_CONSCIOUS | AB_CHECK_INCAPACITATED click_to_activate = FALSE shared_cooldown = NONE + melee_cooldown_time = 0 SECONDS /// At what range do we check for vision? var/effect_radius = 7 /// How long does it take to play our various animation stages diff --git a/code/modules/mob/living/basic/minebots/minebot_ai.dm b/code/modules/mob/living/basic/minebots/minebot_ai.dm index a4b082f5dd1bbb..33e9821dbc4bbe 100644 --- a/code/modules/mob/living/basic/minebots/minebot_ai.dm +++ b/code/modules/mob/living/basic/minebots/minebot_ai.dm @@ -12,7 +12,7 @@ /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/pet_planning, /datum/ai_planning_subtree/basic_ranged_attack_subtree/minebot, - /datum/ai_planning_subtree/find_and_hunt_target/consume_ores/minebot, + /datum/ai_planning_subtree/find_and_hunt_target/hunt_ores/minebot, /datum/ai_planning_subtree/minebot_mining, /datum/ai_planning_subtree/locate_dead_humans, ) @@ -133,11 +133,11 @@ controller.clear_blackboard_key(target_key) ///store ores in our body -/datum/ai_planning_subtree/find_and_hunt_target/consume_ores/minebot +/datum/ai_planning_subtree/find_and_hunt_target/hunt_ores/minebot hunting_behavior = /datum/ai_behavior/hunt_target/unarmed_attack_target/consume_ores/minebot hunt_chance = 100 -/datum/ai_planning_subtree/find_and_hunt_target/consume_ores/minebot/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) +/datum/ai_planning_subtree/find_and_hunt_target/hunt_ores/minebot/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) var/automated_mining = controller.blackboard[BB_AUTOMATED_MINING] var/mob/living/living_pawn = controller.pawn diff --git a/code/modules/mob/living/basic/pets/dog/corgi.dm b/code/modules/mob/living/basic/pets/dog/corgi.dm index cb0df08d198b9e..9e120c4e8c038a 100644 --- a/code/modules/mob/living/basic/pets/dog/corgi.dm +++ b/code/modules/mob/living/basic/pets/dog/corgi.dm @@ -482,7 +482,7 @@ prey.investigate_log("has been sacrificed by [src].", INVESTIGATE_DEATHS) if (isliving(prey)) var/mob/living/living_sacrifice = prey - living_sacrifice.gib() + living_sacrifice.gib(DROP_ALL_REMAINS) else qdel(prey) diff --git a/code/modules/mob/living/basic/pets/fox.dm b/code/modules/mob/living/basic/pets/fox.dm index 578a64ba08dd89..f7a86be1e5cfb6 100644 --- a/code/modules/mob/living/basic/pets/fox.dm +++ b/code/modules/mob/living/basic/pets/fox.dm @@ -38,7 +38,6 @@ /datum/ai_controller/basic_controller/fox blackboard = list( - BB_BASIC_MOB_FLEEING = TRUE, BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/of_size/ours_or_smaller/ignore_faction, BB_FLEE_TARGETTING_DATUM = new /datum/targetting_datum/basic/ignore_faction ) diff --git a/code/modules/mob/living/basic/pets/sloth.dm b/code/modules/mob/living/basic/pets/sloth.dm new file mode 100644 index 00000000000000..5058e7d53344d3 --- /dev/null +++ b/code/modules/mob/living/basic/pets/sloth.dm @@ -0,0 +1,97 @@ +GLOBAL_DATUM(cargo_sloth, /mob/living/basic/sloth) + +/mob/living/basic/sloth + name = "sloth" + desc = "An adorable, sleepy creature." + icon = 'icons/mob/simple/pets.dmi' + icon_state = "sloth" + icon_living = "sloth" + icon_dead = "sloth_dead" + + speak_emote = list("yawns") + + can_be_held = TRUE + held_state = "sloth" + + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + response_harm_continuous = "kicks" + response_harm_simple = "kick" + + attack_verb_continuous = "bites" + attack_verb_simple = "bite" + attack_sound = 'sound/weapons/bite.ogg' + attack_vis_effect = ATTACK_EFFECT_BITE + + mob_biotypes = MOB_ORGANIC|MOB_BEAST + gold_core_spawnable = FRIENDLY_SPAWN + + melee_damage_lower = 18 + melee_damage_upper = 18 + health = 50 + maxHealth = 50 + speed = 10 // speed is fucking weird man. they aren't fast though don't worry + butcher_results = list(/obj/item/food/meat/slab = 3) + + ai_controller = /datum/ai_controller/basic_controller/sloth + +/mob/living/basic/sloth/Initialize(mapload) + . = ..() + AddElement(/datum/element/pet_bonus, "slowly smiles!") + AddElement(/datum/element/footstep, footstep_type = FOOTSTEP_MOB_CLAW) + AddElement(/datum/element/ai_retaliate) + AddComponent(/datum/component/tree_climber) + + if(!mapload || isnull(GLOB.cargo_sloth) || !is_station_level(z)) + return + + // If someone adds non-cargo sloths to maps we'll have a problem but we're fine for now + GLOB.cargo_sloth = src + +/mob/living/basic/sloth/Destroy() + if(GLOB.cargo_sloth == src) + GLOB.cargo_sloth = null + + return ..() + +/mob/living/basic/sloth/paperwork + name = "Paperwork" + desc = "Cargo's pet sloth. About as useful as the rest of the techs." + gender = MALE + gold_core_spawnable = NO_SPAWN + +/mob/living/basic/sloth/citrus + name = "Citrus" + desc = "Cargo's pet sloth. She's dressed in a horrible sweater." + icon_state = "cool_sloth" + icon_living = "cool_sloth" + icon_dead = "cool_sloth_dead" + gender = FEMALE + butcher_results = list(/obj/item/toy/spinningtoy = 1) + gold_core_spawnable = NO_SPAWN + +/// They're really passive in game, so they just wanna get away if you start smacking them. No trees in space from them to use for clawing your eyes out, but they will try if desperate. +/datum/ai_controller/basic_controller/sloth + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/ignore_faction, + BB_BASIC_MOB_FLEEING = TRUE, + BB_FLEE_TARGETTING_DATUM = new /datum/targetting_datum/basic/ignore_faction, + ) + + ai_traits = STOP_MOVING_WHEN_PULLED + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + + planning_subtrees = list( + /datum/ai_planning_subtree/target_retaliate/to_flee, + /datum/ai_planning_subtree/flee_target/from_flee_key, + /datum/ai_planning_subtree/climb_trees, + /datum/ai_planning_subtree/random_speech/sloth, + ) + +/datum/ai_planning_subtree/random_speech/sloth + speech_chance = 1 + emote_hear = list("snores.", "yawns.") + emote_see = list("dozes off.", "looks around sleepily.") diff --git a/code/modules/mob/living/basic/space_fauna/bear/_bear.dm b/code/modules/mob/living/basic/space_fauna/bear/_bear.dm index 414f28a1e9af55..924cf854276d18 100644 --- a/code/modules/mob/living/basic/space_fauna/bear/_bear.dm +++ b/code/modules/mob/living/basic/space_fauna/bear/_bear.dm @@ -42,7 +42,7 @@ /mob/living/basic/bear/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_SPACEWALK, INNATE_TRAIT) + add_traits(list(TRAIT_SPACEWALK, TRAIT_FENCE_CLIMBER), INNATE_TRAIT) AddElement(/datum/element/ai_retaliate) AddComponent(/datum/component/tree_climber, climbing_distance = 15) AddElement(/datum/element/swabable, CELL_LINE_TABLE_BEAR, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm index d220325ca15f51..fc6997896b0d27 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp_ai_rift_actions.dm @@ -31,7 +31,7 @@ finish_planning = TRUE /datum/ai_planning_subtree/make_carp_rift/panic_teleport/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick) - if (!controller.blackboard[BB_BASIC_MOB_FLEEING]) + if (controller.blackboard[BB_BASIC_MOB_STOP_FLEEING]) return return ..() diff --git a/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm b/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm index b30970145352bc..503264c3dc2a68 100644 --- a/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm +++ b/code/modules/mob/living/basic/space_fauna/carp/carp_controllers.dm @@ -9,6 +9,7 @@ */ /datum/ai_controller/basic_controller/carp blackboard = list( + BB_BASIC_MOB_STOP_FLEEING = TRUE, BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/allow_items(), BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends() ) @@ -35,6 +36,7 @@ */ /datum/ai_controller/basic_controller/carp/pet blackboard = list( + BB_BASIC_MOB_STOP_FLEEING = TRUE, BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/ignore_faction(), BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends() ) @@ -78,6 +80,7 @@ */ /datum/ai_controller/basic_controller/carp/passive blackboard = list( + BB_BASIC_MOB_STOP_FLEEING = TRUE, BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/ignore_faction(), BB_PET_TARGETTING_DATUM = new /datum/targetting_datum/not_friends() ) diff --git a/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm b/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm new file mode 100644 index 00000000000000..c73b008d6b48b6 --- /dev/null +++ b/code/modules/mob/living/basic/space_fauna/changeling/flesh_spider.dm @@ -0,0 +1,75 @@ +/** + * Spider-esque mob summoned by changelings. Exclusively player-controlled. + * An independent hit-and-run antagonist which can make webs and heals itself if left undamaged for a few seconds. + * Not a spider subtype because it keeps getting hit by unrelated balance changes intended for the Giant Spiders gamemode. + */ +/mob/living/basic/flesh_spider + name = "flesh spider" + desc = "A odd fleshy creature in the shape of a spider. Its eyes are pitch black and soulless." + icon = 'icons/mob/simple/arachnoid.dmi' + icon_state = "flesh" + icon_living = "flesh" + icon_dead = "flesh_dead" + mob_biotypes = MOB_ORGANIC|MOB_BUG + speak_emote = list("chitters") + response_help_continuous = "pets" + response_help_simple = "pet" + response_disarm_continuous = "gently pushes aside" + response_disarm_simple = "gently push aside" + damage_coeff = list(BRUTE = 1, BURN = 1.25, TOX = 1, CLONE = 1, STAMINA = 1, OXY = 1) + basic_mob_flags = FLAMMABLE_MOB + status_flags = NONE + speed = -0.1 + maxHealth = 90 + health = 90 + melee_damage_lower = 15 + melee_damage_upper = 20 + obj_damage = 30 + melee_attack_cooldown = CLICK_CD_MELEE + attack_verb_continuous = "bites" + attack_verb_simple = "bite" + attack_sound = 'sound/weapons/bite.ogg' + attack_vis_effect = ATTACK_EFFECT_BITE + unsuitable_cold_damage = 4 + unsuitable_heat_damage = 4 + combat_mode = TRUE + faction = list() // No allies but yourself + pass_flags = PASSTABLE + unique_name = TRUE + lighting_cutoff_red = 22 + lighting_cutoff_green = 5 + lighting_cutoff_blue = 5 + butcher_results = list(/obj/item/food/meat/slab/spider = 2, /obj/item/food/spiderleg = 8) + ai_controller = /datum/ai_controller/basic_controller/giant_spider + +/mob/living/basic/flesh_spider/Initialize(mapload) + . = ..() + ADD_TRAIT(src, TRAIT_WEB_SURFER, INNATE_TRAIT) + AddElement(/datum/element/cliff_walking) + AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) + AddElement(/datum/element/venomous, /datum/reagent/toxin/hunterspider, 5) + AddElement(/datum/element/web_walker, /datum/movespeed_modifier/fast_web) + AddElement(/datum/element/nerfed_pulling, GLOB.typecache_general_bad_things_to_easily_move) + AddElement(/datum/element/prevent_attacking_of_types, GLOB.typecache_general_bad_hostile_attack_targets, "this tastes awful!") + AddComponent(\ + /datum/component/blood_walk,\ + blood_type = /obj/effect/decal/cleanable/blood/bubblegum,\ + blood_spawn_chance = 5,\ + ) + AddComponent(\ + /datum/component/regenerator,\ + regeneration_delay = 4 SECONDS,\ + health_per_second = maxHealth / 6,\ + outline_colour = COLOR_PINK,\ + ) + + var/datum/action/cooldown/mob_cooldown/lay_web/webbing = new(src) + webbing.webbing_time *= 0.7 + webbing.Grant(src) + ai_controller?.set_blackboard_key(BB_SPIDER_WEB_ACTION, webbing) + + var/datum/action/cooldown/mob_cooldown/lay_web/web_spikes/spikes_web = new(src) + spikes_web.Grant(src) + + var/datum/action/cooldown/mob_cooldown/lay_web/sticky_web/web_sticky = new(src) + web_sticky.Grant(src) diff --git a/code/modules/mob/living/basic/space_fauna/headslug.dm b/code/modules/mob/living/basic/space_fauna/changeling/headslug.dm similarity index 100% rename from code/modules/mob/living/basic/space_fauna/headslug.dm rename to code/modules/mob/living/basic/space_fauna/changeling/headslug.dm diff --git a/code/modules/mob/living/basic/space_fauna/demon/demon.dm b/code/modules/mob/living/basic/space_fauna/demon/demon.dm index c2d8c751cde901..741ac27712f8f4 100644 --- a/code/modules/mob/living/basic/space_fauna/demon/demon.dm +++ b/code/modules/mob/living/basic/space_fauna/demon/demon.dm @@ -32,6 +32,7 @@ obj_damage = 40 melee_damage_lower = 10 melee_damage_upper = 15 + melee_attack_cooldown = CLICK_CD_MELEE death_message = "screams in agony as it sublimates into a sulfurous smoke." death_sound = 'sound/magic/demon_dies.ogg' diff --git a/code/modules/mob/living/basic/space_fauna/morph.dm b/code/modules/mob/living/basic/space_fauna/morph.dm index 3f31f7f3735ac8..32115d05602551 100644 --- a/code/modules/mob/living/basic/space_fauna/morph.dm +++ b/code/modules/mob/living/basic/space_fauna/morph.dm @@ -21,6 +21,7 @@ obj_damage = 50 melee_damage_lower = 20 melee_damage_upper = 20 + melee_attack_cooldown = CLICK_CD_MELEE // Oh you KNOW it's gonna be real green lighting_cutoff_red = 10 diff --git a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm index 85369b72eb8cbd..164c25fb896d2f 100644 --- a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm +++ b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat.dm @@ -24,6 +24,7 @@ obj_damage = 10 melee_damage_lower = 13 melee_damage_upper = 15 + melee_attack_cooldown = CLICK_CD_MELEE attack_verb_continuous = "slashes" attack_verb_simple = "slash" attack_sound = 'sound/weapons/bladeslice.ogg' diff --git a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm index 7a30f88b4c27b4..e617ae0a670af5 100644 --- a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm +++ b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_actions.dm @@ -221,31 +221,31 @@ taste_description = "something funny" overdose_threshold = 20 -/datum/reagent/rat_spit/on_mob_metabolize(mob/living/L) - ..() - if(HAS_TRAIT(L, TRAIT_AGEUSIA)) +/datum/reagent/rat_spit/on_mob_metabolize(mob/living/affected_mob) + . = ..() + if(HAS_TRAIT(affected_mob, TRAIT_AGEUSIA)) return - to_chat(L, span_notice("This food has a funny taste!")) + to_chat(affected_mob, span_notice("This food has a funny taste!")) -/datum/reagent/rat_spit/overdose_start(mob/living/M) - ..() - var/mob/living/carbon/victim = M +/datum/reagent/rat_spit/overdose_start(mob/living/affected_mob) + . = ..() + var/mob/living/carbon/victim = affected_mob if (istype(victim) && !(FACTION_RAT in victim.faction)) to_chat(victim, span_userdanger("With this last sip, you feel your body convulsing horribly from the contents you've ingested. As you contemplate your actions, you sense an awakened kinship with rat-kind and their newly risen leader!")) victim.faction |= FACTION_RAT victim.vomit(VOMIT_CATEGORY_DEFAULT) metabolization_rate = 10 * REAGENTS_METABOLISM -/datum/reagent/rat_spit/on_mob_life(mob/living/carbon/C) +/datum/reagent/rat_spit/on_mob_life(mob/living/carbon/affected_mob) + . = ..() if(prob(15)) - to_chat(C, span_notice("You feel queasy!")) - C.adjust_disgust(3) + to_chat(affected_mob, span_notice("You feel queasy!")) + affected_mob.adjust_disgust(3) else if(prob(10)) - to_chat(C, span_warning("That food does not sit up well!")) - C.adjust_disgust(5) + to_chat(affected_mob, span_warning("That food does not sit up well!")) + affected_mob.adjust_disgust(5) else if(prob(5)) - C.vomit(VOMIT_CATEGORY_DEFAULT) - return ..() + affected_mob.vomit(VOMIT_CATEGORY_DEFAULT) /datum/pet_command/protect_owner/glockroach protect_behavior = /datum/ai_behavior/basic_ranged_attack/glockroach diff --git a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_ai.dm b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_ai.dm index ef92c7b3b76b1e..97dbdbd0a7d047 100644 --- a/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_ai.dm +++ b/code/modules/mob/living/basic/space_fauna/regal_rat/regal_rat_ai.dm @@ -1,7 +1,6 @@ /datum/ai_controller/basic_controller/regal_rat blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, - BB_BASIC_MOB_FLEEING = TRUE, BB_FLEE_TARGETTING_DATUM = new /datum/targetting_datum/basic/ignore_faction, ) diff --git a/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm new file mode 100644 index 00000000000000..b3c6935c92efe4 --- /dev/null +++ b/code/modules/mob/living/basic/space_fauna/revenant/_revenant.dm @@ -0,0 +1,444 @@ +/// Source for a trait we get when we're stunned +#define REVENANT_STUNNED_TRAIT "revenant_got_stunned" + +/// Revenants: "Ghosts" that are invisible and move like ghosts, cannot take damage while invisible +/// Can hear deadchat, but are NOT normal ghosts and do NOT have x-ray vision +/// Admin-spawn or random event +/mob/living/basic/revenant + name = "revenant" + desc = "A malevolent spirit." + icon = 'icons/mob/simple/mob.dmi' + icon_state = "revenant_idle" + mob_biotypes = MOB_SPIRIT + incorporeal_move = INCORPOREAL_MOVE_JAUNT + invisibility = INVISIBILITY_REVENANT + health = INFINITY //Revenants don't use health, they use essence instead + maxHealth = INFINITY + plane = GHOST_PLANE + sight = SEE_SELF + throwforce = 0 + + // Going for faint purple spoopy ghost + lighting_cutoff_red = 20 + lighting_cutoff_green = 15 + lighting_cutoff_blue = 35 + + friendly_verb_continuous = "touches" + friendly_verb_simple = "touch" + response_help_continuous = "passes through" + response_help_simple = "pass through" + response_disarm_continuous = "swings through" + response_disarm_simple = "swing through" + response_harm_continuous = "punches through" + response_harm_simple = "punch through" + unsuitable_atmos_damage = 0 + damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) //I don't know how you'd apply those, but revenants no-sell them anyway. + habitable_atmos = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + minimum_survivable_temperature = 0 + maximum_survivable_temperature = INFINITY + + status_flags = NONE + density = FALSE + move_resist = MOVE_FORCE_OVERPOWERING + mob_size = MOB_SIZE_TINY + pass_flags = PASSTABLE | PASSGRILLE | PASSMOB + speed = 1 + unique_name = TRUE + hud_possible = list(ANTAG_HUD) + hud_type = /datum/hud/revenant + + /// The icon we use while just floating around. + var/icon_idle = "revenant_idle" + /// The icon we use while in a revealed state. + var/icon_reveal = "revenant_revealed" + /// The icon we use when stunned (temporarily frozen) + var/icon_stun = "revenant_stun" + /// The icon we use while draining someone. + var/icon_drain = "revenant_draining" + + /// Are we currently dormant (ectoplasm'd)? + var/dormant = FALSE + /// Are we currently draining someone? + var/draining = FALSE + /// Have we already given this revenant abilities? + var/generated_objectives_and_spells = FALSE + + /// Lazylist of drained mobs to ensure that we don't steal a soul from someone twice + var/list/drained_mobs = null + /// List of action ability datums to grant on Initialize. Keep in mind that anything with the `/aoe/revenant` subtype starts locked by default. + var/static/list/datum/action/abilities = list( + /datum/action/cooldown/spell/aoe/revenant/blight, + /datum/action/cooldown/spell/aoe/revenant/defile, + /datum/action/cooldown/spell/aoe/revenant/haunt_object, + /datum/action/cooldown/spell/aoe/revenant/malfunction, + /datum/action/cooldown/spell/aoe/revenant/overload, + /datum/action/cooldown/spell/list_target/telepathy/revenant, + ) + + /// The resource, and health, of revenants. + var/essence = 75 + /// The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount. + var/max_essence = 75 + /// If the revenant regenerates essence or not + var/essence_regenerating = TRUE + /// How much essence regenerates per second + var/essence_regen_amount = 2.5 + /// How much essence the revenant has stolen + var/essence_accumulated = 0 + /// How much stolen essence is available for unlocks + var/essence_excess = 0 + /// How long the revenant is revealed for, is about 2 seconds times this var. + var/unreveal_time = 0 + /// How many perfect, regen-cap increasing souls the revenant has. //TODO, add objective for getting a perfect soul(s?) + var/perfectsouls = 0 + +/mob/living/basic/revenant/Initialize(mapload) + . = ..() + AddElement(/datum/element/simple_flying) + add_traits(list(TRAIT_SPACEWALK, TRAIT_SIXTHSENSE, TRAIT_FREE_HYPERSPACE_MOVEMENT), INNATE_TRAIT) + + for(var/ability in abilities) + var/datum/action/spell = new ability(src) + spell.Grant(src) + + RegisterSignal(src, COMSIG_LIVING_BANED, PROC_REF(on_baned)) + RegisterSignal(src, COMSIG_MOVABLE_PRE_MOVE, PROC_REF(on_move)) + RegisterSignal(src, COMSIG_LIVING_LIFE, PROC_REF(on_life)) + set_random_revenant_name() + + GLOB.revenant_relay_mobs |= src + +/mob/living/basic/revenant/Destroy() + GLOB.revenant_relay_mobs -= src + return ..() + +/mob/living/basic/revenant/Login() + . = ..() + if(!. || isnull(client)) + return FALSE + + var/static/cached_string = null + if(isnull(cached_string)) + cached_string = examine_block(jointext(create_login_string(), "\n")) + + to_chat(src, cached_string, type = MESSAGE_TYPE_INFO) + + if(generated_objectives_and_spells) + return TRUE + + generated_objectives_and_spells = TRUE + mind.set_assigned_role(SSjob.GetJobType(/datum/job/revenant)) + mind.special_role = ROLE_REVENANT + SEND_SOUND(src, sound('sound/effects/ghost.ogg')) + mind.add_antag_datum(/datum/antagonist/revenant) + return TRUE + +/// Signal Handler Injection to handle Life() stuff for revenants +/mob/living/basic/revenant/proc/on_life(seconds_per_tick = SSMOBS_DT, times_fired) + SIGNAL_HANDLER + + if(dormant) + return COMPONENT_LIVING_CANCEL_LIFE_PROCESSING + + if(HAS_TRAIT(src, TRAIT_REVENANT_REVEALED) && essence <= 0) + death() + return COMPONENT_LIVING_CANCEL_LIFE_PROCESSING + + if(essence_regenerating && !HAS_TRAIT(src, TRAIT_REVENANT_INHIBITED) && essence < max_essence) //While inhibited, essence will not regenerate + var/change_in_time = DELTA_WORLD_TIME(SSmobs) + essence = min(essence + (essence_regen_amount * change_in_time), max_essence) + update_mob_action_buttons() //because we update something required by our spells in life, we need to update our buttons + + update_appearance(UPDATE_ICON) + update_health_hud() + +/mob/living/basic/revenant/get_status_tab_items() + . = ..() + . += "Current Essence: [essence >= max_essence ? essence : "[essence] / [max_essence]"] E" + . += "Total Essence Stolen: [essence_accumulated] SE" + . += "Unused Stolen Essence: [essence_excess] SE" + . += "Perfect Souls Stolen: [perfectsouls]" + +/mob/living/basic/revenant/update_health_hud() + if(isnull(hud_used)) + return + + var/essencecolor = "#8F48C6" + if(essence > max_essence) + essencecolor = "#9A5ACB" //oh boy you've got a lot of essence + else if(essence <= 0) + essencecolor = "#1D2953" //oh jeez you're dying + hud_used.healths.maptext = MAPTEXT("
[essence]E
") + +/mob/living/basic/revenant/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null) + if(!message) + return + + if(client) + if(client.prefs.muted & MUTE_IC) + to_chat(src, span_boldwarning("You cannot send IC messages (muted).")) + return + if (!(ignore_spam || forced) && client.handle_spam_prevention(message, MUTE_IC)) + return + + if(sanitize) + message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) + + log_talk(message, LOG_SAY) + var/rendered = span_deadsay("UNDEAD: [src] says, \"[message]\"") + relay_to_list_and_observers(rendered, GLOB.revenant_relay_mobs, src) + +/mob/living/basic/revenant/ClickOn(atom/A, params) //revenants can't interact with the world directly, so we gotta do some wacky override stuff + var/list/modifiers = params2list(params) + if(LAZYACCESS(modifiers, SHIFT_CLICK)) + ShiftClickOn(A) + return + if(LAZYACCESS(modifiers, ALT_CLICK)) + AltClickNoInteract(src, A) + return + if(LAZYACCESS(modifiers, RIGHT_CLICK)) + ranged_secondary_attack(A, modifiers) + return + + if(ishuman(A) && in_range(src, A)) + attempt_harvest(A) + +/mob/living/basic/revenant/ranged_secondary_attack(atom/target, modifiers) + if(HAS_TRAIT(src, TRAIT_REVENANT_INHIBITED) || HAS_TRAIT(src, TRAIT_REVENANT_REVEALED) || HAS_TRAIT(src, TRAIT_NO_TRANSFORM) || !Adjacent(target) || !incorporeal_move_check(target)) + return + + var/list/icon_dimensions = get_icon_dimensions(target.icon) + var/orbitsize = (icon_dimensions["width"] + icon_dimensions["height"]) * 0.5 + orbitsize -= (orbitsize / world.icon_size) * (world.icon_size * 0.25) + orbit(target, orbitsize) + +/mob/living/basic/revenant/adjust_health(amount, updating_health = TRUE, forced = FALSE) + if(!forced && !HAS_TRAIT(src, TRAIT_REVENANT_REVEALED)) + return 0 + + . = amount + + essence = max(0, essence - amount) + if(updating_health) + update_health_hud() + if(essence == 0) + death() + + return . + +/mob/living/basic/revenant/orbit(atom/target) + setDir(SOUTH) // reset dir so the right directional sprites show up + return ..() + +/mob/living/basic/revenant/update_icon_state() + . = ..() + + if(HAS_TRAIT(src, TRAIT_REVENANT_REVEALED)) + icon_state = icon_reveal + return + + if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) + if(draining) + icon_state = icon_drain + else + icon_state = icon_stun + + return + + icon_state = icon_idle + +/mob/living/basic/revenant/med_hud_set_health() + return //we use no hud + +/mob/living/basic/revenant/med_hud_set_status() + return //we use no hud + +/mob/living/basic/revenant/dust(just_ash, drop_items, force) + death() + +/mob/living/basic/revenant/gib() + death() + +/mob/living/basic/revenant/can_perform_action(atom/movable/target, action_bitflags) + return FALSE + +/mob/living/basic/revenant/ex_act(severity, target) + return FALSE //Immune to the effects of explosions. + +/mob/living/basic/revenant/blob_act(obj/structure/blob/attacking_blob) + return //blah blah blobs aren't in tune with the spirit world, or something. + +/mob/living/basic/revenant/singularity_act() + return //don't walk into the singularity expecting to find corpses, okay? + +/mob/living/basic/revenant/narsie_act() + return //most humans will now be either bones or harvesters, but we're still un-alive. + +/mob/living/basic/revenant/bullet_act() + if(!HAS_TRAIT(src, TRAIT_REVENANT_REVEALED) || dormant) + return BULLET_ACT_FORCE_PIERCE + return ..() + +/mob/living/basic/revenant/death() + if(!HAS_TRAIT(src, TRAIT_REVENANT_REVEALED) || dormant) //Revenants cannot die if they aren't revealed //or are already dead + return + ADD_TRAIT(src, TRAIT_NO_TRANSFORM, REVENANT_STUNNED_TRAIT) + dormant = TRUE + + visible_message( + span_warning("[src] lets out a waning screech as violet mist swirls around its dissolving body!"), + span_revendanger("NO! No... it's too late, you can feel your essence [pick("breaking apart", "drifting away")]..."), + ) + + invisibility = 0 + icon_state = "revenant_draining" + playsound(src, 'sound/effects/screech.ogg', 100, TRUE) + + animate(src, alpha = 0, time = 3 SECONDS) + addtimer(CALLBACK(src, PROC_REF(move_to_ectoplasm)), 3 SECONDS) + +/// Forces the mob, once dormant, to move inside ectoplasm until it can regenerate. +/mob/living/basic/revenant/proc/move_to_ectoplasm() + if(QDELETED(src) || !dormant) // something fucky happened, abort. we MUST be dormant to go inside the ectoplasm. + return + + visible_message(span_danger("[src]'s body breaks apart into a fine pile of blue dust.")) + + var/obj/item/ectoplasm/revenant/goop = new(get_turf(src)) // the ectoplasm will handle moving us out of dormancy + goop.old_ckey = client.ckey + goop.revenant = src + forceMove(goop) + +/mob/living/basic/revenant/proc/on_move(datum/source, atom/entering_loc) + SIGNAL_HANDLER + if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) // just in case it occurs, need to provide some feedback + balloon_alert(src, "can't move!") + return + + if(isnull(orbiting) || incorporeal_move_check(entering_loc)) + return + + // we're about to go somewhere we aren't meant to, end the orbit and block the move. feedback will be given in `incorporeal_move_check()` + orbiting.end_orbit(src) + return COMPONENT_MOVABLE_BLOCK_PRE_MOVE + +/// Generates the information the player needs to know how to play their role, and returns it as a list. +/mob/living/basic/revenant/proc/create_login_string() + RETURN_TYPE(/list) + var/list/returnable_list = list() + returnable_list += span_deadsay(span_boldbig("You are a revenant.")) + returnable_list += span_bold("Your formerly mundane spirit has been infused with alien energies and empowered into a revenant.") + returnable_list += span_bold("You are not dead, not alive, but somewhere in between. You are capable of limited interaction with both worlds.") + returnable_list += span_bold("You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.") + returnable_list += span_bold("To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities.") + returnable_list += span_bold("You do not remember anything of your past lives, nor will you remember anything about this one after your death.") + returnable_list += span_bold("Be sure to read the wiki page to learn more.") + return returnable_list + +/mob/living/basic/revenant/proc/set_random_revenant_name() + var/list/built_name_strings = list() + built_name_strings += pick(strings(REVENANT_NAME_FILE, "spirit_type")) + built_name_strings += " of " + built_name_strings += pick(strings(REVENANT_NAME_FILE, "adverb")) + built_name_strings += pick(strings(REVENANT_NAME_FILE, "theme")) + name = built_name_strings.Join("") + +/mob/living/basic/revenant/proc/on_baned(obj/item/weapon, mob/living/user) + SIGNAL_HANDLER + visible_message( + span_warning("[src] violently flinches!"), + span_revendanger("As [weapon] passes through you, you feel your essence draining away!"), + ) + apply_status_effect(/datum/status_effect/revenant/inhibited, 3 SECONDS) + +/// Incorporeal move check: blocked by holy-watered tiles and salt piles. +/mob/living/basic/revenant/proc/incorporeal_move_check(atom/destination) + var/turf/open/floor/step_turf = get_turf(destination) + if(isnull(step_turf)) + return TRUE // what? whatever let it happen + + if(step_turf.turf_flags & NOJAUNT) + to_chat(src, span_warning("Some strange aura is blocking the way.")) + return FALSE + + if(locate(/obj/effect/decal/cleanable/food/salt) in step_turf) + balloon_alert(src, "blocked by salt!") + apply_status_effect(/datum/status_effect/revenant/revealed, 2 SECONDS) + apply_status_effect(/datum/status_effect/incapacitating/paralyzed/revenant, 2 SECONDS) + return FALSE + + if(locate(/obj/effect/blessing) in step_turf) + to_chat(src, span_warning("Holy energies block your path!")) + return FALSE + + return TRUE + +/mob/living/basic/revenant/proc/cast_check(essence_cost) + if(QDELETED(src)) + return + + var/turf/current = get_turf(src) + + if(isclosedturf(current)) + to_chat(src, span_revenwarning("You cannot use abilities from inside of a wall.")) + return FALSE + + for(var/obj/thing in current) + if(!thing.density || thing.CanPass(src, get_dir(current, src))) + continue + to_chat(src, span_revenwarning("You cannot use abilities inside of a dense object.")) + return FALSE + + if(HAS_TRAIT(src, TRAIT_REVENANT_INHIBITED)) + to_chat(src, span_revenwarning("Your powers have been suppressed by a nullifying energy!")) + return FALSE + + if(!change_essence_amount(essence_cost, TRUE)) + to_chat(src, span_revenwarning("You lack the essence to use that ability.")) + return FALSE + + return TRUE + +/mob/living/basic/revenant/proc/unlock(essence_cost) + if(essence_excess < essence_cost) + return FALSE + essence_excess -= essence_cost + update_mob_action_buttons() + return TRUE + +/mob/living/basic/revenant/proc/death_reset() + REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, REVENANT_STUNNED_TRAIT) + forceMove(get_turf(src)) + // clean slate, so no more debilitating effects + remove_status_effect(/datum/status_effect/revenant/revealed) + remove_status_effect(/datum/status_effect/incapacitating/paralyzed/revenant) + remove_status_effect(/datum/status_effect/revenant/inhibited) + draining = FALSE + dormant = FALSE + incorporeal_move = INCORPOREAL_MOVE_JAUNT + invisibility = INVISIBILITY_REVENANT + alpha = 255 + +/mob/living/basic/revenant/proc/change_essence_amount(essence_to_change_by, silent = FALSE, source = null) + if(QDELETED(src)) + return FALSE + + if((essence + essence_to_change_by) < 0) + return FALSE + + essence = max(0, essence + essence_to_change_by) + update_health_hud() + + if(essence_to_change_by > 0) + essence_accumulated = max(0, essence_accumulated + essence_to_change_by) + essence_excess = max(0, essence_excess + essence_to_change_by) + + update_mob_action_buttons() + if(!silent) + if(essence_to_change_by > 0) + to_chat(src, span_revennotice("Gained [essence_to_change_by]E [source ? "from [source]":""].")) + else + to_chat(src, span_revenminor("Lost [essence_to_change_by]E [source ? "from [source]":""].")) + return TRUE + +#undef REVENANT_STUNNED_TRAIT diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/mob/living/basic/space_fauna/revenant/revenant_abilities.dm similarity index 63% rename from code/modules/antagonists/revenant/revenant_abilities.dm rename to code/modules/mob/living/basic/space_fauna/revenant/revenant_abilities.dm index ef00f51e45d947..63f4bbb9dbc3b9 100644 --- a/code/modules/antagonists/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/basic/space_fauna/revenant/revenant_abilities.dm @@ -1,122 +1,6 @@ #define REVENANT_DEFILE_MIN_DAMAGE 30 #define REVENANT_DEFILE_MAX_DAMAGE 50 -/mob/living/simple_animal/revenant/ClickOn(atom/A, params) //revenants can't interact with the world directly. - var/list/modifiers = params2list(params) - if(LAZYACCESS(modifiers, SHIFT_CLICK)) - ShiftClickOn(A) - return - if(LAZYACCESS(modifiers, ALT_CLICK)) - AltClickNoInteract(src, A) - return - if(LAZYACCESS(modifiers, RIGHT_CLICK)) - ranged_secondary_attack(A, modifiers) - return - - if(ishuman(A)) - //Humans are tagged, so this is fine - if(REF(A) in drained_mobs) - to_chat(src, span_revenwarning("[A]'s soul is dead and empty.") ) - else if(in_range(src, A)) - Harvest(A) - -/mob/living/simple_animal/revenant/ranged_secondary_attack(atom/target, modifiers) - if(revealed || inhibited || HAS_TRAIT(src, TRAIT_NO_TRANSFORM) || !Adjacent(target) || !incorporeal_move_check(target)) - return - - var/list/icon_dimensions = get_icon_dimensions(target.icon) - var/orbitsize = (icon_dimensions["width"] + icon_dimensions["height"]) * 0.5 - orbitsize -= (orbitsize / world.icon_size) * (world.icon_size * 0.25) - orbit(target, orbitsize) - -//Harvest; activated by 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 - if(draining) - to_chat(src, span_revenwarning("You are already siphoning the essence of a soul!")) - return - if(!target.stat) - to_chat(src, span_revennotice("[target.p_Their()] soul is too strong to harvest.")) - if(prob(10)) - to_chat(target, span_revennotice("You feel as if you are being watched.")) - return - log_combat(src, target, "started to harvest") - face_atom(target) - draining = TRUE - essence_drained += rand(15, 20) - to_chat(src, span_revennotice("You search for the soul of [target].")) - if(do_after(src, rand(10, 20), target, timed_action_flags = IGNORE_HELD_ITEM)) //did they get deleted in that second? - if(target.ckey) - to_chat(src, span_revennotice("[target.p_Their()] soul burns with intelligence.")) - essence_drained += rand(20, 30) - if(target.stat != DEAD && !HAS_TRAIT(target, TRAIT_WEAK_SOUL)) - to_chat(src, span_revennotice("[target.p_Their()] soul blazes with life!")) - essence_drained += rand(40, 50) - if(HAS_TRAIT(target, TRAIT_WEAK_SOUL) && !target.ckey) - to_chat(src, span_revennotice("[target.p_Their()] soul is weak and underdeveloped. They won't be worth very much.")) - essence_drained = 5 - else - to_chat(src, span_revennotice("[target.p_Their()] soul is weak and faltering.")) - if(do_after(src, rand(15, 20), target, timed_action_flags = IGNORE_HELD_ITEM)) //did they get deleted NOW? - switch(essence_drained) - if(1 to 30) - to_chat(src, span_revennotice("[target] will not yield much essence. Still, every bit counts.")) - if(30 to 70) - to_chat(src, span_revennotice("[target] will yield an average amount of essence.")) - if(70 to 90) - to_chat(src, span_revenboldnotice("Such a feast! [target] will yield much essence to you.")) - if(90 to INFINITY) - to_chat(src, span_revenbignotice("Ah, the perfect soul. [target] will yield massive amounts of essence to you.")) - if(do_after(src, rand(15, 25), target, timed_action_flags = IGNORE_HELD_ITEM)) //how about now - if(!target.stat) - to_chat(src, span_revenwarning("[target.p_Theyre()] now powerful enough to fight off your draining.")) - to_chat(target, span_boldannounce("You feel something tugging across your body before subsiding.")) - draining = 0 - essence_drained = 0 - return //hey, wait a minute... - to_chat(src, span_revenminor("You begin siphoning essence from [target]'s soul.")) - if(target.stat != DEAD) - to_chat(target, span_warning("You feel a horribly unpleasant draining sensation as your grip on life weakens...")) - if(target.stat == SOFT_CRIT) - target.Stun(46) - reveal(46) - stun(46) - target.visible_message(span_warning("[target] suddenly rises slightly into the air, [target.p_their()] skin turning an ashy gray.")) - if(target.can_block_magic(MAGIC_RESISTANCE_HOLY)) - to_chat(src, span_revenminor("Something's wrong! [target] seems to be resisting the siphoning, leaving you vulnerable!")) - target.visible_message(span_warning("[target] slumps onto the ground."), \ - span_revenwarning("Violet lights, dancing in your vision, receding--")) - draining = FALSE - return - var/datum/beam/B = Beam(target,icon_state="drain_life") - if(do_after(src, 46, target, timed_action_flags = IGNORE_HELD_ITEM)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining. - change_essence_amount(essence_drained, FALSE, target) - if(essence_drained <= 90 && target.stat != DEAD && !HAS_TRAIT(target, TRAIT_WEAK_SOUL)) - essence_regen_cap += 5 - to_chat(src, span_revenboldnotice("The absorption of [target]'s living soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap].")) - if(essence_drained > 90) - essence_regen_cap += 15 - perfectsouls++ - to_chat(src, span_revenboldnotice("The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap].")) - to_chat(src, span_revennotice("[target]'s soul has been considerably weakened and will yield no more essence for the time being.")) - target.visible_message(span_warning("[target] slumps onto the ground."), \ - span_revenwarning("Violets lights, dancing in your vision, getting clo--")) - drained_mobs += REF(target) - if(target.stat != DEAD) - target.investigate_log("has died from revenant harvest.", INVESTIGATE_DEATHS) - target.death(FALSE) - else - to_chat(src, span_revenwarning("[target ? "[target] has":"[target.p_Theyve()]"] been drawn out of your grasp. The link has been broken.")) - if(target) //Wait, target is WHERE NOW? - target.visible_message(span_warning("[target] slumps onto the ground."), \ - span_revenwarning("Violets lights, dancing in your vision, receding--")) - qdel(B) - else - to_chat(src, span_revenwarning("You are not close enough to siphon [target ? "[target]'s":"[target.p_their()]"] soul. The link has been broken.")) - draining = FALSE - essence_drained = 0 - //Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob /datum/action/cooldown/spell/list_target/telepathy/revenant name = "Revenant Transmit" @@ -170,8 +54,8 @@ stack_trace("[type] was owned by a non-revenant mob, please don't.") return FALSE - var/mob/living/simple_animal/revenant/ghost = owner - if(ghost.inhibited) + var/mob/living/basic/revenant/ghost = owner + if(ghost.dormant || HAS_TRAIT(ghost, TRAIT_REVENANT_INHIBITED)) return FALSE if(locked && ghost.essence_excess <= unlock_amount) return FALSE @@ -183,7 +67,7 @@ /datum/action/cooldown/spell/aoe/revenant/get_things_to_cast_on(atom/center) return RANGE_TURFS(aoe_radius, center) -/datum/action/cooldown/spell/aoe/revenant/before_cast(mob/living/simple_animal/revenant/cast_on) +/datum/action/cooldown/spell/aoe/revenant/before_cast(mob/living/basic/revenant/cast_on) . = ..() if(. & SPELL_CANCEL_CAST) return @@ -201,16 +85,16 @@ reset_spell_cooldown() return . | SPELL_CANCEL_CAST - if(!cast_on.castcheck(-cast_amount)) + if(!cast_on.cast_check(-cast_amount)) reset_spell_cooldown() return . | SPELL_CANCEL_CAST -/datum/action/cooldown/spell/aoe/revenant/after_cast(mob/living/simple_animal/revenant/cast_on) +/datum/action/cooldown/spell/aoe/revenant/after_cast(mob/living/basic/revenant/cast_on) . = ..() if(reveal_duration > 0 SECONDS) - cast_on.reveal(reveal_duration) + cast_on.apply_status_effect(/datum/status_effect/revenant/revealed, reveal_duration) if(stun_duration > 0 SECONDS) - cast_on.stun(stun_duration) + cast_on.apply_status_effect(/datum/status_effect/incapacitating/paralyzed/revenant, stun_duration) //Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people. /datum/action/cooldown/spell/aoe/revenant/overload @@ -226,10 +110,10 @@ /// The range the shocks from the lights go var/shock_range = 2 - /// The damage the shcoskf rom the lgihts do + /// The damage the shocks from the lights do var/shock_damage = 15 -/datum/action/cooldown/spell/aoe/revenant/overload/cast_on_thing_in_aoe(turf/victim, mob/living/simple_animal/revenant/caster) +/datum/action/cooldown/spell/aoe/revenant/overload/cast_on_thing_in_aoe(turf/victim, mob/living/basic/revenant/caster) for(var/obj/machinery/light/light in victim) if(!light.on) continue @@ -241,7 +125,7 @@ new /obj/effect/temp_visual/revenant(get_turf(light)) addtimer(CALLBACK(src, PROC_REF(overload_shock), light, caster), 20) -/datum/action/cooldown/spell/aoe/revenant/overload/proc/overload_shock(obj/machinery/light/to_shock, mob/living/simple_animal/revenant/caster) +/datum/action/cooldown/spell/aoe/revenant/overload/proc/overload_shock(obj/machinery/light/to_shock, mob/living/basic/revenant/caster) flick("[to_shock.base_state]2", to_shock) for(var/mob/living/carbon/human/human_mob in view(shock_range, to_shock)) if(human_mob == caster) @@ -266,7 +150,7 @@ reveal_duration = 4 SECONDS stun_duration = 2 SECONDS -/datum/action/cooldown/spell/aoe/revenant/defile/cast_on_thing_in_aoe(turf/victim, mob/living/simple_animal/revenant/caster) +/datum/action/cooldown/spell/aoe/revenant/defile/cast_on_thing_in_aoe(turf/victim, mob/living/basic/revenant/caster) for(var/obj/effect/blessing/blessing in victim) qdel(blessing) new /obj/effect/temp_visual/revenant(victim) @@ -315,7 +199,7 @@ unlock_amount = 125 // A note to future coders: do not replace this with an EMP because it will wreck malf AIs and everyone will hate you. -/datum/action/cooldown/spell/aoe/revenant/malfunction/cast_on_thing_in_aoe(turf/victim, mob/living/simple_animal/revenant/caster) +/datum/action/cooldown/spell/aoe/revenant/malfunction/cast_on_thing_in_aoe(turf/victim, mob/living/basic/revenant/caster) for(var/mob/living/simple_animal/bot/bot in victim) if(!(bot.bot_cover_flags & BOT_COVER_EMAGGED)) new /obj/effect/temp_visual/revenant(bot.loc) @@ -356,7 +240,7 @@ cast_amount = 50 unlock_amount = 75 -/datum/action/cooldown/spell/aoe/revenant/blight/cast_on_thing_in_aoe(turf/victim, mob/living/simple_animal/revenant/caster) +/datum/action/cooldown/spell/aoe/revenant/blight/cast_on_thing_in_aoe(turf/victim, mob/living/basic/revenant/caster) for(var/mob/living/mob in victim) if(mob == caster) continue @@ -430,7 +314,7 @@ return things -/datum/action/cooldown/spell/aoe/revenant/haunt_object/cast_on_thing_in_aoe(obj/item/victim, mob/living/simple_animal/revenant/caster) +/datum/action/cooldown/spell/aoe/revenant/haunt_object/cast_on_thing_in_aoe(obj/item/victim, mob/living/basic/revenant/caster) var/distance_from_caster = get_dist(get_turf(victim), get_turf(caster)) var/chance_of_haunting = 150 * (1 / distance_from_caster) if(!prob(chance_of_haunting)) diff --git a/code/modules/mob/living/basic/space_fauna/revenant/revenant_effects.dm b/code/modules/mob/living/basic/space_fauna/revenant/revenant_effects.dm new file mode 100644 index 00000000000000..0eeec231973ee1 --- /dev/null +++ b/code/modules/mob/living/basic/space_fauna/revenant/revenant_effects.dm @@ -0,0 +1,73 @@ +/// Parent type for all unique revenant status effects +/datum/status_effect/revenant + +/datum/status_effect/revenant/on_creation(mob/living/new_owner, duration) + if(isnum(duration)) + src.duration = duration + return ..() + +/datum/status_effect/revenant/revealed + id = "revenant_revealed" + +/datum/status_effect/revenant/revealed/on_apply() + . = ..() + if(!.) + return FALSE + owner.orbiting?.end_orbit(src) + + ADD_TRAIT(owner, TRAIT_REVENANT_REVEALED, TRAIT_STATUS_EFFECT(id)) + owner.invisibility = 0 + owner.incorporeal_move = FALSE + owner.update_appearance(UPDATE_ICON) + owner.update_mob_action_buttons() + +/datum/status_effect/revenant/revealed/on_remove() + REMOVE_TRAIT(owner, TRAIT_REVENANT_REVEALED, TRAIT_STATUS_EFFECT(id)) + + owner.incorporeal_move = INCORPOREAL_MOVE_JAUNT + owner.invisibility = INVISIBILITY_REVENANT + owner.update_appearance(UPDATE_ICON) + owner.update_mob_action_buttons() + return ..() + +/datum/status_effect/revenant/inhibited + id = "revenant_inhibited" + +/datum/status_effect/revenant/inhibited/on_apply() + . = ..() + if(!.) + return FALSE + owner.orbiting?.end_orbit(src) + + ADD_TRAIT(owner, TRAIT_REVENANT_INHIBITED, TRAIT_STATUS_EFFECT(id)) + owner.update_appearance(UPDATE_ICON) + + owner.balloon_alert(owner, "inhibited!") + +/datum/status_effect/revenant/inhibited/on_remove() + REMOVE_TRAIT(owner, TRAIT_REVENANT_INHIBITED, TRAIT_STATUS_EFFECT(id)) + owner.update_appearance(UPDATE_ICON) + + owner.balloon_alert(owner, "uninhibited") + return ..() + +/datum/status_effect/incapacitating/paralyzed/revenant + id = "revenant_paralyzed" + +/datum/status_effect/incapacitating/paralyzed/revenant/on_apply() + . = ..() + if(!.) + return FALSE + owner.orbiting?.end_orbit(src) + + ADD_TRAIT(owner, TRAIT_NO_TRANSFORM, TRAIT_STATUS_EFFECT(id)) + owner.balloon_alert(owner, "can't move!") + owner.update_mob_action_buttons() + owner.update_appearance(UPDATE_ICON) + +/datum/status_effect/incapacitating/paralyzed/revenant/on_remove() + REMOVE_TRAIT(owner, TRAIT_NO_TRANSFORM, TRAIT_STATUS_EFFECT(id)) + owner.update_mob_action_buttons() + owner.balloon_alert(owner, "can move again") + + return ..() diff --git a/code/modules/mob/living/basic/space_fauna/revenant/revenant_harvest.dm b/code/modules/mob/living/basic/space_fauna/revenant/revenant_harvest.dm new file mode 100644 index 00000000000000..b8bb05db484142 --- /dev/null +++ b/code/modules/mob/living/basic/space_fauna/revenant/revenant_harvest.dm @@ -0,0 +1,143 @@ +// This file contains the proc we use for revenant harvesting because it is a very long and bulky proc that takes up a lot of space elsewhere + +/// Container proc for `harvest()`, handles the pre-checks as well as potential early-exits for any reason. +/// Will return FALSE if we can't execute `harvest()`, or will otherwise the result of `harvest()`: a boolean value. +/mob/living/basic/revenant/proc/attempt_harvest(mob/living/carbon/human/target) + if(LAZYFIND(drained_mobs, REF(target))) + to_chat(src, span_revenwarning("[target]'s soul is dead and empty.")) + return FALSE + + if(!cast_check(0)) + return FALSE + + if(draining) + to_chat(src, span_revenwarning("You are already siphoning the essence of a soul!")) + return FALSE + + draining = TRUE + var/value_to_return = harvest_soul(target) + if(!value_to_return) + log_combat(src, target, "stopped the harvest of") + draining = FALSE + + return value_to_return + +/// Harvest; activated by clicking a target, will try to drain their essence. Handles all messages and handling of the target. +/// Returns FALSE if we exit out of the harvest, TRUE if it is fully done. +/mob/living/basic/revenant/proc/harvest_soul(mob/living/carbon/human/target) // this isn't in the main revenant code file because holyyyy shit it's long + if(QDELETED(target)) // what + return FALSE + + // cache pronouns in case they get deleted as well as be a nice micro-opt due to the multiple times we use them + var/target_their = target.p_their() + var/target_Their = target.p_Their() + var/target_Theyre = target.p_Theyre() + var/target_They_have = "[target.p_They()] [target.p_have()]" + + if(target.stat == CONSCIOUS) + to_chat(src, span_revennotice("[target_Their] soul is too strong to harvest.")) + if(prob(10)) + to_chat(target, span_revennotice("You feel as if you are being watched.")) + return FALSE + + log_combat(src, target, "started to harvest") + face_atom(target) + var/essence_drained = rand(15, 20) + + to_chat(src, span_revennotice("You search for the soul of [target].")) + + if(!do_after(src, (rand(10, 20) DECISECONDS), target, timed_action_flags = IGNORE_HELD_ITEM)) //did they get deleted in that second? + return FALSE + + var/target_has_client = !isnull(target.client) + if(target_has_client || target.ckey) // any target that has been occupied with a ckey is considered "intelligent" + to_chat(src, span_revennotice("[target_Their] soul burns with intelligence.")) + essence_drained += rand(20, 30) + + if(target.stat != DEAD && !HAS_TRAIT(target, TRAIT_WEAK_SOUL)) + to_chat(src, span_revennotice("[target_Their] soul blazes with life!")) + essence_drained += rand(40, 50) + + if(!target_has_client && HAS_TRAIT(target, TRAIT_WEAK_SOUL)) + to_chat(src, span_revennotice("[target_Their] soul is weak and underdeveloped. They won't be worth very much.")) + essence_drained = 5 + + to_chat(src, span_revennotice("[target_Their] soul is weak and faltering. It's time to harvest.")) + + if(!do_after(src, (rand(15, 20) DECISECONDS), target, timed_action_flags = IGNORE_HELD_ITEM)) + to_chat(src, span_revennotice("The harvest is abandoned.")) + return FALSE + + switch(essence_drained) + if(1 to 30) + to_chat(src, span_revennotice("[target] will not yield much essence. Still, every bit counts.")) + if(30 to 70) + to_chat(src, span_revennotice("[target] will yield an average amount of essence.")) + if(70 to 90) + to_chat(src, span_revenboldnotice("Such a feast! [target] will yield much essence to you.")) + if(90 to INFINITY) + to_chat(src, span_revenbignotice("Ah, the perfect soul. [target] will yield massive amounts of essence to you.")) + + if(!do_after(src, (rand(15, 25) DECISECONDS), target, timed_action_flags = IGNORE_HELD_ITEM)) //how about now + to_chat(src, span_revenwarning("You are not close enough to siphon [target ? "[target]'s" : "[target_their]"] soul. The link has been broken.")) + return FALSE + + if(target.stat == CONSCIOUS) + to_chat(src, span_revenwarning("[target_Theyre] now powerful enough to fight off your draining!")) + to_chat(target, span_boldannounce("You feel something tugging across your body before subsiding.")) //hey, wait a minute... + return FALSE + + to_chat(src, span_revenminor("You begin siphoning essence from [target]'s soul.")) + if(target.stat != DEAD) + to_chat(target, span_warning("You feel a horribly unpleasant draining sensation as your grip on life weakens...")) + if(target.stat == SOFT_CRIT) + target.Stun(46) + + apply_status_effect(/datum/status_effect/revenant/revealed, 5 SECONDS) + apply_status_effect(/datum/status_effect/incapacitating/paralyzed/revenant, 5 SECONDS) + + target.visible_message(span_warning("[target] suddenly rises slightly into the air, [target_their] skin turning an ashy gray.")) + + if(target.can_block_magic(MAGIC_RESISTANCE_HOLY)) + to_chat(src, span_revenminor("Something's wrong! [target] seems to be resisting the siphoning, leaving you vulnerable!")) + target.visible_message( + span_warning("[target] slumps onto the ground."), + span_revenwarning("Violet lights, dancing in your vision, receding--"), + ) + return FALSE + + var/datum/beam/draining_beam = Beam(target, icon_state = "drain_life") + if(!do_after(src, 4.6 SECONDS, target, timed_action_flags = (IGNORE_HELD_ITEM | IGNORE_INCAPACITATED))) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining. + to_chat(src, span_revenwarning("[target ? "[target]'s soul has" : "[target_They_have]"] been drawn out of your grasp. The link has been broken.")) + if(target) + target.visible_message( + span_warning("[target] slumps onto the ground."), + span_revenwarning("Violet lights, dancing in your vision, receding--"), + ) + qdel(draining_beam) + return FALSE + + change_essence_amount(essence_drained, FALSE, target) + + if(essence_drained <= 90 && target.stat != DEAD && !HAS_TRAIT(target, TRAIT_WEAK_SOUL)) + max_essence += 5 + to_chat(src, span_revenboldnotice("The absorption of [target]'s living soul has increased your maximum essence level. Your new maximum essence is [max_essence].")) + + if(essence_drained > 90) + max_essence += 15 + perfectsouls++ + to_chat(src, span_revenboldnotice("The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [max_essence].")) + + to_chat(src, span_revennotice("[target]'s soul has been considerably weakened and will yield no more essence for the time being.")) + target.visible_message( + span_warning("[target] slumps onto the ground."), + span_revenwarning("Violet lights, dancing in your vision, getting clo--"), + ) + + LAZYADD(drained_mobs, REF(target)) + if(target.stat != DEAD) + target.investigate_log("has died from revenant harvest.", INVESTIGATE_DEATHS) + target.death(FALSE) + + qdel(draining_beam) + return TRUE diff --git a/code/modules/mob/living/basic/space_fauna/revenant/revenant_items.dm b/code/modules/mob/living/basic/space_fauna/revenant/revenant_items.dm new file mode 100644 index 00000000000000..a9e17a9b305ff2 --- /dev/null +++ b/code/modules/mob/living/basic/space_fauna/revenant/revenant_items.dm @@ -0,0 +1,106 @@ +//reforming +/obj/item/ectoplasm/revenant + name = "glimmering residue" + desc = "A pile of fine blue dust. Small tendrils of violet mist swirl around it." + icon = 'icons/effects/effects.dmi' + icon_state = "revenantEctoplasm" + w_class = WEIGHT_CLASS_SMALL + /// Are we currently reforming? + var/reforming = TRUE + /// Are we inert (aka distorted such that we can't reform)? + var/inert = FALSE + /// The key of the revenant that we started the reform as + var/old_ckey + /// The revenant we're currently storing + var/mob/living/basic/revenant/revenant + +/obj/item/ectoplasm/revenant/Initialize(mapload) + . = ..() + addtimer(CALLBACK(src, PROC_REF(try_reform)), 1 MINUTES) + +/obj/item/ectoplasm/revenant/Destroy() + if(!QDELETED(revenant)) + qdel(revenant) + return ..() + +/obj/item/ectoplasm/revenant/attack_self(mob/user) + if(!reforming || inert) + return ..() + user.visible_message( + span_notice("[user] scatters [src] in all directions."), + span_notice("You scatter [src] across the area. The particles slowly fade away."), + ) + user.dropItemToGround(src) + qdel(src) + +/obj/item/ectoplasm/revenant/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) + . = ..() + if(inert) + return + visible_message(span_notice("[src] breaks into particles upon impact, which fade away to nothingness.")) + qdel(src) + +/obj/item/ectoplasm/revenant/examine(mob/user) + . = ..() + if(inert) + . += span_revennotice("It seems inert.") + else if(reforming) + . += span_revenwarning("It is shifting and distorted. It would be wise to destroy this.") + +/obj/item/ectoplasm/revenant/suicide_act(mob/living/user) + user.visible_message(span_suicide("[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the shadow realm!")) + qdel(src) + return OXYLOSS + +/obj/item/ectoplasm/revenant/proc/try_reform() + if(reforming) + reforming = FALSE + reform() + else + inert = TRUE + visible_message(span_warning("[src] settles down and seems lifeless.")) + +/// Actually moves the revenant out of ourself +/obj/item/ectoplasm/revenant/proc/reform() + if(QDELETED(src) || QDELETED(revenant) || inert) + return + + message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.") + forceMove(drop_location()) //In case it's in a backpack or someone's hand + + var/user_name = old_ckey + if(isnull(revenant.client)) + var/mob/potential_user = get_new_user() + revenant.key = potential_user.key + user_name = potential_user.ckey + qdel(potential_user) + + message_admins("[user_name] has been [old_ckey == user_name ? "re":""]made into a revenant by reforming ectoplasm.") + revenant.log_message("was [old_ckey == user_name ? "re":""]made as a revenant by reforming ectoplasm.", LOG_GAME) + visible_message(span_revenboldnotice("[src] suddenly rises into the air before fading away.")) + + revenant.death_reset() + revenant = null + qdel(src) + +/// Handles giving the revenant a new client to control it +/obj/item/ectoplasm/revenant/proc/get_new_user() + message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...") + var/list/candidates = poll_candidates_for_mob("Do you want to be [revenant.name] (reforming)?", ROLE_REVENANT, ROLE_REVENANT, 5 SECONDS, revenant) + + if(!LAZYLEN(candidates)) + message_admins("No candidates were found for the new revenant.") + inert = TRUE + visible_message(span_revenwarning("[src] settles down and seems lifeless.")) + qdel(revenant) + return null + + var/mob/dead/observer/potential_client = pick(candidates) + if(isnull(potential_client)) + qdel(revenant) + message_admins("No candidate was found for the new revenant. Oh well!") + inert = TRUE + visible_message(span_revenwarning("[src] settles down and seems lifeless.")) + return null + + return potential_client diff --git a/code/modules/mob/living/basic/space_fauna/revenant/revenant_objectives.dm b/code/modules/mob/living/basic/space_fauna/revenant/revenant_objectives.dm new file mode 100644 index 00000000000000..7dd391c17e477e --- /dev/null +++ b/code/modules/mob/living/basic/space_fauna/revenant/revenant_objectives.dm @@ -0,0 +1,37 @@ +/datum/objective/revenant + +/datum/objective/revenant/New() + target_amount = rand(350, 600) + explanation_text = "Absorb [target_amount] points of essence from humans." + return ..() + +/datum/objective/revenant/check_completion() + if(!isrevenant(owner.current)) + return FALSE + var/mob/living/basic/revenant/owner_mob = owner.current + if(QDELETED(owner_mob) || owner_mob.stat == DEAD) + return FALSE + var/essence_stolen = owner_mob.essence_accumulated + return essence_stolen >= target_amount + +/datum/objective/revenant_fluff + +/datum/objective/revenant_fluff/New() + var/list/explanation_texts = list( + "Assist and exacerbate existing threats at critical moments.", + "Cause as much chaos and anger as you can without being killed.", + "Damage and render as much of the station rusted and unusable as possible.", + "Disable and cause malfunctions in as many machines as possible.", + "Ensure that any holy weapons are rendered unusable.", + "Heed and obey the requests of the dead, provided that carrying them out wouldn't be too inconvenient or self-destructive.", + "Impersonate or be worshipped as a God.", + "Make the captain as miserable as possible.", + "Make the clown as miserable as possible.", + "Make the crew as miserable as possible.", + "Prevent the use of energy weapons where possible.", + ) + explanation_text = pick(explanation_texts) + return ..() + +/datum/objective/revenant_fluff/check_completion() + return TRUE diff --git a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_ai.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_ai.dm index f998b7b53cd908..9894d15fdfba7b 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_ai.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spider_ai.dm @@ -45,7 +45,6 @@ blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/of_size/ours_or_smaller(), // Hunt mobs our size BB_FLEE_TARGETTING_DATUM = new /datum/targetting_datum/basic/of_size/larger(), // Run away from mobs bigger than we are - BB_BASIC_MOB_FLEEING = TRUE, ) idle_behavior = /datum/idle_behavior/idle_random_walk diff --git a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm index 6df2eb427f4117..8cb7d8398bf366 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/giant_spider/giant_spiders.dm @@ -478,55 +478,6 @@ menu_description = "Weaker version of the nurse spider, specializing in healing their brethren and placing webbings very swiftly, but has very low amount of health and deals low damage." ai_controller = /datum/ai_controller/basic_controller/giant_spider/weak -/** - * ### Flesh Spider - * - * A subtype of giant spider which only occurs from changelings. - * Has the base stats of a hunter, but they can heal themselves and spin webs faster. - * They also occasionally leave puddles of blood when they walk around. Flavorful! - */ -/mob/living/basic/spider/giant/hunter/flesh - name = "flesh spider" - desc = "A odd fleshy creature in the shape of a spider. Its eyes are pitch black and soulless." - icon = 'icons/mob/simple/arachnoid.dmi' - icon_state = "flesh" - icon_living = "flesh" - icon_dead = "flesh_dead" - web_speed = 0.7 - maxHealth = 90 - health = 90 - menu_description = "Self-sufficient spider variant capable of healing themselves and producing webbbing fast." - -/mob/living/basic/spider/giant/hunter/flesh/Initialize(mapload) - . = ..() - AddComponent(/datum/component/blood_walk, \ - blood_type = /obj/effect/decal/cleanable/blood/bubblegum, \ - blood_spawn_chance = 5) - // It might be easier and more fitting to just replace this with Regenerator - AddComponent(/datum/component/healing_touch,\ - heal_brute = 45,\ - heal_burn = 45,\ - self_targetting = HEALING_TOUCH_SELF_ONLY,\ - interaction_key = DOAFTER_SOURCE_SPIDER,\ - valid_targets_typecache = typecacheof(list(/mob/living/basic/spider/giant/hunter/flesh)),\ - extra_checks = CALLBACK(src, PROC_REF(can_mend)),\ - action_text = "%SOURCE% begins mending themselves...",\ - complete_text = "%SOURCE%'s wounds mend together.",\ - ) - - var/datum/action/cooldown/mob_cooldown/lay_web/web_spikes/spikes_web = new(src) - spikes_web.Grant(src) - - var/datum/action/cooldown/mob_cooldown/lay_web/sticky_web/web_sticky = new(src) - web_sticky.Grant(src) - -/// Prevent you from healing other flesh spiders, or healing when on fire -/mob/living/basic/spider/giant/hunter/flesh/proc/can_mend(mob/living/source, mob/living/target) - if (on_fire) - balloon_alert(src, "on fire!") - return FALSE - return TRUE - /** * ### Viper Spider (Wizard) * diff --git a/code/modules/mob/living/basic/space_fauna/spider/spider.dm b/code/modules/mob/living/basic/space_fauna/spider/spider.dm index e96482439f9825..53b48129e2ed49 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/spider.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/spider.dm @@ -13,6 +13,7 @@ response_disarm_continuous = "gently pushes aside" response_disarm_simple = "gently push aside" initial_language_holder = /datum/language_holder/spider + melee_attack_cooldown = CLICK_CD_MELEE damage_coeff = list(BRUTE = 1, BURN = 1.25, TOX = 1, CLONE = 1, STAMINA = 1, OXY = 1) basic_mob_flags = FLAMMABLE_MOB status_flags = NONE @@ -48,7 +49,7 @@ /mob/living/basic/spider/Initialize(mapload) . = ..() - ADD_TRAIT(src, TRAIT_WEB_SURFER, INNATE_TRAIT) + add_traits(list(TRAIT_WEB_SURFER, TRAIT_FENCE_CLIMBER), INNATE_TRAIT) AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) AddElement(/datum/element/nerfed_pulling, GLOB.typecache_general_bad_things_to_easily_move) AddElement(/datum/element/prevent_attacking_of_types, GLOB.typecache_general_bad_hostile_attack_targets, "this tastes awful!") diff --git a/code/modules/mob/living/basic/space_fauna/spider/spiderlings/spiderling.dm b/code/modules/mob/living/basic/space_fauna/spider/spiderlings/spiderling.dm index 7108983c310511..c949b438683cb6 100644 --- a/code/modules/mob/living/basic/space_fauna/spider/spiderlings/spiderling.dm +++ b/code/modules/mob/living/basic/space_fauna/spider/spiderlings/spiderling.dm @@ -61,7 +61,6 @@ /datum/ai_controller/basic_controller/spiderling blackboard = list( BB_FLEE_TARGETTING_DATUM = new /datum/targetting_datum/basic/of_size/larger, // Run away from mobs bigger than we are - BB_BASIC_MOB_FLEEING = TRUE, BB_VENTCRAWL_COOLDOWN = 20 SECONDS, // enough time to get splatted while we're out in the open. BB_TIME_TO_GIVE_UP_ON_VENT_PATHING = 30 SECONDS, ) diff --git a/code/modules/mob/living/basic/space_fauna/statue/statue.dm b/code/modules/mob/living/basic/space_fauna/statue/statue.dm index bce35146ecfc69..d2ea5e8a831d05 100644 --- a/code/modules/mob/living/basic/space_fauna/statue/statue.dm +++ b/code/modules/mob/living/basic/space_fauna/statue/statue.dm @@ -162,7 +162,7 @@ maxHealth = 5000 melee_damage_lower = 65 melee_damage_upper = 65 - faction = list("statue","mining") + faction = list(FACTION_STATUE,FACTION_MINING) /mob/living/basic/statue/frosty/Initialize(mapload) . = ..() diff --git a/code/modules/mob/living/basic/space_fauna/supermatter_spider.dm b/code/modules/mob/living/basic/space_fauna/supermatter_spider.dm new file mode 100644 index 00000000000000..2a3ba326eaca95 --- /dev/null +++ b/code/modules/mob/living/basic/space_fauna/supermatter_spider.dm @@ -0,0 +1,102 @@ +/// A nasty little robotic bug that dusts people on attack. Jeepers. This should be a very, very, very rare spawn. +/mob/living/basic/supermatter_spider + name = "supermatter spider" + desc= "A sliver of supermatter placed upon a robotically enhanced pedestal." + + icon = 'icons/mob/simple/smspider.dmi' + icon_state = "smspider" + icon_living = "smspider" + icon_dead = "smspider_dead" + + gender = NEUTER + mob_biotypes = MOB_BUG|MOB_ROBOTIC + speak_emote = list("vibrates") + + + attack_verb_continuous = "slices" + attack_verb_simple = "slice" + attack_sound = 'sound/effects/supermatter.ogg' + attack_vis_effect = ATTACK_EFFECT_CLAW + + maxHealth = 10 + health = 10 + minimum_survivable_temperature = TCMB + maximum_survivable_temperature = T0C + 1250 + habitable_atmos = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + death_message = "falls to the ground, its shard dulling to a miserable grey!" + + faction = list(FACTION_HOSTILE) + + // Gold, supermatter tinted + lighting_cutoff_red = 30 + lighting_cutoff_green = 30 + lighting_cutoff_blue = 10 + + ai_controller = /datum/ai_controller/basic_controller/supermatter_spider + + /// If we successfully dust something, should we die? + var/single_use = TRUE + +/mob/living/basic/supermatter_spider/Initialize(mapload) + . = ..() + AddComponent(/datum/component/swarming) + + AddElement(/datum/element/ai_retaliate) + AddElement(/datum/element/footstep, FOOTSTEP_MOB_CLAW) + + RegisterSignal(src, COMSIG_HOSTILE_PRE_ATTACKINGTARGET, PROC_REF(on_attack)) + +/// Proc that we call on attacking something to dust 'em. +/mob/living/basic/supermatter_spider/proc/on_attack(mob/living/basic/source, atom/target) + SIGNAL_HANDLER + + if(isliving(target)) + var/mob/living/victim = target + victim.investigate_log("has been dusted by [src].", INVESTIGATE_DEATHS) + dust_feedback(target) + victim.dust() + if(single_use) + death() + return COMPONENT_HOSTILE_NO_ATTACK + + if(!isturf(target)) + dust_feedback(target) + qdel(target) + if(single_use) + death() + return COMPONENT_HOSTILE_NO_ATTACK + +/// Simple proc that plays the supermatter dusting sound and sends a visible message. +/mob/living/basic/supermatter_spider/proc/dust_feedback(atom/target) + playsound(get_turf(src), 'sound/effects/supermatter.ogg', 10, TRUE) + visible_message(span_danger("[src] knocks into [target], turning [target.p_them()] to dust in a brilliant flash of light!")) + +/mob/living/basic/supermatter_spider/overcharged + name = "overcharged supermatter spider" + desc = "A sliver of overcharged supermatter placed upon a robotically enhanced pedestal. This one seems especially dangerous." + icon_state = "smspideroc" + icon_living = "smspideroc" + maxHealth = 25 + health = 25 + single_use = FALSE + +/datum/ai_controller/basic_controller/supermatter_spider + blackboard = list( + BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, + ) + + ai_movement = /datum/ai_movement/basic_avoidance + idle_behavior = /datum/idle_behavior/idle_random_walk + + planning_subtrees = list( + /datum/ai_planning_subtree/target_retaliate, + /datum/ai_planning_subtree/simple_find_target, + /datum/ai_planning_subtree/attack_obstacle_in_path, + /datum/ai_planning_subtree/random_speech/supermatter_spider, + /datum/ai_planning_subtree/basic_melee_attack_subtree, + ) + +/datum/ai_planning_subtree/random_speech/supermatter_spider + speech_chance = 7 + emote_hear = list("clinks", "clanks") + emote_see = list("vibrates") diff --git a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/inflation.dm b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/inflation.dm index d459648892b018..a9e2b538bdd741 100644 --- a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/inflation.dm +++ b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/inflation.dm @@ -65,7 +65,7 @@ fugu.melee_damage_upper = 20 fugu.status_flags |= GODMODE fugu.obj_damage = 60 - fugu.ai_controller.set_blackboard_key(BB_BASIC_MOB_FLEEING, FALSE) + fugu.ai_controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, TRUE) fugu.ai_controller.CancelActions() /datum/status_effect/inflated/on_remove() @@ -84,7 +84,7 @@ if (fugu.stat != DEAD) fugu.icon_state = "Fugu0" fugu.obj_damage = 0 - fugu.ai_controller.set_blackboard_key(BB_BASIC_MOB_FLEEING, TRUE) + fugu.ai_controller.set_blackboard_key(BB_BASIC_MOB_STOP_FLEEING, FALSE) fugu.ai_controller.CancelActions() /// Remove status effect if we die diff --git a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_ai.dm b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_ai.dm index 9d3a09c5348f2c..e405ee3755abf1 100644 --- a/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_ai.dm +++ b/code/modules/mob/living/basic/space_fauna/wumborian_fugu/wumborian_ai.dm @@ -2,7 +2,6 @@ /datum/ai_controller/basic_controller/wumborian_fugu blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(), - BB_BASIC_MOB_FLEEING = TRUE, ) ai_movement = /datum/ai_movement/basic_avoidance diff --git a/code/modules/mob/living/basic/vermin/crab.dm b/code/modules/mob/living/basic/vermin/crab.dm index abe5c25117b6db..4843c6e6f7b11d 100644 --- a/code/modules/mob/living/basic/vermin/crab.dm +++ b/code/modules/mob/living/basic/vermin/crab.dm @@ -77,7 +77,7 @@ ///The basic ai controller for crabs /datum/ai_controller/basic_controller/crab blackboard = list( - BB_BASIC_MOB_FLEEING = FALSE, + BB_BASIC_MOB_STOP_FLEEING = TRUE, BB_TARGETTING_DATUM = new /datum/targetting_datum/basic/of_size/ours_or_smaller, BB_FLEE_TARGETTING_DATUM = new /datum/targetting_datum/basic/ignore_faction, ) diff --git a/code/modules/mob/living/basic/vermin/frog.dm b/code/modules/mob/living/basic/vermin/frog.dm index 191ea12b4df33c..64dbafb45f85d2 100644 --- a/code/modules/mob/living/basic/vermin/frog.dm +++ b/code/modules/mob/living/basic/vermin/frog.dm @@ -26,7 +26,7 @@ response_harm_simple = "splat" density = FALSE faction = list(FACTION_HOSTILE, FACTION_MAINT_CREATURES) - attack_sound = 'sound/effects/reee.ogg' + attack_sound = null // SKYRAT EDIT - No more frog ear-rape - ORIGINAL: attack_sound = 'sound/effects/reee.ogg' butcher_results = list(/obj/item/food/nugget = 1) pass_flags = PASSTABLE | PASSGRILLE | PASSMOB mob_size = MOB_SIZE_TINY @@ -40,7 +40,7 @@ ai_controller = /datum/ai_controller/basic_controller/frog - var/stepped_sound = 'sound/effects/huuu.ogg' + var/stepped_sound = null // SKYRAT EDIT - No more frog ear-rape - ORIGINA: var/stepped_sound = 'sound/effects/huuu.ogg' ///How much of a reagent the mob injects on attack var/poison_per_bite = 3 ///What reagent the mob injects targets with diff --git a/code/modules/mob/living/basic/vermin/mouse.dm b/code/modules/mob/living/basic/vermin/mouse.dm index 46e175c5323bb4..87d549ac5234e1 100644 --- a/code/modules/mob/living/basic/vermin/mouse.dm +++ b/code/modules/mob/living/basic/vermin/mouse.dm @@ -376,8 +376,7 @@ /// The mouse AI controller /datum/ai_controller/basic_controller/mouse - blackboard = list( - BB_BASIC_MOB_FLEEING = TRUE, // Always cowardly + blackboard = list( // Always cowardly BB_CURRENT_HUNTING_TARGET = null, // cheese BB_LOW_PRIORITY_HUNTING_TARGET = null, // cable BB_TARGETTING_DATUM = new /datum/targetting_datum/basic(), // Use this to find people to run away from diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index 9354f02e2b2df9..bc0d2e3d8e81ae 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -41,11 +41,14 @@ //Effects of bloodloss var/word = pick("dizzy","woozy","faint") switch(blood_volume) - if(BLOOD_VOLUME_EXCESS to BLOOD_VOLUME_MAX_LETHAL) + if(BLOOD_VOLUME_MAX_LETHAL to INFINITY) if(SPT_PROB(7.5, seconds_per_tick)) to_chat(src, span_userdanger("Blood starts to tear your skin apart. You're going to burst!")) investigate_log("has been gibbed by having too much blood.", INVESTIGATE_DEATHS) inflate_gib() + if(BLOOD_VOLUME_EXCESS to BLOOD_VOLUME_MAX_LETHAL) + if(SPT_PROB(5, seconds_per_tick)) + to_chat(src, span_warning("You feel your skin swelling.")) if(BLOOD_VOLUME_MAXIMUM to BLOOD_VOLUME_EXCESS) if(SPT_PROB(5, seconds_per_tick)) to_chat(src, span_warning("You feel terribly bloated.")) @@ -94,7 +97,7 @@ //Blood loss still happens in locker, floor stays clean if(isturf(loc) && prob(sqrt(amt)*BLOOD_DRIP_RATE_MOD)) - add_splatter_floor(loc, (amt >= 10)) + add_splatter_floor(loc, (amt <= 10)) /mob/living/carbon/human/bleed(amt) amt *= physiology.bleed_mod diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 10cff8c19acd1f..9918a21b4f6d40 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -552,7 +552,7 @@ /obj/item/organ/internal/brain/apply_organ_damage(damage_amount, maximum = maxHealth, required_organ_flag = NONE) . = ..() if(!owner) - return + return FALSE if(damage >= 60) owner.add_mood_event("brain_damage", /datum/mood_event/brain_damage) else diff --git a/code/modules/mob/living/carbon/alien/adult/adult_update_icons.dm b/code/modules/mob/living/carbon/alien/adult/adult_update_icons.dm index 8c2111511236bc..bbfd68f8186b8b 100644 --- a/code/modules/mob/living/carbon/alien/adult/adult_update_icons.dm +++ b/code/modules/mob/living/carbon/alien/adult/adult_update_icons.dm @@ -76,7 +76,7 @@ //Royals have bigger sprites, so inhand things must be handled differently. /mob/living/carbon/alien/adult/royal/update_held_items() - ..() + . = ..() remove_overlay(HANDS_LAYER) var/list/hands = list() diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index bc7a663206ae52..63ef8830435e12 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -103,7 +103,7 @@ In all, this is a lot like the monkey code. /N var/obj/item/organ/internal/ears/ears = get_organ_slot(ORGAN_SLOT_EARS) switch (severity) if (EXPLODE_DEVASTATE) - gib() + gib(DROP_ALL_REMAINS) if (EXPLODE_HEAVY) take_overall_damage(60, 60) diff --git a/code/modules/mob/living/carbon/alien/damage_procs.dm b/code/modules/mob/living/carbon/alien/damage_procs.dm index 8861a55d9931c6..5dbffda96739e0 100644 --- a/code/modules/mob/living/carbon/alien/damage_procs.dm +++ b/code/modules/mob/living/carbon/alien/damage_procs.dm @@ -11,5 +11,5 @@ return FALSE ///aliens are immune to stamina damage. -/mob/living/carbon/alien/setStaminaLoss(amount, updating_stamina = 1) +/mob/living/carbon/alien/setStaminaLoss(amount, updating_stamina = 1, forced = FALSE, required_biotype) return FALSE diff --git a/code/modules/mob/living/carbon/alien/death.dm b/code/modules/mob/living/carbon/alien/death.dm index 718186c9078e00..f5a0b7ace1b47f 100644 --- a/code/modules/mob/living/carbon/alien/death.dm +++ b/code/modules/mob/living/carbon/alien/death.dm @@ -1,5 +1,5 @@ -/mob/living/carbon/alien/spawn_gibs(with_bodyparts) - if(with_bodyparts) +/mob/living/carbon/alien/spawn_gibs(drop_bitflags=NONE) + if(drop_bitflags & DROP_BODYPARTS) new /obj/effect/gibspawner/xeno(drop_location(), src) else new /obj/effect/gibspawner/xeno/bodypartless(drop_location(), src) diff --git a/code/modules/mob/living/carbon/alien/larva/death.dm b/code/modules/mob/living/carbon/alien/larva/death.dm index 8fd6329a0c1de1..4b7f9f93218456 100644 --- a/code/modules/mob/living/carbon/alien/larva/death.dm +++ b/code/modules/mob/living/carbon/alien/larva/death.dm @@ -6,8 +6,8 @@ update_icons() -/mob/living/carbon/alien/larva/spawn_gibs(with_bodyparts) - if(with_bodyparts) +/mob/living/carbon/alien/larva/spawn_gibs(drop_bitflags=NONE) + if(drop_bitflags & DROP_BODYPARTS) new /obj/effect/gibspawner/larva(drop_location(), src) else new /obj/effect/gibspawner/larva/bodypartless(drop_location(), src) diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm index 5ef9b23c418212..af796c9ff685f7 100644 --- a/code/modules/mob/living/carbon/alien/organs.dm +++ b/code/modules/mob/living/carbon/alien/organs.dm @@ -336,7 +336,7 @@ if(owner) shake_camera(owner, 2, 5) owner.investigate_log("has been gibbed by something inside [owner.p_their()] stomach.", INVESTIGATE_DEATHS) - owner.gib() + owner.gib(DROP_ALL_REMAINS) qdel(src) /obj/item/organ/internal/stomach/alien/proc/eject_stomach(list/turf/targets, spit_range, content_speed, particle_delay, particle_count=4) 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 37fb827f3a5d5c..5a6746ec6fa8b2 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -126,8 +126,8 @@ if(gib_on_success) new_xeno.visible_message(span_danger("[new_xeno] bursts out of [owner] in a shower of gore!"), span_userdanger("You exit [owner], your previous host."), span_hear("You hear organic matter ripping and tearing!")) - // owner.investigate_log("has been gibbed by an alien larva.", INVESTIGATE_DEATHS) SKYRAT EDIT REMOVAL - ALIEN QOL - don't ever gib host. - // owner.gib(TRUE) SKYRAT EDIT REMOVAL - ALIEN QOL - don't ever gib host. + //owner.investigate_log("has been gibbed by an alien larva.", INVESTIGATE_DEATHS) // SKYRAT EDIT REMOVAL - ALIEN QOL - don't ever gib host. + //owner.gib(DROP_ORGANS|DROP_BODYPARTS) // SKYRAT EDIT ADDITION BEGIN - ALIEN QOL - You aren't getting gibbed but you aren't going to be having fun owner.apply_damage(150, BRUTE, BODY_ZONE_CHEST, wound_bonus = 30, sharpness = SHARP_POINTY) owner.spawn_gibs() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index de77200f940dbe..35dffd7c27ea93 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -10,6 +10,7 @@ COMSIG_CARBON_DISARM_COLLIDE = PROC_REF(disarm_collision), ) AddElement(/datum/element/connect_loc, loc_connections) + ADD_TRAIT(src, TRAIT_CAN_HOLD_ITEMS, INNATE_TRAIT) // Carbons are assumed to be innately capable of having arms, we check their arms count instead /mob/living/carbon/Destroy() //This must be done first, so the mob ghosts correctly before DNA etc is nulled @@ -27,45 +28,6 @@ QDEL_NULL(dna) GLOB.carbon_list -= src -/mob/living/carbon/perform_hand_swap(held_index) - . = ..() - if(!.) - return - - if(!held_index) - held_index = (active_hand_index % held_items.len)+1 - - if(!isnum(held_index)) - CRASH("You passed [held_index] into swap_hand instead of a number. WTF man") - - var/oindex = active_hand_index - active_hand_index = held_index - if(hud_used) - var/atom/movable/screen/inventory/hand/H - H = hud_used.hand_slots["[oindex]"] - if(H) - H.update_appearance() - H = hud_used.hand_slots["[held_index]"] - if(H) - H.update_appearance() - - -/mob/living/carbon/activate_hand(selhand) //l/r OR 1-held_items.len - if(!selhand) - selhand = (active_hand_index % held_items.len)+1 - - if(istext(selhand)) - selhand = lowertext(selhand) - if(selhand == "right" || selhand == "r") - selhand = 2 - if(selhand == "left" || selhand == "l") - selhand = 1 - - if(selhand != active_hand_index) - swap_hand(selhand) - else - mode() // Activate held item - /mob/living/carbon/attackby(obj/item/item, mob/living/user, params) if(!all_wounds || !(!user.combat_mode || user == src)) return ..() @@ -467,17 +429,18 @@ playsound(get_turf(src), 'sound/effects/splat.ogg', 50, TRUE) + var/need_mob_update = FALSE var/turf/location = get_turf(src) if(!blood) adjust_nutrition(-lost_nutrition) - adjustToxLoss(-3) + need_mob_update += adjustToxLoss(-3, updating_health = FALSE) for(var/i = 0 to distance) if(blood) if(location) add_splatter_floor(location) if(vomit_flags & MOB_VOMIT_HARM) - adjustBruteLoss(3) + need_mob_update += adjustBruteLoss(3, updating_health = FALSE) else if(location) location.add_vomit_floor(src, vomit_type, vomit_flags, purge_ratio) // call purge when doing detoxicfication to pump more chems out of the stomach. @@ -485,6 +448,8 @@ location = get_step(location, starting_dir) if (location?.is_blocked_turf()) break + if(need_mob_update) // so we only have to call updatehealth() once as opposed to n times + updatehealth() return TRUE diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 789a459b49287c..a51e9c3430e447 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -479,8 +479,7 @@ var/immediately_stun = should_stun && !(flags & SHOCK_DELAY_STUN) if (immediately_stun) if (paralyze) - //Paralyze(40) - SKYRAT EDIT REMOVAL - StaminaKnockdown(10, TRUE) // SKYRAT EDIT ADDITION + StaminaKnockdown(stun_duration / 4) // SKYRAT EDIT CHANGE - ORIGINAL: Paralyze(40) else Knockdown(stun_duration) //Jitter and other fluff. @@ -494,8 +493,7 @@ ///Called slightly after electrocute act to apply a secondary stun. /mob/living/carbon/proc/secondary_shock(paralyze, stun_duration) if (paralyze) - //Paralyze(60) - SKYRAT EDIT REMOVAL - StaminaKnockdown(10, TRUE) //SKYRAT EDIT ADDITION + StaminaKnockdown(stun_duration / 6) // SKYRAT EDIT CHANGE - ORIGINAL: Paralyze(60) else Knockdown(stun_duration) @@ -768,7 +766,7 @@ amount = min(amount, 0) //Prevents oxy damage but not healing . = ..() - check_passout(.) + check_passout() /mob/living/carbon/proc/get_interaction_efficiency(zone) var/obj/item/bodypart/limb = get_bodypart(zone) @@ -777,12 +775,12 @@ /mob/living/carbon/setOxyLoss(amount, updating_health = TRUE, forced, required_biotype, required_respiration_type) . = ..() - check_passout(.) + check_passout() /** * Check to see if we should be passed out from oyxloss */ -/mob/living/carbon/proc/check_passout(oxyloss) +/mob/living/carbon/proc/check_passout() if(!isnum(oxyloss)) return if(oxyloss <= 50) diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index bcf5f495715a48..c467cd2f0017a0 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -2,7 +2,7 @@ blood_volume = BLOOD_VOLUME_NORMAL gender = MALE pressure_resistance = 15 - hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,GLAND_HUD) + hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,GLAND_HUD, DNR_HUD) // SKYRAT EDIT ADDITION - DNR ICON has_limbs = TRUE held_items = list(null, null) num_legs = 0 //Populated on init through list/bodyparts diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm index 2aab0a5e2bb6c1..d4fa006957e717 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -282,11 +282,17 @@ update_body() /mob/living/carbon/update_held_items() + . = ..() remove_overlay(HANDS_LAYER) if (handcuffed) drop_all_held_items() return + overlays_standing[HANDS_LAYER] = get_held_overlays() + apply_overlay(HANDS_LAYER) + +/// Generate held item overlays +/mob/living/carbon/proc/get_held_overlays() var/list/hands = list() for(var/obj/item/I in held_items) if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) @@ -307,9 +313,7 @@ icon_file = I.righthand_file hands += I.build_worn_icon(default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE) - - overlays_standing[HANDS_LAYER] = hands - apply_overlay(HANDS_LAYER) + return hands /mob/living/carbon/update_fire_overlay(stacks, on_fire, last_icon_state, suffix = "") var/fire_icon = "[dna?.species.fire_overlay || "human"]_[stacks > MOB_BIG_FIRE_STACK_THRESHOLD ? "big_fire" : "small_fire"][suffix]" diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index 6e0c7cef8670c5..040bf76a3db027 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -56,40 +56,42 @@ return amount /mob/living/carbon/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) - if(!forced && (status_flags & GODMODE)) - return FALSE + if(!can_adjust_brute_loss(amount, forced, required_bodytype)) + return 0 if(amount > 0) - take_overall_damage(brute = amount, updating_health = updating_health, required_bodytype = required_bodytype) + . = take_overall_damage(brute = amount, updating_health = updating_health, forced = forced, required_bodytype = required_bodytype) else - heal_overall_damage(brute = abs(amount), required_bodytype = required_bodytype, updating_health = updating_health) - return amount + . = heal_overall_damage(brute = abs(amount), required_bodytype = required_bodytype, updating_health = updating_health, forced = forced) /mob/living/carbon/setBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) + if(!forced && (status_flags & GODMODE)) + return FALSE var/current = getBruteLoss() var/diff = amount - current if(!diff) - return - adjustBruteLoss(diff, updating_health, forced, required_bodytype) + return FALSE + return adjustBruteLoss(diff, updating_health, forced, required_bodytype) /mob/living/carbon/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) - if(!forced && (status_flags & GODMODE)) - return FALSE + if(!can_adjust_fire_loss(amount, forced, required_bodytype)) + return 0 if(amount > 0) - take_overall_damage(burn = amount, updating_health = updating_health, required_bodytype = required_bodytype) + . = take_overall_damage(burn = amount, updating_health = updating_health, forced = forced, required_bodytype = required_bodytype) else - heal_overall_damage(burn = abs(amount), required_bodytype = required_bodytype, updating_health = updating_health) - return amount + . = heal_overall_damage(burn = abs(amount), required_bodytype = required_bodytype, updating_health = updating_health, forced = forced) /mob/living/carbon/setFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) + if(!forced && (status_flags & GODMODE)) + return FALSE var/current = getFireLoss() var/diff = amount - current if(!diff) - return - adjustFireLoss(diff, updating_health, forced, required_bodytype) + return FALSE + return adjustFireLoss(diff, updating_health, forced, required_bodytype) -/mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = MOB_ORGANIC) - if(!forced && !(mob_biotypes & required_biotype)) - return +/mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL) + if(!can_adjust_tox_loss(amount, forced, required_biotype)) + return 0 if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage amount = -amount if(HAS_TRAIT(src, TRAIT_TOXIMMUNE)) //Prevents toxin damage, but not healing @@ -98,11 +100,11 @@ blood_volume = max(blood_volume - (5*amount), 0) else blood_volume = max(blood_volume - amount, 0) - else if(HAS_TRAIT(src, TRAIT_TOXIMMUNE)) //Prevents toxin damage, but not healing + else if(!forced && HAS_TRAIT(src, TRAIT_TOXIMMUNE)) //Prevents toxin damage, but not healing amount = min(amount, 0) return ..() -/mob/living/carbon/adjustStaminaLoss(amount, updating_stamina, forced, required_biotype) +/mob/living/carbon/adjustStaminaLoss(amount, updating_stamina, forced, required_biotype = ALL) . = ..() if(amount > 0) stam_regen_start_time = world.time + STAMINA_REGEN_BLOCK_TIME @@ -115,14 +117,16 @@ * * amount - damage to be done * * maximum - currently an arbitrarily large number, can be set so as to limit damage * * required_organ_flag - targets only a specific organ type if set to ORGAN_ORGANIC or ORGAN_ROBOTIC + * + * Returns: The net change in damage from apply_organ_damage() */ /mob/living/carbon/adjustOrganLoss(slot, amount, maximum, required_organ_flag = NONE) var/obj/item/organ/affected_organ = get_organ_slot(slot) if(!affected_organ || (status_flags & GODMODE)) - return + return FALSE if(required_organ_flag && !(affected_organ.organ_flags & required_organ_flag)) - return - affected_organ.apply_organ_damage(amount, maximum) + return FALSE + return affected_organ.apply_organ_damage(amount, maximum) /** * If an organ exists in the slot requested, and we are capable of taking damage (we don't have [GODMODE] on), call the set damage proc on that organ, which can @@ -132,16 +136,18 @@ * * slot - organ slot, like [ORGAN_SLOT_HEART] * * amount - damage to be set to * * required_organ_flag - targets only a specific organ type if set to ORGAN_ORGANIC or ORGAN_ROBOTIC + * + * Returns: The net change in damage from set_organ_damage() */ /mob/living/carbon/setOrganLoss(slot, amount, required_organ_flag = NONE) var/obj/item/organ/affected_organ = get_organ_slot(slot) if(!affected_organ || (status_flags & GODMODE)) - return + return FALSE if(required_organ_flag && !(affected_organ.organ_flags & required_organ_flag)) - return + return FALSE if(affected_organ.damage == amount) - return - affected_organ.set_organ_damage(amount) + return FALSE + return affected_organ.set_organ_damage(amount) /** * If an organ exists in the slot requested, return the amount of damage that organ has @@ -200,14 +206,16 @@ * It automatically updates health status */ /mob/living/carbon/heal_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype = NONE, target_zone = null) + . = FALSE var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute, burn, required_bodytype, target_zone) if(!parts.len) return + var/obj/item/bodypart/picked = pick(parts) - var/damage_calculator = picked.get_damage(TRUE) //heal_damage returns update status T/F instead of amount healed so we dance gracefully around this - if(picked.heal_damage(brute, burn, required_bodytype)) + var/damage_calculator = picked.get_damage() //heal_damage returns update status T/F instead of amount healed so we dance gracefully around this + if(picked.heal_damage(abs(brute), abs(burn), required_bodytype = required_bodytype)) update_damage_overlays() - return max(damage_calculator - picked.get_damage(TRUE), 0) + return (damage_calculator - picked.get_damage()) /** @@ -218,15 +226,25 @@ * It automatically updates health status */ /mob/living/carbon/take_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE) + . = FALSE + if(status_flags & GODMODE) + return var/list/obj/item/bodypart/parts = get_damageable_bodyparts(required_bodytype) if(!parts.len) return + var/obj/item/bodypart/picked = pick(parts) - if(picked.receive_damage(brute, burn, check_armor ? run_armor_check(picked, (brute ? MELEE : burn ? FIRE : null)) : FALSE, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) + var/damage_calculator = picked.get_damage() + if(picked.receive_damage(abs(brute), abs(burn), check_armor ? run_armor_check(picked, (brute ? MELEE : burn ? FIRE : null)) : FALSE, wound_bonus = wound_bonus, bare_wound_bonus = bare_wound_bonus, sharpness = sharpness)) update_damage_overlays() + return (damage_calculator - picked.get_damage()) + +/mob/living/carbon/heal_overall_damage(brute = 0, burn = 0, stamina = 0, required_bodytype, updating_health = TRUE, forced = FALSE) + . = FALSE + // treat negative args as positive + brute = abs(brute) + burn = abs(burn) -///Heal MANY bodyparts, in random order -/mob/living/carbon/heal_overall_damage(brute = 0, burn = 0, stamina = 0, required_bodytype, updating_health = TRUE) var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute, burn, required_bodytype) var/update = NONE @@ -235,25 +253,35 @@ var/brute_was = picked.brute_dam var/burn_was = picked.burn_dam + . += picked.get_damage() - update |= picked.heal_damage(brute, burn, required_bodytype, FALSE) + update |= picked.heal_damage(brute, burn, updating_health = FALSE, forced = forced, required_bodytype = required_bodytype) + + . -= picked.get_damage() // return the net amount of damage healed brute = round(brute - (brute_was - picked.brute_dam), DAMAGE_PRECISION) burn = round(burn - (burn_was - picked.burn_dam), DAMAGE_PRECISION) parts -= picked + + if(!.) // no change? no need to update anything + return + if(updating_health) updatehealth() if(update) update_damage_overlays() -/// damage MANY bodyparts, in random order -/mob/living/carbon/take_overall_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_bodytype) - if(status_flags & GODMODE) - return //godmode +/mob/living/carbon/take_overall_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, forced = FALSE, required_bodytype) + . = FALSE + if(!forced && (status_flags & GODMODE)) + return + // treat negative args as positive + brute = abs(brute) + burn = abs(burn) var/list/obj/item/bodypart/parts = get_damageable_bodyparts(required_bodytype) - var/update = 0 + var/update = NONE while(parts.len && (brute > 0 || burn > 0)) var/obj/item/bodypart/picked = pick(parts) var/brute_per_part = round(brute/parts.len, DAMAGE_PRECISION) @@ -261,14 +289,21 @@ var/brute_was = picked.brute_dam var/burn_was = picked.burn_dam + . += picked.get_damage() + // disabling wounds from these for now cuz your entire body snapping cause your heart stopped would suck + update |= picked.receive_damage(brute_per_part, burn_per_part, blocked = FALSE, updating_health = FALSE, forced = forced, required_bodytype = required_bodytype, wound_bonus = CANT_WOUND) - update |= picked.receive_damage(brute_per_part, burn_per_part, FALSE, updating_health, required_bodytype, wound_bonus = CANT_WOUND) // disabling wounds from these for now cuz your entire body snapping cause your heart stopped would suck + . -= picked.get_damage() // return the net amount of damage healed brute = round(brute - (picked.brute_dam - brute_was), DAMAGE_PRECISION) burn = round(burn - (picked.burn_dam - burn_was), DAMAGE_PRECISION) parts -= picked + + if(!.) // no change? no need to update anything + return + if(updating_health) updatehealth() if(update) diff --git a/code/modules/mob/living/carbon/death.dm b/code/modules/mob/living/carbon/death.dm index 4d14fb7df669aa..bbf82ccefc56a7 100644 --- a/code/modules/mob/living/carbon/death.dm +++ b/code/modules/mob/living/carbon/death.dm @@ -24,9 +24,9 @@ M.Scale(1.8, 1.2) animate(src, time = 40, transform = M, easing = SINE_EASING) -/mob/living/carbon/gib(no_brain, no_organs, no_bodyparts, safe_gib = FALSE) +/mob/living/carbon/gib(drop_bitflags=NONE) add_memory_in_range(src, 7, /datum/memory/witness_gib, protagonist = src) - if(safe_gib) // If you want to keep all the mob's items and not have them deleted + if(drop_bitflags & DROP_ITEMS) for(var/obj/item/W in src) dropItemToGround(W) if(prob(50)) @@ -37,39 +37,33 @@ visible_message(span_danger("[M] bursts out of [src]!")) return ..() -/mob/living/carbon/spill_organs(no_brain, no_organs, no_bodyparts) +/mob/living/carbon/spill_organs(drop_bitflags=NONE) var/atom/Tsec = drop_location() - if(!no_bodyparts) - if(no_organs)//so the organs don't get transferred inside the bodyparts we'll drop. - for(var/organ in organs) - if(no_brain || !istype(organ, /obj/item/organ/internal/brain)) - qdel(organ) - else //we're going to drop all bodyparts except chest, so the only organs that needs spilling are those inside it. - for(var/obj/item/organ/organ as anything in organs) - if(no_brain && istype(organ, /obj/item/organ/internal/brain)) - qdel(organ) //so the brain isn't transferred to the head when the head drops. - continue - var/org_zone = check_zone(organ.zone) //both groin and chest organs. - if(org_zone == BODY_ZONE_CHEST) - organ.Remove(src) - organ.forceMove(Tsec) - organ.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5) - else - for(var/obj/item/organ/organ as anything in organs) - if(no_brain && istype(organ, /obj/item/organ/internal/brain)) - qdel(organ) - continue - if(no_organs && !istype(organ, /obj/item/organ/internal/brain)) - qdel(organ) - continue + + for(var/obj/item/organ/organ as anything in organs) + if((drop_bitflags & DROP_BRAIN) && istype(organ, /obj/item/organ/internal/brain)) + if(drop_bitflags & DROP_BODYPARTS) + continue // the head will drop, so the brain should stay inside + organ.Remove(src) organ.forceMove(Tsec) - organ.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5) + organ.throw_at(get_edge_target_turf(src, pick(GLOB.alldirs)), rand(1,3), 5) + continue + + if((drop_bitflags & DROP_ORGANS) && !istype(organ, /obj/item/organ/internal/brain)) + if((drop_bitflags & DROP_BODYPARTS) && (check_zone(organ.zone) != BODY_ZONE_CHEST)) + continue // only chest & groin organs will be ejected + + organ.Remove(src) + organ.forceMove(Tsec) + organ.throw_at(get_edge_target_turf(src, pick(GLOB.alldirs)), rand(1,3), 5) + continue + + qdel(organ) -/// Launches all bodyparts away from the mob. skip_head will keep the head attached. -/mob/living/carbon/spread_bodyparts(skip_head = FALSE) +/mob/living/carbon/spread_bodyparts(drop_bitflags=NONE) for(var/obj/item/bodypart/part as anything in bodyparts) - if(skip_head && part.body_zone == BODY_ZONE_HEAD) + if(!(drop_bitflags & DROP_BRAIN) && part.body_zone == BODY_ZONE_HEAD) continue else if(part.body_zone == BODY_ZONE_CHEST) continue diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index 50817e54f8f535..22589f0944078b 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -449,6 +449,13 @@ GLOBAL_LIST_EMPTY(features_by_species) wearer.hud_used?.update_locked_slots() worn_items_fit_body_check(wearer) +/** + * Normalizes blood in a human if it is excessive. If it is above BLOOD_VOLUME_NORMAL, this will clamp it to that value. It will not give the human more blodo than they have less than this value. + */ +/datum/species/proc/normalize_blood(mob/living/carbon/human/blood_possessing_human) + var/normalized_blood_values = max(blood_possessing_human.blood_volume, 0, BLOOD_VOLUME_NORMAL) + blood_possessing_human.blood_volume = normalized_blood_values + /** * Proc called when a carbon becomes this species. * @@ -459,34 +466,37 @@ GLOBAL_LIST_EMPTY(features_by_species) * * old_species - The species that the carbon used to be before becoming this race, used for regenerating organs. * * pref_load - Preferences to be loaded from character setup, loads in preferred mutant things like bodyparts, digilegs, skin color, etc. */ -/datum/species/proc/on_species_gain(mob/living/carbon/human/C, datum/species/old_species, pref_load) +/datum/species/proc/on_species_gain(mob/living/carbon/human/human_who_gained_species, datum/species/old_species, pref_load) SHOULD_CALL_PARENT(TRUE) // Drop the items the new species can't wear - if(C.hud_used) - C.hud_used.update_locked_slots() + if(human_who_gained_species.hud_used) + human_who_gained_species.hud_used.update_locked_slots() - C.mob_biotypes = inherent_biotypes - C.mob_respiration_type = inherent_respiration_type - C.butcher_results = knife_butcher_results?.Copy() + human_who_gained_species.mob_biotypes = inherent_biotypes + human_who_gained_species.mob_respiration_type = inherent_respiration_type + human_who_gained_species.butcher_results = knife_butcher_results?.Copy() if(old_species.type != type) - replace_body(C, src) + replace_body(human_who_gained_species, src) - regenerate_organs(C, old_species, visual_only = C.visual_only_organs) + regenerate_organs(human_who_gained_species, old_species, visual_only = human_who_gained_species.visual_only_organs) // Drop the items the new species can't wear - INVOKE_ASYNC(src, PROC_REF(worn_items_fit_body_check), C, TRUE) + INVOKE_ASYNC(src, PROC_REF(worn_items_fit_body_check), human_who_gained_species, TRUE) //Assigns exotic blood type if the species has one - if(exotic_bloodtype && C.dna.blood_type != exotic_bloodtype) - C.dna.blood_type = exotic_bloodtype + if(exotic_bloodtype && human_who_gained_species.dna.blood_type != exotic_bloodtype) + human_who_gained_species.dna.blood_type = exotic_bloodtype //Otherwise, check if the previous species had an exotic bloodtype and we do not have one and assign a random blood type //(why the fuck is blood type not tied to a fucking DNA block?) else if(old_species.exotic_bloodtype && !exotic_bloodtype) - C.dna.blood_type = random_blood_type() + human_who_gained_species.dna.blood_type = random_blood_type() + + //Resets blood if it is excessively high so they don't gib + normalize_blood(human_who_gained_species) - if(ishuman(C)) - var/mob/living/carbon/human/human = C + if(ishuman(human_who_gained_species)) + var/mob/living/carbon/human/human = human_who_gained_species for(var/obj/item/organ/external/organ_path as anything in external_organs) if(!should_external_organ_apply_to(organ_path, human)) continue @@ -495,25 +505,27 @@ GLOBAL_LIST_EMPTY(features_by_species) var/obj/item/organ/external/new_organ = SSwardrobe.provide_type(organ_path) new_organ.Insert(human, special=TRUE, drop_if_replaced=FALSE) + + if(length(inherent_traits)) - C.add_traits(inherent_traits, SPECIES_TRAIT) + human_who_gained_species.add_traits(inherent_traits, SPECIES_TRAIT) if(inherent_factions) for(var/i in inherent_factions) - C.faction += i //Using +=/-= for this in case you also gain the faction from a different source. + human_who_gained_species.faction += i //Using +=/-= for this in case you also gain the faction from a different source. // All languages associated with this language holder are added with source [LANGUAGE_SPECIES] // rather than source [LANGUAGE_ATOM], so we can track what to remove if our species changes again var/datum/language_holder/gaining_holder = GLOB.prototype_language_holders[species_language_holder] for(var/language in gaining_holder.understood_languages) - C.grant_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES) + human_who_gained_species.grant_language(language, UNDERSTOOD_LANGUAGE, LANGUAGE_SPECIES) for(var/language in gaining_holder.spoken_languages) - C.grant_language(language, SPOKEN_LANGUAGE, LANGUAGE_SPECIES) + human_who_gained_species.grant_language(language, SPOKEN_LANGUAGE, LANGUAGE_SPECIES) for(var/language in gaining_holder.blocked_languages) - C.add_blocked_language(language, LANGUAGE_SPECIES) - C.regenerate_icons() + human_who_gained_species.add_blocked_language(language, LANGUAGE_SPECIES) + human_who_gained_species.regenerate_icons() - SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species) + SEND_SIGNAL(human_who_gained_species, COMSIG_SPECIES_GAIN, src, old_species) properly_gained = TRUE @@ -1444,7 +1456,7 @@ GLOBAL_LIST_EMPTY(features_by_species) var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.brain_mod H.adjustOrganLoss(ORGAN_SLOT_BRAIN, damage_amount) SEND_SIGNAL(H, COMSIG_MOB_AFTER_APPLY_DAMAGE, damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item) - return 1 + return TRUE /datum/species/proc/on_hit(obj/projectile/P, mob/living/carbon/human/H) // called when hit by a projectile @@ -1893,12 +1905,21 @@ GLOBAL_LIST_EMPTY(features_by_species) /datum/species/proc/on_owner_login(mob/living/carbon/human/owner) return +/** + * Gets a description of the species' *physical* attributes. What makes playing as one different. Used in magic mirrors. + * + * Returns a string. + */ + +/datum/species/proc/get_physical_attributes() + return "An unremarkable species." /** * Gets a short description for the specices. Should be relatively succinct. * Used in the preference menu. * * Returns a string. */ + /datum/species/proc/get_species_description() SHOULD_CALL_PARENT(FALSE) diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 90b94689796c16..3c0ffb2536b790 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -5,8 +5,8 @@ GLOBAL_LIST_EMPTY(dead_players_during_shift) /mob/living/carbon/human/dust_animation() new /obj/effect/temp_visual/dust_animation(loc, dna.species.dust_anim) -/mob/living/carbon/human/spawn_gibs(with_bodyparts) - if(with_bodyparts) +/mob/living/carbon/human/spawn_gibs(drop_bitflags=NONE) + if(drop_bitflags & DROP_BODYPARTS) new /obj/effect/gibspawner/human(drop_location(), src, get_static_viruses()) else new /obj/effect/gibspawner/human/bodypartless(drop_location(), src, get_static_viruses()) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 680e5c14f7ea6e..0905a4ac40ff83 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -733,7 +733,7 @@ if(heal_flags & HEAL_NEGATIVE_MUTATIONS) for(var/datum/mutation/human/existing_mutation in dna.mutations) if(existing_mutation.quality != POSITIVE) - dna.remove_mutation(existing_mutation.name) + dna.remove_mutation(existing_mutation) if(heal_flags & HEAL_TEMP) set_coretemperature(get_body_temp_normal(apply_change = FALSE)) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index b02aaf03b17bf4..233f9fe25fd29e 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -414,7 +414,7 @@ if(EXPLODE_LIGHT) SSexplosions.low_mov_atom += thing investigate_log("has been gibbed by an explosion.", INVESTIGATE_DEATHS) - gib() + gib(DROP_ALL_REMAINS) return TRUE else brute_loss = 500 diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index fb015a237d04d0..cfda7721da0c97 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -5,7 +5,7 @@ icon = 'icons/mob/human/human.dmi' icon_state = "human_basic" appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE|LONG_GLIDE - hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD,GLAND_HUD,SENTIENT_DISEASE_HUD,FAN_HUD,PERMIT_HUD) //SKYRAT EDIT: ADD PERMIT_HUD + hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD,GLAND_HUD,SENTIENT_DISEASE_HUD,FAN_HUD,PERMIT_HUD, DNR_HUD) //SKYRAT EDIT ADDITION - PERMIT_HUD, DNR_HUD hud_type = /datum/hud/human pressure_resistance = 25 can_buckle = TRUE diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm index bb112144447fd5..42eb727a83d331 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -87,7 +87,6 @@ There are several things that need to be remembered: if(check_obscured_slots(transparent_protection = TRUE) & ITEM_SLOT_ICLOTHING) return - var/target_overlay = uniform.icon_state if(uniform.adjusted == ALT_STYLE) target_overlay = "[target_overlay]_d" @@ -102,19 +101,29 @@ There are several things that need to be remembered: var/handled_by_bodytype = TRUE var/icon_file var/woman + var/digi // SKYRAT EDIT ADDITION - Digi female gender shaping + var/female_sprite_flags = uniform.female_sprite_flags // SKYRAT EDIT ADDITION - Digi female gender shaping var/mutant_styles = NONE // SKYRAT EDIT ADDITON - mutant styles to pass down to build_worn_icon. //BEGIN SPECIES HANDLING if((bodytype & BODYTYPE_MONKEY) && (uniform.supports_variations_flags & CLOTHING_MONKEY_VARIATION)) - icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_UNIFORM, w_uniform, src) // SKYRAT EDIT CHANGE + icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_UNIFORM, w_uniform, src) // SKYRAT EDIT CHANGE - ORIGINAL: icon_file = MONKEY_UNIFORM_FILE else if((bodytype & BODYTYPE_DIGITIGRADE) && (uniform.supports_variations_flags & CLOTHING_DIGITIGRADE_VARIATION)) - icon_file = uniform.worn_icon_digi || DIGITIGRADE_UNIFORM_FILE // SKYRAT EDIT CHANGE + icon_file = uniform.worn_icon_digi || DIGITIGRADE_UNIFORM_FILE // SKYRAT EDIT CHANGE - ORIGINAL: icon_file = DIGITIGRADE_UNIFORM_FILE + digi = TRUE // SKYRAT EDIT ADDITION - Digi female gender shaping // SKYRAT EDIT ADDITION - birbs else if(bodytype & BODYTYPE_CUSTOM) icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_UNIFORM, w_uniform, src) // Might have to refactor how this works eventually, maybe. // SKYRAT EDIT END //Female sprites have lower priority than digitigrade sprites - else if(dna.species.sexes && (bodytype & BODYTYPE_HUMANOID) && physique == FEMALE && !(uniform.female_sprite_flags & NO_FEMALE_UNIFORM)) //Agggggggghhhhh + if(dna.species.sexes && (bodytype & BODYTYPE_HUMANOID) && physique == FEMALE && !(female_sprite_flags & NO_FEMALE_UNIFORM)) //Agggggggghhhhh // SKYRAT EDIT CHANGE - ORIGINAL: else if(dna.species.sexes && (bodytype & BODYTYPE_HUMANOID) && physique == FEMALE && !(uniform.female_sprite_flags & NO_FEMALE_UNIFORM)) woman = TRUE + // SKYRAT EDIT ADDITION START - Digi female gender shaping + if(digi) + mutant_styles |= STYLE_DIGI // for passing to wear_female_version + if(!(female_sprite_flags & FEMALE_UNIFORM_DIGI_FULL)) + female_sprite_flags &= ~FEMALE_UNIFORM_FULL // clear the FEMALE_UNIFORM_DIGI_FULL bit if it was set, we don't want that. + female_sprite_flags |= FEMALE_UNIFORM_TOP_ONLY // And set the FEMALE_UNIFORM_TOP bit if it is unset. + // SKYRAT EDIT ADDITION END if(!icon_exists(icon_file, RESOLVE_ICON_STATE(uniform))) icon_file = DEFAULT_UNIFORM_FILE @@ -131,7 +140,7 @@ There are several things that need to be remembered: default_layer = UNIFORM_LAYER, default_icon_file = icon_file, isinhands = FALSE, - female_uniform = woman ? uniform.female_sprite_flags : null, + female_uniform = woman ? female_sprite_flags : null, // SKYRAT EDIT CHANGE - Digi female gender shaping - ORIGINAL: female_uniform = woman ? uniform.female_sprite_flags : null, override_state = target_overlay, override_file = handled_by_bodytype ? icon_file : null, mutant_styles = mutant_styles, // SKYRAT EDIT ADDITION - Taur-friendly uniforms! @@ -157,7 +166,9 @@ There are several things that need to be remembered: var/obj/item/worn_item = wear_id update_hud_id(worn_item) var/icon_file = 'icons/mob/clothing/id.dmi' + id_overlay = wear_id.build_worn_icon(default_layer = ID_LAYER, default_icon_file = icon_file) + if(!id_overlay) return @@ -167,6 +178,7 @@ There are several things that need to be remembered: apply_overlay(ID_LAYER) + /mob/living/carbon/human/update_worn_gloves() remove_overlay(GLOVES_LAYER) @@ -644,12 +656,7 @@ There are several things that need to be remembered: apply_overlay(LEGCUFF_LAYER) throw_alert("legcuffed", /atom/movable/screen/alert/restrained/legcuffed, new_master = src.legcuffed) -/mob/living/carbon/human/update_held_items() - remove_overlay(HANDS_LAYER) - if (handcuffed) - drop_all_held_items() - return - +/mob/living/carbon/human/get_held_overlays() var/list/hands = list() for(var/obj/item/worn_item in held_items) var/held_index = get_held_index_of_item(worn_item) @@ -678,11 +685,10 @@ There are several things that need to be remembered: held_in_hand?.held_hand_offset?.apply_offset(hand_overlay) hands += hand_overlay - overlays_standing[HANDS_LAYER] = hands - apply_overlay(HANDS_LAYER) + return hands -/proc/wear_female_version(t_color, icon, layer, type, greyscale_colors) - var/index = "[t_color]-[greyscale_colors]" +/proc/wear_female_version(t_color, icon, layer, type, greyscale_colors, mutant_styles) // SKYRAT EDIT CHANGE - Digi female gender shaping - ORIGINAL: /proc/wear_female_version(t_color, icon, layer, type, greyscale_colors) + var/index = "[t_color]-[greyscale_colors][(mutant_styles & STYLE_DIGI) ? "-d" : ""]" // SKYRAT EDIT CHANGE - Digi female gender shaping - Original: var/index = "[t_color]-[greyscale_colors]]" var/icon/female_clothing_icon = GLOB.female_clothing_icons[index] if(!female_clothing_icon) //Create standing/laying icons if they don't exist generate_female_clothing(index, t_color, icon, type) @@ -834,7 +840,7 @@ mutant_styles: The mutant style - taur bodytype, STYLE_TESHARI, etc. // SKYRAT E var/mutable_appearance/standing if(female_uniform) - standing = wear_female_version(t_state, file2use, layer2use, female_uniform, greyscale_colors) //should layer2use be in sync with the adjusted value below? needs testing - shiz + standing = wear_female_version(t_state, file2use, layer2use, female_uniform, greyscale_colors, mutant_styles) //should layer2use be in sync with the adjusted value below? needs testing - shiz // SKYRAT EDIT CHANGE - ORIGINAL: standing = wear_female_version(t_state, file2use, layer2use, female_uniform, greyscale_colors) if(!standing) standing = mutable_appearance(file2use, t_state, -layer2use) // SKYRAT EDIT ADDITION START - Taur-friendly uniforms and suits @@ -879,7 +885,6 @@ mutant_styles: The mutant style - taur bodytype, STYLE_TESHARI, etc. // SKYRAT E return standing - /// Returns offsets used for equipped item overlays in list(px_offset,py_offset) form. /obj/item/proc/get_worn_offsets(isinhands) . = list(0,0) //(px,py) diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm index 58a46da81a4882..349742a15e5368 100644 --- a/code/modules/mob/living/carbon/human/species_types/abductors.dm +++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm @@ -28,6 +28,11 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/abductor, ) + +/datum/species/abductor/get_physical_attributes() + return "Abductors do not need to breathe, eat, do not have blood, a heart, stomach, or lungs and cannot be infected by human viruses. \ + Their hardy physique prevents their skin from being wounded or dismembered, but their chunky tridactyl hands make it hard to operate human equipment." + /datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() var/datum/atom_hud/abductor_hud = GLOB.huds[DATA_HUD_ABDUCTOR] diff --git a/code/modules/mob/living/carbon/human/species_types/android.dm b/code/modules/mob/living/carbon/human/species_types/android.dm index e0da3a4ecbf3e6..ed8163a153889b 100644 --- a/code/modules/mob/living/carbon/human/species_types/android.dm +++ b/code/modules/mob/living/carbon/human/species_types/android.dm @@ -51,3 +51,8 @@ . = ..() // Androids don't eat, hunger or metabolise foods. Let's do some cleanup. C.set_safe_hunger_level() + +/datum/species/android/get_physical_attributes() + return "Androids are almost, but not quite, identical to fully augmented humans. \ + Unlike those, though, they're completely immune to toxin damage, don't have blood or organs (besides their head), don't get hungry, and can reattach their limbs! \ + That said, an EMP will devastate them and they cannot process any chemicals." 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 8b429bbeb8f6bd..c9609f2d43baff 100644 --- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm +++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm @@ -74,7 +74,7 @@ if(QDELETED(my_head)) my_head = null human.investigate_log("has been gibbed by the loss of [human.p_their()] head.", INVESTIGATE_DEATHS) - human.gib() + human.gib(DROP_ALL_REMAINS) return if(my_head.loc.name != human.real_name && istype(my_head.loc, /obj/item/bodypart/head)) @@ -87,7 +87,7 @@ if(illegal_head) my_head = null human.investigate_log("has been gibbed by having an illegal head put on [human.p_their()] shoulders.", INVESTIGATE_DEATHS) - human.gib() // Yeah so giving them a head on their body is really not a good idea, so their original head will remain but uh, good luck fixing it after that. + human.gib(DROP_ALL_REMAINS) // Yeah so giving them a head on their body is really not a good idea, so their original head will remain but uh, good luck fixing it after that. /datum/species/dullahan/proc/update_vision_perspective(mob/living/carbon/human/human) var/obj/item/organ/internal/eyes/eyes = human.get_organ_slot(ORGAN_SLOT_EYES) @@ -114,6 +114,8 @@ eyes_toggle_perspective_action?.Trigger() owner_first_client_connection_handled = TRUE +/datum/species/dullahan/get_physical_attributes() + return "A dullahan is much like a human, but their head is detached from their body and must be carried around." /datum/species/dullahan/get_species_description() return "An angry spirit, hanging onto the land of the living for \ @@ -265,7 +267,7 @@ if(isdullahan(human)) var/datum/species/dullahan/dullahan_species = human.dna.species dullahan_species.my_head = null - owner.gib() + owner.gib(DROP_ALL_REMAINS) owner = null return ..() diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm index 42c718477bce25..4c28d190efff4a 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -209,6 +209,11 @@ 'sound/voice/ethereal/ethereal_scream_3.ogg', ) +/datum/species/ethereal/get_physical_attributes() + return "Ethereals process electricity as their power supply, not food, and are somewhat resistant to it.\ + They do so via their crystal core, their equivalent of a human heart, which will also encase them in a reviving crystal if they die.\ + However, their skin is very thin and easy to pierce with brute weaponry." + /datum/species/ethereal/get_species_description() return "Coming from the planet of Sprout, the theocratic ethereals are \ separated socially by caste, and espouse a dogma of aiding the weak and \ @@ -272,7 +277,7 @@ TRAIT_FIXED_MUTANT_COLORS, TRAIT_FIXED_HAIRCOLOR, TRAIT_AGENDER, - TRAIT_TENACIOUS, + TRAIT_TENACIOUS, // this doesn't work. tenacity is an element TRAIT_NOBREATH, TRAIT_RESISTHIGHPRESSURE, TRAIT_RESISTLOWPRESSURE, @@ -287,6 +292,10 @@ BODY_ZONE_CHEST = /obj/item/bodypart/chest/ethereal, ) +/datum/species/ethereal/lustrous/get_physical_attributes() + return "Lustrous are what remains of an Ethereal after freebasing esoteric drugs. \ + They are pressure immune, virus immune, can see bluespace tears in reality, and have a really weird scream. They remain vulnerable to physical damage." + /datum/species/ethereal/lustrous/get_scream_sound(mob/living/carbon/human/ethereal) return pick( 'sound/voice/ethereal/lustrous_scream_1.ogg', diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm index c8e14a6afd12d5..61647c5aba23cf 100644 --- a/code/modules/mob/living/carbon/human/species_types/felinid.dm +++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm @@ -147,6 +147,10 @@ human_for_preview.update_body(TRUE) // SKYRAT EDIT END +/datum/species/human/felinid/get_physical_attributes() + return "Felinids are very similar to humans in almost all respects, with their biggest differences being the ability to lick their wounds, \ + and an increased sensitivity to noise, which is often detrimental. They are also rather fond of eating oranges." + /datum/species/human/felinid/get_species_description() return "Felinids are one of the many types of bespoke genetic \ modifications to come of humanity's mastery of genetic science, and are \ diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm index 7f1d1112115693..c36252bbcb2dc9 100644 --- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm @@ -37,6 +37,9 @@ return 30 //Flyswatters deal 30x damage to flypeople. return 1 +/datum/species/fly/get_physical_attributes() + return "These hideous creatures suffer from pesticide immensely, eat waste, and are incredibly vulnerable to bright lights. They do have wings though." + /datum/species/fly/get_species_description() return "With no official documentation or knowledge of the origin of \ this species, they remain a mystery to most. Any and all rumours among \ 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 3f5f46edf6c3ac..91ec9dfe0c5c57 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -58,6 +58,10 @@ name += " [pick(GLOB.last_names)]" return name +/datum/species/golem/get_physical_attributes() + return "Golems are hardy creatures made out of stone, which are thus naturally resistant to many dangers, including asphyxiation, fire, radiation, electricity, and viruses.\ + They gain special abilities depending on the type of material consumed, but they need to consume material to keep their body animated." + /datum/species/golem/create_pref_unique_perks() var/list/to_add = list() diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index 2c997274ffb9e8..9db5a3253eb60d 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -18,7 +18,7 @@ human_mob.skin_tone = random_skin_tone() /datum/species/human/get_scream_sound(mob/living/carbon/human/human) - if(human.gender == MALE) + if(human.physique == MALE) if(prob(1)) return 'sound/voice/human/wilhelm_scream.ogg' return pick( 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 82f0e88c2bd790..2f5c977110a351 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -201,6 +201,11 @@ BODY_ZONE_CHEST = /obj/item/bodypart/chest/slime, ) +/datum/species/jelly/slime/get_physical_attributes() + return "Slimepeople have jelly for blood and their vacuoles can extremely quickly convert plasma to it if they're breathing it in.\ + They can then use the excess blood to split off an excess body, which their consciousness can transfer to at will or on death.\ + Most things that are toxic heal them, but most things that prevent toxicity damage them!" + /datum/species/jelly/slime/on_species_loss(mob/living/carbon/C) if(slime_split) slime_split.Remove(C) @@ -501,6 +506,10 @@ /// The cooldown of us using exteracts COOLDOWN_DECLARE(extract_cooldown) +/datum/species/jelly/luminescent/get_physical_attributes() + return "Luminescent are able to integrate slime extracts into themselves for wondrous effects. \ + Most things that are toxic heal them, but most things that prevent toxicity damage them!" + //Species datums don't normally implement destroy, but JELLIES SUCK ASS OUT OF A STEEL STRAW and have to i guess /datum/species/jelly/luminescent/Destroy(force) current_extract = null @@ -670,6 +679,10 @@ /// Special "project thought" telepathy action for stargazers. var/datum/action/innate/project_thought/project_action +/datum/species/jelly/stargazer/get_physical_attributes() + return "Stargazers can link others' minds with their own, creating a private communication channel. \ + Most things that are toxic heal them, but most things that prevent toxicity damage them!" + /datum/species/jelly/stargazer/on_species_gain(mob/living/carbon/grant_to, datum/species/old_species) . = ..() project_action = new(src) diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index 68420fe460fc14..020cd7b4ebf89b 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -89,6 +89,10 @@ 'sound/voice/lizard/lizard_scream_3.ogg', ) +/datum/species/lizard/get_physical_attributes() + return "Lizardpeople can withstand slightly higher temperatures than most species, but they are very vulnerable to the cold \ + and can't regulate their body-temperature internally, making the vacuum of space extremely deadly to them." + /datum/species/lizard/get_species_description() return "The militaristic Lizardpeople hail originally from Tizira, but have grown \ throughout their centuries in the stars to possess a large spacefaring \ @@ -155,6 +159,10 @@ Lizard subspecies: ASHWALKERS BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/lizard, ) +/datum/species/lizard/get_physical_attributes() + return "Ash Walkers are identical to lizardpeople in almost all aspects. \ + Unlike them, they're always digitigrade, they can breathe Lavaland's often noxious atmosphere and resist viruses. They are usually illiterate." + /* Lizard subspecies: SILVER SCALED */ @@ -184,6 +192,11 @@ Lizard subspecies: SILVER SCALED ///See above var/old_eye_color_right +/datum/species/lizard/silverscale/get_physical_attributes() + return "Silver Scales are to lizardpeople what angels are to humans. \ + Mostly identical, they are holy, don't breathe, don't get viruses, their hide cannot be pierced, love the taste of wine, \ + and their tongue allows them to turn into a statue, for some reason." + /datum/species/lizard/silverscale/on_species_gain(mob/living/carbon/human/new_silverscale, datum/species/old_species, pref_load) old_mutcolor = new_silverscale.dna.features["mcolor"] old_eye_color_left = new_silverscale.eye_color_left diff --git a/code/modules/mob/living/carbon/human/species_types/monkeys.dm b/code/modules/mob/living/carbon/human/species_types/monkeys.dm index 243c1be83b3587..2d054c67c71208 100644 --- a/code/modules/mob/living/carbon/human/species_types/monkeys.dm +++ b/code/modules/mob/living/carbon/human/species_types/monkeys.dm @@ -133,6 +133,10 @@ 'sound/creatures/monkey/monkey_screech_7.ogg', ) +/datum/species/monkey/get_physical_attributes() + return "Monkeys are slippery, can crawl into vents, and are more dextrous than humans.. but only when stealing things. \ + Natural monkeys cannot operate machinery or most tools with their paws, but unusually clever monkeys or those that were once something else can." + /datum/species/monkey/get_species_description() return "Monkeys are a type of primate that exist between humans and animals on the evolutionary chain. \ Every year, on Monkey Day, Nanotrasen shows their respect for the little guys by allowing them to roam the station freely." diff --git a/code/modules/mob/living/carbon/human/species_types/mothmen.dm b/code/modules/mob/living/carbon/human/species_types/mothmen.dm index 9f576e03f0721c..adb5ffa62aab87 100644 --- a/code/modules/mob/living/carbon/human/species_types/mothmen.dm +++ b/code/modules/mob/living/carbon/human/species_types/mothmen.dm @@ -16,6 +16,7 @@ mutanteyes = /obj/item/organ/internal/eyes/moth changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT species_language_holder = /datum/language_holder/moth + death_sound = 'sound/voice/moth/moth_death.ogg' wing_types = list(/obj/item/organ/external/wings/functional/moth/megamoth, /obj/item/organ/external/wings/functional/moth/mothra) payday_modifier = 1.0 family_heirlooms = list(/obj/item/flashlight/lantern/heirloom_moth) @@ -58,6 +59,10 @@ /datum/species/moth/get_scream_sound(mob/living/carbon/human/human) return 'sound/voice/moth/scream_moth.ogg' +/datum/species/moth/get_physical_attributes() + return "Moths have large and fluffy wings, which help them navigate the station if gravity is offline by pushing the air around them. \ + Due to that, it isn't of much use out in space. Their eyes are very sensitive." + /datum/species/moth/get_species_description() return "Hailing from a planet that was lost long ago, the moths travel \ the galaxy as a nomadic people aboard a colossal fleet of ships, seeking a new homeland." diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 910c10a099a81b..67f57f75a5ad25 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -145,6 +145,10 @@ 'sound/voice/plasmaman/plasmeme_scream_3.ogg', ) +/datum/species/plasmaman/get_physical_attributes() + return "Plasmamen literally breathe and live plasma. They spontaneously combust on contact with oxygen, and besides all the quirks that go with that, \ + they're very vulnerable to all kinds of physical damage due to their brittle structure." + /datum/species/plasmaman/get_species_description() return "Found on the Icemoon of Freyja, plasmamen consist of colonial \ fungal organisms which together form a sentient being. In human space, \ diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index 3703f2527ac95d..0b645fd120a1c4 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -43,26 +43,29 @@ ) return ..() -/datum/species/pod/spec_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) +/datum/species/pod/spec_life(mob/living/carbon/human/podperson, seconds_per_tick, times_fired) . = ..() - if(H.stat == DEAD) + if(podperson.stat == DEAD) return var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing - if(isturf(H.loc)) //else, there's considered to be no light - var/turf/T = H.loc - light_amount = min(1, T.get_lumcount()) - 0.5 - H.adjust_nutrition(5 * light_amount * seconds_per_tick) + if(isturf(podperson.loc)) //else, there's considered to be no light + var/turf/turf_loc = podperson.loc + light_amount = min(1, turf_loc.get_lumcount()) - 0.5 + podperson.adjust_nutrition(5 * light_amount * seconds_per_tick) if(light_amount > 0.2) //if there's enough light, heal - H.heal_overall_damage(brute = 0.5 * seconds_per_tick, burn = 0.5 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC) - H.adjustToxLoss(-0.5 * seconds_per_tick) - H.adjustOxyLoss(-0.5 * seconds_per_tick) + var/need_mob_update = FALSE + need_mob_update += podperson.heal_overall_damage(brute = 0.5 * seconds_per_tick, burn = 0.5 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) + need_mob_update += podperson.adjustToxLoss(-0.5 * seconds_per_tick, updating_health = FALSE) + need_mob_update += podperson.adjustOxyLoss(-0.5 * seconds_per_tick, updating_health = FALSE) + if(need_mob_update) + podperson.updatehealth() - if(H.nutrition > NUTRITION_LEVEL_ALMOST_FULL) //don't make podpeople fat because they stood in the sun for too long - H.set_nutrition(NUTRITION_LEVEL_ALMOST_FULL) + if(podperson.nutrition > NUTRITION_LEVEL_ALMOST_FULL) //don't make podpeople fat because they stood in the sun for too long + podperson.set_nutrition(NUTRITION_LEVEL_ALMOST_FULL) - if(H.nutrition < NUTRITION_LEVEL_STARVING + 50) - H.take_overall_damage(brute = 1 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC) + if(podperson.nutrition < NUTRITION_LEVEL_STARVING + 50) + podperson.take_overall_damage(brute = 1 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC) /datum/species/pod/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired) . = ..() @@ -71,13 +74,9 @@ if(chem.type == /datum/reagent/toxin/plantbgone) affected.adjustToxLoss(3 * REM * seconds_per_tick) -// SKYRAT EDIT ADDITION -/datum/species/pod/get_species_description() - return "Plant lore!" - -/datum/species/pod/get_species_lore() - return list("You're a plant!") -// SKYRAT EDIT END +/datum/species/pod/get_physical_attributes() + return "Podpeople are in many ways the inverse of shadows, healing in light and starving with the dark. \ + Their bodies are like tinder and easy to char." /datum/species/pod/create_pref_unique_perks() var/list/to_add = list() 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 a8b1be203a3b36..1bd77a4356f08a 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -37,6 +37,9 @@ return TRUE return ..() +/datum/species/shadow/get_physical_attributes() + return "These cursed creatures heal in the dark, but suffer in the light much more heavily. Their eyes let them see in the dark as though it were day." + /datum/species/shadow/get_species_description() return "Victims of a long extinct space alien. Their flesh is a sickly \ seethrough filament, their tangled insides in clear view. Their form \ diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index 3ac0483f8ce031..67051c20607252 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -56,6 +56,11 @@ return TRUE return ..() +/datum/species/skeleton/get_physical_attributes() + return "These humerus folk lack any fleshy biology, which allows them to resist pressure, temperature, radiation, asphyxiation and even toxins. \ + However, due to that same fact, it is quite hard to heal them as well. The calcium found in common space milk is highly effective at treating their wounds. \ + Their limbs are easy to pop off their joints, but they can somehow just slot them back in." + /datum/species/skeleton/get_species_description() return "A rattling skeleton! They descend upon Space Station 13 \ Every year to spook the crew! \"I've got a BONE to pick with you!\"" diff --git a/code/modules/mob/living/carbon/human/species_types/snail.dm b/code/modules/mob/living/carbon/human/species_types/snail.dm index 689a02cfbec000..036b5ad5c24746 100644 --- a/code/modules/mob/living/carbon/human/species_types/snail.dm +++ b/code/modules/mob/living/carbon/human/species_types/snail.dm @@ -28,6 +28,11 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/snail ) + +/datum/species/snail/get_physical_attributes() + return "Snailpeople emit a viscous, slippery ooze when crawling along the ground, which they are somewhat faster at than other species. \ + They are almost purely made of water, making them extremely susceptible to shocks, and salt will scour them heavily." + /datum/species/snail/handle_chemical(datum/reagent/chem, mob/living/carbon/human/affected, seconds_per_tick, times_fired) . = ..() if(. & COMSIG_MOB_STOP_REAGENT_CHECK) 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 d24e5f3d2727e9..c07f0478c03ea5 100644 --- a/code/modules/mob/living/carbon/human/species_types/vampire.dm +++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm @@ -44,10 +44,13 @@ /datum/species/vampire/spec_life(mob/living/carbon/human/vampire, seconds_per_tick, times_fired) . = ..() if(istype(vampire.loc, /obj/structure/closet/crate/coffin)) - vampire.heal_overall_damage(brute = 2 * seconds_per_tick, burn = 2 * seconds_per_tick, required_bodytype = BODYTYPE_ORGANIC) - vampire.adjustToxLoss(-2 * seconds_per_tick) - vampire.adjustOxyLoss(-2 * seconds_per_tick) - vampire.adjustCloneLoss(-2 * seconds_per_tick) + var/need_mob_update = FALSE + need_mob_update += vampire.heal_overall_damage(brute = 2 * seconds_per_tick, burn = 2 * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) + need_mob_update += vampire.adjustToxLoss(-2 * seconds_per_tick, updating_health = FALSE,) + need_mob_update += vampire.adjustOxyLoss(-2 * seconds_per_tick, updating_health = FALSE,) + need_mob_update += vampire.adjustCloneLoss(-2 * seconds_per_tick, updating_health = FALSE,) + if(need_mob_update) + vampire.updatehealth() return vampire.blood_volume -= 0.125 * seconds_per_tick if(vampire.blood_volume <= BLOOD_VOLUME_SURVIVE) @@ -66,6 +69,10 @@ return 2 //Whips deal 2x damage to vampires. Vampire killer. return 1 +/datum/species/vampire/get_physical_attributes() + return "Vampires are afflicted with the Thirst, needing to sate it by draining the blood out of another living creature. However, they do not need to breathe or eat normally. \ + They will instantly turn into dust if they run out of blood or enter a holy area. However, coffins stabilize and heal them, and they can transform into bats!" + /datum/species/vampire/get_species_description() return "A classy Vampire! They descend upon Space Station Thirteen Every year to spook the crew! \"Bleeg!!\"" diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index d8b2125aa64e43..4f9b6f1b4af0bd 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -66,6 +66,10 @@ return TRUE return ..() +/datum/species/zombie/get_physical_attributes() + return "Zombies are undead, and thus completely immune to any enviromental hazard, or any physical threat besides blunt force trauma and burns. \ + Their limbs are easy to pop off their joints, but they can somehow just slot them back in." + /datum/species/zombie/get_species_description() return "A rotting zombie! They descend upon Space Station Thirteen Every year to spook the crew! \"Sincerely, the Zombies!\"" @@ -151,24 +155,27 @@ if(.) COOLDOWN_START(src, regen_cooldown, REGENERATION_DELAY) -/datum/species/zombie/infectious/spec_life(mob/living/carbon/C, seconds_per_tick, times_fired) +/datum/species/zombie/infectious/spec_life(mob/living/carbon/carbon_mob, seconds_per_tick, times_fired) . = ..() - C.set_combat_mode(TRUE) // THE SUFFERING MUST FLOW + carbon_mob.set_combat_mode(TRUE) // THE SUFFERING MUST FLOW //Zombies never actually die, they just fall down until they regenerate enough to rise back up. //They must be restrained, beheaded or gibbed to stop being a threat. if(COOLDOWN_FINISHED(src, regen_cooldown)) var/heal_amt = heal_rate - if(HAS_TRAIT(C, TRAIT_CRITICAL_CONDITION)) + if(HAS_TRAIT(carbon_mob, TRAIT_CRITICAL_CONDITION)) heal_amt *= 2 - C.heal_overall_damage(heal_amt * seconds_per_tick, heal_amt * seconds_per_tick) - C.adjustToxLoss(-heal_amt * seconds_per_tick) - for(var/i in C.all_wounds) + var/need_mob_update = FALSE + need_mob_update += carbon_mob.heal_overall_damage(heal_amt * seconds_per_tick, heal_amt * seconds_per_tick, updating_health = FALSE) + need_mob_update += carbon_mob.adjustToxLoss(-heal_amt * seconds_per_tick, updating_health = FALSE) + if(need_mob_update) + carbon_mob.updatehealth() + for(var/i in carbon_mob.all_wounds) var/datum/wound/iter_wound = i if(SPT_PROB(2-(iter_wound.severity/2), seconds_per_tick)) iter_wound.remove_wound() - if(!HAS_TRAIT(C, TRAIT_CRITICAL_CONDITION) && SPT_PROB(2, seconds_per_tick)) - playsound(C, pick(spooks), 50, TRUE, 10) + if(!HAS_TRAIT(carbon_mob, TRAIT_CRITICAL_CONDITION) && SPT_PROB(2, seconds_per_tick)) + playsound(carbon_mob, pick(spooks), 50, TRUE, 10) //Congrats you somehow died so hard you stopped being a zombie /datum/species/zombie/infectious/spec_death(gibbed, mob/living/carbon/C) @@ -192,7 +199,7 @@ // Your skin falls off /datum/species/human/krokodil_addict - name = "\improper Human" + name = "\improper Krokodil Human" id = SPECIES_ZOMBIE_KROKODIL examine_limb_id = SPECIES_HUMAN changesource_flags = MIRROR_BADMIN | WABBAJACK | ERT_SPAWN diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 990f27f07070b8..4da9129b1fecd7 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -37,9 +37,8 @@ if(getStaminaLoss() > 0 && stam_regen_start_time <= world.time) adjustStaminaLoss(-INFINITY) - var/bprv = handle_bodyparts(seconds_per_tick, times_fired) - if(bprv & BODYPART_LIFE_UPDATE_HEALTH) - updatehealth() + + handle_bodyparts(seconds_per_tick, times_fired) if(. && mind) //. == not dead for(var/key in mind.addiction_points) @@ -410,10 +409,13 @@ //-- NITRIUM --// if(nitrium_pp) + var/need_mob_update = FALSE if(nitrium_pp > 0.5) - adjustFireLoss(nitrium_pp * 0.15) + need_mob_update += adjustFireLoss(nitrium_pp * 0.15, updating_health = FALSE) if(nitrium_pp > 5) - adjustToxLoss(nitrium_pp * 0.05) + need_mob_update += adjustToxLoss(nitrium_pp * 0.05, updating_health = FALSE) + if(need_mob_update) + updatehealth() // Handle chemical euphoria mood event, caused by N2O. if (n2o_euphoria == EUPHORIA_ACTIVE) @@ -492,7 +494,8 @@ return for(var/obj/item/organ/internal/organ in organs) // On-death is where organ decay is handled - organ?.on_death(seconds_per_tick, times_fired) // organ can be null due to reagent metabolization causing organ shuffling + if(organ?.owner) // organ + owner can be null due to reagent metabolization causing organ shuffling + organ.on_death(seconds_per_tick, times_fired) // We need to re-check the stat every organ, as one of our others may have revived us if(stat != DEAD) break @@ -757,7 +760,7 @@ if(HAS_TRAIT(src, TRAIT_STABLELIVER) || HAS_TRAIT(src, TRAIT_LIVERLESS_METABOLISM)) return - adjustToxLoss(0.6 * seconds_per_tick, TRUE, TRUE) + adjustToxLoss(0.6 * seconds_per_tick, forced = TRUE) adjustOrganLoss(pick(ORGAN_SLOT_HEART, ORGAN_SLOT_LUNGS, ORGAN_SLOT_STOMACH, ORGAN_SLOT_EYES, ORGAN_SLOT_EARS), 0.5* seconds_per_tick) /mob/living/carbon/proc/undergoing_liver_failure() @@ -814,6 +817,7 @@ var/obj/item/organ/internal/heart/heart = get_organ_slot(ORGAN_SLOT_HEART) if(!istype(heart)) - return + return FALSE heart.beating = !status + return TRUE diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index dfae5d2baf1d8e..45a35bb6e158b1 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -53,7 +53,7 @@ return adjustStaminaLoss(damage) /// return the damage amount for the type given -/mob/living/proc/get_damage_amount(damagetype = BRUTE) +/mob/living/proc/get_current_damage_of_type(damagetype = BRUTE) switch(damagetype) if(BRUTE) return getBruteLoss() @@ -159,136 +159,191 @@ return TRUE - /mob/living/proc/getBruteLoss() return bruteloss -/mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) - SEND_SIGNAL(src, COMSIG_MOB_LOSS_BRUTE, amount) //SKYRAT EDIT ADDITION +/mob/living/proc/can_adjust_brute_loss(amount, forced, required_bodytype) if(!forced && (status_flags & GODMODE)) return FALSE + if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_BRUTE_DAMAGE, BRUTE, amount, forced) & COMPONENT_IGNORE_CHANGE) + return FALSE + return TRUE + +/mob/living/proc/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL) + if (!can_adjust_brute_loss(amount, forced, required_bodytype)) + return 0 + . = bruteloss bruteloss = clamp((bruteloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + . -= bruteloss + if(!.) // no change, no need to update + return 0 if(updating_health) updatehealth() - return amount -/mob/living/proc/setBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) + +/mob/living/proc/setBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL) if(!forced && (status_flags & GODMODE)) - return + return FALSE . = bruteloss bruteloss = amount + + if(!.) // no change, no need to update + return FALSE if(updating_health) updatehealth() + . -= bruteloss /mob/living/proc/getOxyLoss() return oxyloss -/mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype, required_respiration_type = ALL) - - SEND_SIGNAL(src, COMSIG_MOB_LOSS_OXY, amount) //SKYRAT EDIT ADDITION +/mob/living/proc/can_adjust_oxy_loss(amount, forced, required_biotype, required_respiration_type) if(!forced) if(status_flags & GODMODE) - return - - var/obj/item/organ/internal/lungs/affected_lungs = get_organ_slot(ORGAN_SLOT_LUNGS) - if(isnull(affected_lungs)) - if(!(mob_respiration_type & required_respiration_type)) // if the mob has no lungs, use mob_respiration_type - return - else - if(!(affected_lungs.respiration_type & required_respiration_type)) // otherwise use the lungs' respiration_type - return + return FALSE + if (required_respiration_type) + var/obj/item/organ/internal/lungs/affected_lungs = get_organ_slot(ORGAN_SLOT_LUNGS) + if(isnull(affected_lungs)) + if(!(mob_respiration_type & required_respiration_type)) // if the mob has no lungs, use mob_respiration_type + return FALSE + else + if(!(affected_lungs.respiration_type & required_respiration_type)) // otherwise use the lungs' respiration_type + return FALSE + if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_OXY_DAMAGE, OXY, amount, forced) & COMPONENT_IGNORE_CHANGE) + return FALSE + return TRUE +/mob/living/proc/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL, required_respiration_type = ALL) + if(!can_adjust_oxy_loss(amount, forced, required_biotype, required_respiration_type)) + return 0 . = oxyloss oxyloss = clamp((oxyloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + . -= oxyloss + if(!.) // no change, no need to update + return FALSE if(updating_health) updatehealth() - -/mob/living/proc/setOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype, required_respiration_type = ALL) +/mob/living/proc/setOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL, required_respiration_type = ALL) if(!forced) if(status_flags & GODMODE) - return + return FALSE var/obj/item/organ/internal/lungs/affected_lungs = get_organ_slot(ORGAN_SLOT_LUNGS) if(isnull(affected_lungs)) if(!(mob_respiration_type & required_respiration_type)) - return + return FALSE else if(!(affected_lungs.respiration_type & required_respiration_type)) - return - + return FALSE . = oxyloss oxyloss = amount + . -= oxyloss + if(!.) // no change, no need to update + return FALSE if(updating_health) updatehealth() - /mob/living/proc/getToxLoss() return toxloss -/mob/living/proc/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) - SEND_SIGNAL(src, COMSIG_MOB_LOSS_TOX, amount) //SKYRAT EDIT ADDITION - if(!forced && (status_flags & GODMODE)) +/mob/living/proc/can_adjust_tox_loss(amount, forced, required_biotype) + if(!forced && ((status_flags & GODMODE) || !(mob_biotypes & required_biotype))) return FALSE - if(!forced && !(mob_biotypes & required_biotype)) - return + if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_TOX_DAMAGE, TOX, amount, forced) & COMPONENT_IGNORE_CHANGE) + return FALSE + return TRUE + +/mob/living/proc/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL) + if(!can_adjust_tox_loss(amount, forced, required_biotype)) + return 0 + . = toxloss toxloss = clamp((toxloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + . -= toxloss + if(!.) // no change, no need to update + return FALSE if(updating_health) updatehealth() - return amount -/mob/living/proc/setToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) +/mob/living/proc/setToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL) if(!forced && (status_flags & GODMODE)) return FALSE if(!forced && !(mob_biotypes & required_biotype)) - return + return FALSE + . = toxloss toxloss = amount + . -= toxloss + if(!.) // no change, no need to update + return FALSE if(updating_health) updatehealth() - return amount /mob/living/proc/getFireLoss() return fireloss -/mob/living/proc/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) - SEND_SIGNAL(src, COMSIG_MOB_LOSS_FIRE, amount) //SKYRAT EDIT ADDITION +/mob/living/proc/can_adjust_fire_loss(amount, forced, required_bodytype) if(!forced && (status_flags & GODMODE)) return FALSE + if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_BURN_DAMAGE, BURN, amount, forced) & COMPONENT_IGNORE_CHANGE) + return FALSE + return TRUE + +/mob/living/proc/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL) + if(!can_adjust_fire_loss(amount, forced, required_bodytype)) + return 0 + . = fireloss fireloss = clamp((fireloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + . -= fireloss + if(. == 0) // no change, no need to update + return if(updating_health) updatehealth() - return amount -/mob/living/proc/setFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) +/mob/living/proc/setFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype = ALL) if(!forced && (status_flags & GODMODE)) - return + return 0 . = fireloss fireloss = amount + . -= fireloss + if(. == 0) // no change, no need to update + return 0 if(updating_health) updatehealth() /mob/living/proc/getCloneLoss() return cloneloss -/mob/living/proc/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) - SEND_SIGNAL(src, COMSIG_MOB_LOSS_CLONE, amount) //SKYRAT EDIT ADDITION - if(!forced && ( (status_flags & GODMODE) || HAS_TRAIT(src, TRAIT_NOCLONELOSS)) ) +/mob/living/proc/can_adjust_clone_loss(amount, forced, required_biotype) + if(!forced && (!(mob_biotypes & required_biotype) || status_flags & GODMODE || HAS_TRAIT(src, TRAIT_NOCLONELOSS))) + return FALSE + if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_CLONE_DAMAGE, CLONE, amount, forced) & COMPONENT_IGNORE_CHANGE) return FALSE + return TRUE + +/mob/living/proc/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL) + if(!can_adjust_clone_loss(amount, forced, required_biotype)) + return 0 + . = cloneloss cloneloss = clamp((cloneloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, maxHealth * 2) + . -= cloneloss + if(. == 0) // no change, no need to update + return 0 if(updating_health) updatehealth() - return amount -/mob/living/proc/setCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) +/mob/living/proc/setCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype = ALL) if(!forced && ( (status_flags & GODMODE) || HAS_TRAIT(src, TRAIT_NOCLONELOSS)) ) return FALSE + if(!forced && !(mob_biotypes & required_biotype)) + return FALSE + . = cloneloss cloneloss = amount + . -= cloneloss + if(!.) // no change, no need to update + return FALSE if(updating_health) updatehealth() - return amount /mob/living/proc/adjustOrganLoss(slot, amount, maximum, required_organ_flag) - SEND_SIGNAL(src, COMSIG_MOB_LOSS_ORGAN, slot, amount) //SKYRAT EDIT ADDITION return /mob/living/proc/setOrganLoss(slot, amount, maximum, required_organ_flag) @@ -300,65 +355,84 @@ /mob/living/proc/getStaminaLoss() return staminaloss -/mob/living/proc/adjustStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype) - if(!forced && (status_flags & GODMODE)) +/mob/living/proc/can_adjust_stamina_loss(amount, forced, required_biotype) + if(!forced && (!(mob_biotypes & required_biotype) || status_flags & GODMODE)) return FALSE - if(required_biotype && !(mob_biotypes & required_biotype)) - return + if(SEND_SIGNAL(src, COMSIG_LIVING_ADJUST_STAMINA_DAMAGE, STAMINA, amount, forced) & COMPONENT_IGNORE_CHANGE) + return FALSE + return TRUE + +/mob/living/proc/adjustStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype = ALL) + if(!can_adjust_stamina_loss(amount, forced, required_biotype)) + return 0 + . = staminaloss staminaloss = clamp((staminaloss + (amount * CONFIG_GET(number/damage_multiplier))), 0, max_stamina) + . -= staminaloss + if(. == 0) // no change, no need to update + return 0 if(updating_stamina) updatehealth() - SEND_SIGNAL(src, COMSIG_MOB_LOSS_STAMINA, amount) //SKYRAT EDIT ADDITION - return -/mob/living/proc/setStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype) - if(!forced && ( (status_flags & GODMODE) || HAS_TRAIT(src, TRAIT_NOCLONELOSS)) ) +/mob/living/proc/setStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype = ALL) + if(!forced && (status_flags & GODMODE)) + return FALSE + if(!forced && !(mob_biotypes & required_biotype)) return FALSE + . = staminaloss staminaloss = amount + . -= staminaloss + if(!.) // no change, no need to update + return FALSE if(updating_stamina) updatehealth() /** * heal ONE external organ, organ gets randomly selected from damaged ones. * - * needs to return amount healed in order to calculate things like tend wounds xp gain + * returns the net change in damage */ /mob/living/proc/heal_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype = NONE, target_zone = null) - . = (adjustBruteLoss(-brute, FALSE) + adjustFireLoss(-burn, FALSE)) //zero as argument for no instant health update + . = (adjustBruteLoss(-abs(brute), updating_health = FALSE) + adjustFireLoss(-abs(burn), updating_health = FALSE)) + if(!.) // no change, no need to update + return FALSE if(updating_health) updatehealth() /// damage ONE external organ, organ gets randomly selected from damaged ones. /mob/living/proc/take_bodypart_damage(brute = 0, burn = 0, updating_health = TRUE, required_bodytype, check_armor = FALSE, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE) - adjustBruteLoss(brute, FALSE) //zero as argument for no instant health update - adjustFireLoss(burn, FALSE) + . = (adjustBruteLoss(abs(brute), updating_health = FALSE) + adjustFireLoss(abs(burn), updating_health = FALSE)) + if(!.) // no change, no need to update + return FALSE if(updating_health) updatehealth() -/// heal MANY bodyparts, in random order -/mob/living/proc/heal_overall_damage(brute = 0, burn = 0, stamina = 0, required_bodytype, updating_health = TRUE) - adjustBruteLoss(-brute, FALSE) //zero as argument for no instant health update - adjustFireLoss(-burn, FALSE) - adjustStaminaLoss(-stamina, FALSE) +/// heal MANY bodyparts, in random order. note: stamina arg nonfunctional for carbon mobs +/mob/living/proc/heal_overall_damage(brute = 0, burn = 0, stamina = 0, required_bodytype, updating_health = TRUE, forced = FALSE) + . = (adjustBruteLoss(-abs(brute), updating_health = FALSE, forced = forced) + \ + adjustFireLoss(-abs(burn), updating_health = FALSE, forced = forced) + \ + adjustStaminaLoss(-abs(stamina), updating_stamina = FALSE, forced = forced)) + if(!.) // no change, no need to update + return FALSE if(updating_health) updatehealth() -/// damage MANY bodyparts, in random order -/mob/living/proc/take_overall_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, required_bodytype) - adjustBruteLoss(brute, FALSE) //zero as argument for no instant health update - adjustFireLoss(burn, FALSE) - adjustStaminaLoss(stamina, FALSE) +/// damage MANY bodyparts, in random order. note: stamina arg nonfunctional for carbon mobs +/mob/living/proc/take_overall_damage(brute = 0, burn = 0, stamina = 0, updating_health = TRUE, forced = FALSE, required_bodytype) + . = (adjustBruteLoss(abs(brute), updating_health = FALSE, forced = forced) + \ + adjustFireLoss(abs(burn), updating_health = FALSE, forced = forced) + \ + adjustStaminaLoss(abs(stamina), updating_stamina = FALSE, forced = forced)) + if(!.) // no change, no need to update + return FALSE if(updating_health) updatehealth() ///heal up to amount damage, in a given order /mob/living/proc/heal_ordered_damage(amount, list/damage_types) - . = amount //we'll return the amount of damage healed - for(var/i in damage_types) - var/amount_to_heal = min(amount, get_damage_amount(i)) //heal only up to the amount of damage we have + . = FALSE //we'll return the amount of damage healed + for(var/damagetype in damage_types) + var/amount_to_heal = min(abs(amount), get_current_damage_of_type(damagetype)) //heal only up to the amount of damage we have if(amount_to_heal) - apply_damage_type(-amount_to_heal, i) + . += apply_damage_type(-amount_to_heal, damagetype) amount -= amount_to_heal //remove what we healed from our current amount if(!amount) break - . -= amount //if there's leftover healing, remove it from what we return diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 53a8d259393091..6174a5793bc90b 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -1,12 +1,14 @@ /** * Blow up the mob into giblets * - * Arguments: - * * no_brain - Should the mob NOT drop a brain? - * * no_organs - Should the mob NOT drop organs? - * * no_bodyparts - Should the mob NOT drop bodyparts? -*/ -/mob/living/proc/gib(no_brain, no_organs, no_bodyparts) + * drop_bitflags: (see code/__DEFINES/blood.dm) + * * DROP_BRAIN - Gibbed mob will drop a brain + * * DROP_ORGANS - Gibbed mob will drop organs + * * DROP_BODYPARTS - Gibbed mob will drop bodyparts (arms, legs, etc.) + * * DROP_ITEMS - Gibbed mob will drop carried items (otherwise they get deleted) + * * DROP_ALL_REMAINS - Gibbed mob will drop everything +**/ +/mob/living/proc/gib(drop_bitflags=NONE) var/prev_lying = lying_angle if(stat != DEAD) death(TRUE) @@ -14,25 +16,47 @@ if(!prev_lying) gib_animation() - spill_organs(no_brain, no_organs, no_bodyparts, TRUE) //SKYRAT EDIT CHANGE - ORIGINAL: spill_organs(no_brain, no_organs, no_bodyparts) + ghostize() + spill_organs(drop_bitflags) - if(!no_bodyparts) - spread_bodyparts(no_brain, no_organs) + if(drop_bitflags & DROP_BODYPARTS) + spread_bodyparts(drop_bitflags) - spawn_gibs(no_bodyparts) - SEND_SIGNAL(src, COMSIG_LIVING_GIBBED, no_brain, no_organs, no_bodyparts) + spawn_gibs(drop_bitflags) + SEND_SIGNAL(src, COMSIG_LIVING_GIBBED, drop_bitflags) qdel(src) /mob/living/proc/gib_animation() return -/mob/living/proc/spawn_gibs() +/** + * Spawn bloody gib mess on the floor + * + * drop_bitflags: (see code/__DEFINES/blood.dm) + * * DROP_BODYPARTS - Gibs will spawn with bodypart limbs present +**/ +/mob/living/proc/spawn_gibs(drop_bitflags=NONE) new /obj/effect/gibspawner/generic(drop_location(), src, get_static_viruses()) -/mob/living/proc/spill_organs() +/** + * Drops a mob's organs on the floor + * + * drop_bitflags: (see code/__DEFINES/blood.dm) + * * DROP_BRAIN - Mob will drop a brain + * * DROP_ORGANS - Mob will drop organs + * * DROP_BODYPARTS - Mob will drop bodyparts (arms, legs, etc.) + * * DROP_ALL_REMAINS - Mob will drop everything +**/ +/mob/living/proc/spill_organs(drop_bitflags=NONE) return -/mob/living/proc/spread_bodyparts() +/** + * Launches all bodyparts away from the mob + * + * drop_bitflags: (see code/__DEFINES/blood.dm) + * * DROP_BRAIN - Detaches the head from the mob and launches it away from the body +**/ +/mob/living/proc/spread_bodyparts(drop_bitflags=NONE) return /** @@ -58,6 +82,7 @@ dust_animation() spawn_dust(just_ash) + ghostize() QDEL_IN(src,5) // since this is sometimes called in the middle of movement, allow half a second for movement to finish, ghosting to happen and animation to play. Looks much nicer and doesn't cause multiple runtimes. /mob/living/proc/dust_animation() diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index cb4d4a8241a6a2..dbb602aa2be53f 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -143,6 +143,8 @@ var/mob/living/carbon/human/H = user var/open = FALSE var/obj/item/organ/external/wings/functional/wings = H.get_organ_slot(ORGAN_SLOT_EXTERNAL_WINGS) + + // open/close functional wings if(istype(wings)) if(wings.wings_open) open = TRUE @@ -150,6 +152,10 @@ else H.OpenWings() addtimer(CALLBACK(wings, open ? TYPE_PROC_REF(/obj/item/organ/external/wings/functional, open_wings) : TYPE_PROC_REF(/obj/item/organ/external/wings/functional, close_wings)), wing_time) + + // play moth flutter noise if moth wing + if(istype(wings, /obj/item/organ/external/wings/moth)) + playsound(H, 'sound/voice/moth/moth_flutter.ogg', 50, TRUE) */ //SKYRAT EDIT REMOVAL END @@ -193,7 +199,7 @@ return var/mob/living/carbon/human/human_user = user if(human_user.dna.species.id == SPECIES_HUMAN && !HAS_MIND_TRAIT(human_user, TRAIT_MIMING)) - if(human_user.gender == FEMALE) + if(human_user.physique == FEMALE) return pick('sound/voice/human/gasp_female1.ogg', 'sound/voice/human/gasp_female2.ogg', 'sound/voice/human/gasp_female3.ogg') else return pick('sound/voice/human/gasp_male1.ogg', 'sound/voice/human/gasp_male2.ogg') @@ -487,7 +493,7 @@ /datum/emote/living/tremble key = "tremble" key_third_person = "trembles" - message = "trembles in fear!" + message = "trembles!" #define TREMBLE_LOOP_DURATION (4.4 SECONDS) /datum/emote/living/tremble/run_emote(mob/living/user, params, type_override, intentional) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index aacdc60b56a17c..37a1253ad495ac 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -12,7 +12,10 @@ /mob/living/proc/Life(seconds_per_tick = SSMOBS_DT, times_fired) set waitfor = FALSE - SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds_per_tick, times_fired) + var/signal_result = SEND_SIGNAL(src, COMSIG_LIVING_LIFE, seconds_per_tick, times_fired) + + if(signal_result & COMPONENT_LIVING_CANCEL_LIFE_PROCESSING) // mmm less work + return if (client) var/turf/T = get_turf(src) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index e4fe206cf63926..c409b84c4e2130 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -807,8 +807,8 @@ */ /mob/living/proc/revive(full_heal_flags = NONE, excess_healing = 0, force_grab_ghost = FALSE) if(excess_healing) - adjustOxyLoss(-excess_healing, FALSE) - adjustToxLoss(-excess_healing, FALSE, TRUE) //slime friendly + adjustOxyLoss(-excess_healing, updating_health = FALSE) + adjustToxLoss(-excess_healing, updating_health = FALSE, forced = TRUE) //slime friendly updatehealth() grab_ghost(force_grab_ghost) @@ -857,13 +857,13 @@ var/oxy_to_heal = heal_to - getOxyLoss() var/tox_to_heal = heal_to - getToxLoss() if(brute_to_heal < 0) - adjustBruteLoss(brute_to_heal, FALSE) + adjustBruteLoss(brute_to_heal, updating_health = FALSE) if(burn_to_heal < 0) - adjustFireLoss(burn_to_heal, FALSE) + adjustFireLoss(burn_to_heal, updating_health = FALSE) if(oxy_to_heal < 0) - adjustOxyLoss(oxy_to_heal, FALSE) + adjustOxyLoss(oxy_to_heal, updating_health = FALSE) if(tox_to_heal < 0) - adjustToxLoss(tox_to_heal, FALSE, TRUE) + adjustToxLoss(tox_to_heal, updating_health = FALSE, forced = TRUE) // Run updatehealth once to set health for the revival check updatehealth() @@ -894,17 +894,17 @@ SHOULD_CALL_PARENT(TRUE) if(heal_flags & HEAL_TOX) - setToxLoss(0, FALSE, TRUE) + setToxLoss(0, updating_health = FALSE, forced = TRUE) if(heal_flags & HEAL_OXY) - setOxyLoss(0, FALSE, TRUE) + setOxyLoss(0, updating_health = FALSE, forced = TRUE) if(heal_flags & HEAL_CLONE) - setCloneLoss(0, FALSE, TRUE) + setCloneLoss(0, updating_health = FALSE, forced = TRUE) if(heal_flags & HEAL_BRUTE) - setBruteLoss(0, FALSE, TRUE) + setBruteLoss(0, updating_health = FALSE, forced = TRUE) if(heal_flags & HEAL_BURN) - setFireLoss(0, FALSE, TRUE) + setFireLoss(0, updating_health = FALSE, forced = TRUE) if(heal_flags & HEAL_STAM) - setStaminaLoss(0, FALSE, TRUE) + setStaminaLoss(0, updating_stamina = FALSE, forced = TRUE) // I don't really care to keep this under a flag set_nutrition(NUTRITION_LEVEL_FED + 50) @@ -1308,7 +1308,7 @@ return /mob/living/can_hold_items(obj/item/I) - return usable_hands && ..() + return ..() && HAS_TRAIT(src, TRAIT_CAN_HOLD_ITEMS) && usable_hands /mob/living/can_perform_action(atom/movable/target, action_bitflags) if(!istype(target)) @@ -1479,6 +1479,7 @@ var/picked_animal = pick( /mob/living/basic/bat, /mob/living/basic/bear, + /mob/living/basic/blob_minion/blobbernaut, /mob/living/basic/butterfly, /mob/living/basic/carp, /mob/living/basic/carp/magic, @@ -1487,6 +1488,8 @@ /mob/living/basic/chicken, /mob/living/basic/cow, /mob/living/basic/crab, + /mob/living/basic/goat, + /mob/living/basic/gorilla, /mob/living/basic/headslug, /mob/living/basic/killer_tomato, /mob/living/basic/lizard, @@ -1504,10 +1507,7 @@ /mob/living/basic/statue, /mob/living/basic/stickman, /mob/living/basic/stickman/dog, - /mob/living/simple_animal/hostile/blob/blobbernaut/independent, - /mob/living/simple_animal/hostile/gorilla, /mob/living/simple_animal/hostile/megafauna/dragon/lesser, - /mob/living/simple_animal/hostile/retaliate/goat, /mob/living/simple_animal/parrot, /mob/living/simple_animal/pet/cat, /mob/living/simple_animal/pet/cat/cak, diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 0d309ff10c9334..01362dfb1ba55d 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -181,6 +181,7 @@ return ..() /mob/living/fire_act() + . = ..() adjust_fire_stacks(3) ignite_mob() @@ -463,7 +464,7 @@ addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(cult_ending_helper), CULT_VICTORY_MASS_CONVERSION), 120) addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(ending_helper)), 270) if(client) - makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, src, cultoverride = TRUE) + makeNewConstruct(/mob/living/basic/construct/harvester, src, cultoverride = TRUE) else switch(rand(1, 4)) if(1) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 766a7ef89a8144..5b2f0fc020bf7d 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -1,6 +1,6 @@ /mob/living see_invisible = SEE_INVISIBLE_LIVING - hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD) + hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD, DNR_HUD) // SKYRAT EDIT ADDITION - DNR_HUD pressure_resistance = 10 hud_type = /datum/hud/living @@ -225,3 +225,6 @@ /// What our current gravity state is. Used to avoid duplicate animates and such var/gravity_state = null + + /// Whether this mob can be mutated into a cybercop via quantum server get_valid_domain_targets(). Specifically dodges megafauna + var/can_be_cybercop = TRUE diff --git a/code/modules/mob/living/living_say.dm b/code/modules/mob/living/living_say.dm index 3a09256ee69b3f..52daa3c2f0ab92 100644 --- a/code/modules/mob/living/living_say.dm +++ b/code/modules/mob/living/living_say.dm @@ -387,8 +387,7 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( if(!M.client.prefs.read_preference(/datum/preference/toggle/enable_runechat) || (SSlag_switch.measures[DISABLE_RUNECHAT] && !HAS_TRAIT(src, TRAIT_BYPASS_MEASURES))) speech_bubble_recipients.Add(M.client) found_client = TRUE - - if(voice && found_client && !message_mods[MODE_CUSTOM_SAY_ERASE_INPUT] && !HAS_TRAIT(src, TRAIT_SIGN_LANG) && !HAS_TRAIT(src, TRAIT_UNKNOWN)) + if(SStts.tts_enabled && voice && found_client && !message_mods[MODE_CUSTOM_SAY_ERASE_INPUT] && !HAS_TRAIT(src, TRAIT_SIGN_LANG) && !HAS_TRAIT(src, TRAIT_UNKNOWN)) var/tts_message_to_use = tts_message if(!tts_message_to_use) tts_message_to_use = message_raw @@ -404,7 +403,7 @@ GLOBAL_LIST_INIT(message_modes_stat_limits, list( filter += tts_filter.Join(",") if(ishuman(src)) var/mob/living/carbon/human/human_speaker = src - if(human_speaker.wear_mask) + if(istype(human_speaker.wear_mask, /obj/item/clothing/mask)) var/obj/item/clothing/mask/worn_mask = human_speaker.wear_mask if(worn_mask.voice_override) voice_to_use = worn_mask.voice_override diff --git a/code/modules/mob/living/silicon/ai/ai_defense.dm b/code/modules/mob/living/silicon/ai/ai_defense.dm index ae17e13f269acc..7445815c9d77b4 100644 --- a/code/modules/mob/living/silicon/ai/ai_defense.dm +++ b/code/modules/mob/living/silicon/ai/ai_defense.dm @@ -43,7 +43,7 @@ switch(severity) if(EXPLODE_DEVASTATE) investigate_log("has been gibbed by an explosion.", INVESTIGATE_DEATHS) - gib() + gib(DROP_ALL_REMAINS) if(EXPLODE_HEAVY) if (stat != DEAD) adjustBruteLoss(60) diff --git a/code/modules/mob/living/silicon/damage_procs.dm b/code/modules/mob/living/silicon/damage_procs.dm index 8ee146508a4149..4fe6e688632cb1 100644 --- a/code/modules/mob/living/silicon/damage_procs.dm +++ b/code/modules/mob/living/silicon/damage_procs.dm @@ -18,19 +18,19 @@ /mob/living/silicon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) //immune to tox damage return FALSE -/mob/living/silicon/setToxLoss(amount, updating_health = TRUE, forced = FALSE) +/mob/living/silicon/setToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) return FALSE -/mob/living/silicon/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE) //immune to clone damage +/mob/living/silicon/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) //immune to clone damage return FALSE -/mob/living/silicon/setCloneLoss(amount, updating_health = TRUE, forced = FALSE) +/mob/living/silicon/setCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) return FALSE /mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype) //immune to stamina damage. return FALSE -/mob/living/silicon/setStaminaLoss(amount, updating_health = TRUE) +/mob/living/silicon/setStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype) return FALSE /mob/living/silicon/adjustOrganLoss(slot, amount, maximum = 500, required_organ_flag) //immune to organ damage (no organs, duh) @@ -45,7 +45,7 @@ return FALSE -/mob/living/silicon/setOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) +/mob/living/silicon/setOxyLoss(amount, updating_health = TRUE, forced = FALSE, forced = FALSE, required_biotype) if(isAI(src)) //ditto return ..() diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index 7df2e7d339065c..be713b429a6b51 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -401,6 +401,7 @@ /mob/living/silicon/robot/perform_hand_swap() cycle_modules() + return TRUE /mob/living/silicon/robot/can_hold_items(obj/item/I) return (I && (I in model.modules)) //Only if it's part of our model. diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 30559e616b569d..fe28d41fe846fe 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -385,7 +385,7 @@ else explosion(src, devastation_range = -1, light_impact_range = 2) investigate_log("has self-destructed.", INVESTIGATE_DEATHS) - gib() + gib(DROP_ALL_REMAINS) /mob/living/silicon/robot/proc/UnlinkSelf() set_connected_ai(null) diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index f820d3ca1cfc53..09440ec22a3f05 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -414,14 +414,14 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real adjustBruteLoss(30) else investigate_log("has been gibbed a blob.", INVESTIGATE_DEATHS) - gib() + gib(DROP_ALL_REMAINS) return TRUE /mob/living/silicon/robot/ex_act(severity, target) switch(severity) if(EXPLODE_DEVASTATE) investigate_log("has been gibbed by an explosion.", INVESTIGATE_DEATHS) - gib() + gib(DROP_ALL_REMAINS) return if(EXPLODE_HEAVY) if (stat != DEAD) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index fbe9986c3ca3c6..8a1f20d28c4b75 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -21,7 +21,7 @@ var/designation = "" var/radiomod = "" //Radio character used before state laws/arrivals announce to allow department transmissions, default, or none at all. var/obj/item/camera/siliconcam/aicamera = null //photography - hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_TRACK_HUD) + hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_TRACK_HUD, DNR_HUD) // SKYRAT EDIT ADDITION - DNR HUD var/obj/item/radio/borg/radio = null ///If this is a path, this gets created as an object in Initialize. diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm index 6345320d9d9966..9640dbb9de4403 100644 --- a/code/modules/mob/living/simple_animal/damage_procs.dm +++ b/code/modules/mob/living/simple_animal/damage_procs.dm @@ -19,36 +19,48 @@ toggle_ai(AI_ON) /mob/living/simple_animal/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) + if(!can_adjust_brute_loss(amount, forced, required_bodytype)) + return 0 if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[BRUTE]) . = adjustHealth(amount * damage_coeff[BRUTE] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) + if(!can_adjust_fire_loss(amount, forced, required_bodytype)) + return 0 if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[BURN]) . = adjustHealth(amount * damage_coeff[BURN] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustOxyLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype, required_respiration_type) + if(!can_adjust_oxy_loss(amount, forced, required_biotype, required_respiration_type)) + return 0 if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[OXY]) . = adjustHealth(amount * damage_coeff[OXY] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) + if(!can_adjust_tox_loss(amount, forced, required_biotype)) + return 0 if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[TOX]) . = adjustHealth(amount * damage_coeff[TOX] * CONFIG_GET(number/damage_multiplier), updating_health, forced) -/mob/living/simple_animal/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE) +/mob/living/simple_animal/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE, required_biotype) + if(!can_adjust_clone_loss(amount, forced, required_biotype)) + return 0 if(forced) . = adjustHealth(amount * CONFIG_GET(number/damage_multiplier), updating_health, forced) else if(damage_coeff[CLONE]) . = adjustHealth(amount * damage_coeff[CLONE] * CONFIG_GET(number/damage_multiplier), updating_health, forced) /mob/living/simple_animal/adjustStaminaLoss(amount, updating_stamina = TRUE, forced = FALSE, required_biotype) + if(!can_adjust_stamina_loss(amount, forced, required_biotype)) + return 0 if(forced) staminaloss = max(0, min(max_staminaloss, staminaloss + amount)) else 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 a0f078acd92e85..75471c3cc30874 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -173,6 +173,7 @@ . = ..() GLOB.drones_list += src access_card = new /obj/item/card/id/advanced/simple_bot(src) + AddComponent(/datum/component/basic_inhands, y_offset = getItemPixelShiftY()) // Doing this hurts my soul, but simple_animal access reworks are for another day. var/datum/id_trim/job/cap_trim = SSid_access.trim_singletons_by_path[/datum/id_trim/job/captain] diff --git a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm index 69c2ac3e8cf73c..90391dff58546c 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm @@ -27,45 +27,6 @@ if(slot_flags & (ITEM_SLOT_HANDS|ITEM_SLOT_BACKPACK|ITEM_SLOT_DEX_STORAGE)) update_inv_internal_storage() -/mob/living/simple_animal/drone/update_held_items() - remove_overlay(DRONE_HANDS_LAYER) - var/list/hands_overlays = list() - - var/obj/item/l_hand = get_item_for_held_index(1) - var/obj/item/r_hand = get_item_for_held_index(2) - - var/y_shift = getItemPixelShiftY() - - if(r_hand) - var/mutable_appearance/r_hand_overlay = r_hand.build_worn_icon(default_layer = DRONE_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) - if(y_shift) - r_hand_overlay.pixel_y += y_shift - - hands_overlays += r_hand_overlay - - if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - SET_PLANE_EXPLICIT(r_hand, ABOVE_HUD_PLANE, src) - r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand)) - client.screen |= r_hand - - if(l_hand) - var/mutable_appearance/l_hand_overlay = l_hand.build_worn_icon(default_layer = DRONE_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) - if(y_shift) - l_hand_overlay.pixel_y += y_shift - - hands_overlays += l_hand_overlay - - if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - SET_PLANE_EXPLICIT(l_hand, ABOVE_HUD_PLANE, src) - l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand)) - client.screen |= l_hand - - - if(hands_overlays.len) - drone_overlays[DRONE_HANDS_LAYER] = hands_overlays - apply_overlay(DRONE_HANDS_LAYER) - - /mob/living/simple_animal/drone/proc/update_inv_internal_storage() if(internal_storage && client && hud_used?.hud_shown) internal_storage.screen_loc = ui_drone_storage diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm deleted file mode 100644 index af1b4eb13705e5..00000000000000 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ /dev/null @@ -1,121 +0,0 @@ -//goat -/mob/living/simple_animal/hostile/retaliate/goat - name = "goat" - desc = "Not known for their pleasant disposition." - icon_state = "goat" - icon_living = "goat" - icon_dead = "goat_dead" - speak = list("EHEHEHEHEH","eh?") - speak_emote = list("brays") - emote_hear = list("brays.") - emote_see = list("shakes their head.", "stamps a foot.", "glares around.") - speak_chance = 1 - turns_per_move = 5 - butcher_results = list(/obj/item/food/meat/slab/grassfed = 4) - response_help_continuous = "pets" - response_help_simple = "pet" - response_disarm_continuous = "gently pushes aside" - response_disarm_simple = "gently push aside" - response_harm_continuous = "kicks" - response_harm_simple = "kick" - faction = list(FACTION_NEUTRAL) - mob_biotypes = MOB_ORGANIC|MOB_BEAST - attack_same = 1 - attack_verb_continuous = "kicks" - attack_verb_simple = "kick" - attack_sound = 'sound/weapons/punch1.ogg' - attack_vis_effect = ATTACK_EFFECT_KICK - health = 40 - maxHealth = 40 - minbodytemp = 180 - melee_damage_lower = 1 - melee_damage_upper = 2 - environment_smash = ENVIRONMENT_SMASH_NONE - stop_automated_movement_when_pulled = 1 - blood_volume = BLOOD_VOLUME_NORMAL - - footstep_type = FOOTSTEP_MOB_SHOE - -/mob/living/simple_animal/hostile/retaliate/goat/Initialize(mapload) - AddComponent(/datum/component/udder) - AddElement(/datum/element/cliff_walking) //we walk the cliff - . = ..() - -/mob/living/simple_animal/hostile/retaliate/goat/Life(seconds_per_tick = SSMOBS_DT, times_fired) - . = ..() - if(.) - //chance to go crazy and start wacking stuff - if(!enemies.len && SPT_PROB(0.5, seconds_per_tick)) - Retaliate() - - if(enemies.len && SPT_PROB(5, seconds_per_tick)) - enemies.Cut() - LoseTarget() - src.visible_message(span_notice("[src] calms down.")) - if(stat != CONSCIOUS) - return - - eat_plants() - if(pulledby) - return - - for(var/direction in shuffle(list(1,2,4,8,5,6,9,10))) - var/turf/step = get_step(src, direction) - - if(!istype(step)) - return - - var/vine = locate(/obj/structure/spacevine) in step - var/mushroom = locate(/obj/structure/glowshroom) in step - var/flower = locate(/obj/structure/alien/resin/flower_bud) in step - - if(vine || mushroom || flower) - Move(step, get_dir(src, step)) - -/mob/living/simple_animal/hostile/retaliate/goat/Retaliate() - ..() - src.visible_message(span_danger("[src] gets an evil-looking gleam in [p_their()] eye.")) - -/mob/living/simple_animal/hostile/retaliate/goat/Move() - . = ..() - if(!stat) - eat_plants() - -/mob/living/simple_animal/hostile/retaliate/goat/proc/eat_plants() - var/obj/structure/spacevine/vine = locate(/obj/structure/spacevine) in loc - if(vine) - vine.eat(src) - - var/obj/structure/alien/resin/flower_bud/flower = locate(/obj/structure/alien/resin/flower_bud) in loc - if(flower) - flower.take_damage(rand(30, 50), BRUTE, 0) - - var/obj/structure/glowshroom/mushroom = locate(/obj/structure/glowshroom) in loc - if(mushroom) - qdel(mushroom) - - if((vine || flower || mushroom) && prob(10)) - say("Nom") // bon appetit - playsound(src, 'sound/items/eatfood.ogg', rand(30, 50), TRUE) - -/mob/living/simple_animal/hostile/retaliate/goat/AttackingTarget() - . = ..() - - if(!. || !isliving(target)) - return - - var/mob/living/plant_target = target - if(!(plant_target.mob_biotypes & MOB_PLANT)) - return - - plant_target.adjustBruteLoss(20) - playsound(src, 'sound/items/eatfood.ogg', rand(30, 50), TRUE) - var/obj/item/bodypart/edible_bodypart - - if(ishuman(plant_target)) - var/mob/living/carbon/human/plant_man = target - edible_bodypart = pick(plant_man.bodyparts) - edible_bodypart.dismember() - - plant_target.visible_message(span_warning("[src] takes a big chomp out of [plant_target]!"), \ - span_userdanger("[src] takes a big chomp out of your [edible_bodypart || "body"]!")) diff --git a/code/modules/mob/living/simple_animal/friendly/sloth.dm b/code/modules/mob/living/simple_animal/friendly/sloth.dm deleted file mode 100644 index 8e308c58d12d2a..00000000000000 --- a/code/modules/mob/living/simple_animal/friendly/sloth.dm +++ /dev/null @@ -1,68 +0,0 @@ -GLOBAL_DATUM(cargo_sloth, /mob/living/simple_animal/sloth) - -/mob/living/simple_animal/sloth - name = "sloth" - desc = "An adorable, sleepy creature." - icon = 'icons/mob/simple/pets.dmi' - icon_state = "sloth" - icon_living = "sloth" - icon_dead = "sloth_dead" - speak_emote = list("yawns") - emote_hear = list("snores.","yawns.") - emote_see = list("dozes off.", "looks around sleepily.") - speak_chance = 1 - turns_per_move = 5 - can_be_held = TRUE - butcher_results = list(/obj/item/food/meat/slab = 3) - response_help_continuous = "pets" - response_help_simple = "pet" - response_disarm_continuous = "gently pushes aside" - response_disarm_simple = "gently push aside" - response_harm_continuous = "kicks" - response_harm_simple = "kick" - mob_biotypes = MOB_ORGANIC|MOB_BEAST - gold_core_spawnable = FRIENDLY_SPAWN - melee_damage_lower = 18 - melee_damage_upper = 18 - health = 50 - maxHealth = 50 - speed = 10 - held_state = "sloth" - ///In the case 'melee_damage_upper' is somehow raised above 0 - attack_verb_continuous = "bites" - attack_verb_simple = "bite" - attack_sound = 'sound/weapons/bite.ogg' - attack_vis_effect = ATTACK_EFFECT_BITE - - footstep_type = FOOTSTEP_MOB_CLAW - -/mob/living/simple_animal/sloth/Initialize(mapload) - . = ..() - AddElement(/datum/element/pet_bonus, "slowly smiles!") - // If someone adds non-cargo sloths to maps we'll have a problem but we're fine for now - if(!GLOB.cargo_sloth && mapload && is_station_level(z)) - GLOB.cargo_sloth = src - -/mob/living/simple_animal/sloth/Destroy() - if(GLOB.cargo_sloth == src) - GLOB.cargo_sloth = null - - return ..() - -//Cargo Sloth -/mob/living/simple_animal/sloth/paperwork - name = "Paperwork" - desc = "Cargo's pet sloth. About as useful as the rest of the techs." - gold_core_spawnable = NO_SPAWN - -//Cargo Sloth 2 - -/mob/living/simple_animal/sloth/citrus - name = "Citrus" - desc = "Cargo's pet sloth. She's dressed in a horrible sweater." - icon_state = "cool_sloth" - icon_living = "cool_sloth" - icon_dead = "cool_sloth_dead" - gender = FEMALE - butcher_results = list(/obj/item/toy/spinningtoy = 1) - gold_core_spawnable = NO_SPAWN diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index ea5e0685b53fea..4ca35a673577ed 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -6,7 +6,8 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians desc = "A mysterious being that stands by its charge, ever vigilant." speak_emote = list("hisses") gender = NEUTER - mob_biotypes = NONE + mob_biotypes = MOB_SPECIAL + sentience_type = SENTIENCE_HUMANOID bubble_icon = "guardian" response_help_continuous = "passes through" response_help_simple = "pass through" @@ -89,6 +90,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians GLOB.parasites += src update_theme(theme) AddElement(/datum/element/simple_flying) + AddComponent(/datum/component/basic_inhands) manifest_effects() /mob/living/simple_animal/hostile/guardian/Destroy() //if deleted by admins or something random, cut from the summoner @@ -461,32 +463,6 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians cut_overlay(overlay) guardian_overlays[cache_index] = null -/mob/living/simple_animal/hostile/guardian/update_held_items() - remove_overlay(GUARDIAN_HANDS_LAYER) - var/list/hands_overlays = list() - var/obj/item/l_hand = get_item_for_held_index(1) - var/obj/item/r_hand = get_item_for_held_index(2) - - if(r_hand) - hands_overlays += r_hand.build_worn_icon(default_layer = GUARDIAN_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) - - if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - SET_PLANE_EXPLICIT(r_hand, ABOVE_HUD_PLANE, src) - r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand)) - client.screen |= r_hand - - if(l_hand) - hands_overlays += l_hand.build_worn_icon(default_layer = GUARDIAN_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) - - if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - SET_PLANE_EXPLICIT(l_hand, ABOVE_HUD_PLANE, src) - l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand)) - client.screen |= l_hand - - if(length(hands_overlays)) - guardian_overlays[GUARDIAN_HANDS_LAYER] = hands_overlays - apply_overlay(GUARDIAN_HANDS_LAYER) - /mob/living/simple_animal/hostile/guardian/regenerate_icons() update_held_items() diff --git a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm index 798b2067c6334d..d2fbfc33c877d3 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm @@ -22,17 +22,9 @@ dropItemToGround(internal_storage) /mob/living/simple_animal/hostile/guardian/dextrous/examine(mob/user) - if(dextrous) - . = list("This is [icon2html(src)] \a [src]!\n[desc]", EXAMINE_SECTION_BREAK) //SKYRAT EDIT CHANGE - for(var/obj/item/held_item in held_items) - if(held_item.item_flags & (ABSTRACT|EXAMINE_SKIP|HAND_ITEM)) - continue - . += "It has [held_item.get_examine_string(user)] in its [get_held_index_name(get_held_index_of_item(held_item))]." - if(internal_storage && !(internal_storage.item_flags & ABSTRACT)) - . += "It is holding [internal_storage.get_examine_string(user)] in its internal storage." - . += "" - else - return ..() + . = ..() + if(internal_storage && !(internal_storage.item_flags & ABSTRACT)) + . += span_info("It is holding [internal_storage.get_examine_string(user)] in its internal storage.") /mob/living/simple_animal/hostile/guardian/dextrous/recall_effects() drop_all_held_items() 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 5347f049e13cb3..9afdf231ce7c41 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/support.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm @@ -47,10 +47,13 @@ span_userdanger("[src] heals you!"), null, COMBAT_MESSAGE_RANGE, src) to_chat(src, span_notice("You heal [target]!")) playsound(target, attack_sound, 50, TRUE, TRUE, frequency = -1) //play punch in REVERSE - target.adjustBruteLoss(-healing_amount) - target.adjustFireLoss(-healing_amount) - target.adjustOxyLoss(-healing_amount) - target.adjustToxLoss(-healing_amount, forced = TRUE) + var/need_mob_update + need_mob_update = target.adjustBruteLoss(-healing_amount, updating_health = FALSE) + need_mob_update += target.adjustFireLoss(-healing_amount, updating_health = FALSE) + need_mob_update += target.adjustOxyLoss(-healing_amount, updating_health = FALSE) + need_mob_update += target.adjustToxLoss(-healing_amount, updating_health = FALSE, forced = TRUE) + if(need_mob_update) + target.updatehealth() var/obj/effect/temp_visual/heal/heal_effect = new /obj/effect/temp_visual/heal(get_turf(target)) heal_effect.color = guardian_color diff --git a/code/modules/mob/living/simple_animal/hostile/blob.dm b/code/modules/mob/living/simple_animal/hostile/blob.dm deleted file mode 100644 index 7a40a01239c89e..00000000000000 --- a/code/modules/mob/living/simple_animal/hostile/blob.dm +++ /dev/null @@ -1,101 +0,0 @@ -//Do not spawn -/mob/living/simple_animal/hostile/blob - icon = 'icons/mob/nonhuman-player/blob.dmi' - pass_flags = PASSBLOB - faction = list(ROLE_BLOB) - bubble_icon = "blob" - speak_emote = null //so we use verb_yell/verb_say/etc - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - minbodytemp = 0 - maxbodytemp = INFINITY - unique_name = 1 - combat_mode = TRUE - // ... Blob colored lighting - lighting_cutoff_red = 20 - lighting_cutoff_green = 40 - lighting_cutoff_blue = 30 - initial_language_holder = /datum/language_holder/empty - retreat_distance = null //! retreat doesn't obey pass_flags, so won't work on blob mobs. - /// Blob camera that controls the blob - var/mob/camera/blob/overmind = null - /// If this is related to anything else - var/independent = FALSE - /// The factory blob tile that generated this blob minion - var/obj/structure/blob/special/factory/factory - -/mob/living/simple_animal/hostile/blob/update_icons() - if(overmind) - add_atom_colour(overmind.blobstrain.color, FIXED_COLOUR_PRIORITY) - else - remove_atom_colour(FIXED_COLOUR_PRIORITY) - -/mob/living/simple_animal/hostile/blob/Initialize(mapload) - . = ..() - if(!independent) //no pulling people deep into the blob - remove_verb(src, /mob/living/verb/pulled) - else - pass_flags &= ~PASSBLOB - -/mob/living/simple_animal/hostile/blob/death() - factory = null - if(overmind) - overmind.blob_mobs -= src - overmind = null - return ..() - -/mob/living/simple_animal/hostile/blob/get_status_tab_items() - . = ..() - if(overmind) - . += "Blobs to Win: [overmind.blobs_legit.len]/[overmind.blobwincount]" - -/mob/living/simple_animal/hostile/blob/blob_act(obj/structure/blob/B) - if(stat != DEAD && health < maxHealth) - for(var/unused in 1 to 2) - var/obj/effect/temp_visual/heal/heal_effect = new /obj/effect/temp_visual/heal(get_turf(src)) //hello yes you are being healed - if(overmind) - heal_effect.color = overmind.blobstrain.complementary_color - else - heal_effect.color = "#000000" - adjustHealth(-maxHealth*BLOBMOB_HEALING_MULTIPLIER) - -/mob/living/simple_animal/hostile/blob/fire_act(exposed_temperature, exposed_volume) - ..() - if(exposed_temperature) - adjustFireLoss(clamp(0.01 * exposed_temperature, 1, 5)) - else - adjustFireLoss(5) - -/mob/living/simple_animal/hostile/blob/CanAllowThrough(atom/movable/mover, border_dir) - . = ..() - if(istype(mover, /obj/structure/blob)) - return TRUE - -///override to use astar/JPS instead of walk_to so we can take our blob pass_flags into account. -/mob/living/simple_animal/hostile/blob/Goto(target, delay, minimum_distance) - if(prevent_goto_movement) - return FALSE - if(target == src.target) - approaching_target = TRUE - else - approaching_target = FALSE - - SSmove_manager.jps_move(moving = src, chasing = target, delay = delay, repath_delay = 2 SECONDS, minimum_distance = minimum_distance, simulated_only = FALSE, skip_first = TRUE, timeout = 5 SECONDS, flags = MOVEMENT_LOOP_IGNORE_GLIDE) - return TRUE - -/mob/living/simple_animal/hostile/blob/Process_Spacemove(movement_dir = 0, continuous_move = FALSE) - for(var/obj/structure/blob/blob in range(1, src)) - return 1 - return ..() - -/mob/living/simple_animal/hostile/blob/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null) - if(sanitize) - message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) - var/spanned_message = say_quote(message) - var/rendered = "\[Blob Telepathy\] [real_name] [spanned_message]" - for(var/creature in GLOB.mob_list) - if(isovermind(creature) || isblobmonster(creature)) - to_chat(creature, rendered) - if(isobserver(creature)) - var/link = FOLLOW_LINK(creature, src) - to_chat(creature, "[link] [rendered]") - diff --git a/code/modules/mob/living/simple_animal/hostile/blobbernaut.dm b/code/modules/mob/living/simple_animal/hostile/blobbernaut.dm deleted file mode 100644 index dc1d038795f3cd..00000000000000 --- a/code/modules/mob/living/simple_animal/hostile/blobbernaut.dm +++ /dev/null @@ -1,109 +0,0 @@ -/mob/living/simple_animal/hostile/blob/blobbernaut - name = "blobbernaut" - desc = "A hulking, mobile chunk of blobmass." - icon_state = "blobbernaut" - icon_living = "blobbernaut" - icon_dead = "blobbernaut_dead" - health = BLOBMOB_BLOBBERNAUT_HEALTH - maxHealth = BLOBMOB_BLOBBERNAUT_HEALTH - damage_coeff = list(BRUTE = 0.5, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1) - melee_damage_lower = BLOBMOB_BLOBBERNAUT_DMG_SOLO_LOWER - melee_damage_upper = BLOBMOB_BLOBBERNAUT_DMG_SOLO_UPPER - obj_damage = BLOBMOB_BLOBBERNAUT_DMG_OBJ - attack_verb_continuous = "slams" - attack_verb_simple = "slam" - attack_sound = 'sound/effects/blobattack.ogg' - verb_say = "gurgles" - verb_ask = "demands" - verb_exclaim = "roars" - verb_yell = "bellows" - force_threshold = 10 - pressure_resistance = 50 - mob_size = MOB_SIZE_LARGE - hud_type = /datum/hud/living/blobbernaut - -/mob/living/simple_animal/hostile/blob/blobbernaut/Initialize(mapload) - . = ..() - add_cell_sample() - -/mob/living/simple_animal/hostile/blob/blobbernaut/mind_initialize() - . = ..() - if(independent | !overmind) - return - var/datum/antagonist/blob_minion/blobbernaut/naut = new(overmind) - mind.add_antag_datum(naut) - -/mob/living/simple_animal/hostile/blob/blobbernaut/add_cell_sample() - AddElement(/datum/element/swabable, CELL_LINE_TABLE_BLOBBERNAUT, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) - -/mob/living/simple_animal/hostile/blob/blobbernaut/Life(seconds_per_tick = SSMOBS_DT, times_fired) - if(!..()) - return FALSE - var/list/blobs_in_area = range(2, src) - - if(independent) - return FALSE // strong independent blobbernaut that don't need no blob - - var/damagesources = 0 - - if(!(locate(/obj/structure/blob) in blobs_in_area)) - damagesources++ - - if(!factory) - damagesources++ - else - if(locate(/obj/structure/blob/special/core) in blobs_in_area) - adjustHealth(-maxHealth*BLOBMOB_BLOBBERNAUT_HEALING_CORE * seconds_per_tick) - var/obj/effect/temp_visual/heal/heal_effect = new /obj/effect/temp_visual/heal(get_turf(src)) //hello yes you are being healed - if(overmind) - heal_effect.color = overmind.blobstrain.complementary_color - else - heal_effect.color = "#000000" - if(locate(/obj/structure/blob/special/node) in blobs_in_area) - adjustHealth(-maxHealth*BLOBMOB_BLOBBERNAUT_HEALING_NODE * seconds_per_tick) - var/obj/effect/temp_visual/heal/heal_effect = new /obj/effect/temp_visual/heal(get_turf(src)) - if(overmind) - heal_effect.color = overmind.blobstrain.complementary_color - else - heal_effect.color = "#000000" - - if(!damagesources) - return FALSE - - adjustHealth(maxHealth * BLOBMOB_BLOBBERNAUT_HEALTH_DECAY * damagesources * seconds_per_tick) //take 2.5% of max health as damage when not near the blob or if the naut has no factory, 5% if both - var/mutable_appearance/healing = mutable_appearance('icons/mob/nonhuman-player/blob.dmi', "nautdamage", MOB_LAYER+0.01) - healing.appearance_flags = RESET_COLOR - - if(overmind) - healing.color = overmind.blobstrain.complementary_color - - flick_overlay_view(healing, 0.8 SECONDS) - -/mob/living/simple_animal/hostile/blob/blobbernaut/AttackingTarget() - . = ..() - if(. && isliving(target) && overmind) - overmind.blobstrain.blobbernaut_attack(target, src) - -/mob/living/simple_animal/hostile/blob/blobbernaut/update_icons() - ..() - if(overmind) //if we have an overmind, we're doing chemical reactions instead of pure damage - melee_damage_lower = BLOBMOB_BLOBBERNAUT_DMG_LOWER - melee_damage_upper = BLOBMOB_BLOBBERNAUT_DMG_UPPER - attack_verb_continuous = overmind.blobstrain.blobbernaut_message - else - melee_damage_lower = initial(melee_damage_lower) - melee_damage_upper = initial(melee_damage_upper) - attack_verb_continuous = initial(attack_verb_continuous) - -/mob/living/simple_animal/hostile/blob/blobbernaut/death(gibbed) - if(factory) - factory.blobbernaut = null //remove this blobbernaut from its factory - factory.max_integrity = initial(factory.max_integrity) - flick("blobbernaut_death", src) - return ..() - -/mob/living/simple_animal/hostile/blob/blobbernaut/independent - independent = TRUE - gold_core_spawnable = HOSTILE_SPAWN - - diff --git a/code/modules/mob/living/simple_animal/hostile/blobspore.dm b/code/modules/mob/living/simple_animal/hostile/blobspore.dm deleted file mode 100644 index 501afde41b091d..00000000000000 --- a/code/modules/mob/living/simple_animal/hostile/blobspore.dm +++ /dev/null @@ -1,168 +0,0 @@ -/mob/living/simple_animal/hostile/blob/blobspore - name = "blob spore" - desc = "A floating, fragile spore." - icon_state = "blobpod" - icon_living = "blobpod" - health_doll_icon = "blobpod" - health = BLOBMOB_SPORE_HEALTH - maxHealth = BLOBMOB_SPORE_HEALTH - verb_say = "psychically pulses" - verb_ask = "psychically probes" - verb_exclaim = "psychically yells" - verb_yell = "psychically screams" - melee_damage_lower = BLOBMOB_SPORE_DMG_LOWER - melee_damage_upper = BLOBMOB_SPORE_DMG_UPPER - environment_smash = ENVIRONMENT_SMASH_NONE - obj_damage = 0 - attack_verb_continuous = "hits" - attack_verb_simple = "hit" - attack_sound = 'sound/weapons/genhit1.ogg' - del_on_death = TRUE - death_message = "explodes into a cloud of gas!" - gold_core_spawnable = NO_SPAWN //gold slime cores should only spawn the independent subtype - /// Size of cloud produced from a dying spore - var/death_cloud_size = 1 - /// The attached person - var/mob/living/carbon/human/corpse - /// If this is attached to a person - var/is_zombie = FALSE - /// Whether or not this is a fragile spore from Distributed Neurons - var/is_weak = FALSE - -/mob/living/simple_animal/hostile/blob/blobspore/Initialize(mapload, obj/structure/blob/special/linked_node) - . = ..() - AddElement(/datum/element/simple_flying) - - if(!istype(linked_node)) - return - - factory = linked_node - factory.spores += src - if(linked_node.overmind && istype(linked_node.overmind.blobstrain, /datum/blobstrain/reagent/distributed_neurons) && !istype(src, /mob/living/simple_animal/hostile/blob/blobspore/weak)) - notify_ghosts("A controllable spore has been created in \the [get_area(src)].", source = src, action = NOTIFY_ORBIT, flashwindow = FALSE, header = "Sentient Spore Created") - add_cell_sample() - -/mob/living/simple_animal/hostile/blob/blobspore/mind_initialize() - . = ..() - if(independent || !overmind) - return FALSE - var/datum/antagonist/blob_minion/blob_zombie/zombie = new(overmind) - mind.add_antag_datum(zombie) - -/mob/living/simple_animal/hostile/blob/blobspore/Life(seconds_per_tick = SSMOBS_DT, times_fired) - if(!is_zombie && isturf(loc)) - for(var/mob/living/carbon/human/target in view(src,1)) //Only for corpse right next to/on same tile - if(!is_weak && target.stat == DEAD) - zombify(target) - break - if(factory && !is_valid_z_level(get_turf(src), get_turf(factory))) - death() - return ..() - -/mob/living/simple_animal/hostile/blob/blobspore/attack_ghost(mob/user) - . = ..() - if(.) - return - humanize_pod(user) - -/mob/living/simple_animal/hostile/blob/blobspore/death(gibbed) - // On death, create a small smoke of harmful gas (s-Acid) - var/datum/effect_system/fluid_spread/smoke/chem/spores = new - var/turf/location = get_turf(src) - - // Create the reagents to put into the air - create_reagents(10) - - if(overmind?.blobstrain) - overmind.blobstrain.on_sporedeath(src) - else - reagents.add_reagent(/datum/reagent/toxin/spore, 10) - - // Attach the smoke spreader and setup/start it. - spores.attach(location) - spores.set_up(death_cloud_size, holder = src, location = location, carry = reagents, silent = TRUE) - spores.start() - if(factory) - factory.spore_delay = world.time + factory.spore_cooldown //put the factory on cooldown - - return ..() - -/mob/living/simple_animal/hostile/blob/blobspore/death() - if(factory) - factory.spores -= src - corpse?.forceMove(loc) - corpse = null - return ..() - -/mob/living/simple_animal/hostile/blob/blobspore/update_icons() - if(overmind) - add_atom_colour(overmind.blobstrain.complementary_color, FIXED_COLOUR_PRIORITY) - else - remove_atom_colour(FIXED_COLOUR_PRIORITY) - if(!is_zombie) - return FALSE - - copy_overlays(corpse, TRUE) - var/mutable_appearance/blob_head_overlay = mutable_appearance('icons/mob/nonhuman-player/blob.dmi', "blob_head") - if(overmind) - blob_head_overlay.color = overmind.blobstrain.complementary_color - color = initial(color) // looks better. - add_overlay(blob_head_overlay) - -/mob/living/simple_animal/hostile/blob/blobspore/add_cell_sample() - AddElement(/datum/element/swabable, CELL_LINE_TABLE_BLOBSPORE, CELL_VIRUS_TABLE_GENERIC_MOB, 1, 5) - -/mob/living/simple_animal/hostile/blob/blobspore/independent - gold_core_spawnable = HOSTILE_SPAWN - independent = TRUE - -/mob/living/simple_animal/hostile/blob/blobspore/weak - name = "fragile blob spore" - health = 15 - maxHealth = 15 - melee_damage_lower = 1 - melee_damage_upper = 2 - death_cloud_size = 0 - is_weak = TRUE - -/** Ghost control a blob zombie */ -/mob/living/simple_animal/hostile/blob/blobspore/proc/humanize_pod(mob/user) - if((!overmind || istype(src, /mob/living/simple_animal/hostile/blob/blobspore/weak) || !istype(overmind.blobstrain, /datum/blobstrain/reagent/distributed_neurons)) && !is_zombie) - return FALSE - if(key || stat) - return FALSE - var/pod_ask = tgui_alert(usr, "Are you bulbous enough?", "Blob Spore", list("Yes", "No")) - if(pod_ask != "Yes" || QDELETED(src)) - return FALSE - if(key) - to_chat(user, span_warning("Someone else already took this spore!")) - return FALSE - key = user.key - log_message("took control of [name].", LOG_GAME) - -/** Zombifies a dead mob, turning it into a blob zombie */ -/mob/living/simple_animal/hostile/blob/blobspore/proc/zombify(mob/living/carbon/human/target) - is_zombie = 1 - if(target.wear_suit) - maxHealth += target.get_armor_rating(MELEE) // That zombie's got armor, I want armor! - maxHealth += 40 - health = maxHealth - name = "blob zombie" - desc = "A shambling corpse animated by the blob." - mob_biotypes |= MOB_HUMANOID - melee_damage_lower += 8 - melee_damage_upper += 11 - obj_damage = 20 // now that it has a corpse to puppet, it can properly attack structures - environment_smash = ENVIRONMENT_SMASH_STRUCTURES - movement_type = GROUND - death_cloud_size = 0 - icon = target.icon - icon_state = "zombie" - target.set_facial_hairstyle("Shaved", update = FALSE) - target.set_hairstyle("Bald", update = TRUE) - target.forceMove(src) - corpse = target - update_icons() - visible_message(span_warning("The corpse of [target.name] suddenly rises!")) - if(!key) - notify_ghosts("\A [src] has been created in \the [get_area(src)].", source = src, action = NOTIFY_ORBIT, flashwindow = FALSE, header = "Blob Zombie Created") diff --git a/code/modules/mob/living/simple_animal/hostile/constructs/constructs.dm b/code/modules/mob/living/simple_animal/hostile/constructs/constructs.dm index 23f7590dc8e247..31150a4dc89c17 100644 --- a/code/modules/mob/living/simple_animal/hostile/constructs/constructs.dm +++ b/code/modules/mob/living/simple_animal/hostile/constructs/constructs.dm @@ -3,7 +3,7 @@ real_name = "Construct" desc = "" gender = NEUTER - mob_biotypes = NONE + mob_biotypes = MOB_MINERAL | MOB_SPECIAL speak_emote = list("hisses") response_help_continuous = "thinks better of touching" response_help_simple = "think better of touching" diff --git a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm deleted file mode 100644 index cceb0cdf58cb89..00000000000000 --- a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm +++ /dev/null @@ -1,174 +0,0 @@ -#define GORILLA_TOTAL_LAYERS 1 - -/mob/living/simple_animal/hostile/gorilla - name = "Gorilla" - desc = "A ground-dwelling, predominantly herbivorous ape that inhabits the forests of central Africa." - icon = 'icons/mob/simple/gorilla.dmi' - icon_state = "crawling" - icon_living = "crawling" - icon_dead = "dead" - health_doll_icon = "crawling" - mob_biotypes = MOB_ORGANIC|MOB_HUMANOID - speak_chance = 80 - maxHealth = 220 - health = 220 - loot = list(/obj/effect/gibspawner/generic/animal) - butcher_results = list(/obj/item/food/meat/slab/gorilla = 4) - response_help_continuous = "prods" - response_help_simple = "prod" - response_disarm_continuous = "challenges" - response_disarm_simple = "challenge" - response_harm_continuous = "thumps" - response_harm_simple = "thump" - speed = 0.5 - melee_damage_lower = 15 - melee_damage_upper = 18 - damage_coeff = list(BRUTE = 1, BURN = 1.5, TOX = 1.5, CLONE = 0, STAMINA = 0, OXY = 1.5) - obj_damage = 20 - environment_smash = ENVIRONMENT_SMASH_WALLS - attack_verb_continuous = "pummels" - attack_verb_simple = "pummel" - attack_sound = 'sound/weapons/punch1.ogg' - dextrous = TRUE - hud_type = /datum/hud/dextrous - held_items = list(null, null) - faction = list(FACTION_MONKEY, FACTION_JUNGLE) - robust_searching = TRUE - stat_attack = HARD_CRIT - minbodytemp = 270 - maxbodytemp = 350 - unique_name = TRUE - footstep_type = FOOTSTEP_MOB_BAREFOOT - - var/list/gorilla_overlays[GORILLA_TOTAL_LAYERS] - var/oogas = 0 - -// Gorillas like to dismember limbs from unconscious mobs. -// Returns null when the target is not an unconscious carbon mob; a list of limbs (possibly empty) otherwise. -/mob/living/simple_animal/hostile/gorilla/proc/get_target_bodyparts(atom/hit_target) - if(!iscarbon(hit_target)) - return - - var/mob/living/carbon/carbon_target = hit_target - if(carbon_target.stat < UNCONSCIOUS) - return - - var/list/parts = list() - for(var/obj/item/bodypart/part as anything in carbon_target.bodyparts) - if(part.body_part == HEAD || part.body_part == CHEST) - continue - if(part.bodypart_flags & BODYPART_UNREMOVABLE) - continue - parts += part - return parts - -/mob/living/simple_animal/hostile/gorilla/AttackingTarget(atom/attacked_target) - . = ..() - if(!.) - return - - if(client) - oogaooga() - - var/list/parts = get_target_bodyparts(target) - if(length(parts)) - var/obj/item/bodypart/to_dismember = pick(parts) - to_dismember.dismember() - return - - if(isliving(target)) - var/mob/living/living_target = target - if(prob(80)) - living_target.throw_at(get_edge_target_turf(living_target, dir), rand(1, 2), 7, src) - - else - living_target.Paralyze(2 SECONDS) - visible_message(span_danger("[src] knocks [living_target] down!")) - -/mob/living/simple_animal/hostile/gorilla/CanAttack(atom/the_target) - var/list/parts = get_target_bodyparts(target) - return ..() && !ismonkey(the_target) && (!parts || length(parts) > 3) - -/mob/living/simple_animal/hostile/gorilla/CanSmashTurfs(turf/T) - return iswallturf(T) - -/mob/living/simple_animal/hostile/gorilla/gib(no_brain) - if(!no_brain) - var/mob/living/brain/gorilla_brain = new(drop_location()) - gorilla_brain.name = real_name - gorilla_brain.real_name = real_name - mind?.transfer_to(gorilla_brain) - return ..() - -/mob/living/simple_animal/hostile/gorilla/handle_automated_speech(override) - if(speak_chance && (override || prob(speak_chance))) - playsound(src, 'sound/creatures/gorilla.ogg', 50) - return ..() - -/mob/living/simple_animal/hostile/gorilla/can_use_guns(obj/item/G) - to_chat(src, span_warning("Your meaty finger is much too large for the trigger guard!")) - return FALSE - -/mob/living/simple_animal/hostile/gorilla/proc/oogaooga() - oogas -= 1 - if(oogas <= 0) - oogas = rand(2,6) - playsound(src, 'sound/creatures/gorilla.ogg', 50) - -/mob/living/simple_animal/hostile/gorilla/lesser - name = "lesser Gorilla" - desc = "An adolescent Gorilla. It may not be fully grown but, much like a banana, that just means it's sturdier and harder to chew!" - speak_chance = 100 // compensating for something - maxHealth = 120 - health = 120 - butcher_results = list(/obj/item/food/meat/slab/gorilla = 2) - speed = 0.35 - melee_damage_lower = 10 - melee_damage_upper = 15 - obj_damage = 15 - stat_attack = SOFT_CRIT - unique_name = TRUE - -/mob/living/simple_animal/hostile/gorilla/lesser/Initialize(mapload) - . = ..() - transform *= 0.75 // smolrilla - -/mob/living/simple_animal/hostile/gorilla/cargo_domestic - name = "Cargorilla" // Overriden, normally - icon = 'icons/mob/simple/cargorillia.dmi' - desc = "Cargo's pet gorilla. They seem to have an 'I love Mom' tattoo." - maxHealth = 200 - health = 200 - faction = list(FACTION_NEUTRAL, FACTION_MONKEY, FACTION_JUNGLE) - gold_core_spawnable = NO_SPAWN - unique_name = FALSE - -/mob/living/simple_animal/hostile/gorilla/cargo_domestic/Initialize(mapload) - . = ..() - ADD_TRAIT(src, TRAIT_PACIFISM, INNATE_TRAIT) - AddComponent(/datum/component/crate_carrier) - -/// Poll ghosts for control of the gorilla. -/mob/living/simple_animal/hostile/gorilla/cargo_domestic/proc/poll_for_gorilla() - AddComponent(\ - /datum/component/ghost_direct_control,\ - poll_candidates = TRUE,\ - poll_length = 30 SECONDS,\ - role_name = "Cargorilla",\ - assumed_control_message = "You are Cargorilla, a pacifistic friend of the station and carrier of freight.",\ - poll_ignore_key = POLL_IGNORE_CARGORILLA,\ - after_assumed_control = CALLBACK(src, PROC_REF(became_player_controlled)),\ - ) - -/// Called once a ghost assumes control -/mob/living/simple_animal/hostile/gorilla/cargo_domestic/proc/became_player_controlled() - mind.set_assigned_role(SSjob.GetJobType(/datum/job/cargo_technician)) - mind.special_role = "Cargorilla" - to_chat(src, span_notice("You can pick up crates by clicking on them, and drop them by clicking on the ground.")) - -/obj/item/card/id/advanced/cargo_gorilla - name = "cargorilla ID" - desc = "A card used to provide ID and determine access across the station. A gorilla-sized ID for a gorilla-sized cargo technician." - trim = /datum/id_trim/job/cargo_technician - -#undef GORILLA_TOTAL_LAYERS diff --git a/code/modules/mob/living/simple_animal/hostile/gorilla/visuals_icons.dm b/code/modules/mob/living/simple_animal/hostile/gorilla/visuals_icons.dm deleted file mode 100644 index 39dfe8f7d899e5..00000000000000 --- a/code/modules/mob/living/simple_animal/hostile/gorilla/visuals_icons.dm +++ /dev/null @@ -1,56 +0,0 @@ -#define GORILLA_HANDS_LAYER 1 - -/mob/living/simple_animal/hostile/gorilla/proc/apply_overlay(cache_index) - . = gorilla_overlays[cache_index] - if(.) - add_overlay(.) - -/mob/living/simple_animal/hostile/gorilla/proc/remove_overlay(cache_index) - var/I = gorilla_overlays[cache_index] - if(I) - cut_overlay(I) - gorilla_overlays[cache_index] = null - -/mob/living/simple_animal/hostile/gorilla/update_held_items() - cut_overlays("standing_overlay") - remove_overlay(GORILLA_HANDS_LAYER) - - var/standing = FALSE - for(var/I in held_items) - if(I) - standing = TRUE - break - if(!standing) - if(stat != DEAD) - icon_state = "crawling" - set_varspeed(0.5) - return ..() - if(stat != DEAD) - icon_state = "standing" - set_varspeed(1) // Gorillas are slow when standing up. - - var/list/hands_overlays = list() - - var/obj/item/l_hand = get_item_for_held_index(1) - var/obj/item/r_hand = get_item_for_held_index(2) - - if(r_hand) - var/mutable_appearance/r_hand_overlay = r_hand.build_worn_icon(default_layer = GORILLA_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE) - r_hand_overlay.pixel_y -= 1 - hands_overlays += r_hand_overlay - - if(l_hand) - var/mutable_appearance/l_hand_overlay = l_hand.build_worn_icon(default_layer = GORILLA_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE) - l_hand_overlay.pixel_y -= 1 - hands_overlays += l_hand_overlay - - if(hands_overlays.len) - gorilla_overlays[GORILLA_HANDS_LAYER] = hands_overlays - apply_overlay(GORILLA_HANDS_LAYER) - add_overlay("standing_overlay") - return ..() - -/mob/living/simple_animal/hostile/gorilla/regenerate_icons() - update_held_items() - -#undef GORILLA_HANDS_LAYER diff --git a/code/modules/mob/living/simple_animal/hostile/heretic_monsters.dm b/code/modules/mob/living/simple_animal/hostile/heretic_monsters.dm deleted file mode 100644 index 2c0b9ba983a09f..00000000000000 --- a/code/modules/mob/living/simple_animal/hostile/heretic_monsters.dm +++ /dev/null @@ -1,428 +0,0 @@ -/mob/living/simple_animal/hostile/heretic_summon - name = "Eldritch Demon" - real_name = "Eldritch Demon" - desc = "A horror from beyond this realm." - icon = 'icons/mob/nonhuman-player/eldritch_mobs.dmi' - gender = NEUTER - mob_biotypes = NONE - attack_sound = 'sound/weapons/punch1.ogg' - response_help_continuous = "thinks better of touching" - response_help_simple = "think better of touching" - response_disarm_continuous = "flails at" - response_disarm_simple = "flail at" - response_harm_continuous = "reaps" - response_harm_simple = "tears" - speak_emote = list("screams") - speak_chance = 1 - speed = 0 - combat_mode = TRUE - stop_automated_movement = TRUE - AIStatus = AI_OFF - // Sort of greenish brown, to match the vibeTM - lighting_cutoff_red = 20 - lighting_cutoff_green = 25 - lighting_cutoff_blue = 5 - damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - minbodytemp = 0 - maxbodytemp = INFINITY - movement_type = GROUND - pressure_resistance = 100 - del_on_death = TRUE - death_message = "implodes into itself." - loot = list(/obj/effect/gibspawner/human) - faction = list(FACTION_HERETIC) - simple_mob_flags = SILENCE_RANGED_MESSAGE - - /// Innate spells that are added when a beast is created. - var/list/actions_to_add - -/mob/living/simple_animal/hostile/heretic_summon/Initialize(mapload) - . = ..() - for(var/spell in actions_to_add) - var/datum/action/cooldown/spell/new_spell = new spell(src) - new_spell.Grant(src) - -/mob/living/simple_animal/hostile/heretic_summon/raw_prophet - name = "Raw Prophet" - real_name = "Raw Prophet" - desc = "An abomination stitched together from a few severed arms and one lost eye." - icon_state = "raw_prophet" - icon_living = "raw_prophet" - status_flags = CANPUSH - melee_damage_lower = 5 - melee_damage_upper = 10 - maxHealth = 65 - health = 65 - sight = SEE_MOBS|SEE_OBJS|SEE_TURFS - loot = list(/obj/effect/gibspawner/human, /obj/item/bodypart/arm/left, /obj/item/organ/internal/eyes) - actions_to_add = list( - /datum/action/cooldown/spell/jaunt/ethereal_jaunt/ash/long, - /datum/action/cooldown/spell/list_target/telepathy/eldritch, - /datum/action/cooldown/spell/pointed/blind/eldritch, - /datum/action/innate/expand_sight, - ) - /// A weakref to the last target we smacked. Hitting targets consecutively does more damage. - var/datum/weakref/last_target - -/mob/living/simple_animal/hostile/heretic_summon/raw_prophet/Initialize(mapload) - . = ..() - var/on_link_message = "You feel something new enter your sphere of mind... \ - You hear whispers of people far away, screeches of horror and a huming of welcome to [src]'s Mansus Link." - - var/on_unlink_message = "Your mind shatters as [src]'s Mansus Link leaves your mind." - - AddComponent( \ - /datum/component/mind_linker/active_linking, \ - network_name = "Mansus Link", \ - chat_color = "#568b00", \ - post_unlink_callback = CALLBACK(src, PROC_REF(after_unlink)), \ - speech_action_background_icon_state = "bg_heretic", \ - speech_action_overlay_state = "bg_heretic_border", \ - linker_action_path = /datum/action/cooldown/spell/pointed/manse_link, \ - link_message = on_link_message, \ - unlink_message = on_unlink_message, \ - ) - -/mob/living/simple_animal/hostile/heretic_summon/raw_prophet/attack_animal(mob/living/simple_animal/user, list/modifiers) - if(user == src) // Easy to hit yourself + very fragile = accidental suicide, prevent that - return - - return ..() - -/mob/living/simple_animal/hostile/heretic_summon/raw_prophet/AttackingTarget(atom/attacked_target) - if(WEAKREF(attacked_target) == last_target) - melee_damage_lower = min(melee_damage_lower + 5, 30) - melee_damage_upper = min(melee_damage_upper + 5, 35) - else - melee_damage_lower = initial(melee_damage_lower) - melee_damage_upper = initial(melee_damage_upper) - - . = ..() - if(!.) - return - - SpinAnimation(5, 1) - last_target = WEAKREF(attacked_target) - -/mob/living/simple_animal/hostile/heretic_summon/raw_prophet/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) - . = ..() - var/rotation_degree = (360 / 3) - if(movement_dir & WEST || movement_dir & SOUTH) - rotation_degree *= -1 - - var/matrix/to_turn = matrix(transform) - to_turn = turn(transform, rotation_degree) - animate(src, transform = to_turn, time = 0.1 SECONDS) - -/* - * Callback for the mind_linker component. - * Stuns people who are ejected from the network. - */ -/mob/living/simple_animal/hostile/heretic_summon/raw_prophet/proc/after_unlink(mob/living/unlinked_mob) - if(QDELETED(unlinked_mob) || unlinked_mob.stat == DEAD) - return - - INVOKE_ASYNC(unlinked_mob, TYPE_PROC_REF(/mob, emote), "scream") - unlinked_mob.AdjustParalyzed(0.5 SECONDS) //micro stun - -// What if we took a linked list... But made it a mob? -/// The "Terror of the Night" / Armsy, a large worm made of multiple bodyparts that occupies multiple tiles -/mob/living/simple_animal/hostile/heretic_summon/armsy - name = "Terror of the night" - real_name = "Armsy" - desc = "An abomination made from dozens and dozens of severed and malformed limbs piled onto each other." - icon_state = "armsy_start" - icon_living = "armsy_start" - maxHealth = 200 - health = 200 - melee_damage_lower = 10 - melee_damage_upper = 15 - move_force = MOVE_FORCE_OVERPOWERING - move_resist = MOVE_FORCE_OVERPOWERING - pull_force = MOVE_FORCE_OVERPOWERING - movement_type = GROUND - mob_size = MOB_SIZE_HUGE - sentience_type = SENTIENCE_BOSS - environment_smash = ENVIRONMENT_SMASH_RWALLS - mob_biotypes = MOB_ORGANIC|MOB_SPECIAL - obj_damage = 200 - ranged_cooldown_time = 5 - ranged = TRUE - rapid = 1 - actions_to_add = list(/datum/action/cooldown/spell/worm_contract) - ///Previous segment in the chain - var/mob/living/simple_animal/hostile/heretic_summon/armsy/back - ///Next segment in the chain - var/mob/living/simple_animal/hostile/heretic_summon/armsy/front - ///Your old location - var/oldloc - ///Allow / disallow pulling - var/allow_pulling = FALSE - ///How many arms do we have to eat to expand? - var/stacks_to_grow = 5 - ///Currently eaten arms - var/current_stacks = 0 - ///Does this follow other pieces? - var/follow = TRUE - -/* - * Arguments - * * spawn_bodyparts - whether we spawn additional armsy bodies until we reach length. - * * worm_length - the length of the worm we're creating. Below 3 doesn't work very well. - */ -/mob/living/simple_animal/hostile/heretic_summon/armsy/Initialize(mapload, spawn_bodyparts = TRUE, worm_length = 6) - . = ..() - if(worm_length < 3) - stack_trace("[type] created with invalid len ([worm_length]). Reverting to 3.") - worm_length = 3 //code breaks below 3, let's just not allow it. - - oldloc = loc - RegisterSignal(src, COMSIG_MOVABLE_MOVED, PROC_REF(update_chain_links)) - if(!spawn_bodyparts) - return - - AddComponent(/datum/component/blood_walk, \ - blood_type = /obj/effect/decal/cleanable/blood/tracks, \ - target_dir_change = TRUE) - - allow_pulling = TRUE - // Sets the hp of the head to be exactly the (length * hp), so the head is de facto the hardest to destroy. - maxHealth = worm_length * maxHealth - health = maxHealth - - // The previous link in the chain - var/mob/living/simple_animal/hostile/heretic_summon/armsy/prev = src - // The current link in the chain - var/mob/living/simple_animal/hostile/heretic_summon/armsy/current - - for(var/i in 1 to worm_length) - current = new type(drop_location(), FALSE) - current.icon_state = "armsy_mid" - current.icon_living = "armsy_mid" - current.AIStatus = AI_OFF - current.front = prev - prev.back = current - prev = current - - prev.icon_state = "armsy_end" - prev.icon_living = "armsy_end" - -/mob/living/simple_animal/hostile/heretic_summon/armsy/adjustBruteLoss(amount, updating_health, forced, required_bodytype) - if(back) - return back.adjustBruteLoss(amount, updating_health, forced) - - return ..() - -/mob/living/simple_animal/hostile/heretic_summon/armsy/adjustFireLoss(amount, updating_health, forced, required_bodytype) - if(back) - return back.adjustFireLoss(amount, updating_health, forced) - - return ..() - -// We are literally a vessel of otherworldly destruction, we bring our own gravity unto this plane -/mob/living/simple_animal/hostile/heretic_summon/armsy/has_gravity(turf/gravity_turf) - return TRUE - -/mob/living/simple_animal/hostile/heretic_summon/armsy/can_be_pulled() - return FALSE - -/// Updates every body in the chain to force move onto a single tile. -/mob/living/simple_animal/hostile/heretic_summon/armsy/proc/contract_next_chain_into_single_tile() - if(!back) - return - - back.forceMove(loc) - back.contract_next_chain_into_single_tile() - -/* - * Recursively get the length of our chain. - */ -/mob/living/simple_animal/hostile/heretic_summon/armsy/proc/get_length() - . = 1 - if(back) - . += back.get_length() - -/// Updates the next mob in the chain to move to our last location. Fixes the chain if somehow broken. -/mob/living/simple_animal/hostile/heretic_summon/armsy/proc/update_chain_links() - SIGNAL_HANDLER - - if(!follow) - return - - if(back && back.loc != oldloc) - back.Move(oldloc) - - // self fixing properties if somehow broken - if(front && loc != front.oldloc) - forceMove(front.oldloc) - - oldloc = loc - -/mob/living/simple_animal/hostile/heretic_summon/armsy/Destroy() - if(front) - front.icon_state = "armsy_end" - front.icon_living = "armsy_end" - front.back = null - front = null - if(back) - QDEL_NULL(back) // chain destruction baby - return ..() - -/* - * Handle healing our chain. - * - * Eating arms off the ground heals us, - * and if we eat enough arms while above - * a certain health threshold, we even gain back parts! - */ -/mob/living/simple_animal/hostile/heretic_summon/armsy/proc/heal() - if(back) - back.heal() - return - - adjustBruteLoss(-maxHealth * 0.5, FALSE) - adjustFireLoss(-maxHealth * 0.5, FALSE) - - if(health < maxHealth * 0.8) - return - - current_stacks++ - if(current_stacks < stacks_to_grow) - return - - var/mob/living/simple_animal/hostile/heretic_summon/armsy/prev = new type(drop_location(), FALSE) - icon_state = "armsy_mid" - icon_living = "armsy_mid" - back = prev - prev.icon_state = "armsy_end" - prev.icon_living = "armsy_end" - prev.front = src - prev.AIStatus = AI_OFF - current_stacks = 0 - -/mob/living/simple_animal/hostile/heretic_summon/armsy/Shoot(atom/targeted_atom) - GiveTarget(targeted_atom) - AttackingTarget() - -/mob/living/simple_animal/hostile/heretic_summon/armsy/AttackingTarget() - if(istype(target, /obj/item/bodypart/arm)) - playsound(src, 'sound/magic/demon_consume.ogg', 50, TRUE) - qdel(target) - heal() - return - if(target == back || target == front) - return - if(back) - back.GiveTarget(target) - back.AttackingTarget() - if(!Adjacent(target)) - return - do_attack_animation(target) - - if(iscarbon(target)) - var/mob/living/carbon/carbon_target = target - if(HAS_TRAIT(carbon_target, TRAIT_NODISMEMBER)) - return ..() - - var/list/parts_to_remove = list() - for(var/obj/item/bodypart/bodypart in carbon_target.bodyparts) - if(bodypart.body_part != HEAD && bodypart.body_part != CHEST && bodypart.body_part != LEG_LEFT && bodypart.body_part != LEG_RIGHT) - if(!(bodypart.bodypart_flags & BODYPART_UNREMOVABLE)) - parts_to_remove += bodypart - - if(parts_to_remove.len && prob(10)) - var/obj/item/bodypart/lost_arm = pick(parts_to_remove) - lost_arm.dismember() - - return ..() - -/mob/living/simple_animal/hostile/heretic_summon/armsy/prime - name = "Lord of the Night" - real_name = "Master of Decay" - maxHealth = 400 - health = 400 - melee_damage_lower = 30 - melee_damage_upper = 50 - -/mob/living/simple_animal/hostile/heretic_summon/armsy/prime/Initialize(mapload, spawn_bodyparts = TRUE, worm_length = 9) - . = ..() - var/matrix/matrix_transformation = matrix() - matrix_transformation.Scale(1.4, 1.4) - transform = matrix_transformation - -/mob/living/simple_animal/hostile/heretic_summon/rust_spirit - name = "Rust Walker" - real_name = "Rusty" - desc = "An incomprehensible abomination. Everywhere it steps, it appears to be actively seeping life out of its surroundings." - icon_state = "rust_walker_s" - icon_living = "rust_walker_s" - status_flags = CANPUSH - maxHealth = 75 - health = 75 - melee_damage_lower = 15 - melee_damage_upper = 20 - sight = SEE_TURFS - actions_to_add = list( - /datum/action/cooldown/spell/aoe/rust_conversion/small, - /datum/action/cooldown/spell/basic_projectile/rust_wave/short, - ) - -/mob/living/simple_animal/hostile/heretic_summon/rust_spirit/setDir(newdir) - . = ..() - if(newdir == NORTH) - icon_state = "rust_walker_n" - else if(newdir == SOUTH) - icon_state = "rust_walker_s" - update_appearance(UPDATE_ICON_STATE) - -/mob/living/simple_animal/hostile/heretic_summon/rust_spirit/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) - . = ..() - playsound(src, 'sound/effects/footstep/rustystep1.ogg', 100, TRUE) - -/mob/living/simple_animal/hostile/heretic_summon/rust_spirit/Life(seconds_per_tick = SSMOBS_DT, times_fired) - if(stat == DEAD) - return ..() - - var/turf/our_turf = get_turf(src) - if(HAS_TRAIT(our_turf, TRAIT_RUSTY)) - adjustBruteLoss(-1.5 * seconds_per_tick, FALSE) - adjustFireLoss(-1.5 * seconds_per_tick, FALSE) - - return ..() - -/mob/living/simple_animal/hostile/heretic_summon/ash_spirit - name = "Ash Man" - real_name = "Ashy" - desc = "An incomprehensible abomination. As it moves, a thin trail of ash follows, appearing from seemingly nowhere." - icon_state = "ash_walker" - icon_living = "ash_walker" - status_flags = CANPUSH - maxHealth = 75 - health = 75 - melee_damage_lower = 15 - melee_damage_upper = 20 - sight = SEE_TURFS - actions_to_add = list( - /datum/action/cooldown/spell/jaunt/ethereal_jaunt/ash, - /datum/action/cooldown/spell/pointed/cleave, - /datum/action/cooldown/spell/fire_sworn, - ) - -/mob/living/simple_animal/hostile/heretic_summon/stalker - name = "Flesh Stalker" - real_name = "Flesh Stalker" - desc = "An abomination made from several limbs and organs. Every moment you stare at it, it appears to shift and change unnaturally." - icon_state = "stalker" - icon_living = "stalker" - status_flags = CANPUSH - maxHealth = 150 - health = 150 - melee_damage_lower = 15 - melee_damage_upper = 20 - sight = SEE_MOBS - actions_to_add = list( - /datum/action/cooldown/spell/shapeshift/eldritch, - /datum/action/cooldown/spell/jaunt/ethereal_jaunt/ash, - /datum/action/cooldown/spell/emp/eldritch, - ) diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm index 5ef5987942e2ec..04bb2f94cc9c69 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/leaper.dm @@ -132,9 +132,10 @@ taste_mult = 1.3 /datum/reagent/toxin/leaper_venom/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) + . = ..() if(volume >= 10) - M.adjustToxLoss(5 * REM * seconds_per_tick, 0) - ..() + if(M.adjustToxLoss(5 * REM * seconds_per_tick, updating_health = FALSE)) + . = UPDATE_MOB_HEALTH /obj/effect/temp_visual/leaper_crush name = "grim tidings" diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm b/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm deleted file mode 100644 index 444635f2dc344f..00000000000000 --- a/code/modules/mob/living/simple_animal/hostile/jungle/mook.dm +++ /dev/null @@ -1,229 +0,0 @@ -#define MOOK_ATTACK_NEUTRAL 0 -#define MOOK_ATTACK_WARMUP 1 -#define MOOK_ATTACK_ACTIVE 2 -#define MOOK_ATTACK_RECOVERY 3 -#define ATTACK_INTERMISSION_TIME 5 - -//Fragile but highly aggressive wanderers that pose a large threat in numbers. -//They'll attempt to leap at their target from afar using their hatchets. -/mob/living/simple_animal/hostile/jungle/mook - name = "wanderer" - desc = "This unhealthy looking primitive is wielding a rudimentary hatchet, swinging it with wild abandon. One isn't much of a threat, but in numbers they can quickly overwhelm a superior opponent." - icon = 'icons/mob/simple/jungle/mook.dmi' - icon_state = "mook" - icon_living = "mook" - icon_dead = "mook_dead" - mob_biotypes = MOB_ORGANIC|MOB_HUMANOID - SET_BASE_PIXEL(-16, -8) - - maxHealth = 45 - health = 45 - melee_damage_lower = 30 - melee_damage_upper = 30 - ranged = TRUE - ranged_cooldown_time = 10 - pass_flags_self = LETPASSTHROW - robust_searching = TRUE - stat_attack = HARD_CRIT - attack_sound = 'sound/weapons/rapierhit.ogg' - attack_vis_effect = ATTACK_EFFECT_SLASH - death_sound = 'sound/voice/mook_death.ogg' - aggro_vision_range = 15 //A little more aggressive once in combat to balance out their really low HP - var/attack_state = MOOK_ATTACK_NEUTRAL - var/struck_target_leap = FALSE - - footstep_type = FOOTSTEP_MOB_BAREFOOT - -/mob/living/simple_animal/hostile/jungle/mook/CanAllowThrough(atom/movable/mover, border_dir) - . = ..() - if(istype(mover, /mob/living/simple_animal/hostile/jungle/mook)) - var/mob/living/simple_animal/hostile/jungle/mook/mook_moover = mover - if(mook_moover.attack_state == MOOK_ATTACK_ACTIVE && mook_moover.throwing) - return TRUE - -/mob/living/simple_animal/hostile/jungle/mook/death() - desc = "A deceased primitive. Upon closer inspection, it was suffering from severe cellular degeneration and its garments are machine made..."//Can you guess the twist - return ..() - -/mob/living/simple_animal/hostile/jungle/mook/AttackingTarget() - if(isliving(target)) - if(ranged_cooldown <= world.time && attack_state == MOOK_ATTACK_NEUTRAL) - var/mob/living/L = target - if(L.incapacitated()) - WarmupAttack(forced_slash_combo = TRUE) - return - WarmupAttack() - return - return ..() - -/mob/living/simple_animal/hostile/jungle/mook/Goto() - if(attack_state != MOOK_ATTACK_NEUTRAL) - return - return ..() - -/mob/living/simple_animal/hostile/jungle/mook/Move() - if(attack_state == MOOK_ATTACK_WARMUP || attack_state == MOOK_ATTACK_RECOVERY) - return - return ..() - -/mob/living/simple_animal/hostile/jungle/mook/proc/WarmupAttack(forced_slash_combo = FALSE) - if(attack_state == MOOK_ATTACK_NEUTRAL && target) - attack_state = MOOK_ATTACK_WARMUP - SSmove_manager.stop_looping(src) - update_icons() - if(prob(50) && get_dist(src,target) <= 3 || forced_slash_combo) - addtimer(CALLBACK(src, PROC_REF(SlashCombo)), ATTACK_INTERMISSION_TIME) - return - addtimer(CALLBACK(src, PROC_REF(LeapAttack)), ATTACK_INTERMISSION_TIME + rand(0,3)) - return - attack_state = MOOK_ATTACK_RECOVERY - ResetNeutral() - -/mob/living/simple_animal/hostile/jungle/mook/proc/SlashCombo() - if(attack_state == MOOK_ATTACK_WARMUP && !stat) - attack_state = MOOK_ATTACK_ACTIVE - update_icons() - SlashAttack() - addtimer(CALLBACK(src, PROC_REF(SlashAttack)), 3) - addtimer(CALLBACK(src, PROC_REF(SlashAttack)), 6) - addtimer(CALLBACK(src, PROC_REF(AttackRecovery)), 9) - -/mob/living/simple_animal/hostile/jungle/mook/proc/SlashAttack() - if(target && !stat && attack_state == MOOK_ATTACK_ACTIVE) - melee_damage_lower = 15 - melee_damage_upper = 15 - var/mob_direction = get_dir(src,target) - var/atom/target_from = GET_TARGETS_FROM(src) - if(get_dist(src,target) > 1) - step(src,mob_direction) - if(isturf(target_from.loc) && target.Adjacent(target_from) && isliving(target)) - var/mob/living/L = target - L.attack_animal(src) - return - var/swing_turf = get_step(src,mob_direction) - new /obj/effect/temp_visual/kinetic_blast(swing_turf) - playsound(src, 'sound/weapons/slashmiss.ogg', 50, TRUE) - -/mob/living/simple_animal/hostile/jungle/mook/proc/LeapAttack() - if(target && !stat && attack_state == MOOK_ATTACK_WARMUP) - attack_state = MOOK_ATTACK_ACTIVE - ADD_TRAIT(src, TRAIT_UNDENSE, LEAPING_TRAIT) - melee_damage_lower = 30 - melee_damage_upper = 30 - update_icons() - new /obj/effect/temp_visual/mook_dust(get_turf(src)) - playsound(src, 'sound/weapons/thudswoosh.ogg', 25, TRUE) - playsound(src, 'sound/voice/mook_leap_yell.ogg', 100, TRUE) - var/target_turf = get_turf(target) - throw_at(target_turf, 7, 1, src, FALSE, callback = CALLBACK(src, PROC_REF(AttackRecovery))) - return - attack_state = MOOK_ATTACK_RECOVERY - ResetNeutral() - -/mob/living/simple_animal/hostile/jungle/mook/proc/AttackRecovery() - if(attack_state == MOOK_ATTACK_ACTIVE && !stat) - attack_state = MOOK_ATTACK_RECOVERY - REMOVE_TRAIT(src, TRAIT_UNDENSE, LEAPING_TRAIT) - face_atom(target) - if(!struck_target_leap) - update_icons() - struck_target_leap = FALSE - if(prob(40)) - attack_state = MOOK_ATTACK_NEUTRAL - if(target) - if(isliving(target)) - var/mob/living/L = target - if(L.incapacitated() && L.stat != DEAD) - addtimer(CALLBACK(src, PROC_REF(WarmupAttack), TRUE), ATTACK_INTERMISSION_TIME) - return - addtimer(CALLBACK(src, PROC_REF(WarmupAttack)), ATTACK_INTERMISSION_TIME) - return - addtimer(CALLBACK(src, PROC_REF(ResetNeutral)), ATTACK_INTERMISSION_TIME) - -/mob/living/simple_animal/hostile/jungle/mook/proc/ResetNeutral() - if(attack_state == MOOK_ATTACK_RECOVERY) - attack_state = MOOK_ATTACK_NEUTRAL - ranged_cooldown = world.time + ranged_cooldown_time - update_icons() - if(target && !stat) - update_icons() - Goto(target, move_to_delay, minimum_distance) - -/mob/living/simple_animal/hostile/jungle/mook/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - . = ..() - if(isliving(hit_atom) && attack_state == MOOK_ATTACK_ACTIVE) - var/mob/living/L = hit_atom - if(CanAttack(L)) - L.attack_animal(src) - struck_target_leap = TRUE - REMOVE_TRAIT(src, TRAIT_UNDENSE, LEAPING_TRAIT) - update_icons() - var/mook_under_us = FALSE - for(var/A in get_turf(src)) - if(struck_target_leap && mook_under_us) - break - if(A == src) - continue - if(isliving(A)) - var/mob/living/ML = A - if(!struck_target_leap && CanAttack(ML))//Check if some joker is attempting to use rest to evade us - struck_target_leap = TRUE - ML.attack_animal(src) - REMOVE_TRAIT(src, TRAIT_UNDENSE, LEAPING_TRAIT) - struck_target_leap = TRUE - update_icons() - continue - if(istype(ML, /mob/living/simple_animal/hostile/jungle/mook) && !mook_under_us)//If we land on the same tile as another mook, spread out so we don't stack our sprite on the same tile - var/mob/living/simple_animal/hostile/jungle/mook/M = ML - if(!M.stat) - mook_under_us = TRUE - var/anydir = pick(GLOB.cardinals) - Move(get_step(src, anydir), anydir) - continue - -/mob/living/simple_animal/hostile/jungle/mook/handle_automated_action() - if(attack_state) - return - return ..() - -/mob/living/simple_animal/hostile/jungle/mook/OpenFire() - if(isliving(target)) - var/mob/living/L = target - if(L.incapacitated()) - return - WarmupAttack() - -/mob/living/simple_animal/hostile/jungle/mook/update_icons() - . = ..() - if(!stat) - switch(attack_state) - if(MOOK_ATTACK_NEUTRAL) - icon_state = "mook" - if(MOOK_ATTACK_WARMUP) - icon_state = "mook_warmup" - if(MOOK_ATTACK_ACTIVE) - if(!density) - icon_state = "mook_leap" - return - if(struck_target_leap) - icon_state = "mook_strike" - return - icon_state = "mook_slash_combo" - if(MOOK_ATTACK_RECOVERY) - icon_state = "mook" - -/obj/effect/temp_visual/mook_dust - name = "dust" - desc = "It's just a dust cloud!" - icon = 'icons/mob/simple/jungle/mook.dmi' - icon_state = "mook_leap_cloud" - layer = BELOW_MOB_LAYER - plane = GAME_PLANE - SET_BASE_PIXEL(-16, -16) - duration = 10 - -#undef MOOK_ATTACK_NEUTRAL -#undef MOOK_ATTACK_WARMUP -#undef MOOK_ATTACK_ACTIVE -#undef MOOK_ATTACK_RECOVERY -#undef ATTACK_INTERMISSION_TIME 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 3484c27375da46..5bb9f314ed1560 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/_megafauna.dm @@ -70,7 +70,10 @@ return ..() /mob/living/simple_animal/hostile/megafauna/death(gibbed, list/force_grant) - if(health > 0) + if(gibbed) // in case they've been force dusted + return ..() + + if(health > 0) // prevents instakills return var/datum/status_effect/crusher_damage/crusher_dmg = has_status_effect(/datum/status_effect/crusher_damage) ///Whether we killed the megafauna with primarily crusher damage or not @@ -100,8 +103,8 @@ /mob/living/simple_animal/hostile/megafauna/gib() if(health > 0) return - else - ..() + + return ..() /mob/living/simple_animal/hostile/megafauna/singularity_act() set_health(0) @@ -110,8 +113,11 @@ /mob/living/simple_animal/hostile/megafauna/dust(just_ash, drop_items, force) if(!force && health > 0) return - else - ..() + + crusher_loot.Cut() + loot.Cut() + + return ..() /mob/living/simple_animal/hostile/megafauna/AttackingTarget() if(recovery_time >= world.time) 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 8a92ca680f77e2..5c63ca4e884005 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm @@ -607,7 +607,7 @@ holder_animal.mind.transfer_to(possessor) possessor.mind.grab_ghost(force = TRUE) holder_animal.investigate_log("has been gibbed by [src].", INVESTIGATE_DEATHS) - holder_animal.gib() + holder_animal.gib(DROP_ALL_REMAINS) return ..() return ..() diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm index 66d487c8697e04..84e2d9c049b8bf 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/drake.dm @@ -272,7 +272,7 @@ if(!isclosedturf(T) && !islava(T)) var/lava_turf = /turf/open/lava/smooth var/reset_turf = T.type - T.ChangeTurf(lava_turf, flags = CHANGETURF_INHERIT_AIR) + T.TerraformTurf(lava_turf, flags = CHANGETURF_INHERIT_AIR) addtimer(CALLBACK(T, TYPE_PROC_REF(/turf, ChangeTurf), reset_turf, null, CHANGETURF_INHERIT_AIR), reset_time, TIMER_OVERRIDE|TIMER_UNIQUE) /obj/effect/temp_visual/drakewall diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm index e9cf04b9c21076..26f3690fef13cd 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/wendigo.dm @@ -267,6 +267,10 @@ Difficulty: Hard /mob/living/simple_animal/hostile/megafauna/wendigo/death(gibbed, list/force_grant) if(health > 0) return + + if(!true_spawn) + return ..() + var/obj/effect/portal/permanent/one_way/exit = new /obj/effect/portal/permanent/one_way(starting) exit.id = "wendigo arena exit" exit.add_atom_colour(COLOR_RED_LIGHT, ADMIN_COLOUR_PRIORITY) diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index 2fec84385b2d2b..d07775b42bd538 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -113,6 +113,7 @@ GLOBAL_LIST_INIT(animatable_blacklist, list(/obj/structure/table, /obj/structure /mob/living/simple_animal/hostile/mimic/copy/Initialize(mapload, obj/copy, mob/living/creator, destroy_original = 0, no_googlies = FALSE) . = ..() + ADD_TRAIT(src, TRAIT_PERMANENTLY_MORTAL, INNATE_TRAIT) // They won't remember their original contents upon ressurection and would just be floating eyes if (no_googlies) overlay_googly_eyes = FALSE CopyObject(copy, creator, destroy_original) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm index 58d9988256f14c..d91f312b454d88 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/elites/goliath_broodmother.dm @@ -211,7 +211,7 @@ mother.children_list -= src visible_message(span_warning("[src] explodes!")) explosion(src, flame_range = 3, adminlog = FALSE) - gib() + gib(DROP_ALL_REMAINS) /obj/effect/goliath_tentacle/broodmother grapple_time = 1 SECONDS diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm deleted file mode 100644 index 25d1ea9da742e1..00000000000000 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/ice_demon.dm +++ /dev/null @@ -1,85 +0,0 @@ -/mob/living/simple_animal/hostile/asteroid/ice_demon - name = "demonic watcher" - desc = "A creature formed entirely out of ice, bluespace energy emanates from inside of it." - icon = 'icons/mob/simple/icemoon/icemoon_monsters.dmi' - icon_state = "ice_demon" - icon_living = "ice_demon" - icon_dead = "ice_demon_dead" - icon_gib = "syndicate_gib" - mob_biotypes = MOB_ORGANIC|MOB_BEAST - mouse_opacity = MOUSE_OPACITY_ICON - speak_emote = list("telepathically cries") - speed = 2 - move_to_delay = 2 - projectiletype = /obj/projectile/temp/ice_demon - projectilesound = 'sound/weapons/pierce.ogg' - ranged = TRUE - ranged_message = "manifests ice" - ranged_cooldown_time = 1.5 SECONDS - minimum_distance = 3 - retreat_distance = 3 - maxHealth = 150 - health = 150 - obj_damage = 40 - melee_damage_lower = 15 - melee_damage_upper = 15 - attack_verb_continuous = "slices" - attack_verb_simple = "slice" - attack_sound = 'sound/weapons/bladeslice.ogg' - attack_vis_effect = ATTACK_EFFECT_SLASH - vision_range = 9 - aggro_vision_range = 9 - move_force = MOVE_FORCE_VERY_STRONG - move_resist = MOVE_FORCE_VERY_STRONG - pull_force = MOVE_FORCE_VERY_STRONG - del_on_death = TRUE - loot = list() - crusher_loot = /obj/item/crusher_trophy/demon_core /// SKYRAT EDIT CHANGE - ORIGINAL : crusher_loot = /obj/item/crusher_trophy/watcher_wing/ice_wing - death_message = "fades as the energies that tied it to this world dissipate." - death_sound = 'sound/magic/demon_dies.ogg' - stat_attack = HARD_CRIT - robust_searching = TRUE - footstep_type = FOOTSTEP_MOB_CLAW - /// Distance the demon will teleport from the target - var/teleport_distance = 3 - -/mob/living/simple_animal/hostile/asteroid/ice_demon/Initialize(mapload) - . = ..() - AddElement(/datum/element/simple_flying) - -/obj/projectile/temp/ice_demon - name = "ice blast" - icon_state = "ice_2" - damage = 5 - damage_type = BURN - armor_flag = ENERGY - speed = 1 - pixel_speed_multiplier = 0.25 - range = 200 - temperature = -75 - -/mob/living/simple_animal/hostile/asteroid/ice_demon/OpenFire() - ranged_cooldown = world.time + ranged_cooldown_time - // Sentient ice demons teleporting has been linked to server crashes - if(client) - return ..() - if(teleport_distance <= 0) - return ..() - var/list/possible_ends = view(teleport_distance, target.loc) - view(teleport_distance - 1, target.loc) - for(var/turf/closed/turf_to_remove in possible_ends) - possible_ends -= turf_to_remove - if(!possible_ends.len) - return ..() - var/turf/end = pick(possible_ends) - do_teleport(src, end, 0, channel=TELEPORT_CHANNEL_BLUESPACE, forced = TRUE) - SLEEP_CHECK_DEATH(8, src) - return ..() - -/mob/living/simple_animal/hostile/asteroid/ice_demon/death(gibbed) - move_force = MOVE_FORCE_DEFAULT - move_resist = MOVE_RESIST_DEFAULT - pull_force = PULL_FORCE_DEFAULT - new /obj/item/stack/ore/bluespace_crystal(loc, 3) - if(prob(5)) - new /obj/item/raw_anomaly_core/bluespace(loc) - return ..() diff --git a/code/modules/mob/living/simple_animal/hostile/smspider.dm b/code/modules/mob/living/simple_animal/hostile/smspider.dm deleted file mode 100644 index 150180a11cff62..00000000000000 --- a/code/modules/mob/living/simple_animal/hostile/smspider.dm +++ /dev/null @@ -1,64 +0,0 @@ -/mob/living/simple_animal/hostile/smspider - name = "supermatter spider" - desc= "A sliver of supermatter placed upon a robotically enhanced pedestal." - icon = 'icons/mob/simple/smspider.dmi' - icon_state = "smspider" - icon_living = "smspider" - icon_dead = "smspider_dead" - gender = NEUTER - mob_biotypes = MOB_BUG|MOB_ROBOTIC - turns_per_move = 2 - speak_emote = list("vibrates") - emote_see = list("vibrates") - emote_taunt = list("vibrates") - taunt_chance = 40 - combat_mode = TRUE - maxHealth = 10 - health = 10 - minbodytemp = 0 - maxbodytemp = 1500 - attack_verb_continuous = "slices" - attack_verb_simple = "slice" - attack_sound = 'sound/effects/supermatter.ogg' - attack_vis_effect = ATTACK_EFFECT_CLAW - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - robust_searching = 1 - faction = list(FACTION_HOSTILE) - // Gold, supermatter tinted - lighting_cutoff_red = 30 - lighting_cutoff_green = 30 - lighting_cutoff_blue = 10 - death_message = "falls to the ground, its shard dulling to a miserable grey!" - footstep_type = FOOTSTEP_MOB_CLAW - var/overcharged = FALSE // if true, spider will not die if it dusts a limb - -/mob/living/simple_animal/hostile/smspider/AttackingTarget() - . = ..() - if(isliving(target)) - playsound(get_turf(src), 'sound/effects/supermatter.ogg', 10, TRUE) - visible_message(span_danger("[src] knocks into [target], turning them to dust in a brilliant flash of light!")) - var/mob/living/victim = target - victim.investigate_log("has been dusted by [src].", INVESTIGATE_DEATHS) - victim.dust() - if(!overcharged) - death() - else if(!isturf(target)) - playsound(get_turf(src), 'sound/effects/supermatter.ogg', 10, TRUE) - visible_message(span_danger("[src] knocks into [target], turning it to dust in a brilliant flash of light!")) - qdel(target) - if(!overcharged) - death() - return FALSE - -/mob/living/simple_animal/hostile/smspider/Initialize(mapload) - . = ..() - AddComponent(/datum/component/swarming) - -/mob/living/simple_animal/hostile/smspider/overcharged - name = "overcharged supermatter spider" - desc = "A sliver of overcharged supermatter placed upon a robotically enhanced pedestal. This one seems especially dangerous." - icon_state = "smspideroc" - icon_living = "smspideroc" - maxHealth = 25 - health = 25 - overcharged = TRUE diff --git a/code/modules/mob/living/simple_animal/revenant.dm b/code/modules/mob/living/simple_animal/revenant.dm deleted file mode 100644 index 6e2ec11afeac8a..00000000000000 --- a/code/modules/mob/living/simple_animal/revenant.dm +++ /dev/null @@ -1,548 +0,0 @@ -//Revenants: based off of wraiths from Goon -//"Ghosts" that are invisible and move like ghosts, cannot take damage while invisible -//Can hear deadchat, but are NOT normal ghosts and do NOT have x-ray vision -//Admin-spawn or random event - -/// Source for a trait we get when we're stunned -#define REVENANT_STUNNED_TRAIT "revenant_got_stunned" - -/mob/living/simple_animal/revenant - name = "revenant" - desc = "A malevolent spirit." - icon = 'icons/mob/simple/mob.dmi' - icon_state = "revenant_idle" - var/icon_idle = "revenant_idle" - var/icon_reveal = "revenant_revealed" - var/icon_stun = "revenant_stun" - var/icon_drain = "revenant_draining" - var/stasis = FALSE - mob_biotypes = MOB_SPIRIT - incorporeal_move = INCORPOREAL_MOVE_JAUNT - invisibility = INVISIBILITY_REVENANT - health = INFINITY //Revenants don't use health, they use essence instead - maxHealth = INFINITY - plane = GHOST_PLANE - sight = SEE_SELF - throwforce = 0 - - // Going for faint purple spoopy ghost - lighting_cutoff_red = 20 - lighting_cutoff_green = 15 - lighting_cutoff_blue = 35 - response_help_continuous = "passes through" - response_help_simple = "pass through" - response_disarm_continuous = "swings through" - response_disarm_simple = "swing through" - response_harm_continuous = "punches through" - response_harm_simple = "punch through" - unsuitable_atmos_damage = 0 - damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) //I don't know how you'd apply those, but revenants no-sell them anyway. - atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) - minbodytemp = 0 - maxbodytemp = INFINITY - harm_intent_damage = 0 - friendly_verb_continuous = "touches" - friendly_verb_simple = "touch" - status_flags = 0 - wander = FALSE - density = FALSE - move_resist = MOVE_FORCE_OVERPOWERING - mob_size = MOB_SIZE_TINY - pass_flags = PASSTABLE | PASSGRILLE | PASSMOB - speed = 1 - unique_name = TRUE - hud_possible = list(ANTAG_HUD) - hud_type = /datum/hud/revenant - - var/essence = 75 //The resource, and health, of revenants. - var/essence_regen_cap = 75 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount. - var/essence_regenerating = TRUE //If the revenant regenerates essence or not - var/essence_regen_amount = 2.5 //How much essence regenerates per second - var/essence_accumulated = 0 //How much essence the revenant has stolen - var/essence_excess = 0 //How much stolen essence avilable for unlocks - var/revealed = FALSE //If the revenant can take damage from normal sources. - var/unreveal_time = 0 //How long the revenant is revealed for, is about 2 seconds times this var. - var/unstun_time = 0 //How long the revenant is stunned for, is about 2 seconds times this var. - var/inhibited = FALSE //If the revenant's abilities are blocked by a chaplain's power. - var/essence_drained = 0 //How much essence the revenant will drain from the corpse it's feasting on. - var/draining = FALSE //If the revenant is draining someone. - var/list/drained_mobs = list() //Cannot harvest the same mob twice - var/perfectsouls = 0 //How many perfect, regen-cap increasing souls the revenant has. //TODO, add objective for getting a perfect soul(s?) - var/generated_objectives_and_spells = FALSE - -/mob/living/simple_animal/revenant/Initialize(mapload) - . = ..() - AddElement(/datum/element/simple_flying) - add_traits(list(TRAIT_SPACEWALK, TRAIT_SIXTHSENSE, TRAIT_FREE_HYPERSPACE_MOVEMENT), INNATE_TRAIT) - - // Starting spells - - var/datum/action/cooldown/spell/list_target/telepathy/revenant/telepathy = new(src) - telepathy.Grant(src) - - // Starting spells that start locked - var/datum/action/cooldown/spell/aoe/revenant/overload/lights_go_zap = new(src) - lights_go_zap.Grant(src) - - var/datum/action/cooldown/spell/aoe/revenant/defile/windows_go_smash = new(src) - windows_go_smash.Grant(src) - - var/datum/action/cooldown/spell/aoe/revenant/blight/botany_go_mad = new(src) - botany_go_mad.Grant(src) - - var/datum/action/cooldown/spell/aoe/revenant/malfunction/shuttle_go_emag = new(src) - shuttle_go_emag.Grant(src) - - var/datum/action/cooldown/spell/aoe/revenant/haunt_object/toolbox_go_bonk = new(src) - toolbox_go_bonk.Grant(src) - - RegisterSignal(src, COMSIG_LIVING_BANED, PROC_REF(on_baned)) - random_revenant_name() - -/mob/living/simple_animal/revenant/can_perform_action(atom/movable/target, action_bitflags) - return FALSE - -/mob/living/simple_animal/revenant/proc/random_revenant_name() - var/built_name = "" - built_name += pick(strings(REVENANT_NAME_FILE, "spirit_type")) - built_name += " of " - built_name += pick(strings(REVENANT_NAME_FILE, "adverb")) - built_name += pick(strings(REVENANT_NAME_FILE, "theme")) - name = built_name - -/mob/living/simple_animal/revenant/Login() - . = ..() - if(!. || !client) - return FALSE - to_chat(src, span_deadsay("You are a revenant.")) - to_chat(src, "Your formerly mundane spirit has been infused with alien energies and empowered into a revenant.") - to_chat(src, "You are not dead, not alive, but somewhere in between. You are capable of limited interaction with both worlds.") - to_chat(src, "You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.") - to_chat(src, "To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities.") - to_chat(src, "You do not remember anything of your past lives, nor will you remember anything about this one after your death.") - to_chat(src, "Be sure to read the wiki page to learn more.") - if(!generated_objectives_and_spells) - generated_objectives_and_spells = TRUE - mind.set_assigned_role(SSjob.GetJobType(/datum/job/revenant)) - mind.special_role = ROLE_REVENANT - SEND_SOUND(src, sound('sound/effects/ghost.ogg')) - mind.add_antag_datum(/datum/antagonist/revenant) - -//Life, Stat, Hud Updates, and Say -/mob/living/simple_animal/revenant/Life(seconds_per_tick = SSMOBS_DT, times_fired) - if(stasis) - return - var/delta_time = DELTA_WORLD_TIME(SSmobs) - if(revealed && essence <= 0) - death() - if(unreveal_time && world.time >= unreveal_time) - unreveal_time = 0 - revealed = FALSE - incorporeal_move = INCORPOREAL_MOVE_JAUNT - invisibility = INVISIBILITY_REVENANT - to_chat(src, span_revenboldnotice("You are once more concealed.")) - if(unstun_time && world.time >= unstun_time) - unstun_time = 0 - REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, REVENANT_STUNNED_TRAIT) - to_chat(src, span_revenboldnotice("You can move again!")) - if(essence_regenerating && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate - essence = min(essence + (essence_regen_amount * delta_time), essence_regen_cap) - update_mob_action_buttons() //because we update something required by our spells in life, we need to update our buttons - update_spooky_icon() - update_health_hud() - ..() - -/mob/living/simple_animal/revenant/get_status_tab_items() - . = ..() - . += "Current Essence: [essence >= essence_regen_cap ? essence : "[essence] / [essence_regen_cap]"]E" - . += "Total Essence Stolen: [essence_accumulated]SE" - . += "Unused Stolen Essence: [essence_excess]SE" - . += "Perfect Souls Stolen: [perfectsouls]" - -/mob/living/simple_animal/revenant/update_health_hud() - if(hud_used) - var/essencecolor = "#8F48C6" - if(essence > essence_regen_cap) - essencecolor = "#9A5ACB" //oh boy you've got a lot of essence - else if(!essence) - essencecolor = "#1D2953" //oh jeez you're dying - hud_used.healths.maptext = MAPTEXT("
[essence]E
") - -/mob/living/simple_animal/revenant/med_hud_set_health() - return //we use no hud - -/mob/living/simple_animal/revenant/med_hud_set_status() - return //we use no hud - -/mob/living/simple_animal/revenant/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null, filterproof = null, message_range = 7, datum/saymode/saymode = null) - if(!message) - return - if(sanitize) - message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) - src.log_talk(message, LOG_SAY) - var/rendered = span_deadsay("UNDEAD: [src] says, \"[message]\"") - for(var/mob/M in GLOB.mob_list) - if(isrevenant(M)) - to_chat(M, rendered) - else if(isobserver(M)) - var/link = FOLLOW_LINK(M, src) - to_chat(M, "[link] [rendered]") - return - - -//Immunities - -/mob/living/simple_animal/revenant/ex_act(severity, target) - return FALSE //Immune to the effects of explosions. - -/mob/living/simple_animal/revenant/blob_act(obj/structure/blob/B) - return //blah blah blobs aren't in tune with the spirit world, or something. - -/mob/living/simple_animal/revenant/singularity_act() - return //don't walk into the singularity expecting to find corpses, okay? - -/mob/living/simple_animal/revenant/narsie_act() - return //most humans will now be either bones or harvesters, but we're still un-alive. - -/mob/living/simple_animal/revenant/bullet_act() - if(!revealed || stasis) - return BULLET_ACT_FORCE_PIERCE - return ..() - -//damage, gibbing, and dying -/mob/living/simple_animal/revenant/proc/on_baned(obj/item/weapon, mob/living/user) - SIGNAL_HANDLER - visible_message(span_warning("[src] violently flinches!"), \ - span_revendanger("As [weapon] passes through you, you feel your essence draining away!")) - inhibited = TRUE - update_mob_action_buttons() - addtimer(CALLBACK(src, PROC_REF(reset_inhibit)), 3 SECONDS) - -/mob/living/simple_animal/revenant/proc/reset_inhibit() - inhibited = FALSE - update_mob_action_buttons() - -/mob/living/simple_animal/revenant/adjustHealth(amount, updating_health = TRUE, forced = FALSE) - if(!forced && !revealed) - return FALSE - . = amount - essence = max(0, essence-amount) - if(updating_health) - update_health_hud() - if(!essence) - death() - -/mob/living/simple_animal/revenant/dust(just_ash, drop_items, force) - death() - -/mob/living/simple_animal/revenant/gib() - death() - -/mob/living/simple_animal/revenant/death() - if(!revealed || stasis) //Revenants cannot die if they aren't revealed //or are already dead - return - stasis = TRUE - to_chat(src, span_revendanger("NO! No... it's too late, you can feel your essence [pick("breaking apart", "drifting away")]...")) - ADD_TRAIT(src, TRAIT_NO_TRANSFORM, REVENANT_STUNNED_TRAIT) - revealed = TRUE - invisibility = 0 - playsound(src, 'sound/effects/screech.ogg', 100, TRUE) - visible_message(span_warning("[src] lets out a waning screech as violet mist swirls around its dissolving body!")) - icon_state = "revenant_draining" - for(var/i = alpha, i > 0, i -= 10) - stoplag() - alpha = i - visible_message(span_danger("[src]'s body breaks apart into a fine pile of blue dust.")) - var/reforming_essence = essence_regen_cap //retain the gained essence capacity - var/obj/item/ectoplasm/revenant/R = new(get_turf(src)) - R.essence = max(reforming_essence - 15 * perfectsouls, 75) //minus any perfect souls - R.old_key = client.key //If the essence reforms, the old revenant is put back in the body - R.revenant = src - invisibility = INVISIBILITY_ABSTRACT - revealed = FALSE - ghostize(0)//Don't re-enter invisible corpse - - -//reveal, stun, icon updates, cast checks, and essence changing -/mob/living/simple_animal/revenant/proc/reveal(time) - if(!src) - return - if(time <= 0) - return - revealed = TRUE - invisibility = 0 - incorporeal_move = FALSE - if(!unreveal_time) - to_chat(src, span_revendanger("You have been revealed!")) - unreveal_time = world.time + time - else - to_chat(src, span_revenwarning("You have been revealed!")) - unreveal_time = unreveal_time + time - update_spooky_icon() - orbiting?.end_orbit(src) - -/mob/living/simple_animal/revenant/proc/stun(time) - if(!src) - return - if(time <= 0) - return - ADD_TRAIT(src, TRAIT_NO_TRANSFORM, REVENANT_STUNNED_TRAIT) - if(!unstun_time) - to_chat(src, span_revendanger("You cannot move!")) - unstun_time = world.time + time - else - to_chat(src, span_revenwarning("You cannot move!")) - unstun_time = unstun_time + time - update_spooky_icon() - orbiting?.end_orbit(src) - -/mob/living/simple_animal/revenant/proc/update_spooky_icon() - if(revealed) - if(HAS_TRAIT(src, TRAIT_NO_TRANSFORM)) - if(draining) - icon_state = icon_drain - else - icon_state = icon_stun - else - icon_state = icon_reveal - else - icon_state = icon_idle - -/mob/living/simple_animal/revenant/proc/castcheck(essence_cost) - if(!src) - return - var/turf/T = get_turf(src) - if(isclosedturf(T)) - to_chat(src, span_revenwarning("You cannot use abilities from inside of a wall.")) - return FALSE - for(var/obj/O in T) - if(O.density && !O.CanPass(src, get_dir(T, src))) - to_chat(src, span_revenwarning("You cannot use abilities inside of a dense object.")) - return FALSE - if(inhibited) - to_chat(src, span_revenwarning("Your powers have been suppressed by nulling energy!")) - return FALSE - if(!change_essence_amount(essence_cost, TRUE)) - to_chat(src, span_revenwarning("You lack the essence to use that ability.")) - return FALSE - return TRUE - -/mob/living/simple_animal/revenant/proc/unlock(essence_cost) - if(essence_excess < essence_cost) - return FALSE - essence_excess -= essence_cost - update_mob_action_buttons() - return TRUE - -/mob/living/simple_animal/revenant/proc/change_essence_amount(essence_amt, silent = FALSE, source = null) - if(!src) - return - if(essence + essence_amt < 0) - return - essence = max(0, essence+essence_amt) - update_health_hud() - if(essence_amt > 0) - essence_accumulated = max(0, essence_accumulated+essence_amt) - essence_excess = max(0, essence_excess+essence_amt) - update_mob_action_buttons() - if(!silent) - if(essence_amt > 0) - to_chat(src, span_revennotice("Gained [essence_amt]E[source ? " from [source]":""].")) - else - to_chat(src, span_revenminor("Lost [essence_amt]E[source ? " from [source]":""].")) - return 1 - -/mob/living/simple_animal/revenant/proc/death_reset() - revealed = FALSE - unreveal_time = 0 - REMOVE_TRAIT(src, TRAIT_NO_TRANSFORM, REVENANT_STUNNED_TRAIT) - unstun_time = 0 - inhibited = FALSE - draining = FALSE - incorporeal_move = INCORPOREAL_MOVE_JAUNT - invisibility = INVISIBILITY_REVENANT - alpha=255 - stasis = FALSE - -/mob/living/simple_animal/revenant/orbit(atom/target) - setDir(SOUTH) // reset dir so the right directional sprites show up - return ..() - -/mob/living/simple_animal/revenant/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) - if(!orbiting) // only needed when orbiting - return ..() - if(incorporeal_move_check(src)) - return ..() - - // back back back it up, the orbitee went somewhere revenant cannot - orbiting?.end_orbit(src) - abstract_move(old_loc) // gross but maybe orbit component will be able to check pre move in the future - -/mob/living/simple_animal/revenant/stop_orbit(datum/component/orbiter/orbits) - // reset the simple_flying animation - animate(src, pixel_y = 2, time = 1 SECONDS, loop = -1, flags = ANIMATION_RELATIVE) - animate(pixel_y = -2, time = 1 SECONDS, flags = ANIMATION_RELATIVE) - return ..() - -/// Incorporeal move check: blocked by holy-watered tiles and salt piles. -/mob/living/simple_animal/revenant/proc/incorporeal_move_check(atom/destination) - var/turf/open/floor/stepTurf = get_turf(destination) - if(stepTurf) - var/obj/effect/decal/cleanable/food/salt/salt = locate() in stepTurf - if(salt) - to_chat(src, span_warning("[salt] bars your passage!")) - reveal(20) - stun(20) - return - if(stepTurf.turf_flags & NOJAUNT) - to_chat(src, span_warning("Some strange aura is blocking the way.")) - return - if(locate(/obj/effect/blessing) in stepTurf) - to_chat(src, span_warning("Holy energies block your path!")) - return - return TRUE - -//reforming -/obj/item/ectoplasm/revenant - name = "glimmering residue" - desc = "A pile of fine blue dust. Small tendrils of violet mist swirl around it." - icon = 'icons/effects/effects.dmi' - icon_state = "revenantEctoplasm" - w_class = WEIGHT_CLASS_SMALL - var/essence = 75 //the maximum essence of the reforming revenant - var/reforming = TRUE - var/inert = FALSE - var/old_key //key of the previous revenant, will have first pick on reform. - var/mob/living/simple_animal/revenant/revenant - -/obj/item/ectoplasm/revenant/Initialize(mapload) - . = ..() - addtimer(CALLBACK(src, PROC_REF(try_reform)), 600) - -/obj/item/ectoplasm/revenant/proc/scatter() - qdel(src) - -/obj/item/ectoplasm/revenant/proc/try_reform() - if(reforming) - reforming = FALSE - reform() - else - inert = TRUE - visible_message(span_warning("[src] settles down and seems lifeless.")) - -/obj/item/ectoplasm/revenant/attack_self(mob/user) - if(!reforming || inert) - return ..() - user.visible_message(span_notice("[user] scatters [src] in all directions."), \ - span_notice("You scatter [src] across the area. The particles slowly fade away.")) - user.dropItemToGround(src) - scatter() - -/obj/item/ectoplasm/revenant/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) - ..() - if(inert) - return - visible_message(span_notice("[src] breaks into particles upon impact, which fade away to nothingness.")) - scatter() - -/obj/item/ectoplasm/revenant/examine(mob/user) - . = ..() - if(inert) - . += span_revennotice("It seems inert.") - else if(reforming) - . += span_revenwarning("It is shifting and distorted. It would be wise to destroy this.") - -/obj/item/ectoplasm/revenant/proc/reform() - if(QDELETED(src) || QDELETED(revenant) || inert) - return - var/key_of_revenant - message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.") - forceMove(drop_location()) //In case it's in a backpack or someone's hand - revenant.forceMove(loc) - if(old_key) - for(var/mob/M in GLOB.dead_mob_list) - if(M.client && M.client.key == old_key) //Only recreates the mob if the mob the client is in is dead - key_of_revenant = old_key - break - if(!key_of_revenant) - message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...") - var/list/candidates = poll_candidates_for_mob("Do you want to be [revenant.name] (reforming)?", ROLE_REVENANT, ROLE_REVENANT, 5 SECONDS, revenant) - if(!LAZYLEN(candidates)) - qdel(revenant) - message_admins("No candidates were found for the new revenant. Oh well!") - inert = TRUE - visible_message(span_revenwarning("[src] settles down and seems lifeless.")) - return - var/mob/dead/observer/C = pick(candidates) - key_of_revenant = C.key - if(!key_of_revenant) - qdel(revenant) - message_admins("No ckey was found for the new revenant. Oh well!") - inert = TRUE - visible_message(span_revenwarning("[src] settles down and seems lifeless.")) - return - - message_admins("[key_of_revenant] has been [old_key == key_of_revenant ? "re":""]made into a revenant by reforming ectoplasm.") - revenant.log_message("was [old_key == key_of_revenant ? "re":""]made as a revenant by reforming ectoplasm.", LOG_GAME) - visible_message(span_revenboldnotice("[src] suddenly rises into the air before fading away.")) - - revenant.essence = essence - revenant.essence_regen_cap = essence - revenant.death_reset() - revenant.key = key_of_revenant - revenant = null - qdel(src) - -/obj/item/ectoplasm/revenant/suicide_act(mob/living/user) - user.visible_message(span_suicide("[user] is inhaling [src]! It looks like [user.p_theyre()] trying to visit the shadow realm!")) - scatter() - return OXYLOSS - -/obj/item/ectoplasm/revenant/Destroy() - if(!QDELETED(revenant)) - qdel(revenant) - return ..() - -//objectives -/datum/objective/revenant - var/targetAmount = 100 - -/datum/objective/revenant/New() - targetAmount = rand(350,600) - explanation_text = "Absorb [targetAmount] points of essence from humans." - ..() - -/datum/objective/revenant/check_completion() - if(!isrevenant(owner.current)) - return FALSE - var/mob/living/simple_animal/revenant/R = owner.current - if(!R || R.stat == DEAD) - return FALSE - var/essence_stolen = R.essence_accumulated - if(essence_stolen < targetAmount) - return FALSE - return TRUE - -/datum/objective/revenant_fluff - -/datum/objective/revenant_fluff/New() - var/list/explanation_texts = list( - "Assist and exacerbate existing threats at critical moments.", \ - "Impersonate or be worshipped as a god.", \ - "Cause as much chaos and anger as you can without being killed.", \ - "Damage and render as much of the station rusted and unusable as possible.", \ - "Disable and cause malfunctions in as many machines as possible.", \ - "Ensure that any holy weapons are rendered unusable.", \ - "Heed and obey the requests of the dead, provided that carrying them out wouldn't be too inconvenient or self-destructive.", \ - "Make the crew as miserable as possible.", \ - "Make the clown as miserable as possible.", \ - "Make the captain as miserable as possible.", \ - "Prevent the use of energy weapons where possible.", - ) - explanation_text = pick(explanation_texts) - ..() - -/datum/objective/revenant_fluff/check_completion() - return TRUE - -#undef REVENANT_STUNNED_TRAIT diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 041c76fac42f34..85c146b29c8278 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -177,6 +177,7 @@ stack_trace("Simple animal being instantiated in nullspace") update_simplemob_varspeed() if(dextrous) + AddElement(/datum/element/dextrous, hud_type = hud_type) AddComponent(/datum/component/personal_crafting) add_traits(list(TRAIT_ADVANCEDTOOLUSER, TRAIT_CAN_STRIP), ROUNDSTART_TRAIT) ADD_TRAIT(src, TRAIT_NOFIRE_SPREAD, ROUNDSTART_TRAIT) @@ -447,21 +448,20 @@ /mob/living/simple_animal/death(gibbed) drop_loot() - if(dextrous) - drop_all_held_items() if(del_on_death) ..() //Prevent infinite loops if the mob Destroy() is overridden in such //a manner as to cause a call to death() again //Pain del_on_death = FALSE qdel(src) - else - health = 0 - icon_state = icon_dead - if(flip_on_death) - transform = transform.Turn(180) - ADD_TRAIT(src, TRAIT_UNDENSE, BASIC_MOB_DEATH_TRAIT) - ..() + return + + health = 0 + icon_state = icon_dead + if(flip_on_death) + transform = transform.Turn(180) + ADD_TRAIT(src, TRAIT_UNDENSE, BASIC_MOB_DEATH_TRAIT) + return ..() /mob/living/simple_animal/proc/CanAttack(atom/the_target) if(!isatom(the_target)) // no @@ -558,49 +558,12 @@ /mob/living/simple_animal/get_idcard(hand_first) return (..() || access_card) -/mob/living/simple_animal/can_hold_items(obj/item/I) - return dextrous && ..() - -/mob/living/simple_animal/activate_hand(selhand) - if(!dextrous) - return ..() - if(!selhand) - selhand = (active_hand_index % held_items.len)+1 - if(istext(selhand)) - selhand = lowertext(selhand) - if(selhand == "right" || selhand == "r") - selhand = 2 - if(selhand == "left" || selhand == "l") - selhand = 1 - if(selhand != active_hand_index) - swap_hand(selhand) - else - mode() - -/mob/living/simple_animal/perform_hand_swap(hand_index) - . = ..() - if(!.) - return - if(!dextrous) - return - if(!hand_index) - hand_index = (active_hand_index % held_items.len)+1 - var/oindex = active_hand_index - active_hand_index = hand_index - if(hud_used) - var/atom/movable/screen/inventory/hand/H - H = hud_used.hand_slots["[hand_index]"] - if(H) - H.update_appearance() - H = hud_used.hand_slots["[oindex]"] - if(H) - H.update_appearance() - /mob/living/simple_animal/put_in_hands(obj/item/I, del_on_fail = FALSE, merge_stacks = TRUE, ignore_animation = TRUE) . = ..() update_held_items() /mob/living/simple_animal/update_held_items() + . = ..() if(!client || !hud_used || hud_used.hud_version == HUD_STYLE_NOHUD) return var/turf/our_turf = get_turf(src) diff --git a/code/modules/mob/living/simple_animal/slime/life.dm b/code/modules/mob/living/simple_animal/slime/life.dm index a103a55b996174..3c34a68d6a26e3 100644 --- a/code/modules/mob/living/simple_animal/slime/life.dm +++ b/code/modules/mob/living/simple_animal/slime/life.dm @@ -199,8 +199,11 @@ var/mob/living/animal_victim = prey var/totaldamage = 0 //total damage done to this unfortunate animal - totaldamage += animal_victim.adjustBruteLoss(rand(2, 4) * 0.5 * seconds_per_tick) - totaldamage += animal_victim.adjustToxLoss(rand(1, 2) * 0.5 * seconds_per_tick) + var/need_mob_update + need_mob_update = totaldamage += animal_victim.adjustBruteLoss(rand(2, 4) * 0.5 * seconds_per_tick, updating_health = FALSE) + need_mob_update += totaldamage += animal_victim.adjustToxLoss(rand(1, 2) * 0.5 * seconds_per_tick, updating_health = FALSE) + if(need_mob_update) + animal_victim.updatehealth() if(totaldamage <= 0) //if we did no(or negative!) damage to it, stop Feedstop(0, 0) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 2fdec7468993af..9002033a13e97b 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -808,18 +808,26 @@ * * This sends you back to the lobby creating a new dead mob * - * Only works if flag/norespawn is allowed in config + * Only works if flag/allow_respawn is allowed in config */ /mob/verb/abandon_mob() set name = "Respawn" set category = "OOC" - if (CONFIG_GET(flag/norespawn)) - if (!check_rights_for(usr.client, R_ADMIN)) - to_chat(usr, span_boldnotice("Respawning is not enabled!")) - return - else if (tgui_alert(usr, "Respawning is currently disabled, do you want to use your permissions to circumvent it?", "Respawn", list("Yes", "No")) != "Yes") - return + switch(CONFIG_GET(flag/allow_respawn)) + if(RESPAWN_FLAG_NEW_CHARACTER) + if(tgui_alert(usr, "Note, respawning is only allowed as another character. If you don't have another free slot you may not be able to respawn.", "Respawn", list("Ok", "Nevermind")) != "Ok") + return + + if(RESPAWN_FLAG_FREE) + pass() // Normal respawn + + if(RESPAWN_FLAG_DISABLED) + if (!check_rights_for(usr.client, R_ADMIN)) + to_chat(usr, span_boldnotice("Respawning is not enabled!")) + return + if (tgui_alert(usr, "Respawning is currently disabled, do you want to use your permissions to circumvent it?", "Respawn", list("Yes", "No")) != "Yes") + return if (stat != DEAD) to_chat(usr, span_boldnotice("You must be dead to use this!")) @@ -856,15 +864,14 @@ M.key = key +/// Checks if the mob can respawn yet according to the respawn delay /mob/proc/check_respawn_delay(override_delay = 0) if(!override_delay && !CONFIG_GET(number/respawn_delay)) return TRUE var/death_time = world.time - client.player_details.time_of_death - var/required_delay = override_delay - if(!required_delay) - required_delay = CONFIG_GET(number/respawn_delay) + var/required_delay = override_delay || CONFIG_GET(number/respawn_delay) if(death_time < required_delay) if(!check_rights_for(usr.client, R_ADMIN)) @@ -977,10 +984,45 @@ /// Performs the actual ritual of swapping hands, such as setting the held index variables /mob/proc/perform_hand_swap(held_index) PROTECTED_PROC(TRUE) + if (!HAS_TRAIT(src, TRAIT_CAN_HOLD_ITEMS)) + return FALSE + + if(!held_index) + held_index = (active_hand_index % held_items.len) + 1 + + if(!isnum(held_index)) + CRASH("You passed [held_index] into swap_hand instead of a number. WTF man") + + var/previous_index = active_hand_index + active_hand_index = held_index + if(hud_used) + var/atom/movable/screen/inventory/hand/held_location + held_location = hud_used.hand_slots["[previous_index]"] + if(!isnull(held_location)) + held_location.update_appearance() + held_location = hud_used.hand_slots["[held_index]"] + if(!isnull(held_location)) + held_location.update_appearance() return TRUE -/mob/proc/activate_hand(selhand) - return +/mob/proc/activate_hand(selected_hand) + if (!HAS_TRAIT(src, TRAIT_CAN_HOLD_ITEMS)) + return + + if(!selected_hand) + selected_hand = (active_hand_index % held_items.len)+1 + + if(istext(selected_hand)) + selected_hand = lowertext(selected_hand) + if(selected_hand == "right" || selected_hand == "r") + selected_hand = 2 + if(selected_hand == "left" || selected_hand == "l") + selected_hand = 1 + + if(selected_hand != active_hand_index) + swap_hand(selected_hand) + else + mode() /mob/proc/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) //For sec bot threat assessment return 0 @@ -1405,8 +1447,11 @@ . = ..() VV_DROPDOWN_OPTION("", "---------") VV_DROPDOWN_OPTION(VV_HK_GIB, "Gib") + VV_DROPDOWN_OPTION(VV_HK_REMOVE_SPELL, "Remove Spell") VV_DROPDOWN_OPTION(VV_HK_GIVE_SPELL, "Give Spell") VV_DROPDOWN_OPTION(VV_HK_REMOVE_SPELL, "Remove Spell") + VV_DROPDOWN_OPTION(VV_HK_GIVE_MOB_ACTION, "Give Mob Ability") + VV_DROPDOWN_OPTION(VV_HK_REMOVE_MOB_ACTION, "Remove Mob Ability") VV_DROPDOWN_OPTION(VV_HK_GIVE_DISEASE, "Give Disease") VV_DROPDOWN_OPTION(VV_HK_GODMODE, "Toggle Godmode") VV_DROPDOWN_OPTION(VV_HK_DROP_ALL, "Drop Everything") @@ -1433,6 +1478,14 @@ if(!check_rights(R_ADMIN)) return usr.client.cmd_admin_godmode(src) + if(href_list[VV_HK_GIVE_MOB_ACTION]) + if(!check_rights(NONE)) + return + usr.client.give_mob_action(src) + if(href_list[VV_HK_REMOVE_MOB_ACTION]) + if(!check_rights(NONE)) + return + usr.client.remove_mob_action(src) if(href_list[VV_HK_GIVE_SPELL]) if(!check_rights(NONE)) return diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 7df256d1873321..8b8a8cff943ad7 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -323,7 +323,7 @@ return FALSE var/brute_damage = brute_heal > burn_heal //changes repair text based on how much brute/burn was supplied if((brute_heal > 0 && affecting.brute_dam > 0) || (burn_heal > 0 && affecting.burn_dam > 0)) - if(affecting.heal_damage(brute_heal, burn_heal, BODYTYPE_ROBOTIC)) + if(affecting.heal_damage(brute_heal, burn_heal, required_bodytype = BODYTYPE_ROBOTIC)) human.update_damage_overlays() user.visible_message(span_notice("[user] fixes some of the [brute_damage ? "dents on" : "burnt wires in"] [human]'s [affecting.name]."), \ span_notice("You fix some of the [brute_damage ? "dents on" : "burnt wires in"] [human == user ? "your" : "[human]'s"] [affecting.name].")) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index e9b0f532da5a3a..a5aa8c2c1453d9 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -132,7 +132,7 @@ //Basically an optional override for our glide size //Sometimes you want to look like you're moving with a delay you don't actually have yet visual_delay = 0 - var/old_dir = dir + var/old_dir = mob.dir . = ..() @@ -253,9 +253,9 @@ if(salt) to_chat(L, span_warning("[salt] bars your passage!")) if(isrevenant(L)) - var/mob/living/simple_animal/revenant/R = L - R.reveal(20) - R.stun(20) + var/mob/living/basic/revenant/ghostie = L + ghostie.apply_status_effect(/datum/status_effect/revenant/revealed, 2 SECONDS) + ghostie.apply_status_effect(/datum/status_effect/incapacitating/paralyzed/revenant, 2 SECONDS) return if(stepTurf.turf_flags & NOJAUNT) to_chat(L, span_warning("Some strange aura is blocking the way.")) diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm index 9bc6a5b22dbc08..fe901b3ad9e2af 100644 --- a/code/modules/mob/mob_transformation_simple.dm +++ b/code/modules/mob/mob_transformation_simple.dm @@ -66,7 +66,7 @@ else desired_mob.key = key - SEND_SIGNAL(src, COMSIG_MOB_CHANGED_TYPE) + SEND_SIGNAL(src, COMSIG_MOB_CHANGED_TYPE, desired_mob) if(delete_old_mob) QDEL_IN(src, 1) return desired_mob diff --git a/code/modules/mob/mob_update_icons.dm b/code/modules/mob/mob_update_icons.dm index 8a6464ee1825ac..b8b84f8782afe1 100644 --- a/code/modules/mob/mob_update_icons.dm +++ b/code/modules/mob/mob_update_icons.dm @@ -26,7 +26,8 @@ ///Updates the held items overlay(s) & HUD element. /mob/proc/update_held_items() - return + SHOULD_CALL_PARENT(TRUE) + SEND_SIGNAL(src, COMSIG_MOB_UPDATE_HELD_ITEMS) ///Updates the mask overlay & HUD element. /mob/proc/update_worn_mask() diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index 1dde25c7802f61..fccd64ab70540d 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -12,6 +12,7 @@ /mob/proc/adjust_bodytemperature(amount,min_temp=0,max_temp=INFINITY) if(bodytemperature >= min_temp && bodytemperature <= max_temp) bodytemperature = clamp(bodytemperature + amount,min_temp,max_temp) + return TRUE /// Sight here is the mob.sight var, which tells byond what to actually show to our client /// See [code\__DEFINES\sight.dm] for more details diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 09ce3b3c65c8ce..290177f5baf506 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -298,7 +298,7 @@ regenerate_icons() icon = null invisibility = INVISIBILITY_MAXIMUM - var/mob/living/simple_animal/hostile/gorilla/new_gorilla = new (get_turf(src)) + var/mob/living/basic/gorilla/new_gorilla = new (get_turf(src)) new_gorilla.set_combat_mode(TRUE) if(mind) mind.transfer_to(new_gorilla) @@ -372,7 +372,7 @@ if(!MP) return FALSE //Sanity, this should never happen. - if(ispath(MP, /mob/living/simple_animal/hostile/construct)) + if(ispath(MP, /mob/living/simple_animal/hostile/construct) || ispath(MP, /mob/living/basic/construct)) return FALSE //Verbs do not appear for players. //Good mobs! diff --git a/code/modules/mob_spawn/corpses/job_corpses.dm b/code/modules/mob_spawn/corpses/job_corpses.dm index c8dd458f42db19..3893f3e1ba6965 100644 --- a/code/modules/mob_spawn/corpses/job_corpses.dm +++ b/code/modules/mob_spawn/corpses/job_corpses.dm @@ -83,4 +83,4 @@ name = JOB_ROBOTICIST outfit = /datum/outfit/job/roboticist icon_state = "corpseroboticist" - + diff --git a/code/modules/mob_spawn/corpses/nonhuman_corpses.dm b/code/modules/mob_spawn/corpses/nonhuman_corpses.dm index 060f7e178be2f6..ce02c6894aee88 100644 --- a/code/modules/mob_spawn/corpses/nonhuman_corpses.dm +++ b/code/modules/mob_spawn/corpses/nonhuman_corpses.dm @@ -46,6 +46,13 @@ pixel_x = -12 base_pixel_x = -12 +/obj/effect/mob_spawn/corpse/watcher + mob_type = /mob/living/basic/mining/watcher + icon = 'icons/mob/simple/lavaland/lavaland_monsters_wide.dmi' + icon_state = "watcher_dead_helper" + pixel_x = -12 + base_pixel_x = -12 + /// Dead headcrab for changeling-themed ruins /obj/effect/mob_spawn/corpse/headcrab mob_type = /mob/living/basic/headslug/beakless diff --git a/code/modules/mob_spawn/ghost_roles/mining_roles.dm b/code/modules/mob_spawn/ghost_roles/mining_roles.dm index de461380b543a9..9a1536a83d8521 100644 --- a/code/modules/mob_spawn/ghost_roles/mining_roles.dm +++ b/code/modules/mob_spawn/ghost_roles/mining_roles.dm @@ -207,7 +207,7 @@ yolk.underwear = "Nude" yolk.equipOutfit(/datum/outfit/ashwalker)//this is an authentic mess we're making yolk.update_body() - yolk.gib() + yolk.gib(DROP_ALL_REMAINS) QDEL_NULL(egg) return ..() @@ -236,7 +236,7 @@ return ..() /obj/effect/mob_spawn/ghost_role/human/ash_walker/allow_spawn(mob/user, silent = FALSE) - if(!(user.key in team.players_spawned))//one per person unless you get a bonus spawn + if(!(user.ckey in team.players_spawned))//one per person unless you get a bonus spawn return TRUE if(!silent) to_chat(user, span_warning("You have exhausted your usefulness to the Necropolis.")) @@ -254,7 +254,7 @@ spawned_human.mind.add_antag_datum(/datum/antagonist/ashwalker, team) spawned_human.remove_language(/datum/language/common) - team.players_spawned += (spawned_human.key) + team.players_spawned += (spawned_human.ckey) eggshell.egg = null QDEL_NULL(eggshell) @@ -316,7 +316,7 @@ ears = /obj/item/radio/headset/syndicate/alt shoes = /obj/item/clothing/shoes/combat r_pocket = /obj/item/gun/ballistic/automatic/pistol - r_hand = /obj/item/gun/ballistic/rifle/sniper_rifle + r_hand = /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano/evil // SKYRAT EDIT - Original: /obj/item/gun/ballistic/rifle/sniper_rifle implants = list(/obj/item/implant/weapons_auth) id_trim = /datum/id_trim/syndicom/skyrat/interdyne //SKYRAT EDIT diff --git a/code/modules/mob_spawn/ghost_roles/spider_roles.dm b/code/modules/mob_spawn/ghost_roles/spider_roles.dm index e3dbea6b1ba7b7..fb3d470f5aa800 100644 --- a/code/modules/mob_spawn/ghost_roles/spider_roles.dm +++ b/code/modules/mob_spawn/ghost_roles/spider_roles.dm @@ -41,8 +41,9 @@ color = rgb(148, 0, 211) /obj/structure/spider/eggcluster/bloody + icon = 'icons/mob/simple/meteor_heart.dmi' + icon_state = "eggs" name = "bloody egg cluster" - color = rgb(255, 0, 0) /obj/structure/spider/eggcluster/midwife name = "midwife egg cluster" @@ -72,6 +73,8 @@ var/cluster_type = /obj/structure/spider/eggcluster /// Physical structure housing the spawner var/obj/structure/spider/eggcluster/egg + /// Which antag datum do we grant? + var/granted_datum = /datum/antagonist/spider /// The types of spiders that the spawner can produce var/list/potentialspawns = list( /mob/living/basic/spider/growing/spiderling/nurse, @@ -124,10 +127,11 @@ /obj/effect/mob_spawn/ghost_role/spider/special(mob/living/basic/spider/spawned_mob, mob/mob_possessor) . = ..() - spawned_mob.directive = directive + if (isspider(spawned_mob)) + spawned_mob.directive = directive egg.spawner = null QDEL_NULL(egg) - var/datum/antagonist/spider/spider_antag = new(directive) + var/datum/antagonist/spider/spider_antag = new granted_datum(directive) spawned_mob.mind.add_antag_datum(spider_antag) /obj/effect/mob_spawn/ghost_role/spider/enriched @@ -144,15 +148,18 @@ /obj/effect/mob_spawn/ghost_role/spider/bloody name = "bloody egg cluster" - color = rgb(255, 0, 0) - you_are_text = "You are a bloody spider." + icon = 'icons/mob/simple/meteor_heart.dmi' + icon_state = "eggs" + you_are_text = "You are a flesh spider." flavour_text = "An abomination of nature set upon the station by changelings. Your only goal is to kill, terrorize, and survive." - directive = "You are the spawn of a vicious changeling. You have no ambitions except to wreak havoc and ensure your own survival. You are aggressive to all living beings outside of your species, including changelings." + faction = list() + directive = null cluster_type = /obj/structure/spider/eggcluster/bloody potentialspawns = list( - /mob/living/basic/spider/giant/hunter/flesh, + /mob/living/basic/flesh_spider, ) flash_window = TRUE + granted_datum = /datum/antagonist/spider/flesh /obj/effect/mob_spawn/ghost_role/spider/midwife name = "midwife egg cluster" @@ -175,6 +182,14 @@ * * newname - If set, renames the mob to this name */ /obj/effect/mob_spawn/ghost_role/spider/create(mob/user, newname) + var/chosen_spider = length(potentialspawns) > 1 ? get_radial_choice(user) : potentialspawns[1] + if(QDELETED(src) || QDELETED(user) || isnull(chosen_spider)) + return FALSE + mob_type = chosen_spider + return ..() + +/// Pick a spider type from a radial menu +/obj/effect/mob_spawn/ghost_role/spider/proc/get_radial_choice(mob/user) var/list/spider_list = list() var/list/display_spiders = list() for(var/choice in potentialspawns) @@ -196,9 +211,6 @@ display_spiders[initial(spider.name)] = option sort_list(display_spiders) + var/chosen_spider = show_radial_menu(user, egg, display_spiders, radius = 38) - chosen_spider = spider_list[chosen_spider] - if(QDELETED(src) || QDELETED(user) || !chosen_spider) - return FALSE - mob_type = chosen_spider - return ..() + return spider_list[chosen_spider] diff --git a/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm b/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm index 96a75842b1b61d..8ab475dce015d9 100644 --- a/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm +++ b/code/modules/mob_spawn/ghost_roles/venus_human_trap.dm @@ -4,7 +4,7 @@ desc = "A large pulsating plant..." icon = 'icons/mob/spacevines.dmi' icon_state = "bud0" - mob_type = /mob/living/simple_animal/hostile/venus_human_trap + mob_type = /mob/living/basic/venus_human_trap density = FALSE prompt_name = "venus human trap" you_are_text = "You are a venus human trap." @@ -23,7 +23,7 @@ flower_bud = null return ..() -/obj/effect/mob_spawn/ghost_role/venus_human_trap/equip(mob/living/simple_animal/hostile/venus_human_trap/spawned_human_trap) +/obj/effect/mob_spawn/ghost_role/venus_human_trap/equip(mob/living/basic/venus_human_trap/spawned_human_trap) if(spawned_human_trap && flower_bud) if(flower_bud.trait_flags & SPACEVINE_HEAT_RESISTANT) spawned_human_trap.unsuitable_heat_damage = 0 diff --git a/code/modules/mob_spawn/mob_spawn.dm b/code/modules/mob_spawn/mob_spawn.dm index a853d48c0eca88..02b3ea1866f87d 100644 --- a/code/modules/mob_spawn/mob_spawn.dm +++ b/code/modules/mob_spawn/mob_spawn.dm @@ -32,6 +32,8 @@ var/facial_haircolor ///sets a human's skin tone var/skin_tone + /// Weakref to the mob this spawner created - just if you needed to do something with it. + var/datum/weakref/spawned_mob_ref /obj/effect/mob_spawn/Initialize(mapload) . = ..() @@ -44,6 +46,7 @@ name_mob(spawned_mob, newname) special(spawned_mob, mob_possessor) equip(spawned_mob) + spawned_mob_ref = WEAKREF(spawned_mob) return spawned_mob /obj/effect/mob_spawn/proc/special(mob/living/spawned_mob) @@ -250,6 +253,7 @@ if(isnull(created)) // If we explicitly return FALSE instead of just not returning a mob, we don't want to spam the admins CRASH("An instance of [type] didn't return anything when creating a mob, this might be broken!") + SEND_SIGNAL(src, COMSIG_GHOSTROLE_SPAWNED, created) check_uses() // Now we check if the spawner should delete itself or not return created @@ -304,6 +308,11 @@ ///burn damage this corpse will spawn with var/burn_damage = 0 + ///what environmental storytelling script should this corpse have + var/corpse_description = "" + ///optionally different text to display if the target is a clown + var/naive_corpse_description = "" + /obj/effect/mob_spawn/corpse/Initialize(mapload, no_spawn) . = ..() if(no_spawn) @@ -321,6 +330,8 @@ spawned_mob.adjustOxyLoss(oxy_damage) spawned_mob.adjustBruteLoss(brute_damage) spawned_mob.adjustFireLoss(burn_damage) + if (corpse_description) + spawned_mob.AddComponent(/datum/component/temporary_description, corpse_description, naive_corpse_description) /obj/effect/mob_spawn/corpse/create(mob/mob_possessor, newname) . = ..() diff --git a/code/modules/mod/mod_link.dm b/code/modules/mod/mod_link.dm index 8a3340fad3e153..12ce7fa48271e9 100644 --- a/code/modules/mod/mod_link.dm +++ b/code/modules/mod/mod_link.dm @@ -173,6 +173,10 @@ /obj/item/clothing/neck/link_scryer/examine(mob/user) . = ..() + // SKYRAT EDIT NIFSOFT SCRYERS - START + if(custom_examine_controls) + return + // SKYRAT EDIT NIFSOFT SCRYERS - END if(cell) . += span_notice("The battery charge reads [cell.percent()]%. Right-click with an empty hand to remove it.") else diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index f11c6b9b4b904b..f8daa9bab544f3 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -260,6 +260,12 @@ /obj/item/mod/module/jump_jet, ) +/obj/item/mod/control/pre_equipped/nuclear/no_jetpack + +/obj/item/mod/control/pre_equipped/nuclear/no_jetpack/Initialize(mapload, new_theme, new_skin, new_core) + applied_modules -= list(/obj/item/mod/module/jetpack/advanced, /obj/item/mod/module/jump_jet) + return ..() + /obj/item/mod/control/pre_equipped/nuclear/plasmaman /obj/item/mod/control/pre_equipped/nuclear/plasmaman/Initialize(mapload, new_theme, new_skin, new_core) diff --git a/code/modules/mod/modules/modules_ninja.dm b/code/modules/mod/modules/modules_ninja.dm index 90c731a7c367d3..7a38238594df36 100644 --- a/code/modules/mod/modules/modules_ninja.dm +++ b/code/modules/mod/modules/modules_ninja.dm @@ -275,7 +275,7 @@ var/mob/living/living_user = user to_chat(living_user, span_danger("fATaL EERRoR: 382200-*#00CODE RED\nUNAUTHORIZED USE DETECteD\nCoMMENCING SUB-R0UTIN3 13...\nTERMInATING U-U-USER...")) living_user.investigate_log("has been gibbed by using a MODsuit equipped with [src].", INVESTIGATE_DEATHS) - living_user.gib() + living_user.gib(DROP_ALL_REMAINS) /obj/item/mod/module/dna_lock/reinforced/on_emp(datum/source, severity) return diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm index 2c7ae6821fe8da..7e331433b4f275 100644 --- a/code/modules/mod/modules/modules_security.dm +++ b/code/modules/mod/modules/modules_security.dm @@ -361,13 +361,95 @@ /obj/item/mod/module/active_sonar name = "MOD active sonar" desc = "Ancient tech from the 20th century, this module uses sonic waves to detect living creatures within the user's radius. \ + Its basic function slowly scans around the user for any bio-signatures, however it can be overclocked to scan everywhere at once.\ Its loud ping is much harder to hide in an indoor station than in the outdoor operations it was designed for." icon_state = "active_sonar" module_type = MODULE_USABLE - use_power_cost = DEFAULT_CHARGE_DRAIN * 4 + idle_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 + use_power_cost = DEFAULT_CHARGE_DRAIN * 3 complexity = 2 incompatible_modules = list(/obj/item/mod/module/active_sonar) cooldown_time = 15 SECONDS + /// Time between us displaying radial scans + var/scan_cooldown_time = 0.5 SECONDS + /// The current slice we're going to scan + var/scanned_slice = 1 + /// How many slices we make 360 + var/radar_slices = 8 // 45 degrees each + + /// A list of all creatures in range sorted by angle. + var/list/sorted_creatures = list() + /// A keyed list of all creatures + var/list/keyed_creatures = list() + + /// Time between us displaying radial scans + COOLDOWN_DECLARE(scan_cooldown) + +/obj/item/mod/module/active_sonar/Initialize(mapload) + . = ..() + for(var/i in 1 to radar_slices) + sorted_creatures += list(list()) + +/obj/item/mod/module/active_sonar/on_suit_activation() + RegisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED, PROC_REF(sort_all_creatures)) + +/obj/item/mod/module/active_sonar/on_suit_deactivation(deleting = FALSE) + UnregisterSignal(mod.wearer, COMSIG_MOVABLE_MOVED) + +/// Detects all living creatures within world.view, and returns the amount. +/obj/item/mod/module/active_sonar/proc/detect_living_creatures() + var/creatures_detected = 0 + for(var/mob/living/creature in range(world.view, mod.wearer)) + if(creature == mod.wearer || creature.stat == DEAD) + continue + if(keyed_creatures[creature]) + creatures_detected++ + continue + sort_creature_angle(creature) + RegisterSignal(creature, COMSIG_MOVABLE_MOVED, PROC_REF(sort_creature_angle)) + creatures_detected++ + return creatures_detected + +/// Swaps around where a creature is, when they move or when they're first detected +/obj/item/mod/module/active_sonar/proc/sort_creature_angle(mob/living/creature, atom/old_loc, movement_dir, forced) + SIGNAL_HANDLER + var/oldgroup = keyed_creatures[creature] + var/newgroup = round(get_angle(mod.wearer, creature) / (360 / radar_slices)) + 1 + if(oldgroup) + if(creature.stat == DEAD || get_dist(get_turf(mod.wearer), get_turf(creature)) > world.view) + sorted_creatures[oldgroup] -= creature + keyed_creatures -= creature + UnregisterSignal(creature, COMSIG_MOVABLE_MOVED) + return + + if(oldgroup != newgroup) + sorted_creatures[oldgroup] -= creature + + sorted_creatures[newgroup] += creature + keyed_creatures[creature] = newgroup + +/// Swaps all creatures when mod.wearer moves +/obj/item/mod/module/active_sonar/proc/sort_all_creatures(mob/living/wearer, atom/old_loc, movement_dir, forced) + SIGNAL_HANDLER + + for(var/mob/living/creature as anything in keyed_creatures) + sort_creature_angle(creature) // Kinda spaghetti but it honestly seems like the shortest path to the same result + +/obj/item/mod/module/active_sonar/on_process(seconds_per_tick) + . = ..() + if(!.) + return + if(!COOLDOWN_FINISHED(src, cooldown_timer) || !COOLDOWN_FINISHED(src, scan_cooldown)) + return + detect_living_creatures() + for(var/mob/living/creature as anything in sorted_creatures[scanned_slice]) + new /obj/effect/temp_visual/sonar_ping(mod.wearer.loc, mod.wearer, creature, "sonar_ping_small", FALSE) + // Next slice! + scanned_slice++ + // IT'S ENOUGH SLICES + if(scanned_slice > radar_slices) + scanned_slice = 1 + COOLDOWN_START(src, scan_cooldown, scan_cooldown_time) /obj/item/mod/module/active_sonar/on_use() . = ..() @@ -377,14 +459,10 @@ playsound(mod.wearer, 'sound/mecha/skyfall_power_up.ogg', vol = 20, vary = TRUE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) if(!do_after(mod.wearer, 1.1 SECONDS, target = mod)) return - var/creatures_detected = 0 - for(var/mob/living/creature in range(9, mod.wearer)) - if(creature == mod.wearer || creature.stat == DEAD) - continue + playsound(mod.wearer, 'sound/effects/ping_hit.ogg', vol = 75, vary = TRUE) // Should be audible for the radius of the sonar + to_chat(mod.wearer, span_notice("You slam your fist into the ground, sending out a sonic wave that detects [detect_living_creatures()] living beings nearby!")) + for(var/mob/living/creature as anything in keyed_creatures) new /obj/effect/temp_visual/sonar_ping(mod.wearer.loc, mod.wearer, creature) - creatures_detected++ - playsound(mod.wearer, 'sound/effects/ping_hit.ogg', vol = 75, vary = TRUE, extrarange = MEDIUM_RANGE_SOUND_EXTRARANGE) // Should be audible for the radius of the sonar - to_chat(mod.wearer, span_notice("You slam your fist into the ground, sending out a sonic wave that detects [creatures_detected] living beings nearby!")) #define SHOOTING_ASSISTANT_OFF "Currently Off" #define STORMTROOPER_MODE "Quick Fire Stormtrooper" diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 6fe91c9575b669..0de25b903abeee 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -42,7 +42,7 @@ ///The program currently active on the tablet. var/datum/computer_file/program/active_program ///Idle programs on background. They still receive process calls but can't be interacted with. - var/list/idle_threads = list() + var/list/datum/computer_file/program/idle_threads = list() /// Amount of programs that can be ran at once var/max_idle_programs = 2 @@ -72,12 +72,10 @@ /// The built-in light's color, editable by players. var/comp_light_color = "#FFFFFF" - ///The last recorded amount of power used. - var/last_power_usage = 0 ///Power usage when the computer is open (screen is active) and can be interacted with. - var/base_active_power_usage = 75 - ///Power usage when the computer is idle and screen is off (currently only applies to laptops) - var/base_idle_power_usage = 5 + var/base_active_power_usage = 15 // SKYRAT EDIT CHANGE - Original: 125 + ///Power usage when the computer is idle and screen is off. + var/base_idle_power_usage = 2 // SKYRAT EDIT CHANGE - Original: 5 // Modular computers can run on various devices. Each DEVICE (Laptop, Console & Tablet) // must have it's own DMI file. Icon states must be called exactly the same in all files, but may look differently @@ -369,6 +367,9 @@ /obj/item/modular_computer/add_context(atom/source, list/context, obj/item/held_item, mob/living/user) . = ..() + if(held_item?.tool_behaviour == TOOL_SCREWDRIVER && internal_cell) + context[SCREENTIP_CONTEXT_RMB] = "Remove Cell" + . = CONTEXTUAL_SCREENTIP_SET if(held_item?.tool_behaviour == TOOL_WRENCH) context[SCREENTIP_CONTEXT_RMB] = "Deconstruct" . = CONTEXTUAL_SCREENTIP_SET @@ -440,7 +441,7 @@ to_chat(user, span_warning("You press the power button, but the computer fails to boot up, displaying variety of errors before shutting down again.")) return FALSE - if(use_power()) // use_power() checks if the PC is powered + if(use_power()) // checks if the PC is powered if(issynth) to_chat(user, span_notice("You send an activation signal to \the [src], turning it on.")) else @@ -462,7 +463,6 @@ // Process currently calls handle_power(), may be expanded in future if more things are added. /obj/item/modular_computer/process(seconds_per_tick) if(!enabled) // The computer is turned off - last_power_usage = 0 return if(atom_integrity <= integrity_failure * max_integrity) @@ -736,7 +736,7 @@ return if(istype(attacking_item, /obj/item/stock_parts/cell)) - if(ismachinery(loc)) + if(ismachinery(physical)) return if(internal_cell) to_chat(user, span_warning("You try to connect \the [attacking_item] to \the [src], but its connectors are occupied.")) @@ -800,6 +800,16 @@ return ..() +/obj/item/modular_computer/screwdriver_act_secondary(mob/living/user, obj/item/tool) + . = ..() + if(internal_cell) + user.balloon_alert(user, "cell removed") + internal_cell.forceMove(drop_location()) + internal_cell = null + return TOOL_ACT_TOOLTYPE_SUCCESS + else + user.balloon_alert(user, "no cell!") + /obj/item/modular_computer/wrench_act_secondary(mob/living/user, obj/item/tool) . = ..() tool.play_tool_sound(src, user, 20, volume=20) diff --git a/code/modules/modular_computers/computers/item/computer_power.dm b/code/modules/modular_computers/computers/item/computer_power.dm index 6b6230ed0d4ce8..24950621de6e28 100644 --- a/code/modules/modular_computers/computers/item/computer_power.dm +++ b/code/modules/modular_computers/computers/item/computer_power.dm @@ -1,9 +1,13 @@ +///The multiplier given to the base overtime charge drain value if its flashlight is on. +#define FLASHLIGHT_DRAIN_MULTIPLIER 1.1 + // Tries to draw power from charger or, if no operational charger is present, from power cell. /obj/item/modular_computer/proc/use_power(amount = 0) if(check_power_override()) return TRUE - if(ismachinery(loc)) - var/obj/machinery/machine_holder = loc + + if(ismachinery(physical)) + var/obj/machinery/machine_holder = physical if(machine_holder.powered()) machine_holder.use_power(amount) return TRUE @@ -27,20 +31,31 @@ return if(active_program) active_program.event_powerfailure() + if(light_on) + set_light_on(FALSE) for(var/datum/computer_file/program/programs as anything in idle_threads) programs.event_powerfailure() shutdown_computer(loud = FALSE) -// Handles power-related things, such as battery interaction, recharging, shutdown when it's discharged +///Takes the charge necessary from the Computer, shutting it off if it's unable to provide it. +///Charge depends on whether the PC is on, and what programs are running/idle on it. /obj/item/modular_computer/proc/handle_power(seconds_per_tick) var/power_usage = screen_on ? base_active_power_usage : base_idle_power_usage - if(use_power(power_usage)) - last_power_usage = power_usage + if(light_on) + power_usage *= FLASHLIGHT_DRAIN_MULTIPLIER + if(active_program) + power_usage += active_program.power_cell_use + for(var/datum/computer_file/program/open_programs as anything in idle_threads) + if(!open_programs.power_cell_use) + continue + if(open_programs in idle_threads) + power_usage += (open_programs.power_cell_use / 2) + + if(use_power(power_usage * seconds_per_tick)) return TRUE - else - power_failure() - return FALSE + power_failure() + return FALSE ///Used by subtypes for special cases for power usage, returns TRUE if it should stop the use_power chain. /obj/item/modular_computer/proc/check_power_override() @@ -49,3 +64,5 @@ //Integrated (Silicon) tablets don't drain power, because the tablet is required to state laws, so it being disabled WILL cause problems. /obj/item/modular_computer/pda/silicon/check_power_override() return TRUE + +#undef FLASHLIGHT_DRAIN_MULTIPLIER diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm index d5dcf98c623021..1b87a014f185b0 100644 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ b/code/modules/modular_computers/computers/item/computer_ui.dm @@ -44,7 +44,7 @@ // Operates TGUI /obj/item/modular_computer/ui_interact(mob/user, datum/tgui/ui) - if(!enabled || !user.can_read(src, READING_CHECK_LITERACY) || !use_power()) + if(!enabled || !user.can_read(src, READING_CHECK_LITERACY)) if(ui) ui.close() return diff --git a/code/modules/modular_computers/computers/item/role_tablet_presets.dm b/code/modules/modular_computers/computers/item/role_tablet_presets.dm index b96f61d44b4b91..e2f1b354eda283 100644 --- a/code/modules/modular_computers/computers/item/role_tablet_presets.dm +++ b/code/modules/modular_computers/computers/item/role_tablet_presets.dm @@ -270,6 +270,14 @@ /datum/computer_file/program/skill_tracker, ) +/obj/item/modular_computer/pda/bitrunner + name = "bit runner PDA" + greyscale_colors = "#D6B328#6BC906" + starting_programs = list( + /datum/computer_file/program/arcade, + /datum/computer_file/program/skill_tracker, + ) + /** * Service */ diff --git a/code/modules/modular_computers/computers/machinery/modular_computer.dm b/code/modules/modular_computers/computers/machinery/modular_computer.dm index 293cdd9c5f71a5..c54d3295fe389b 100644 --- a/code/modules/modular_computers/computers/machinery/modular_computer.dm +++ b/code/modules/modular_computers/computers/machinery/modular_computer.dm @@ -13,8 +13,6 @@ var/internal_cell = null ///A flag that describes this device type var/hardware_flag = PROGRAM_CONSOLE - ///Power usage during last tick - var/last_power_usage = 0 /// Amount of programs that can be ran at once var/max_idle_programs = 4 @@ -72,7 +70,7 @@ set_light(cpu?.enabled ? light_strength : 0) /obj/machinery/modular_computer/update_icon_state() - if(!cpu || !cpu.enabled || !cpu.use_power() || (machine_stat & NOPOWER)) + if(!cpu || !cpu.enabled || (machine_stat & NOPOWER)) icon_state = icon_state_unpowered else icon_state = icon_state_powered @@ -83,7 +81,7 @@ if(!cpu) return . - if(cpu.enabled && cpu.use_power()) + if(cpu.enabled) . += cpu.active_program?.program_icon_state || screen_icon_state_menu else if(!(machine_stat & NOPOWER)) . += screen_icon_screensaver diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 1f36713380dff2..6f693b5bf998b2 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -1,8 +1,14 @@ +///The default amount a program should take in cell use. +#define PROGRAM_BASIC_CELL_USE 15 + // /program/ files are executable programs that do things. /datum/computer_file/program filetype = "PRG" /// File name. FILE NAME MUST BE UNIQUE IF YOU WANT THE PROGRAM TO BE DOWNLOADABLE FROM NTNET! filename = "UnknownProgram" + + ///How much power running this program costs. + var/power_cell_use = PROGRAM_BASIC_CELL_USE /// List of required accesses to *run* the program. Any match will do. var/list/required_access = list() /// List of required access to download or file host the program. Any match will do. @@ -211,3 +217,5 @@ computer.update_tablet_open_uis(usr) computer.update_appearance(UPDATE_ICON) return TRUE + +#undef PROGRAM_BASIC_CELL_USE diff --git a/code/modules/modular_computers/file_system/programs/budgetordering.dm b/code/modules/modular_computers/file_system/programs/budgetordering.dm index c261f3a3d4357d..d2133697194335 100644 --- a/code/modules/modular_computers/file_system/programs/budgetordering.dm +++ b/code/modules/modular_computers/file_system/programs/budgetordering.dm @@ -118,9 +118,11 @@ if(SSshuttle.supply_blocked) message = blockade_warning data["message"] = message + var/list/amount_by_name = list() var/cart_list = list() for(var/datum/supply_order/order in SSshuttle.shopping_list) if(cart_list[order.pack.name]) + amount_by_name[order.pack.name] += 1 cart_list[order.pack.name][1]["amount"]++ cart_list[order.pack.name][1]["cost"] += order.get_final_cost() if(order.department_destination) @@ -145,15 +147,23 @@ data["cart"] += cart_list[item_id] data["requests"] = list() - for(var/datum/supply_order/SO in SSshuttle.request_list) + for(var/datum/supply_order/order in SSshuttle.request_list) + var/datum/supply_pack/pack = order.pack + amount_by_name[pack.name] += 1 data["requests"] += list(list( - "object" = SO.pack.name, - "cost" = SO.pack.get_cost(), - "orderer" = SO.orderer, - "reason" = SO.reason, - "id" = SO.id + "object" = pack.name, + "cost" = pack.get_cost(), + "orderer" = order.orderer, + "reason" = order.reason, + "id" = order.id )) + data["amount_by_name"] = amount_by_name + + return data +/datum/computer_file/program/budgetorders/ui_static_data(mob/user) + var/list/data = list() + data["max_order"] = CARGO_MAX_ORDER return data /datum/computer_file/program/budgetorders/ui_act(action, params, datum/tgui/ui) @@ -233,15 +243,20 @@ return if(pack.goody && !self_paid) - playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + playsound(computer, 'sound/machines/buzz-sigh.ogg', 50, FALSE) computer.say("ERROR: Small crates may only be purchased by private accounts.") return + if(SSshuttle.supply.get_order_count(pack) == OVER_ORDER_LIMIT) + playsound(computer, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + computer.say("ERROR: No more then [CARGO_MAX_ORDER] of any pack may be ordered at once") + return + if(!requestonly && !self_paid && ishuman(usr) && !account) var/obj/item/card/id/id_card = computer.computer_id_slot?.GetID() account = SSeconomy.get_dep_account(id_card?.registered_account?.account_job.paycheck_department) - var/turf/T = get_turf(src) + var/turf/T = get_turf(computer) var/datum/supply_order/SO = new(pack, name, rank, ckey, reason, account) SO.generateRequisition(T) if((requestonly && !self_paid) || !(computer.computer_id_slot?.GetID())) diff --git a/code/modules/modular_computers/file_system/programs/crewmanifest.dm b/code/modules/modular_computers/file_system/programs/crewmanifest.dm index 3215f62eef84cd..cdd05d6b4c64f0 100644 --- a/code/modules/modular_computers/file_system/programs/crewmanifest.dm +++ b/code/modules/modular_computers/file_system/programs/crewmanifest.dm @@ -4,7 +4,7 @@ category = PROGRAM_CATEGORY_CREW program_icon_state = "id" extended_desc = "Program for viewing and printing the current crew manifest" - transfer_access = list(ACCESS_COMMAND) + transfer_access = list(ACCESS_SECURITY, ACCESS_COMMAND) requires_ntnet = TRUE size = 4 tgui_id = "NtosCrewManifest" diff --git a/code/modules/modular_computers/file_system/programs/frontier.dm b/code/modules/modular_computers/file_system/programs/frontier.dm index cf6cc4b2bc273c..b724892da7e1c4 100644 --- a/code/modules/modular_computers/file_system/programs/frontier.dm +++ b/code/modules/modular_computers/file_system/programs/frontier.dm @@ -25,7 +25,7 @@ /datum/computer_file/program/scipaper_program/on_start(mob/living/user) . = ..() if(!CONFIG_GET(flag/no_default_techweb_link) && !linked_techweb) - CONNECT_TO_RND_SERVER_ROUNDSTART(linked_techweb, src) + CONNECT_TO_RND_SERVER_ROUNDSTART(linked_techweb, computer) /datum/computer_file/program/scipaper_program/application_attackby(obj/item/attacking_item, mob/living/user) if(!istype(attacking_item, /obj/item/multitool)) diff --git a/code/modules/modular_computers/file_system/programs/secureye.dm b/code/modules/modular_computers/file_system/programs/secureye.dm index bba55b4474efb5..6e3e69cdccfc51 100644 --- a/code/modules/modular_computers/file_system/programs/secureye.dm +++ b/code/modules/modular_computers/file_system/programs/secureye.dm @@ -100,18 +100,19 @@ /datum/computer_file/program/secureye/ui_data() var/list/data = list() - data["network"] = network data["activeCamera"] = null var/obj/machinery/camera/active_camera = camera_ref?.resolve() if(active_camera) data["activeCamera"] = list( name = active_camera.c_tag, + ref = REF(active_camera), status = active_camera.status, ) return data /datum/computer_file/program/secureye/ui_static_data(mob/user) var/list/data = list() + data["network"] = network data["mapRef"] = cam_screen.assigned_map data["can_spy"] = !!spying var/list/cameras = get_camera_list(network) @@ -120,6 +121,7 @@ var/obj/machinery/camera/C = cameras[i] data["cameras"] += list(list( name = C.c_tag, + ref = REF(C), )) return data @@ -130,13 +132,14 @@ return switch(action) if("switch_camera") - var/c_tag = format_text(params["name"]) - var/list/cameras = get_camera_list(network) - var/obj/machinery/camera/selected_camera = cameras[c_tag] - camera_ref = WEAKREF(selected_camera) + var/obj/machinery/camera/selected_camera = locate(params["camera"]) in GLOB.cameranet.cameras + if(selected_camera) + camera_ref = WEAKREF(selected_camera) + else + camera_ref = null if(!spying) playsound(computer, get_sfx(SFX_TERMINAL_TYPE), 25, FALSE) - if(!selected_camera) + if(isnull(camera_ref)) return TRUE if(internal_tracker && internal_tracker.tracking) internal_tracker.set_tracking(FALSE) diff --git a/code/modules/modular_computers/file_system/programs/techweb.dm b/code/modules/modular_computers/file_system/programs/techweb.dm index 9c097b2fb9b024..dc9538cf3580d4 100644 --- a/code/modules/modular_computers/file_system/programs/techweb.dm +++ b/code/modules/modular_computers/file_system/programs/techweb.dm @@ -24,7 +24,7 @@ /datum/computer_file/program/science/on_start(mob/living/user) . = ..() if(!CONFIG_GET(flag/no_default_techweb_link) && !stored_research) - CONNECT_TO_RND_SERVER_ROUNDSTART(stored_research, src) + CONNECT_TO_RND_SERVER_ROUNDSTART(stored_research, computer) /datum/computer_file/program/science/application_attackby(obj/item/attacking_item, mob/living/user) if(!istype(attacking_item, /obj/item/multitool)) diff --git a/code/modules/movespeed/modifiers/status_effects.dm b/code/modules/movespeed/modifiers/status_effects.dm index e8aad88c50d3c7..65245880ef42ba 100644 --- a/code/modules/movespeed/modifiers/status_effects.dm +++ b/code/modules/movespeed/modifiers/status_effects.dm @@ -37,3 +37,19 @@ /datum/movespeed_modifier/status_effect/tired_post_charge multiplicative_slowdown = 3 + +/// Get slower the more gold is in your system. +/datum/movespeed_modifier/status_effect/midas_blight + id = MOVESPEED_ID_MIDAS_BLIGHT + +/datum/movespeed_modifier/status_effect/midas_blight/soft + multiplicative_slowdown = 0.25 + +/datum/movespeed_modifier/status_effect/midas_blight/medium + multiplicative_slowdown = 0.75 + +/datum/movespeed_modifier/status_effect/midas_blight/hard + multiplicative_slowdown = 1.5 + +/datum/movespeed_modifier/status_effect/midas_blight/gold + multiplicative_slowdown = 2 diff --git a/code/modules/pai/camera.dm b/code/modules/pai/camera.dm index a091b208638f61..319f20e3699903 100644 --- a/code/modules/pai/camera.dm +++ b/code/modules/pai/camera.dm @@ -1,10 +1,3 @@ -/mob/living/silicon/pai/ClickOn(atom/target, params) - . = ..() - if(aicamera && aicamera.in_camera_mode) - aicamera.toggle_camera_mode(sound = FALSE) - aicamera.captureimage(target, usr) - return TRUE - /obj/item/camera/siliconcam/pai_camera name = "pAI photo camera" light_color = COLOR_PAI_GREEN @@ -13,7 +6,7 @@ var/number = length(stored) picture.picture_name = "Image [number] (taken by [loc.name])" stored[picture] = TRUE - playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, TRUE, -3) + playsound(src, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, TRUE, -3) balloon_alert(user, "image recorded") /** diff --git a/code/modules/pai/defense.dm b/code/modules/pai/defense.dm index 3a888fa9c83a10..75c437c2546e06 100644 --- a/code/modules/pai/defense.dm +++ b/code/modules/pai/defense.dm @@ -73,17 +73,17 @@ to_chat(src, span_userdanger("The impact degrades your holochassis!")) return amount -/mob/living/silicon/pai/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) - return take_holo_damage(amount) +/// Called when we take burn or brute damage, pass it to the shell instead +/mob/living/silicon/pai/proc/on_shell_damaged(datum/hurt, type, amount, forced) + SIGNAL_HANDLER + take_holo_damage(amount) + return COMPONENT_IGNORE_CHANGE -/mob/living/silicon/pai/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE, required_bodytype) - return take_holo_damage(amount) - -/mob/living/silicon/pai/adjustStaminaLoss(amount, updating_stamina, forced = FALSE, required_biotype) - if(forced) - take_holo_damage(amount) - else - take_holo_damage(amount * 0.25) +/// Called when we take stamina damage, pass it to the shell instead +/mob/living/silicon/pai/proc/on_shell_weakened(datum/hurt, type, amount, forced) + SIGNAL_HANDLER + take_holo_damage(amount * ((forced) ? 1 : 0.25)) + return COMPONENT_IGNORE_CHANGE /mob/living/silicon/pai/getBruteLoss() return HOLOCHASSIS_MAX_HEALTH - holochassis_health diff --git a/code/modules/pai/hud.dm b/code/modules/pai/hud.dm index 530780758d2491..523d57d17b31c1 100644 --- a/code/modules/pai/hud.dm +++ b/code/modules/pai/hud.dm @@ -147,7 +147,8 @@ required_software = "Photography Module" /atom/movable/screen/pai/image_take/Click() - if(!..()) + . = ..() + if(!.) return var/mob/living/silicon/pai/pAI = usr pAI.aicamera.toggle_camera_mode(usr) diff --git a/code/modules/pai/pai.dm b/code/modules/pai/pai.dm index e1a4dfb0ae0b77..3c0a1bfb82cca6 100644 --- a/code/modules/pai/pai.dm +++ b/code/modules/pai/pai.dm @@ -227,6 +227,8 @@ update_appearance(UPDATE_DESC) RegisterSignal(src, COMSIG_LIVING_CULT_SACRIFICED, PROC_REF(on_cult_sacrificed)) + RegisterSignals(src, list(COMSIG_LIVING_ADJUST_BRUTE_DAMAGE, COMSIG_LIVING_ADJUST_BURN_DAMAGE), PROC_REF(on_shell_damaged)) + RegisterSignal(src, COMSIG_LIVING_ADJUST_STAMINA_DAMAGE, PROC_REF(on_shell_weakened)) /mob/living/silicon/pai/make_laws() laws = new /datum/ai_laws/pai() diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 318fca21f57734..9971c0da7f7bbd 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -54,12 +54,26 @@ droppoint = drop_location() if(collapse) visible_message(span_warning("The stack of paper collapses!")) - for(var/atom/movable/movable_atom in contents) - movable_atom.forceMove(droppoint) - if(!movable_atom.pixel_y) - movable_atom.pixel_y = rand(-3,3) - if(!movable_atom.pixel_x) - movable_atom.pixel_x = rand(-3,3) + for(var/obj/item/paper/stacked_paper in paper_stack) //first, dump all of the paper that already exists + stacked_paper.forceMove(droppoint) + if(!stacked_paper.pixel_y) + stacked_paper.pixel_y = rand(-3,3) + if(!stacked_paper.pixel_x) + stacked_paper.pixel_x = rand(-3,3) + paper_stack -= stacked_paper + total_paper -= 1 + for(var/i in 1 to total_paper) //second, generate new paper for the remainder + var/obj/item/paper/new_paper = generate_paper() + new_paper.forceMove(droppoint) + if(!new_paper.pixel_y) + new_paper.pixel_y = rand(-3,3) + if(!new_paper.pixel_x) + new_paper.pixel_x = rand(-3,3) + if(bin_pen) + var/obj/item/pen/pen = bin_pen + pen.forceMove(droppoint) + bin_pen = null + total_paper = 0 update_appearance() /obj/item/paper_bin/fire_act(exposed_temperature, exposed_volume) @@ -212,6 +226,8 @@ /obj/item/paper_bin/bundlenatural/dump_contents(atom/droppoint) . = ..() + binding_cable.forceMove(droppoint) + binding_cable = null qdel(src) /obj/item/paper_bin/bundlenatural/update_overlays() @@ -225,7 +241,7 @@ deconstruct(FALSE) /obj/item/paper_bin/bundlenatural/deconstruct(disassembled) - dump_contents() + dump_contents(drop_location()) return ..() /obj/item/paper_bin/bundlenatural/fire_act(exposed_temperature, exposed_volume) diff --git a/code/modules/photography/camera/other.dm b/code/modules/photography/camera/other.dm index e9aa5d94e597a1..166517d055fbae 100644 --- a/code/modules/photography/camera/other.dm +++ b/code/modules/photography/camera/other.dm @@ -9,13 +9,15 @@ continue // time to steal your soul - if(istype(target, /mob/living/simple_animal/revenant)) - var/mob/living/simple_animal/revenant/peek_a_boo = target - peek_a_boo.reveal(2 SECONDS) // no hiding - if(!peek_a_boo.unstun_time) - peek_a_boo.stun(2 SECONDS) - target.visible_message(span_warning("[target] violently flinches!"), \ - span_revendanger("You feel your essence draining away from having your picture taken!")) + if(istype(target, /mob/living/basic/revenant)) + var/mob/living/basic/revenant/peek_a_boo = target + peek_a_boo.apply_status_effect(/datum/status_effect/revenant/revealed, 2 SECONDS) // no hiding + peek_a_boo.apply_status_effect(/datum/status_effect/incapacitating/paralyzed/revenant, 2 SECONDS) + + target.visible_message( + span_warning("[target] violently flinches!"), + span_revendanger("You feel your essence draining away from having your picture taken!"), + ) target.apply_damage(rand(10, 15)) /obj/item/camera/spooky/badmin diff --git a/code/modules/photography/camera/silicon_camera.dm b/code/modules/photography/camera/silicon_camera.dm index 836ecc2690a161..9cdbee1bc2b7ae 100644 --- a/code/modules/photography/camera/silicon_camera.dm +++ b/code/modules/photography/camera/silicon_camera.dm @@ -1,23 +1,47 @@ /obj/item/camera/siliconcam name = "silicon photo camera" - var/in_camera_mode = FALSE + resistance_flags = INDESTRUCTIBLE + /// List of all pictures taken by this camera. var/list/datum/picture/stored = list() -/obj/item/camera/siliconcam/ai_camera - name = "AI photo camera" - flash_enabled = FALSE +/// Checks if we can take a picture at this moment. Returns TRUE if we can, FALSE if we can't. +/obj/item/camera/siliconcam/proc/can_take_picture(mob/living/silicon/clicker) + if(clicker.stat != CONSCIOUS || clicker.incapacitated()) + return FALSE + return TRUE + +/obj/item/camera/siliconcam/proc/InterceptClickOn(mob/living/silicon/clicker, params, atom/clicked_on) + if(!can_take_picture(clicker)) + return + clicker.face_atom(clicked_on) + captureimage(clicked_on, clicker) + toggle_camera_mode(clicker, sound = FALSE) +/// Toggles the camera mode on or off. +/// If sound is TRUE, plays a sound effect and displays a message on successful toggle /obj/item/camera/siliconcam/proc/toggle_camera_mode(mob/user, sound = TRUE) - in_camera_mode = !in_camera_mode + if(user.click_intercept == src) + user.click_intercept = null + + else if(isnull(user.click_intercept)) + user.click_intercept = src + + else + // Trying to turn on camera mode while you have another click intercept active, such as malf abilities + if(sound) + balloon_alert(user, "can't enable camera mode!") + playsound(user, 'sound/machines/buzz-sigh.ogg', 25, TRUE) + return + if(sound) - playsound(src, 'sound/items/wirecutter.ogg', 50, TRUE) - to_chat(user, span_notice("Camera mode: [in_camera_mode ? "Activated" : "Deactivated"].")) + playsound(user, 'sound/items/wirecutter.ogg', 50, TRUE) + balloon_alert(user, "camera mode [user.click_intercept == src ? "activated" : "deactivated"]") /obj/item/camera/siliconcam/proc/selectpicture(mob/user) RETURN_TYPE(/datum/picture) if(!length(stored)) - to_chat(user, span_notice("ERROR: No stored photos located.")) + user.balloon_alert(user, "no stored photos!") return var/list/nametemp = list() var/list/temp = list() @@ -25,9 +49,7 @@ nametemp += stored_photo.picture_name temp[stored_photo.picture_name] = stored_photo var/find = tgui_input_list(user, "Select image", "Storage", nametemp) - if(isnull(find)) - return - if(isnull(temp[find])) + if(isnull(find) || isnull(temp[find])) return return temp[find] @@ -36,48 +58,70 @@ if(istype(selection)) show_picture(user, selection) +/obj/item/camera/siliconcam/ai_camera + name = "AI photo camera" + flash_enabled = FALSE + +/obj/item/camera/siliconcam/ai_camera/can_take_picture(mob/living/silicon/ai/clicker) + if(clicker.control_disabled) + return FALSE + return ..() + +/obj/item/camera/siliconcam/ai_camera/balloon_alert(mob/viewer, text) + if(isAI(loc)) + // redirects balloon alerts on us to balloon alerts on our ai eye + var/mob/living/silicon/ai/ai = loc + return ai.eyeobj.balloon_alert(viewer, text) + + return ..() + /obj/item/camera/siliconcam/ai_camera/after_picture(mob/user, datum/picture/picture) var/number = length(stored) picture.picture_name = "Image [number] (taken by [loc.name])" stored[picture] = TRUE - to_chat(user, span_notice("Image recorded.")) + balloon_alert(user, "image recorded") + user.playsound_local(get_turf(user), pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 50, TRUE, -3) /obj/item/camera/siliconcam/robot_camera name = "Cyborg photo camera" var/printcost = 2 -/obj/item/camera/siliconcam/robot_camera/after_picture(mob/user, datum/picture/picture) - var/mob/living/silicon/robot/C = loc - if(istype(C) && istype(C.connected_ai)) - var/number = C.connected_ai.aicamera.stored.len +/obj/item/camera/siliconcam/robot_camera/can_take_picture(mob/living/silicon/robot/clicker) + if(clicker.lockcharge) + return FALSE + return ..() + +/obj/item/camera/siliconcam/robot_camera/after_picture(mob/living/silicon/robot/user, datum/picture/picture) + if(istype(user) && istype(user.connected_ai)) + var/number = user.connected_ai.aicamera.stored.len picture.picture_name = "Image [number] (taken by [loc.name])" - C.connected_ai.aicamera.stored[picture] = TRUE - to_chat(usr, span_notice("Image recorded and saved to remote database.")) + user.connected_ai.aicamera.stored[picture] = TRUE + balloon_alert(user, "image recorded and uploaded") else var/number = stored.len picture.picture_name = "Image [number] (taken by [loc.name])" stored[picture] = TRUE - to_chat(usr, span_notice("Image recorded and saved to local storage. Upload will happen automatically if unit is lawsynced.")) + balloon_alert(user, "image recorded and saved locally") + playsound(src, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, TRUE, -3) -/obj/item/camera/siliconcam/robot_camera/selectpicture(mob/user) - var/mob/living/silicon/robot/R = loc - if(istype(R) && R.connected_ai) - R.picturesync() - return R.connected_ai.aicamera.selectpicture(user) - else - return ..() +/obj/item/camera/siliconcam/robot_camera/selectpicture(mob/living/silicon/robot/user) + if(istype(user) && user.connected_ai) + user.picturesync() + return user.connected_ai.aicamera.selectpicture(user) + return ..() -/obj/item/camera/siliconcam/robot_camera/proc/borgprint(mob/user) - var/mob/living/silicon/robot/C = loc - if(!istype(C) || C.toner < 20) - to_chat(user, span_warning("Insufficent toner to print image.")) +/obj/item/camera/siliconcam/robot_camera/proc/borgprint(mob/living/silicon/robot/user) + if(!istype(user) || user.toner < printcost) + balloon_alert(user, "not enough toner!") return var/datum/picture/selection = selectpicture(user) if(!istype(selection)) - to_chat(user, span_warning("Invalid Image.")) + balloon_alert(user, "invalid image!") return - var/obj/item/photo/p = new /obj/item/photo(C.loc, selection) - p.pixel_x = p.base_pixel_x + rand(-10, 10) - p.pixel_y = p.base_pixel_y + rand(-10, 10) - C.toner -= printcost //All fun allowed. - user.visible_message(span_notice("[C.name] spits out a photograph from a narrow slot on its chassis."), span_notice("You print a photograph.")) + var/obj/item/photo/printed = new(user.drop_location(), selection) + printed.pixel_x = printed.base_pixel_x + rand(-10, 10) + printed.pixel_y = printed.base_pixel_y + rand(-10, 10) + user.toner -= printcost //All fun allowed. + user.visible_message(span_notice("[user.name] spits out a photograph from a narrow slot on its chassis."), span_notice("You print a photograph.")) + balloon_alert(user, "photograph printed") + playsound(src, 'sound/items/taperecorder/taperecorder_print.ogg', 50, TRUE, -3) diff --git a/code/modules/photography/photos/photo.dm b/code/modules/photography/photos/photo.dm index 9be79a58266534..b34ff459c0075f 100644 --- a/code/modules/photography/photos/photo.dm +++ b/code/modules/photography/photos/photo.dm @@ -54,11 +54,11 @@ icon = I return ..() -/obj/item/photo/suicide_act(mob/living/carbon/user) +/obj/item/photo/suicide_act(mob/living/carbon/human/user) user.visible_message(span_suicide("[user] is taking one last look at \the [src]! It looks like [user.p_theyre()] giving in to death!"))//when you wanna look at photo of waifu one last time before you die... - if (user.gender == MALE) + if (!ishuman(user) || user.physique == MALE) playsound(user, 'sound/voice/human/manlaugh1.ogg', 50, TRUE)//EVERY TIME I DO IT MAKES ME LAUGH - else if (user.gender == FEMALE) + else playsound(user, 'sound/voice/human/womanlaugh.ogg', 50, TRUE) return OXYLOSS diff --git a/code/modules/plumbing/plumbers/acclimator.dm b/code/modules/plumbing/plumbers/acclimator.dm index da5c4529a4230d..6b7a8caba4ac8c 100644 --- a/code/modules/plumbing/plumbers/acclimator.dm +++ b/code/modules/plumbing/plumbers/acclimator.dm @@ -23,9 +23,7 @@ var/enabled = TRUE ///COOLING, HEATING or NEUTRAL. We track this for change, so we dont needlessly update our icon var/acclimate_state - /**We can't take anything in, at least till we're emptied. Down side of the round robin chem transfer, otherwise while emptying 5u of an unreacted chem gets added, - and you get nasty leftovers - */ + ///When conditions are met we send out the stored reagents var/emptying = FALSE /obj/machinery/plumbing/acclimator/Initialize(mapload, bolt, layer) diff --git a/code/modules/plumbing/plumbers/pill_press.dm b/code/modules/plumbing/plumbers/pill_press.dm index 3a9afca5e02642..e04215e94e26eb 100644 --- a/code/modules/plumbing/plumbers/pill_press.dm +++ b/code/modules/plumbing/plumbers/pill_press.dm @@ -3,7 +3,6 @@ name = "chemical press" desc = "A press that makes pills, patches and bottles." icon_state = "pill_press" - buffer = 60 //SKYRAT EDIT HYPOVIALS. This is needed so it can completely fill the vials up. active_power_usage = BASE_MACHINE_ACTIVE_CONSUMPTION * 2 ///maximum size of a pill @@ -12,8 +11,6 @@ var/max_patch_volume = 40 ///maximum size of a bottle var/max_bottle_volume = 50 - //SKYRAT EDIT HYPOVIALS maximum size of a vial - var/max_vial_volume = 60 ///current operating product (pills or patches) var/product = "pill" ///the minimum size a pill or patch can be @@ -72,13 +69,13 @@ reagents.trans_to(P, current_volume) P.name = trim("[product_name] bottle") stored_products += P - //SKYRAT EDIT HYPOVIALS + //SKYRAT EDIT ADDITION BEGIN - HYPOVIALS else if (product == "vial") var/obj/item/reagent_containers/cup/vial/small/P = new(src) reagents.trans_to(P, current_volume) P.name = trim("[product_name] vial") stored_products += P - //SKYRAT EDIT HYPOVIALS END + //SKYRAT EDIT ADDITION END - HYPOVIALS if(stored_products.len) var/pill_amount = 0 for(var/thing in loc) @@ -159,10 +156,10 @@ max_volume = max_patch_volume else if (product == "bottle") max_volume = max_bottle_volume - //SKYRAT EDIT HYPOVIALS + //SKYRAT EDIT ADDITION BEGIN - HYPOVIALS else if (product == "vial") - max_volume = max_vial_volume - //SKYRAT EDIT HPYOVIALS END + max_volume = max_bottle_volume + //SKYRAT EDIT ADDITION END - HYPOVIALS current_volume = clamp(current_volume, min_volume, max_volume) if("change_patch_style") patch_style = params["patch_style"] diff --git a/code/modules/plumbing/plumbers/reaction_chamber.dm b/code/modules/plumbing/plumbers/reaction_chamber.dm index 689d043418b496..36320f18184fed 100644 --- a/code/modules/plumbing/plumbers/reaction_chamber.dm +++ b/code/modules/plumbing/plumbers/reaction_chamber.dm @@ -1,5 +1,8 @@ ///a reaction chamber for plumbing. pretty much everything can react, but this one keeps the reagents separated and only reacts under your given terms +/// coefficient to convert temperature to joules. same lvl as acclimator +#define HEATER_COEFFICIENT 0.05 + /obj/machinery/plumbing/reaction_chamber name = "mixing chamber" desc = "Keeps chemicals separated until given conditions are met." @@ -19,9 +22,6 @@ ///towards which temperature do we build (except during draining)? var/target_temperature = 300 - ///cool/heat power - var/heater_coefficient = 0.05 //same lvl as acclimator - /obj/machinery/plumbing/reaction_chamber/Initialize(mapload, bolt, layer) . = ..() @@ -35,30 +35,48 @@ /// Handles properly detaching signal hooks. /obj/machinery/plumbing/reaction_chamber/proc/on_reagents_del(datum/reagents/reagents) SIGNAL_HANDLER + UnregisterSignal(reagents, list(COMSIG_REAGENTS_REM_REAGENT, COMSIG_REAGENTS_DEL_REAGENT, COMSIG_REAGENTS_CLEAR_REAGENTS, COMSIG_REAGENTS_REACTED, COMSIG_QDELETING)) return NONE /// Handles stopping the emptying process when the chamber empties. /obj/machinery/plumbing/reaction_chamber/proc/on_reagent_change(datum/reagents/holder, ...) SIGNAL_HANDLER - if(holder.total_volume == 0 && emptying) //we were emptying, but now we aren't + + if(!holder.total_volume && emptying) //we were emptying, but now we aren't emptying = FALSE holder.flags |= NO_REACT return NONE /obj/machinery/plumbing/reaction_chamber/process(seconds_per_tick) - if(!emptying || reagents.is_reacting) //suspend heating/cooling during emptying phase - reagents.adjust_thermal_energy((target_temperature - reagents.chem_temp) * heater_coefficient * seconds_per_tick * SPECIFIC_HEAT_DEFAULT * reagents.total_volume) //keep constant with chem heater + //half the power for getting reagents in + var/power_usage = active_power_usage * 0.5 + + if(!emptying || reagents.is_reacting) + //do reactions and stuff reagents.handle_reactions() - use_power(active_power_usage * seconds_per_tick) + //adjust temperature of final solution + var/temp_diff = target_temperature - reagents.chem_temp + if(abs(temp_diff) > 0.01) //if we are not close enough keep going + reagents.adjust_thermal_energy(temp_diff * HEATER_COEFFICIENT * seconds_per_tick * SPECIFIC_HEAT_DEFAULT * reagents.total_volume) //keep constant with chem heater + + //do other stuff with final solution + handle_reagents(seconds_per_tick) + + //full power for doing reactions + power_usage *= 2 + + use_power(power_usage * seconds_per_tick) + +///For subtypes that want to do additional reagent handling +/obj/machinery/plumbing/reaction_chamber/proc/handle_reagents(seconds_per_tick) + return /obj/machinery/plumbing/reaction_chamber/power_change() . = ..() - if(use_power != NO_POWER_USE) - icon_state = initial(icon_state) + "_on" - else - icon_state = initial(icon_state) + + icon_state = initial(icon_state) + "[use_power != NO_POWER_USE ? "_on" : ""]" /obj/machinery/plumbing/reaction_chamber/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) @@ -67,31 +85,29 @@ ui.open() /obj/machinery/plumbing/reaction_chamber/ui_data(mob/user) - var/list/data = list() + . = list() var/list/reagents_data = list() for(var/datum/reagent/required_reagent as anything in required_reagents) //make a list where the key is text, because that looks alot better in the ui than a typepath var/list/reagent_data = list() reagent_data["name"] = initial(required_reagent.name) - reagent_data["required_reagent"] = required_reagents[required_reagent] + reagent_data["volume"] = required_reagents[required_reagent] reagents_data += list(reagent_data) - data["reagents"] = reagents_data - data["emptying"] = emptying - data["temperature"] = round(reagents.chem_temp, 0.1) - data["targetTemp"] = target_temperature - data["isReacting"] = reagents.is_reacting - return data + .["reagents"] = reagents_data + .["emptying"] = emptying + .["temperature"] = round(reagents.chem_temp, 0.1) + .["targetTemp"] = target_temperature + .["isReacting"] = reagents.is_reacting -/obj/machinery/plumbing/reaction_chamber/ui_act(action, params) +/obj/machinery/plumbing/reaction_chamber/ui_act(action, params, datum/tgui/ui, datum/ui_state/state) . = ..() if(.) return TRUE - . = FALSE switch(action) if("add") - var/selected_reagent = tgui_input_list(usr, "Select reagent", "Reagent", GLOB.chemical_name_list) + var/selected_reagent = tgui_input_list(ui.user, "Select reagent", "Reagent", GLOB.chemical_name_list) if(!selected_reagent) return TRUE @@ -104,32 +120,41 @@ if(input_amount) required_reagents[input_reagent] = input_amount - . = TRUE + return TRUE if("remove") var/reagent = get_chem_id(params["chem"]) if(reagent) required_reagents.Remove(reagent) - . = TRUE + return TRUE if("temperature") var/target = text2num(params["target"]) if(target != null) - target_temperature=clamp(target, 0, 1000) - .=TRUE + target_temperature = clamp(target, 0, 1000) + return TRUE + + var/result = handle_ui_act(action, params, ui, state) + if(isnull(result)) + result = FALSE + return result + +/// For custom handling of ui actions from inside a subtype +/obj/machinery/plumbing/reaction_chamber/proc/handle_ui_act(action, params, datum/tgui/ui, datum/ui_state/state) + return null ///Chemistry version of reaction chamber that allows for acid and base buffers to be used while reacting /obj/machinery/plumbing/reaction_chamber/chem name = "reaction chamber" - ///If above this pH, we start dumping buffer into it - var/acidic_limit = 9 ///If below this pH, we start dumping buffer into it - var/alkaline_limit = 5 + var/acidic_limit = 5 + ///If above this pH, we start dumping acid into it + var/alkaline_limit = 9 - ///Beaker that holds the acidic buffer. I don't want to deal with snowflaking so it's just a separate thing. It's a small (50u) beaker + ///beaker that holds the acidic buffer(50u) var/obj/item/reagent_containers/cup/beaker/acidic_beaker - ///beaker that holds the alkaline buffer. + ///beaker that holds the alkaline buffer(50u). var/obj/item/reagent_containers/cup/beaker/alkaline_beaker /obj/machinery/plumbing/reaction_chamber/chem/Initialize(mapload, bolt, layer) @@ -147,13 +172,27 @@ QDEL_NULL(alkaline_beaker) return ..() -/obj/machinery/plumbing/reaction_chamber/chem/process(seconds_per_tick) - //add acidic/alkaine buffer if over/under limit - if(reagents.is_reacting && reagents.ph < alkaline_limit) - alkaline_beaker.reagents.trans_to(reagents, 1 * seconds_per_tick) - if(reagents.is_reacting && reagents.ph > acidic_limit) - acidic_beaker.reagents.trans_to(reagents, 1 * seconds_per_tick) - ..() +/obj/machinery/plumbing/reaction_chamber/chem/handle_reagents(seconds_per_tick) + while(reagents.ph < acidic_limit || reagents.ph > alkaline_limit) + if(machine_stat & NOPOWER) + return + + /** + * figure out which buffer to transfer to restore balance + * if solution is getting too basic(high ph) add some acid to lower it's value + * else if solution is getting too acidic(low ph) add some base to increase it's value + */ + var/datum/reagents/buffer = reagents.ph > alkaline_limit ? acidic_beaker.reagents : alkaline_beaker.reagents + if(!buffer.total_volume) + return + + //transfer buffer and handle reactions, not a proven math but looks logical + var/transfer_amount = FLOOR((reagents.ph > alkaline_limit ? (reagents.ph - alkaline_limit) : (acidic_limit - reagents.ph)) * seconds_per_tick, CHEMICAL_QUANTISATION_LEVEL) + if(transfer_amount <= CHEMICAL_QUANTISATION_LEVEL || !buffer.trans_to(reagents, transfer_amount)) + return + + //some power for accurate ph balancing + use_power(active_power_usage * 0.2 * seconds_per_tick) /obj/machinery/plumbing/reaction_chamber/chem/ui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) @@ -167,16 +206,16 @@ .["reagentAcidic"] = acidic_limit .["reagentAlkaline"] = alkaline_limit -/obj/machinery/plumbing/reaction_chamber/chem/ui_act(action, params) - . = ..() - if (.) - return +/obj/machinery/plumbing/reaction_chamber/chem/handle_ui_act(action, params, datum/tgui/ui, datum/ui_state/state) + . = TRUE switch(action) if("acidic") - acidic_limit = round(text2num(params["target"])) + acidic_limit = clamp(round(text2num(params["target"])), 0, alkaline_limit) if("alkaline") - alkaline_limit = round(text2num(params["target"])) + alkaline_limit = clamp(round(text2num(params["target"])), acidic_limit + 0.01, 14) + else + return FALSE - return TRUE +#undef HEATER_COEFFICIENT diff --git a/code/modules/plumbing/plumbers/teleporter.dm b/code/modules/plumbing/plumbers/teleporter.dm index a8e6e7ae3ac554..7bb098eae4e06a 100644 --- a/code/modules/plumbing/plumbers/teleporter.dm +++ b/code/modules/plumbing/plumbers/teleporter.dm @@ -45,7 +45,7 @@ ///Transfer reagents and display a flashing icon /obj/machinery/plumbing/sender/proc/teleport_chemicals(obj/machinery/plumbing/receiver/R, amount) flick(initial(icon_state) + "_flash", src) - reagents.trans_to(R, amount, round_robin = TRUE) + reagents.trans_to(R, amount) ///A bluespace output pipe for plumbing. Supports multiple recipients. Must be constructed with a circuit board /obj/machinery/plumbing/receiver diff --git a/code/modules/power/apc/apc_malf.dm b/code/modules/power/apc/apc_malf.dm index f13b588842a8bc..3b0703688043d8 100644 --- a/code/modules/power/apc/apc_malf.dm +++ b/code/modules/power/apc/apc_malf.dm @@ -69,7 +69,7 @@ if(forced) occupier.forceMove(drop_location()) INVOKE_ASYNC(occupier, TYPE_PROC_REF(/mob/living, death)) - occupier.gib() + occupier.gib(DROP_ALL_REMAINS) if(!occupier.nuking) //Pinpointers go back to tracking the nuke disk, as long as the AI (somehow) isn't mid-nuking. for(var/obj/item/pinpointer/nuke/disk_pinpointers in GLOB.pinpointer_list) diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 1c83ca58e1d0bf..d11b57bcb93f12 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -112,7 +112,7 @@ return ..() /obj/narsie/attack_ghost(mob/user) - makeNewConstruct(/mob/living/simple_animal/hostile/construct/harvester, user, cultoverride = TRUE, loc_override = loc) + makeNewConstruct(/mob/living/basic/construct/harvester, user, cultoverride = TRUE, loc_override = loc) /obj/narsie/process() var/datum/component/singularity/singularity_component = singularity.resolve() diff --git a/code/modules/projectiles/ammunition/ballistic/pistol.dm b/code/modules/projectiles/ammunition/ballistic/pistol.dm index c61888b95259fd..a2f55f797bdb5f 100644 --- a/code/modules/projectiles/ammunition/ballistic/pistol.dm +++ b/code/modules/projectiles/ammunition/ballistic/pistol.dm @@ -21,6 +21,11 @@ desc = "A 10mm incendiary bullet casing." projectile_type = /obj/projectile/bullet/incendiary/c10mm +/obj/item/ammo_casing/c10mm/reaper + name = "10mm reaper bullet casing" + desc = "A 10mm reaper bullet casing." + projectile_type = /obj/projectile/bullet/c10mm/reaper + // 9mm (Makarov, Stechkin APS, PP-95) /obj/item/ammo_casing/c9mm diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm index 53ff1f8a350419..81e2fe97931c3e 100644 --- a/code/modules/projectiles/ammunition/ballistic/shotgun.dm +++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm @@ -136,6 +136,16 @@ icon_state = "cshell" projectile_type = null +/obj/item/ammo_casing/shotgun/techshell/Initialize(mapload) + . = ..() + + var/static/list/slapcraft_recipe_list = list(/datum/crafting_recipe/meteorslug, /datum/crafting_recipe/pulseslug, /datum/crafting_recipe/dragonsbreath, /datum/crafting_recipe/ionslug, /datum/crafting_recipe/laserslug) + + AddComponent( + /datum/component/slapcrafting,\ + slapcraft_recipes = slapcraft_recipe_list,\ + ) + /obj/item/ammo_casing/shotgun/dart name = "shotgun dart" desc = "A dart for use in shotguns. Can be injected with up to 15 units of any chemical." diff --git a/code/modules/projectiles/ammunition/energy/laser.dm b/code/modules/projectiles/ammunition/energy/laser.dm index fbf9b289aa079e..081f4166236efb 100644 --- a/code/modules/projectiles/ammunition/energy/laser.dm +++ b/code/modules/projectiles/ammunition/energy/laser.dm @@ -16,6 +16,16 @@ e_cost = 62.5 select_name = "kill" +/obj/item/ammo_casing/energy/lasergun/carbine + projectile_type = /obj/projectile/beam/laser/carbine + e_cost = 25 // 40 shots + select_name = "kill" + +/obj/item/ammo_casing/energy/lasergun/carbine/practice + projectile_type = /obj/projectile/beam/laser/carbine/practice + select_name = "practice" + harmful = FALSE + /obj/item/ammo_casing/energy/lasergun/old projectile_type = /obj/projectile/beam/laser e_cost = 200 diff --git a/code/modules/projectiles/boxes_magazines/external/pistol.dm b/code/modules/projectiles/boxes_magazines/external/pistol.dm index 49ea0029f8f6db..8b0bc1da7e5b80 100644 --- a/code/modules/projectiles/boxes_magazines/external/pistol.dm +++ b/code/modules/projectiles/boxes_magazines/external/pistol.dm @@ -107,15 +107,11 @@ multiple_sprites = AMMO_BOX_PER_BULLET /obj/item/ammo_box/magazine/r10mm - name = "regal condor magazine (10mm)" + name = "regal condor magazine (10mm Reaper)" icon_state = "r10mm-8" base_icon_state = "r10mm" - ammo_type = /obj/item/ammo_casing/c10mm + ammo_type = /obj/item/ammo_casing/c10mm/reaper caliber = CALIBER_10MM max_ammo = 8 multiple_sprites = AMMO_BOX_PER_BULLET multiple_sprite_use_base = TRUE - -/obj/item/ammo_box/magazine/r10mm/empty - icon_state = "r10mm-0" - start_empty = TRUE diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm index 576ba6395be72e..efff8c2fc6157c 100644 --- a/code/modules/projectiles/guns/ballistic.dm +++ b/code/modules/projectiles/guns/ballistic.dm @@ -723,7 +723,7 @@ GLOBAL_LIST_INIT(gun_saw_types, typecacheof(list( /obj/item/suppressor name = "suppressor" - desc = "A Scarborough Arms small-arms suppressor for maximum espionage." //SKYRAT EDIT - ORIGINAL: desc = "A syndicate small-arms suppressor for maximum espionage." + desc = "A small-arms suppressor for maximum espionage." //SKYRAT EDIT - ORIGINAL: desc = "A syndicate small-arms suppressor for maximum espionage." icon = 'icons/obj/weapons/guns/ballistic.dmi' icon_state = "suppressor" w_class = WEIGHT_CLASS_TINY diff --git a/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm b/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm index 5d33b3fce5170f..9f7ab7e354c94f 100644 --- a/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm +++ b/code/modules/projectiles/guns/ballistic/bows/bow_arrows.dm @@ -73,7 +73,7 @@ /obj/projectile/bullet/arrow/holy/Initialize(mapload) . = ..() //50 damage to revenants - AddElement(/datum/element/bane, target_type = /mob/living/simple_animal/revenant, damage_multiplier = 0, added_damage = 30) + AddElement(/datum/element/bane, target_type = /mob/living/basic/revenant, damage_multiplier = 0, added_damage = 30) /// special pyre sect arrow /// in the future, this needs a special sprite, but bows don't support non-hardcoded arrow sprites diff --git a/code/modules/projectiles/guns/ballistic/bows/bow_types.dm b/code/modules/projectiles/guns/ballistic/bows/bow_types.dm index 355ed3575a8141..b9ac1af0cca12a 100644 --- a/code/modules/projectiles/guns/ballistic/bows/bow_types.dm +++ b/code/modules/projectiles/guns/ballistic/bows/bow_types.dm @@ -30,7 +30,7 @@ on_clear_callback = CALLBACK(src, PROC_REF(on_cult_rune_removed)), \ effects_we_clear = list(/obj/effect/rune, /obj/effect/heretic_rune) \ ) - AddElement(/datum/element/bane, target_type = /mob/living/simple_animal/revenant, damage_multiplier = 0, added_damage = 25, requires_combat_mode = FALSE) + AddElement(/datum/element/bane, target_type = /mob/living/basic/revenant, damage_multiplier = 0, added_damage = 25, requires_combat_mode = FALSE) /obj/item/gun/ballistic/bow/divine/proc/on_cult_rune_removed(obj/effect/target, mob/living/user) SIGNAL_HANDLER diff --git a/code/modules/projectiles/guns/ballistic/launchers.dm b/code/modules/projectiles/guns/ballistic/launchers.dm index 0b676ae3dfac6a..83c19bf9350129 100644 --- a/code/modules/projectiles/guns/ballistic/launchers.dm +++ b/code/modules/projectiles/guns/ballistic/launchers.dm @@ -97,7 +97,7 @@ REMOVE_TRAIT(user, TRAIT_NO_TRANSFORM, REF(src)) process_fire(user, user, TRUE) if(!QDELETED(user)) //if they weren't gibbed by the explosion, take care of them for good. - user.gib() + user.gib(DROP_ALL_REMAINS) return MANUAL_SUICIDE else sleep(0.5 SECONDS) diff --git a/code/modules/projectiles/guns/ballistic/pistol.dm b/code/modules/projectiles/guns/ballistic/pistol.dm index 220df569ecbd61..f69494e0a18bde 100644 --- a/code/modules/projectiles/guns/ballistic/pistol.dm +++ b/code/modules/projectiles/guns/ballistic/pistol.dm @@ -99,9 +99,6 @@ actions_types = list(/datum/action/item_action/toggle_firemode) obj_flags = UNIQUE_RENAME // if you did the sidequest, you get the customization -/obj/item/gun/ballistic/automatic/pistol/deagle/regal/no_mag - spawnwithmagazine = FALSE - /obj/item/gun/ballistic/automatic/pistol/aps name = "\improper Stechkin APS machine pistol" desc = "A modernized reproduction of an old Soviet machine pistol. It fires quickly, but kicks like a mule. Uses 9mm ammo. Has a threaded barrel for suppressors." //SKYRAT EDIT diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm index 6439b78a9bd986..f87f473ae459bb 100644 --- a/code/modules/projectiles/guns/ballistic/revolver.dm +++ b/code/modules/projectiles/guns/ballistic/revolver.dm @@ -139,6 +139,11 @@ desc = "A modernized 7 round revolver manufactured by Waffle Co. Uses .357 ammo." icon_state = "revolversyndie" +/obj/item/gun/ballistic/revolver/syndicate/cowboy + desc = "A classic revolver, refurbished for modern use. Uses .357 ammo." + //There's already a cowboy sprite in there! + icon_state = "lucky" + /obj/item/gun/ballistic/revolver/mateba name = "\improper Unica 6 auto-revolver" desc = "A retro high-powered autorevolver typically used by officers of the New Russia military. Uses .357 ammo." @@ -275,10 +280,15 @@ user.visible_message(span_danger("[user.name]'s soul is captured by \the [src]!"), span_userdanger("You've lost the gamble! Your soul is forfeit!")) /obj/item/gun/ballistic/revolver/reverse //Fires directly at its user... unless the user is a clown, of course. - name = "\improper Syndicate Revolver" clumsy_check = FALSE icon_state = "revolversyndie" +/obj/item/gun/ballistic/revolver/reverse/Initialize(mapload) + . = ..() + var/obj/item/gun/ballistic/revolver/syndicate/syndie_revolver = /obj/item/gun/ballistic/revolver/syndicate + name = initial(syndie_revolver.name) + desc = initial(syndie_revolver.desc) + /obj/item/gun/ballistic/revolver/reverse/can_trigger_gun(mob/living/user, akimbo_usage) if(akimbo_usage) return FALSE diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm index cb0b5862e162f5..69acb79ac2a339 100644 --- a/code/modules/projectiles/guns/energy/energy_gun.dm +++ b/code/modules/projectiles/guns/energy/energy_gun.dm @@ -77,7 +77,7 @@ name = "\improper X-01 MultiPhase Energy Gun" desc = "This is an expensive, modern recreation of an antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time." icon_state = "hoslaser" - cell_type = /obj/item/stock_parts/cell //SKYRAT EDIT ADDITION - GUNSGALORE + cell_type = /obj/item/stock_parts/cell/hos_gun w_class = WEIGHT_CLASS_NORMAL force = 10 ammo_type = list(/obj/item/ammo_casing/energy/disabler/hos, /obj/item/ammo_casing/energy/laser/hos, /obj/item/ammo_casing/energy/ion/hos) diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm index 0409f2fe037340..94d58bb5e32296 100644 --- a/code/modules/projectiles/guns/energy/laser.dm +++ b/code/modules/projectiles/guns/energy/laser.dm @@ -37,6 +37,26 @@ cell_type = /obj/item/stock_parts/cell //SKYRAT EDIT ADDITION - GUNSGALORE ammo_x_offset = 3 +/obj/item/gun/energy/laser/carbine + name = "laser carbine" + desc = "A modified laser gun which can shoot far faster, but each shot is far less damaging." + icon_state = "laser_carbine" + ammo_type = list(/obj/item/ammo_casing/energy/lasergun/carbine) + var/allow_akimbo = FALSE + +/obj/item/gun/energy/laser/carbine/Initialize(mapload) + . = ..() + AddComponent(/datum/component/automatic_fire, 0.15 SECONDS, allow_akimbo = allow_akimbo) + +/obj/item/gun/energy/laser/carbine/practice + name = "practice laser carbine" + desc = "A modified version of the laser carbine, this one fires even less concentrated energy bolts designed for target practice." + ammo_type = list(/obj/item/ammo_casing/energy/lasergun/carbine/practice) + clumsy_check = FALSE + item_flags = NONE + gun_flags = NOT_A_REAL_GUN + allow_akimbo = TRUE + /obj/item/gun/energy/laser/retro/old name ="laser gun" icon_state = "retro" diff --git a/code/modules/projectiles/guns/special/hand_of_midas.dm b/code/modules/projectiles/guns/special/hand_of_midas.dm new file mode 100644 index 00000000000000..9907352e3f5059 --- /dev/null +++ b/code/modules/projectiles/guns/special/hand_of_midas.dm @@ -0,0 +1,138 @@ +// Hand of Midas + +/obj/item/gun/magic/midas_hand + name = "The Hand of Midas" + desc = "An ancient Egyptian matchlock pistol imbued with the powers of the Greek King Midas. Don't question the cultural or religious implications of this." + ammo_type = /obj/item/ammo_casing/magic/midas_round + icon_state = "midas_hand" + inhand_icon_state = "gun" + worn_icon_state = "gun" + lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' + fire_sound = 'sound/weapons/gun/rifle/shot.ogg' + pinless = TRUE + max_charges = 1 + can_charge = FALSE + item_flags = NEEDS_PERMIT + w_class = WEIGHT_CLASS_BULKY // Should fit on a belt. + force = 3 + trigger_guard = TRIGGER_GUARD_NORMAL + antimagic_flags = NONE + can_hold_up = FALSE + + /// The length of the Midas Blight debuff, dependant on the amount of gold reagent we've sucked up. + var/gold_timer = 3 SECONDS + /// The range that we can suck gold out of people's bodies + var/gold_suck_range = 2 + +/obj/item/gun/magic/midas_hand/examine(mob/user) + . = ..() + var/gold_time_converted = gold_time_convert() + . += span_notice("Your next shot will inflict [gold_time_converted] second[gold_time_converted == 1 ? "" : "s"] of Midas Blight.") + . += span_notice("Right-Click on enemies to drain gold from their bloodstreams to reload [src].") + . += span_notice("[src] can be reloaded using gold coins in a pinch.") + +/obj/item/gun/magic/midas_hand/shoot_with_empty_chamber(mob/living/user) + . = ..() + balloon_alert(user, "not enough gold") + +// Siphon gold from a victim, recharging our gun & removing their Midas Blight debuff in the process. +/obj/item/gun/magic/midas_hand/afterattack_secondary(mob/living/victim, mob/living/user, proximity_flag, click_parameters) + if(!isliving(victim) || !IN_GIVEN_RANGE(user, victim, gold_suck_range)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + if(victim == user) + balloon_alert(user, "can't siphon from self") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + if(!victim.reagents) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + if(!victim.reagents.has_reagent(/datum/reagent/gold, check_subtypes = TRUE)) + balloon_alert(user, "no gold in bloodstream") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + var/gold_beam = user.Beam(victim, icon_state="drain_gold") + if(!do_after(user = user, delay = 1 SECONDS, target = victim, timed_action_flags = (IGNORE_USER_LOC_CHANGE | IGNORE_TARGET_LOC_CHANGE), extra_checks = CALLBACK(src, PROC_REF(check_gold_range), user, victim))) + qdel(gold_beam) + balloon_alert(user, "link broken") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + handle_gold_charges(user, victim.reagents.get_reagent_amount(/datum/reagent/gold, include_subtypes = TRUE)) + victim.reagents.remove_all_type(/datum/reagent/gold, victim.reagents.get_reagent_amount(/datum/reagent/gold, include_subtypes = TRUE)) + victim.remove_status_effect(/datum/status_effect/midas_blight) + qdel(gold_beam) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +// If we botch a shot, we have to start over again by inserting gold coins into the gun. Can only be done if it has no charges or gold. +/obj/item/gun/magic/midas_hand/attackby(obj/item/I, mob/living/user, params) + . = ..() + if(charges || gold_timer) + balloon_alert(user, "already loaded") + return + if(istype(I, /obj/item/coin/gold)) + handle_gold_charges(user, 1.5 SECONDS) + qdel(I) + +/// Handles recharging & inserting gold amount +/obj/item/gun/magic/midas_hand/proc/handle_gold_charges(user, gold_amount) + gold_timer += gold_amount + var/gold_time_converted = gold_time_convert() + balloon_alert(user, "[gold_time_converted] second[gold_time_converted == 1 ? "" : "s"]") + if(!charges) + instant_recharge() + +/// Converts our gold_timer to time in seconds, for various ballons/examines +/obj/item/gun/magic/midas_hand/proc/gold_time_convert() + return min(30 SECONDS, round(gold_timer, 0.2)) / 10 + +/// Checks our range to the person we're sucking gold out of. Double the initial range, so you need to get in close to start. +/obj/item/gun/magic/midas_hand/proc/check_gold_range(mob/living/user, mob/living/victim) + return IN_GIVEN_RANGE(user, victim, gold_suck_range*2) + +/obj/item/ammo_casing/magic/midas_round + projectile_type = /obj/projectile/magic/midas_round + + +/obj/projectile/magic/midas_round + name = "gold pellet" + desc = "A typical flintlock ball, save for the fact it's made of cursed Egyptian gold." + damage_type = BRUTE + damage = 10 + stamina = 20 + armour_penetration = 50 + hitsound = 'sound/effects/coin2.ogg' + icon_state = "pellet" + color = "#FFD700" + /// The gold charge in this pellet + var/gold_charge = 0 + + +/obj/projectile/magic/midas_round/fire(setAngle) + /// Transfer the gold energy to our bullet + var/obj/item/gun/magic/midas_hand/my_gun = fired_from + gold_charge = my_gun.gold_timer + my_gun.gold_timer = 0 + ..() + +// Gives human targets Midas Blight. +/obj/projectile/magic/midas_round/on_hit(atom/target) + . = ..() + if(ishuman(target)) + var/mob/living/carbon/human/my_guy = target + if(isskeleton(my_guy)) // No cheap farming + return + my_guy.apply_status_effect(/datum/status_effect/midas_blight, min(30 SECONDS, round(gold_charge, 0.2))) // 100u gives 10 seconds + return + +/obj/item/gun/magic/midas_hand/suicide_act(mob/living/user) + if(!ishuman(user)) + return + + var/mob/living/carbon/human/victim = user + victim.visible_message(span_suicide("[victim] holds the barrel of [src] to [victim.p_their()] head, lighting the fuse. It looks like [user.p_theyre()] trying to commit suicide!")) + if(!do_after(victim, 1.5 SECONDS)) + return + playsound(src, 'sound/weapons/gun/rifle/shot.ogg', 75, TRUE) + to_chat(victim, span_danger("You don't even have the time to register the gunshot by the time your body has completely converted into a golden statue.")) + var/newcolors = list(rgb(206, 164, 50), rgb(146, 146, 139), rgb(28,28,28), rgb(0,0,0)) + victim.petrify(statue_timer = INFINITY, save_brain = FALSE, colorlist = newcolors) + playsound(victim, 'sound/effects/coin2.ogg', 75, TRUE) + charges = 0 + gold_timer = 0 + return OXYLOSS diff --git a/code/modules/projectiles/guns/special/medbeam.dm b/code/modules/projectiles/guns/special/medbeam.dm index d3ee77ef3b3a31..267470f17013c4 100644 --- a/code/modules/projectiles/guns/special/medbeam.dm +++ b/code/modules/projectiles/guns/special/medbeam.dm @@ -144,10 +144,13 @@ /obj/item/gun/medbeam/proc/on_beam_tick(mob/living/target) if(target.health != target.maxHealth) new /obj/effect/temp_visual/heal(get_turf(target), COLOR_HEALING_CYAN) - target.adjustBruteLoss(-4) - target.adjustFireLoss(-4) - target.adjustToxLoss(-1, forced = TRUE) - target.adjustOxyLoss(-1, forced = TRUE) + var/need_mob_update + need_mob_update = target.adjustBruteLoss(-4, updating_health = FALSE, forced = TRUE) + need_mob_update += target.adjustFireLoss(-4, updating_health = FALSE, forced = TRUE) + need_mob_update += target.adjustToxLoss(-1, updating_health = FALSE, forced = TRUE) + need_mob_update += target.adjustOxyLoss(-1, updating_health = FALSE, forced = TRUE) + if(need_mob_update) + target.updatehealth() return /obj/item/gun/medbeam/proc/on_beam_release(mob/living/target) diff --git a/code/modules/projectiles/guns/special/syringe_gun.dm b/code/modules/projectiles/guns/special/syringe_gun.dm index 270bb8744cc22d..805378c1ffcc40 100644 --- a/code/modules/projectiles/guns/special/syringe_gun.dm +++ b/code/modules/projectiles/guns/special/syringe_gun.dm @@ -206,6 +206,6 @@ /obj/item/gun/syringe/blowgun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0) visible_message(span_danger("[user] shoots the blowgun!")) - user.adjustStaminaLoss(20) + user.adjustStaminaLoss(20, updating_stamina = FALSE) user.adjustOxyLoss(20) return ..() diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 2f5fa84c4419c5..7eb152d3e4a963 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -1161,13 +1161,17 @@ #undef MUZZLE_EFFECT_PIXEL_INCREMENT /// Fire a projectile from this atom at another atom -/atom/proc/fire_projectile(projectile_type, atom/target, sound, firer) +/atom/proc/fire_projectile(projectile_type, atom/target, sound, firer, list/ignore_targets = list()) if (!isnull(sound)) playsound(src, sound, vol = 100, vary = TRUE) var/turf/startloc = get_turf(src) var/obj/projectile/bullet = new projectile_type(startloc) bullet.starting = startloc + var/list/ignore = list() + for (var/atom/thing as anything in ignore_targets) + ignore[thing] = TRUE + bullet.impacted += ignore bullet.firer = firer || src bullet.fired_from = src bullet.yo = target.y - startloc.y @@ -1175,3 +1179,4 @@ bullet.original = target bullet.preparePixelProjectile(target, src) bullet.fire() + return bullet diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index e5c4d520d0e495..a7a5f83329a684 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -28,6 +28,16 @@ damage = 25 bare_wound_bonus = 40 +/obj/projectile/beam/laser/carbine + icon_state = "carbine_laser" + impact_effect_type = /obj/effect/temp_visual/impact_effect/yellow_laser + damage = 10 + +/obj/projectile/beam/laser/carbine/practice + name = "practice laser" + impact_effect_type = /obj/effect/temp_visual/impact_effect/yellow_laser + damage = 0 + //overclocked laser, does a bit more damage but has much higher wound power (-0 vs -20) /obj/projectile/beam/laser/hellfire name = "hellfire laser" diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 90a3d723bf5825..5e938c4995390b 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -12,7 +12,6 @@ wound_bonus = 0 wound_falloff_tile = -5 embed_falloff_tile = -3 - wound_bonus = 20 //SKYRAT EDIT ADDITION /obj/projectile/bullet/smite name = "divine retribution" diff --git a/code/modules/projectiles/projectile/bullets/pistol.dm b/code/modules/projectiles/projectile/bullets/pistol.dm index ece260f92fbdec..8fccc510ff8fda 100644 --- a/code/modules/projectiles/projectile/bullets/pistol.dm +++ b/code/modules/projectiles/projectile/bullets/pistol.dm @@ -42,3 +42,22 @@ name = "10mm incendiary bullet" damage = 20 fire_stacks = 3 + +/obj/projectile/bullet/c10mm/reaper + name = "10mm reaper pellet" + damage = 50 + armour_penetration = 40 + tracer_type = /obj/effect/projectile/tracer/sniper + impact_type = /obj/effect/projectile/impact/sniper + muzzle_type = /obj/effect/projectile/muzzle/sniper + hitscan = TRUE + impact_effect_type = null + hitscan_light_intensity = 3 + hitscan_light_range = 0.75 + hitscan_light_color_override = LIGHT_COLOR_DIM_YELLOW + muzzle_flash_intensity = 5 + muzzle_flash_range = 1 + muzzle_flash_color_override = LIGHT_COLOR_DIM_YELLOW + impact_light_intensity = 5 + impact_light_range = 1 + impact_light_color_override = LIGHT_COLOR_DIM_YELLOW diff --git a/code/modules/projectiles/projectile/special/rocket.dm b/code/modules/projectiles/projectile/special/rocket.dm index 899f737d8cc83f..08a2c18c2f73d6 100644 --- a/code/modules/projectiles/projectile/special/rocket.dm +++ b/code/modules/projectiles/projectile/special/rocket.dm @@ -53,7 +53,7 @@ among other potential differences. This granularity is helpful for things like t if(random_crit_gib) var/mob/living/gibbed_dude = target new /obj/effect/temp_visual/crit(get_turf(gibbed_dude)) - gibbed_dude.gib() + gibbed_dude.gib(DROP_ALL_REMAINS) /// PM9 HEAP rocket - the anti-anything missile you always craved. /obj/projectile/bullet/rocket/heap diff --git a/code/modules/reagents/chemistry/equilibrium.dm b/code/modules/reagents/chemistry/equilibrium.dm index 7d7aff20fae3e1..f46c636c50f59b 100644 --- a/code/modules/reagents/chemistry/equilibrium.dm +++ b/code/modules/reagents/chemistry/equilibrium.dm @@ -324,8 +324,8 @@ //keep limited if(delta_chem_factor > step_target_vol) delta_chem_factor = step_target_vol - else if (delta_chem_factor < CHEMICAL_VOLUME_MINIMUM) - delta_chem_factor = CHEMICAL_VOLUME_MINIMUM + else if (delta_chem_factor < CHEMICAL_QUANTISATION_LEVEL) + delta_chem_factor = CHEMICAL_QUANTISATION_LEVEL //Normalise to multiproducts delta_chem_factor /= product_ratio //delta_chem_factor = round(delta_chem_factor, CHEMICAL_QUANTISATION_LEVEL) // Might not be needed - left here incase testmerge shows that it does. Remove before full commit. diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index 902ccf35e6ac43..c72bfbb6c3ed79 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -1,136 +1,6 @@ -#define REAGENTS_UI_MODE_LOOKUP 0 -#define REAGENTS_UI_MODE_REAGENT 1 -#define REAGENTS_UI_MODE_RECIPE 2 - #define REAGENT_TRANSFER_AMOUNT "amount" #define REAGENT_PURITY "purity" -/// Initialises all /datum/reagent into a list indexed by reagent id -/proc/init_chemical_reagent_list() - var/list/reagent_list = list() - - var/paths = subtypesof(/datum/reagent) - - for(var/path in paths) - if(path in GLOB.fake_reagent_blacklist) - continue - var/datum/reagent/D = new path() - D.mass = rand(10, 800) //This is terrible and should be removed ASAP! - reagent_list[path] = D - - return reagent_list - -/// Creates an list which is indexed by reagent name . used by plumbing reaction chamber and chemical filter UI -/proc/init_chemical_name_list() - var/list/name_list = list() - for(var/X in GLOB.chemical_reagents_list) - var/datum/reagent/Reagent = GLOB.chemical_reagents_list[X] - name_list += Reagent.name - return sort_list(name_list) - - -/proc/build_chemical_reactions_lists() - //Chemical Reactions - Initialises all /datum/chemical_reaction into a list - // It is filtered into multiple lists within a list. - // For example: - // chemical_reactions_list_reactant_index[/datum/reagent/toxin/plasma] is a list of all reactions relating to plasma - //For chemical reaction list product index - indexes reactions based off the product reagent type - see get_recipe_from_reagent_product() in helpers - //For chemical reactions list lookup list - creates a bit list of info passed to the UI. This is saved to reduce lag from new windows opening, since it's a lot of data. - - //Prevent these reactions from appearing in lookup tables (UI code) - var/list/blacklist = typecacheof(/datum/chemical_reaction/randomized) - - if(GLOB.chemical_reactions_list_reactant_index) - return - - //Randomized need to go last since they need to check against conflicts with normal recipes - var/paths = subtypesof(/datum/chemical_reaction) - typesof(/datum/chemical_reaction/randomized) + subtypesof(/datum/chemical_reaction/randomized) - GLOB.chemical_reactions_list = list() //typepath to reaction list - GLOB.chemical_reactions_list_reactant_index = list() //reagents to reaction list - GLOB.chemical_reactions_results_lookup_list = list() //UI glob - GLOB.chemical_reactions_list_product_index = list() //product to reaction list - - var/list/datum/chemical_reaction/reactions = list() - for(var/path in paths) - var/datum/chemical_reaction/reaction = new path() - reactions += reaction - - // Ok so we're gonna do a thingTM here - // I want to distribute all our reactions such that each reagent id links to as few as possible - // I get the feeling there's a canonical way of doing this, but I don't know it - // So instead, we're gonna wing it - var/list/reagent_to_react_count = list() - for(var/datum/chemical_reaction/reaction as anything in reactions) - for(var/reagent_id as anything in reaction.required_reagents) - reagent_to_react_count[reagent_id] += 1 - - var/list/reaction_lookup = GLOB.chemical_reactions_list_reactant_index - // Create filters based on a random reagent id in the required reagents list - this is used to speed up handle_reactions() - // Basically, we only really need to care about ONE reagent, at least when initially filtering, since any others are ignorable - // Doing this separately because it relies on the loop above, and this is easier to parse - for(var/datum/chemical_reaction/reaction as anything in reactions) - var/preferred_id = null - for(var/reagent_id as anything in reaction.required_reagents) - if(!preferred_id) - preferred_id = reagent_id - continue - // If we would have less then they would, take it - if(length(reaction_lookup[reagent_id]) < length(reaction_lookup[preferred_id])) - preferred_id = reagent_id - continue - // If they potentially have more then us, we take it - if(reagent_to_react_count[reagent_id] < reagent_to_react_count[preferred_id]) - preferred_id = reagent_id - continue - if (preferred_id != null) - if(!reaction_lookup[preferred_id]) - reaction_lookup[preferred_id] = list() - reaction_lookup[preferred_id] += reaction - - for(var/datum/chemical_reaction/reaction as anything in reactions) - var/list/product_ids = list() - var/list/reagents = list() - var/list/product_names = list() - var/bitflags = reaction.reaction_tags - - if(!reaction.required_reagents || !reaction.required_reagents.len) //Skip impossible reactions - continue - - GLOB.chemical_reactions_list[reaction.type] = reaction - - for(var/reagent_path in reaction.required_reagents) - var/datum/reagent/reagent = find_reagent_object_from_type(reagent_path) - if(!istype(reagent)) - stack_trace("Invalid reagent found in [reaction] required_reagents: [reagent_path]") - continue - reagents += list(list("name" = reagent.name, "id" = reagent.type)) - - for(var/product in reaction.results) - var/datum/reagent/reagent = find_reagent_object_from_type(product) - if(!istype(reagent)) - stack_trace("Invalid reagent found in [reaction] results: [product]") - continue - product_names += reagent.name - product_ids += product - - var/product_name - if(!length(product_names)) - var/list/names = splittext("[reaction.type]", "/") - product_name = names[names.len] - else - product_name = product_names[1] - - if(!is_type_in_typecache(reaction.type, blacklist)) - //Master list of ALL reactions that is used in the UI lookup table. This is expensive to make, and we don't want to lag the server by creating it on UI request, so it's cached to send to UIs instantly. - GLOB.chemical_reactions_results_lookup_list += list(list("name" = product_name, "id" = reaction.type, "bitflags" = bitflags, "reactants" = reagents)) - - // Create filters based on each reagent id in the required reagents list - this is specifically for finding reactions from product(reagent) ids/typepaths. - for(var/id in product_ids) - if(!GLOB.chemical_reactions_list_product_index[id]) - GLOB.chemical_reactions_list_product_index[id] = list() - GLOB.chemical_reactions_list_product_index[id] += reaction - - ///////////////////////////////Main reagents code///////////////////////////////////////////// /// Holder for a bunch of [/datum/reagent] @@ -147,8 +17,6 @@ var/chem_temp = 150 ///pH of the whole system var/ph = CHEMICAL_NORMAL_PH - /// unused - var/last_tick = 1 /// various flags, see code\__DEFINES\reagents.dm var/flags ///list of reactions currently on going, this is a lazylist for optimisation @@ -171,7 +39,7 @@ ///If we're syncing with the beaker - so return reactions that are actively happening var/ui_beaker_sync = FALSE -/datum/reagents/New(maximum=100, new_flags=0) +/datum/reagents/New(maximum = 100, new_flags = 0) maximum_volume = maximum flags = new_flags @@ -203,21 +71,36 @@ * * override_base_ph - ingore the present pH of the reagent, and instead use the default (i.e. if buffers/reactions alter it) * * ignore splitting - Don't call the process that handles reagent spliting in a mob (impure/inverse) - generally leave this false unless you care about REAGENTS_DONOTSPLIT flags (see reagent defines) */ -/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = DEFAULT_REAGENT_TEMPERATURE, added_purity = null, added_ph, no_react = FALSE, override_base_ph = FALSE, ignore_splitting = FALSE) - // Prevents small amount problems, as well as zero and below zero amounts. - if(amount <= CHEMICAL_QUANTISATION_LEVEL) +/datum/reagents/proc/add_reagent( + datum/reagent/reagent_type, + amount, + list/data = null, + reagtemp = DEFAULT_REAGENT_TEMPERATURE, + added_purity = null, + added_ph, + no_react = FALSE, + override_base_ph = FALSE, + ignore_splitting = FALSE +) + if(!ispath(reagent_type)) + stack_trace("invalid reagent passed to add reagent [reagent_type]") return FALSE if(!IS_FINITE(amount)) - stack_trace("non finite amount passed to add reagent [amount] [reagent]") + stack_trace("non finite amount passed to add reagent [amount] [reagent_type]") return FALSE - if(SEND_SIGNAL(src, COMSIG_REAGENTS_PRE_ADD_REAGENT, reagent, amount, reagtemp, data, no_react) & COMPONENT_CANCEL_REAGENT_ADD) + if(SEND_SIGNAL(src, COMSIG_REAGENTS_PRE_ADD_REAGENT, reagent_type, amount, reagtemp, data, no_react) & COMPONENT_CANCEL_REAGENT_ADD) return FALSE - var/datum/reagent/glob_reagent = GLOB.chemical_reagents_list[reagent] + // Prevents small amount problems, as well as zero and below zero amounts. + amount = FLOOR(amount, CHEMICAL_QUANTISATION_LEVEL) + if(amount <= 0) + return FALSE + + var/datum/reagent/glob_reagent = GLOB.chemical_reagents_list[reagent_type] if(!glob_reagent) - stack_trace("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])") + stack_trace("[my_atom] attempted to add a reagent called '[reagent_type]' which doesn't exist. ([usr])") return FALSE if(isnull(added_purity)) //Because purity additions can be 0 added_purity = glob_reagent.creation_purity //Usually 1 @@ -227,8 +110,8 @@ //Split up the reagent if it's in a mob var/has_split = FALSE if(!ignore_splitting && (flags & REAGENT_HOLDER_ALIVE)) //Stomachs are a pain - they will constantly call on_mob_add unless we split on addition to stomachs, but we also want to make sure we don't double split - var/adjusted_vol = process_mob_reagent_purity(glob_reagent, amount, added_purity) - if(!adjusted_vol) //If we're inverse or FALSE cancel addition + var/adjusted_vol = FLOOR(process_mob_reagent_purity(glob_reagent, amount, added_purity), CHEMICAL_QUANTISATION_LEVEL) + if(adjusted_vol <= 0) //If we're inverse or FALSE cancel addition return TRUE /* We return true here because of #63301 The only cases where this will be false or 0 if its an inverse chem, an impure chem of 0 purity (highly unlikely if even possible), or if glob_reagent is null (which shouldn't happen at all as there's a check for that a few lines up), @@ -240,7 +123,7 @@ update_total() var/cached_total = total_volume if(cached_total + amount > maximum_volume) - amount = (maximum_volume - cached_total) //Doesnt fit in. Make it disappear. shouldn't happen. Will happen. + amount = FLOOR(maximum_volume - cached_total, CHEMICAL_QUANTISATION_LEVEL) //Doesnt fit in. Make it disappear. shouldn't happen. Will happen. if(amount <= 0) return FALSE @@ -255,13 +138,13 @@ //add the reagent to the existing if it exists for(var/datum/reagent/iter_reagent as anything in cached_reagents) - if(iter_reagent.type == reagent) + if(iter_reagent.type == reagent_type) if(override_base_ph) added_ph = iter_reagent.ph iter_reagent.purity = ((iter_reagent.creation_purity * iter_reagent.volume) + (added_purity * amount)) /(iter_reagent.volume + amount) //This should add the purity to the product iter_reagent.creation_purity = iter_reagent.purity iter_reagent.ph = ((iter_reagent.ph*(iter_reagent.volume))+(added_ph*amount))/(iter_reagent.volume+amount) - iter_reagent.volume += round(amount, CHEMICAL_QUANTISATION_LEVEL) + iter_reagent.volume = FLOOR(iter_reagent.volume + amount, CHEMICAL_QUANTISATION_LEVEL) update_total() iter_reagent.on_merge(data, amount) @@ -278,7 +161,7 @@ return TRUE //otherwise make a new one - var/datum/reagent/new_reagent = new reagent(data) + var/datum/reagent/new_reagent = new reagent_type(data) cached_reagents += new_reagent new_reagent.holder = src new_reagent.volume = amount @@ -306,40 +189,68 @@ handle_reactions() return TRUE -/// Like add_reagent but you can enter a list. Format it like this: list(/datum/reagent/toxin = 10, "beer" = 15) -/datum/reagents/proc/add_reagent_list(list/list_reagents, list/data=null) +/** + * Like add_reagent but you can enter a list. + * Arguments + * + * * [list_reagents][list] - list to add. Format it like this: list(/datum/reagent/toxin = 10, "beer" = 15) + * * [data][list] - additional data to add + */ +/datum/reagents/proc/add_reagent_list(list/list_reagents, list/data = null) for(var/r_id in list_reagents) var/amt = list_reagents[r_id] add_reagent(r_id, amt, data) -/// Remove a specific reagent -/datum/reagents/proc/remove_reagent(reagent, amount, safety = TRUE)//Added a safety check for the trans_id_to - if(isnull(amount)) - stack_trace("null amount passed to reagent code") +/** + * Removes a specific reagent. can supress reactions if needed + * Arguments + * + * * [reagent_type][datum/reagent] - the type of reagent + * * amount - the volume to remove + * * safety - if FALSE will initiate reactions upon removing. used for trans_id_to + */ +/datum/reagents/proc/remove_reagent(datum/reagent/reagent_type, amount, safety = TRUE) + if(!ispath(reagent_type)) + stack_trace("invalid reagent passed to remove reagent [reagent_type]") + return FALSE + + if(!IS_FINITE(amount)) + stack_trace("non finite amount passed to remove reagent [amount] [reagent_type]") return FALSE - if(amount < 0 || !IS_FINITE(amount)) - stack_trace("invalid number passed to remove_reagent [amount]") + // Prevents small amount problems, as well as zero and below zero amounts. + amount = FLOOR(amount, CHEMICAL_QUANTISATION_LEVEL) + if(amount <= 0) return FALSE var/list/cached_reagents = reagent_list for(var/datum/reagent/cached_reagent as anything in cached_reagents) - if(cached_reagent.type == reagent) - //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, cached_reagent.volume) - cached_reagent.volume -= amount + if(cached_reagent.type == reagent_type) + cached_reagent.volume = FLOOR(max(cached_reagent.volume - amount, 0), CHEMICAL_QUANTISATION_LEVEL) update_total() if(!safety)//So it does not handle reactions when it need not to handle_reactions() - SEND_SIGNAL(src, COMSIG_REAGENTS_REM_REAGENT, QDELING(cached_reagent) ? reagent : cached_reagent, amount) + SEND_SIGNAL(src, COMSIG_REAGENTS_REM_REAGENT, QDELING(cached_reagent) ? reagent_type : cached_reagent, amount) return TRUE return FALSE -/// Remove an amount of reagents without caring about what they are +/** + * Removes a reagent at random by the specified amount + * Arguments + * + * * amount- the volume to remove + */ /datum/reagents/proc/remove_any(amount = 1) + if(!IS_FINITE(amount)) + stack_trace("non finite amount passed to remove any reagent [amount]") + return FALSE + + amount = FLOOR(amount, CHEMICAL_QUANTISATION_LEVEL) + if(amount <= 0) + return FALSE + var/list/cached_reagents = reagent_list var/total_removed = 0 var/current_list_element = 1 @@ -356,10 +267,10 @@ if(current_list_element > cached_reagents.len) current_list_element = 1 - var/datum/reagent/R = cached_reagents[current_list_element] - var/remove_amt = min(amount-total_removed,round(amount/rand(2,initial_list_length),round(amount/10,0.01))) //double round to keep it at a somewhat even spread relative to amount without getting funky numbers. + var/datum/reagent/target_holder = cached_reagents[current_list_element] + var/remove_amt = min(amount - total_removed, round(amount / rand(2, initial_list_length), round(amount / 10, 0.01))) //double round to keep it at a somewhat even spread relative to amount without getting funky numbers. //min ensures we don't go over amount. - remove_reagent(R.type, remove_amt) + remove_reagent(target_holder.type, remove_amt) current_list_element++ total_removed += remove_amt @@ -368,22 +279,62 @@ handle_reactions() return total_removed //this should be amount unless the loop is prematurely broken, in which case it'll be lower. It shouldn't ever go OVER amount. -/// Removes all reagents from this holder +/** + * Removes all reagents by an amount equal to + * [amount specified] / total volume present in this holder + * Arguments + * + * * amount - the volume of each reagent + */ + /datum/reagents/proc/remove_all(amount = 1) + if(!total_volume) + return FALSE + + if(!IS_FINITE(amount)) + stack_trace("non finite amount passed to remove all reagents [amount]") + return FALSE + + // Prevents small amount problems, as well as zero and below zero amounts. + amount = FLOOR(amount, CHEMICAL_QUANTISATION_LEVEL) + if(amount <= 0) + return FALSE + var/list/cached_reagents = reagent_list - if(total_volume > 0) - var/part = amount / total_volume - for(var/datum/reagent/reagent as anything in cached_reagents) - remove_reagent(reagent.type, reagent.volume * part) + var/part = amount / total_volume + var/remove_amount + var/removed_amount = 0 - //finish_reacting() //A just in case - update total is in here - should be unneeded, make sure to test this - handle_reactions() - return amount + for(var/datum/reagent/reagent as anything in cached_reagents) + remove_amount = FLOOR(reagent.volume * part, CHEMICAL_QUANTISATION_LEVEL) + remove_reagent(reagent.type, remove_amount) + removed_amount += remove_amount + + handle_reactions() + return removed_amount + +/** + * Removes all reagent of X type + * Arguments + * + * * [reagent_type][datum/reagent] - the reagent typepath we are trying to remove + * * amount - the volume of reagent to remove + * * strict - If TRUE will also remove childs of this reagent type + */ +/datum/reagents/proc/remove_all_type(datum/reagent/reagent_type, amount, strict = 0, safety = 1) + if(!ispath(reagent_type)) + stack_trace("invalid reagent path passed to remove all type [reagent_type]") + return FALSE + + if(!IS_FINITE(amount)) + stack_trace("non finite amount passed to remove all type reagent [amount] [reagent_type]") + return FALSE + + // Prevents small amount problems, as well as zero and below zero amounts. + amount = FLOOR(amount, CHEMICAL_QUANTISATION_LEVEL) + if(amount <= 0) + return FALSE -/// Removes all reagent of X type. @strict set to 1 determines whether the childs of the type are included. -/datum/reagents/proc/remove_all_type(reagent_type, amount, strict = 0, safety = 1) - if(!isnum(amount)) - return 1 var/list/cached_reagents = reagent_list var/has_removed_reagent = 0 @@ -403,37 +354,58 @@ return has_removed_reagent -/// Fuck this one reagent -/datum/reagents/proc/del_reagent(target_reagent_typepath) +/** + * Removes an specific reagent from this holder + * Arguments + * + * * [target_reagent_typepath][datum/reagent] - type typepath of the reagent to remove + */ +/datum/reagents/proc/del_reagent(datum/reagent/target_reagent_typepath) + if(!ispath(target_reagent_typepath)) + stack_trace("invalid reagent path passed to del reagent [target_reagent_typepath]") + return FALSE + + //setting the volume to 0 will allow update_total() to clear it up for us var/list/cached_reagents = reagent_list for(var/datum/reagent/reagent as anything in cached_reagents) if(reagent.type == target_reagent_typepath) - if(isliving(my_atom)) - if(reagent.metabolizing) - reagent.metabolizing = FALSE - reagent.on_mob_end_metabolize(my_atom) - reagent.on_mob_delete(my_atom) - - reagent_list -= reagent - LAZYREMOVE(previous_reagent_list, reagent.type) - qdel(reagent) + reagent.volume = 0 update_total() - SEND_SIGNAL(src, COMSIG_REAGENTS_DEL_REAGENT, reagent) - return TRUE + return TRUE + + return FALSE + +/** + * Turn one reagent into another, preserving volume, temp, purity, ph + * Arguments + * + * * [source_reagent_typepath][/datum/reagent] - the typepath of the reagent you are trying to convert + * * [target_reagent_typepath][/datum/reagent] - the final typepath the source_reagent_typepath will be converted into + * * multiplier - the multiplier applied on the source_reagent_typepath volume before converting + * * include_source_subtypes- if TRUE will convert all subtypes of source_reagent_typepath into target_reagent_typepath as well + */ +/datum/reagents/proc/convert_reagent( + datum/reagent/source_reagent_typepath, + datum/reagent/target_reagent_typepath, + multiplier = 1, + include_source_subtypes = FALSE +) + if(!ispath(source_reagent_typepath)) + stack_trace("invalid reagent path passed to convert reagent [source_reagent_typepath]") + return FALSE -/// Turn one reagent into another, preserving volume, temp, purity, ph -/datum/reagents/proc/convert_reagent(source_reagent_typepath, target_reagent_typepath, multiplier = 1, include_source_subtypes = FALSE) var/reagent_amount var/reagent_purity var/reagent_ph if(include_source_subtypes) reagent_ph = ph var/weighted_purity + var/list/reagent_type_list = typecacheof(source_reagent_typepath) for(var/datum/reagent/reagent as anything in reagent_list) - if(reagent.type in typecacheof(source_reagent_typepath)) + if(reagent.type in reagent_type_list) weighted_purity += reagent.volume * reagent.purity reagent_amount += reagent.volume - remove_reagent(reagent.type, reagent.volume) + remove_reagent(reagent.type, reagent.volume * multiplier) reagent_purity = weighted_purity / reagent_amount else var/datum/reagent/source_reagent = get_reagent(source_reagent_typepath) @@ -443,40 +415,40 @@ remove_reagent(source_reagent_typepath, reagent_amount) add_reagent(target_reagent_typepath, reagent_amount * multiplier, reagtemp = chem_temp, added_purity = reagent_purity, added_ph = reagent_ph) -//Converts the creation_purity to purity -/datum/reagents/proc/uncache_creation_purity(id) - var/datum/reagent/R = has_reagent(id) - if(!R) - return - R.purity = R.creation_purity - -/// Remove every reagent except this one -/datum/reagents/proc/isolate_reagent(reagent) - var/list/cached_reagents = reagent_list - for(var/datum/reagent/cached_reagent as anything in cached_reagents) - if(cached_reagent.type != reagent) - del_reagent(cached_reagent.type) - update_total() - /// Removes all reagents /datum/reagents/proc/clear_reagents() var/list/cached_reagents = reagent_list + + //setting volume to 0 will allow update_total() to clean it up for(var/datum/reagent/reagent as anything in cached_reagents) - del_reagent(reagent.type) - SEND_SIGNAL(src, COMSIG_REAGENTS_CLEAR_REAGENTS) + reagent.volume = 0 + update_total() + SEND_SIGNAL(src, COMSIG_REAGENTS_CLEAR_REAGENTS) /** - * Check if this holder contains this reagent. - * Reagent takes a PATH to a reagent. - * Amount checks for having a specific amount of that chemical. - * Needs matabolizing takes into consideration if the chemical is matabolizing when it's checked. - * Check subtypes controls whether it should it should also include subtypes: ispath(type, reagent) versus type == reagent. + * Check if this holder contains this reagent. Reagent takes a PATH to a reagent + * Needs matabolizing takes into consideration if the chemical is metabolizing when it's checked. + * Arguments + * + * * [target_reagent][datum/reagent] - the reagent typepath to check for + * * amount - checks for having a specific amount of that chemical + * * needs_metabolizing - takes into consideration if the chemical is matabolizing when it's checked. + * * check_subtypes - controls whether it should it should also include subtypes: ispath(type, reagent) versus type == reagent. */ -/datum/reagents/proc/has_reagent(reagent, amount = -1, needs_metabolizing = FALSE, check_subtypes = FALSE) +/datum/reagents/proc/has_reagent( + datum/reagent/target_reagent, + amount = -1, + needs_metabolizing = FALSE, + check_subtypes = FALSE +) + if(!ispath(target_reagent)) + stack_trace("invalid reagent path passed to has reagent [target_reagent]") + return FALSE + var/list/cached_reagents = reagent_list for(var/datum/reagent/holder_reagent as anything in cached_reagents) - if (check_subtypes ? ispath(holder_reagent.type, reagent) : holder_reagent.type == reagent) + if (check_subtypes ? ispath(holder_reagent.type, target_reagent) : holder_reagent.type == target_reagent) if(!amount) if(needs_metabolizing && !holder_reagent.metabolizing) if(check_subtypes) @@ -484,7 +456,7 @@ return FALSE return holder_reagent else - if(round(holder_reagent.volume, CHEMICAL_QUANTISATION_LEVEL) >= amount) + if(holder_reagent.volume >= amount) if(needs_metabolizing && !holder_reagent.metabolizing) if(check_subtypes) continue @@ -497,7 +469,10 @@ /** * Check if this holder contains a reagent with a chemical_flags containing this flag * Reagent takes the bitflag to search for - * Amount checks for having a specific amount of reagents matching that chemical + * + * Arguments + * * chemical_flag - the flag to check for + * * amount - checks for having a specific amount of reagents matching that chemical */ /datum/reagents/proc/has_chemical_flag(chemical_flag, amount = 0) var/found_amount = 0 @@ -521,140 +496,156 @@ * * no_react - passed through to [/datum/reagents/proc/add_reagent] * * mob/transferred_by - used for logging * * remove_blacklisted - skips transferring of reagents without REAGENT_CAN_BE_SYNTHESIZED in chemical_flags - * * methods - passed through to [/datum/reagents/proc/expose_single] and [/datum/reagent/proc/on_transfer] - * * show_message - passed through to [/datum/reagents/proc/expose_single] - * * round_robin - if round_robin=TRUE, so transfer 5 from 15 water, 15 sugar and 15 plasma becomes 10, 15, 15 instead of 13.3333, 13.3333 13.3333. Good if you hate floating point errors + * * methods - passed through to [/datum/reagents/proc/expose_multiple] and [/datum/reagent/proc/on_transfer] + * * show_message - passed through to [/datum/reagents/proc/expose_multiple] * * ignore_stomach - when using methods INGEST will not use the stomach as the target */ -/datum/reagents/proc/trans_to(obj/target, amount = 1, multiplier = 1, preserve_data = TRUE, no_react = FALSE, mob/transferred_by, remove_blacklisted = FALSE, methods = NONE, show_message = TRUE, round_robin = FALSE, ignore_stomach = FALSE) - var/list/cached_reagents = reagent_list - if(!target || !total_volume) - return - if(amount < 0) +/datum/reagents/proc/trans_to( + obj/target, + amount = 1, + multiplier = 1, + preserve_data = TRUE, + no_react = FALSE, + mob/transferred_by, + remove_blacklisted = FALSE, + methods = NONE, + show_message = TRUE, + ignore_stomach = FALSE +) + if(QDELETED(target) || !total_volume) return - var/cached_amount = amount + if(!IS_FINITE(amount)) + stack_trace("non finite amount passed to trans_to [amount] amount of reagents") + return FALSE + + var/list/cached_reagents = reagent_list + var/atom/target_atom - var/datum/reagents/R + var/datum/reagents/target_holder if(istype(target, /datum/reagents)) - R = target - target_atom = R.my_atom + target_holder = target + target_atom = target_holder.my_atom else if(!ignore_stomach && (methods & INGEST) && iscarbon(target)) var/mob/living/carbon/eater = target var/obj/item/organ/internal/stomach/belly = eater.get_organ_slot(ORGAN_SLOT_STOMACH) if(!belly) - eater.expel_ingested(my_atom, amount) + var/expel_amount = FLOOR(amount, CHEMICAL_QUANTISATION_LEVEL) + if(expel_amount > 0 ) + eater.expel_ingested(my_atom, expel_amount) return - R = belly.reagents + target_holder = belly.reagents target_atom = belly else if(!target.reagents) return else - R = target.reagents + target_holder = target.reagents target_atom = target + var/cached_amount = amount + + // Prevents small amount problems, as well as zero and below zero amounts. + amount = FLOOR(min(amount * multiplier, total_volume, target_holder.maximum_volume - target_holder.total_volume), CHEMICAL_QUANTISATION_LEVEL) + if(amount <= 0) + return FALSE + //Set up new reagents to inherit the old ongoing reactions if(!no_react) - transfer_reactions(R) + transfer_reactions(target_holder) - amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume) var/trans_data = null - var/transfer_log = list() - var/r_to_send = list() // Validated list of reagents to be exposed - var/reagents_to_remove = list() - if(!round_robin) - var/part = amount / src.total_volume - for(var/datum/reagent/reagent as anything in cached_reagents) - if(remove_blacklisted && !(reagent.chemical_flags & REAGENT_CAN_BE_SYNTHESIZED)) - continue - var/transfer_amount = reagent.volume * part - if(preserve_data) - trans_data = copy_data(reagent) - if(reagent.intercept_reagents_transfer(R, cached_amount))//Use input amount instead. - continue - if(!R.add_reagent(reagent.type, transfer_amount * multiplier, trans_data, chem_temp, reagent.purity, reagent.ph, no_react = TRUE, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT)) //we only handle reaction after every reagent has been transferred. - continue - if(methods) - r_to_send += reagent + var/list/transfer_log = list() + var/list/r_to_send = list() // Validated list of reagents to be exposed + var/list/reagents_to_remove = list() - reagents_to_remove += reagent - - if(isorgan(target_atom)) - R.expose_multiple(r_to_send, target, methods, part, show_message) - else - R.expose_multiple(r_to_send, target_atom, methods, part, show_message) - - for(var/datum/reagent/reagent as anything in reagents_to_remove) - var/transfer_amount = reagent.volume * part - if(methods) - reagent.on_transfer(target_atom, methods, transfer_amount * multiplier) - remove_reagent(reagent.type, transfer_amount) - var/list/reagent_qualities = list(REAGENT_TRANSFER_AMOUNT = transfer_amount, REAGENT_PURITY = reagent.purity) - transfer_log[reagent.type] = reagent_qualities + var/part = amount / total_volume + var/transfer_amount + var/transfered_amount = 0 - else - var/to_transfer = amount - for(var/datum/reagent/reagent as anything in cached_reagents) - if(!to_transfer) - break - if(remove_blacklisted && !(reagent.chemical_flags & REAGENT_CAN_BE_SYNTHESIZED)) - continue - if(preserve_data) - trans_data = copy_data(reagent) - var/transfer_amount = amount - if(amount > reagent.volume) - transfer_amount = reagent.volume - if(reagent.intercept_reagents_transfer(R, cached_amount))//Use input amount instead. - continue - if(!R.add_reagent(reagent.type, transfer_amount * multiplier, trans_data, chem_temp, reagent.purity, reagent.ph, no_react = TRUE, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT)) //we only handle reaction after every reagent has been transferred. - continue - to_transfer = max(to_transfer - transfer_amount , 0) - if(methods) - if(isorgan(target_atom)) - R.expose_single(reagent, target, methods, transfer_amount, show_message) - else - R.expose_single(reagent, target_atom, methods, transfer_amount, show_message) - reagent.on_transfer(target_atom, methods, transfer_amount * multiplier) - remove_reagent(reagent.type, transfer_amount) - var/list/reagent_qualities = list(REAGENT_TRANSFER_AMOUNT = transfer_amount, REAGENT_PURITY = reagent.purity) - transfer_log[reagent.type] = reagent_qualities + //first add reagents to target + for(var/datum/reagent/reagent as anything in cached_reagents) + if(remove_blacklisted && !(reagent.chemical_flags & REAGENT_CAN_BE_SYNTHESIZED)) + continue + if(preserve_data) + trans_data = copy_data(reagent) + if(reagent.intercept_reagents_transfer(target_holder, cached_amount)) + continue + transfer_amount = FLOOR(reagent.volume * part, CHEMICAL_QUANTISATION_LEVEL) + if(!target_holder.add_reagent(reagent.type, transfer_amount, trans_data, chem_temp, reagent.purity, reagent.ph, no_react = TRUE, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT)) //we only handle reaction after every reagent has been transferred. + continue + if(methods) + r_to_send += reagent + reagents_to_remove += list(list("R" = reagent, "T" = transfer_amount)) + transfered_amount += transfer_amount + + //expose target to reagent changes + target_holder.expose_multiple(r_to_send, isorgan(target_atom) ? target : target_atom, methods, part, show_message) + + //remove chemicals that were added above + for(var/list/data as anything in reagents_to_remove) + var/datum/reagent/reagent = data["R"] + transfer_amount = data["T"] + if(methods) + reagent.on_transfer(target_atom, methods, transfer_amount) + remove_reagent(reagent.type, transfer_amount) + transfer_log[reagent.type] = list(REAGENT_TRANSFER_AMOUNT = transfer_amount, REAGENT_PURITY = reagent.purity) if(transferred_by && target_atom) target_atom.add_hiddenprint(transferred_by) //log prints so admins can figure out who touched it last. log_combat(transferred_by, target_atom, "transferred reagents ([get_external_reagent_log_string(transfer_log)]) from [my_atom] to") update_total() - R.update_total() + target_holder.update_total() if(!no_react) - R.handle_reactions() + target_holder.handle_reactions() src.handle_reactions() - return amount + return transfered_amount -/// Transfer a specific reagent id to the target object -/datum/reagents/proc/trans_id_to(obj/target, reagent, amount=1, preserve_data=1)//Not sure why this proc didn't exist before. It does now! /N - var/list/cached_reagents = reagent_list - if (!target) +/** + * Transfer a specific reagent id to the target object + * Arguments + * + * * [target][obj] - the target to transfer reagents to + * * [reagent_type][datum/reagent] - the type of reagent to transfer to the target + * * amount - volume to transfer + * * preserve_data- if TRUE reagent user data will remain preserved + */ +/datum/reagents/proc/trans_id_to( + obj/target, + datum/reagent/reagent_type, + amount = 1, + preserve_data = 1 +) + if (QDELETED(target) || !total_volume) return + if(!IS_FINITE(amount)) + stack_trace("non finite amount passed to trans_id_to [amount] [reagent_type]") + return FALSE + + var/cached_amount = amount + + var/available_volume = get_reagent_amount(reagent_type) var/datum/reagents/holder if(istype(target, /datum/reagents)) holder = target - else if(target.reagents && total_volume > 0 && get_reagent_amount(reagent)) + else if(target.reagents && available_volume) holder = target.reagents else return - if(amount < 0) + + // Prevents small amount problems, as well as zero and below zero amounts. + amount = FLOOR(min(amount, available_volume, holder.maximum_volume - holder.total_volume), CHEMICAL_QUANTISATION_LEVEL) + if(amount <= 0) return - var/cached_amount = amount - if(get_reagent_amount(reagent) < amount) - amount = get_reagent_amount(reagent) - amount = min(round(amount, CHEMICAL_VOLUME_ROUNDING), holder.maximum_volume - holder.total_volume) + var/list/cached_reagents = reagent_list + var/trans_data = null for (var/looping_through_reagents in cached_reagents) var/datum/reagent/current_reagent = looping_through_reagents - if(current_reagent.type == reagent) + if(current_reagent.type == reagent_type) if(preserve_data) trans_data = current_reagent.data if(current_reagent.intercept_reagents_transfer(holder, cached_amount))//Use input amount instead. @@ -669,12 +660,29 @@ holder.handle_reactions() return amount -/// Copies the reagents to the target object -/datum/reagents/proc/copy_to(obj/target, amount = 1, multiplier = 1, preserve_data = TRUE, no_react = FALSE) - var/list/cached_reagents = reagent_list - if(!target || !total_volume) +/** + * Copies the reagents to the target object + * Arguments + * + * * [target][obj] - the target to transfer reagents to + * * multiplier - the multiplier applied on all reagent volumes before transfering + * * preserve_data - preserve user data of all reagents after transfering + * * no_react - if TRUE will not handle reactions + */ +/datum/reagents/proc/copy_to( + atom/target, + amount = 1, + multiplier = 1, + preserve_data = TRUE, + no_react = FALSE +) + if(QDELETED(target) || !total_volume) return + if(!IS_FINITE(amount)) + stack_trace("non finite amount passed to copy_to [amount] amount of reagents") + return FALSE + var/datum/reagents/target_holder if(istype(target, /datum/reagents)) target_holder = target @@ -683,17 +691,24 @@ return target_holder = target.reagents - if(amount < 0) + // Prevents small amount problems, as well as zero and below zero amounts. + amount = FLOOR(min(amount * multiplier, total_volume, target_holder.maximum_volume - target_holder.total_volume), CHEMICAL_QUANTISATION_LEVEL) + if(amount <= 0) return - amount = min(min(amount, total_volume), target_holder.maximum_volume - target_holder.total_volume) + var/list/cached_reagents = reagent_list var/part = amount / total_volume + var/transfer_amount + var/transfered_amount = 0 var/trans_data = null + for(var/datum/reagent/reagent as anything in cached_reagents) - var/copy_amount = reagent.volume * part + transfer_amount = FLOOR(reagent.volume * part, CHEMICAL_QUANTISATION_LEVEL) if(preserve_data) trans_data = reagent.data - target_holder.add_reagent(reagent.type, copy_amount * multiplier, trans_data, chem_temp, reagent.purity, reagent.ph, no_react = TRUE, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT) + if(!target_holder.add_reagent(reagent.type, transfer_amount, trans_data, chem_temp, reagent.purity, reagent.ph, no_react = TRUE, ignore_splitting = reagent.chemical_flags & REAGENT_DONOTSPLIT)) + continue + transfered_amount += transfer_amount if(!no_react) // pass over previous ongoing reactions before handle_reactions is called @@ -702,10 +717,14 @@ target_holder.update_total() target_holder.handle_reactions() - return amount + return transfered_amount -///Multiplies the reagents inside this holder by a specific amount -/datum/reagents/proc/multiply_reagents(multiplier=1) +/** + * Multiplies the reagents inside this holder by a specific amount + * Arguments + * * multiplier - the amount to multiply each reagent by + */ +/datum/reagents/proc/multiply_reagents(multiplier = 1) var/list/cached_reagents = reagent_list if(!total_volume) return @@ -784,9 +803,9 @@ // skip metabolizing effects for small units of toxins if(istype(reagent, /datum/reagent/toxin) && liver && !dead) var/datum/reagent/toxin/toxin = reagent - var/amount = round(toxin.volume, CHEMICAL_QUANTISATION_LEVEL) + var/amount = toxin.volume if(belly) - amount += belly.reagents.get_reagent_amount(toxin.type) + amount = FLOOR(amount + belly.reagents.get_reagent_amount(toxin.type), CHEMICAL_QUANTISATION_LEVEL) if(amount <= liver_tolerance) owner.reagents.remove_reagent(toxin.type, toxin.metabolization_rate * owner.metabolism_efficiency * seconds_per_tick) @@ -865,7 +884,13 @@ need_mob_update += reagent.on_mob_dead(owner, seconds_per_tick) return need_mob_update -/// Signals that metabolization has stopped, triggering the end of trait-based effects +/** + * Signals that metabolization has stopped, triggering the end of trait-based effects + * Arguments + * + * * [C][mob/living/carbon] - the mob to end metabolization on + * * keep_liverless - if true will work without a liver + */ /datum/reagents/proc/end_metabolization(mob/living/carbon/C, keep_liverless = TRUE) var/list/cached_reagents = reagent_list for(var/datum/reagent/reagent as anything in cached_reagents) @@ -907,7 +932,14 @@ return FALSE //prevent addition return added_volume -///Processes any chems that have the REAGENT_IGNORE_STASIS bitflag ONLY +/** + * Processes any chems that have the REAGENT_IGNORE_STASIS bitflag ONLY + * Arguments + * + * * [owner][mob/living/carbon] - the mob we are doing stasis handlng on + * * seconds_per_tick - passed from process + * * times_fired - number of times to metabolize this reagent + */ /datum/reagents/proc/handle_stasis_chems(mob/living/carbon/owner, seconds_per_tick, times_fired) var/need_mob_update = FALSE for(var/datum/reagent/reagent as anything in reagent_list) @@ -918,19 +950,6 @@ owner.updatehealth() update_total() -/** - * Calls [/datum/reagent/proc/on_move] on every reagent in this holder - * - * Arguments: - * * atom/A - passed to on_move - * * Running - passed to on_move - */ -/datum/reagents/proc/conditional_update_move(atom/A, Running = 0) - var/list/cached_reagents = reagent_list - for(var/datum/reagent/reagent as anything in cached_reagents) - reagent.on_move(A, Running) - update_total() - /** * Calls [/datum/reagent/proc/on_update] on every reagent in this holder * @@ -992,16 +1011,16 @@ var/granularity = 1 if(!(reaction.reaction_flags & REACTION_INSTANT)) - granularity = CHEMICAL_VOLUME_MINIMUM + granularity = CHEMICAL_QUANTISATION_LEVEL var/list/cached_required_reagents = reaction.required_reagents for(var/req_reagent in cached_required_reagents) - if(!has_reagent(req_reagent, (cached_required_reagents[req_reagent]*granularity))) + if(!has_reagent(req_reagent, (cached_required_reagents[req_reagent] * granularity))) continue reaction_loop var/list/cached_required_catalysts = reaction.required_catalysts for(var/_catalyst in cached_required_catalysts) - if(!has_reagent(_catalyst, (cached_required_catalysts[_catalyst]*granularity))) + if(!has_reagent(_catalyst, (cached_required_catalysts[_catalyst] * granularity))) continue reaction_loop if(cached_my_atom) @@ -1114,7 +1133,7 @@ * This ends a single instance of an ongoing reaction * * Arguments: -* * E - the equilibrium that will be ended +* * [equilibrium][datum/equilibrium] - the equilibrium that will be ended * Returns: * * mix_message - the associated mix message of a reaction */ @@ -1136,7 +1155,8 @@ //If the reaction pollutes, pollute it here if we have an atom if(equilibrium.reaction.pollutant_type && my_atom) var/turf/my_turf = get_turf(my_atom) - my_turf.pollute_turf(equilibrium.reaction.pollutant_type, equilibrium.reaction.pollutant_amount * equilibrium.reacted_vol) + if(my_turf) // reactions can happen in nullspace (like inside of a mob's stomach for instance). + my_turf.pollute_turf(equilibrium.reaction.pollutant_type, equilibrium.reaction.pollutant_amount * equilibrium.reacted_vol) //SKYRAT EDIT END qdel(equilibrium) update_total() @@ -1145,7 +1165,6 @@ /* * This stops the holder from processing at the end of a series of reactions (i.e. when all the equilibriums are completed) -* * Also resets reaction variables to be null/empty/FALSE so that it can restart correctly in the future */ /datum/reagents/proc/finish_reacting() @@ -1153,7 +1172,7 @@ is_reacting = FALSE //Cap off values for(var/datum/reagent/reagent as anything in reagent_list) - reagent.volume = round(reagent.volume, CHEMICAL_VOLUME_ROUNDING)//To prevent runaways. + reagent.volume = FLOOR(reagent.volume, CHEMICAL_QUANTISATION_LEVEL)//To prevent runaways. LAZYNULL(previous_reagent_list) //reset it to 0 - because any change will be different now. update_total() if(!QDELING(src)) @@ -1253,7 +1272,7 @@ var/datum/cached_my_atom = my_atom var/multiplier = INFINITY for(var/reagent in cached_required_reagents) - multiplier = min(multiplier, round(get_reagent_amount(reagent) / cached_required_reagents[reagent])) + multiplier = FLOOR(min(multiplier, get_reagent_amount(reagent) / cached_required_reagents[reagent]), CHEMICAL_QUANTISATION_LEVEL) if(multiplier == 0)//Incase we're missing reagents - usually from on_reaction being called in an equlibrium when the results.len == 0 handlier catches a misflagged reaction return FALSE @@ -1293,48 +1312,61 @@ //If the reaction pollutes, pollute it here if we have an atom if(selected_reaction.pollutant_type && my_atom) var/turf/my_turf = get_turf(my_atom) - my_turf.pollute_turf(selected_reaction.pollutant_type, selected_reaction.pollutant_amount * multiplier) + if(my_turf) // just to be safe here + my_turf.pollute_turf(selected_reaction.pollutant_type, selected_reaction.pollutant_amount * multiplier) //SKYRAT EDIT END selected_reaction.on_reaction(src, null, multiplier) -///Possibly remove - see if multiple instant reactions is okay (Though, this "sorts" reactions by temp decending) -///Presently unused -/datum/reagents/proc/get_priority_instant_reaction(list/possible_reactions) - if(!length(possible_reactions)) - return FALSE - var/datum/chemical_reaction/selected_reaction = possible_reactions[1] - //select the reaction with the most extreme temperature requirements - for(var/datum/chemical_reaction/competitor as anything in possible_reactions) - 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) - selected_reaction = competitor - return selected_reaction - /// Updates [/datum/reagents/var/total_volume] /datum/reagents/proc/update_total() var/list/cached_reagents = reagent_list - . = 0 // This is a relatively hot proc. - var/total_ph = 0 // I know I know, I'm sorry - for(var/datum/reagent/reagent as anything in cached_reagents) - if((reagent.volume < 0.05) && !is_reacting) - del_reagent(reagent.type) - else if(reagent.volume <= CHEMICAL_VOLUME_MINIMUM)//For clarity - del_reagent(reagent.type) - else - . += reagent.volume - total_ph += (reagent.ph * reagent.volume) - total_volume = . + var/list/deleted_reagents = list() + var/chem_index = 1 + var/num_reagents = length(cached_reagents) + var/total_ph = 0 + . = 0 + + //responsible for removing reagents and computing total ph & volume + //all it's code was taken out of del_reagent() initially for efficiency purposes + while(chem_index <= num_reagents) + var/datum/reagent/reagent = cached_reagents[chem_index] + chem_index += 1 - if(!.) // No volume, default to the base + //remove very small amounts of reagents + if((reagent.volume <= 0.05 && !is_reacting) || reagent.volume <= CHEMICAL_QUANTISATION_LEVEL) + //end metabolization + if(isliving(my_atom)) + if(reagent.metabolizing) + reagent.metabolizing = FALSE + reagent.on_mob_end_metabolize(my_atom) + reagent.on_mob_delete(my_atom) + + //removing it and store in a seperate list for processing later + cached_reagents -= reagent + LAZYREMOVE(previous_reagent_list, reagent.type) + deleted_reagents += reagent + + //move pointer back so we don't overflow & decrease length + chem_index -= 1 + num_reagents -= 1 + continue + + //compute volume & ph like we would normally + . += reagent.volume + total_ph += (reagent.ph * reagent.volume) + + //assign the final values + total_volume = . + if(!.) ph = CHEMICAL_NORMAL_PH - return . - //Keep limited // should really be defines - ph = clamp(total_ph/total_volume, 0, 14) + else + ph = clamp(total_ph / total_volume, 0, 14) + //now send the signals after the volume & ph has been computed + for(var/datum/reagent/deleted_reagent as anything in deleted_reagents) + SEND_SIGNAL(src, COMSIG_REAGENTS_DEL_REAGENT, deleted_reagent) + qdel(deleted_reagent) /** * Applies the relevant expose_ proc for every reagent in this holder @@ -1376,56 +1408,74 @@ return A.expose_reagents(reagents, src, methods, volume_modifier, show_message) -/// Same as [/datum/reagents/proc/expose] but only for one reagent -/datum/reagents/proc/expose_single(datum/reagent/R, atom/A, methods = TOUCH, volume_modifier = 1, show_message = TRUE) - if(isnull(A)) - return null - - if(ispath(R)) - R = get_reagent(R) - if(isnull(R)) - return null - - // Yes, we need the parentheses. - return A.expose_reagents(list((R) = R.volume * volume_modifier), src, methods, volume_modifier, show_message) - /// Is this holder full or not /datum/reagents/proc/holder_full() return total_volume >= maximum_volume -/// Get the amount of this reagent -/datum/reagents/proc/get_reagent_amount(reagent, include_subtypes = FALSE) +/** + * Get the amount of this reagent or the sum of all its subtypes if specified + * Arguments + * * [reagent][datum/reagent] - the typepath of the reagent to look for + * * include_subtypes - if TRUE returns the sum of volumes of all subtypes of the above param reagent + */ +/datum/reagents/proc/get_reagent_amount(datum/reagent/reagent, include_subtypes = FALSE) + if(!ispath(reagent)) + stack_trace("invalid path passed to get_reagent_amount [reagent]") + return 0 + var/list/cached_reagents = reagent_list var/total_amount = 0 for(var/datum/reagent/cached_reagent as anything in cached_reagents) if((!include_subtypes && cached_reagent.type == reagent) || (include_subtypes && ispath(cached_reagent.type, reagent))) - total_amount += round(cached_reagent.volume, CHEMICAL_QUANTISATION_LEVEL) - return total_amount + total_amount += cached_reagent.volume + + return FLOOR(total_amount, CHEMICAL_QUANTISATION_LEVEL) +/** + * Gets the sum of volumes of all reagent type paths present in the list + * Arguments + * * [reagents][list] - list of reagent typepaths + */ /datum/reagents/proc/get_multiple_reagent_amounts(list/reagents) var/list/cached_reagents = reagent_list var/total_amount = 0 for(var/datum/reagent/cached_reagent as anything in cached_reagents) if(cached_reagent.type in reagents) - total_amount += round(cached_reagent.volume, CHEMICAL_QUANTISATION_LEVEL) + total_amount += FLOOR(cached_reagent.volume, CHEMICAL_QUANTISATION_LEVEL) return total_amount -/// Get the purity of this reagent -/datum/reagents/proc/get_reagent_purity(reagent) +/** + * Get the purity of this reagent + * Arguments + * * [reagent][datum/reagent] - the typepath of the specific reagent to get purity of + */ +/datum/reagents/proc/get_reagent_purity(datum/reagent/reagent) + if(!ispath(reagent)) + stack_trace("invalid reagent typepath passed to get_reagent_purity [reagent]") + return 0 + var/list/cached_reagents = reagent_list for(var/datum/reagent/cached_reagent as anything in cached_reagents) if(cached_reagent.type == reagent) return round(cached_reagent.purity, 0.01) return 0 -/// Directly set the purity of all contained reagents to a new value +/** + * Directly set the purity of all contained reagents to a new value + * Arguments + * * new_purity - the new purity value + */ /datum/reagents/proc/set_all_reagents_purity(new_purity = 0) var/list/cached_reagents = reagent_list for(var/datum/reagent/cached_reagent as anything in cached_reagents) cached_reagent.purity = max(0, new_purity) -/// Get the average purity of all reagents (or all subtypes of provided typepath) -/datum/reagents/proc/get_average_purity(parent_type = null) +/** + * Get the average purity of all reagents (or all subtypes of provided typepath) + * Arguments + * * [parent_type][datum/reagent] - the typepath of specific reagents to look for + */ +/datum/reagents/proc/get_average_purity(datum/reagent/parent_type = null) var/total_amount var/weighted_purity var/list/cached_reagents = reagent_list @@ -1436,42 +1486,11 @@ weighted_purity += reagent.volume * reagent.purity return weighted_purity / total_amount -/// Get the average nutriment_factor of all consumable reagents -/datum/reagents/proc/get_average_nutriment_factor() - var/consumable_volume - var/weighted_nutriment_factor - var/list/cached_reagents = reagent_list - for(var/datum/reagent/reagent as anything in cached_reagents) - if(istype(reagent, /datum/reagent/consumable)) - var/datum/reagent/consumable/consumable_reagent = reagent - consumable_volume += consumable_reagent.volume - weighted_nutriment_factor += consumable_reagent.volume * consumable_reagent.nutriment_factor - return weighted_nutriment_factor / consumable_volume - -/// Get a comma separated string of every reagent name in this holder. UNUSED -/datum/reagents/proc/get_reagent_names() - var/list/names = list() - var/list/cached_reagents = reagent_list - for(var/datum/reagent/reagent as anything in cached_reagents) - names += reagent.name - - return jointext(names, ",") - -/// helper function to preserve data across reactions (needed for xenoarch) -/datum/reagents/proc/get_data(reagent_id) - var/list/cached_reagents = reagent_list - for(var/datum/reagent/reagent as anything in cached_reagents) - if(reagent.type == reagent_id) - return reagent.data - -/// helper function to preserve data across reactions (needed for xenoarch) -/datum/reagents/proc/set_data(reagent_id, new_data) - var/list/cached_reagents = reagent_list - for(var/datum/reagent/reagent as anything in cached_reagents) - if(reagent.type == reagent_id) - reagent.data = new_data - -/// Shallow copies (deep copy of viruses) data from the provided reagent into our copy of that reagent +/** + * Shallow copies (deep copy of viruses) data from the provided reagent into our copy of that reagent + * Arguments + * [current_reagent][datum/reagent] - the reagent(not typepath) to copy data from + */ /datum/reagents/proc/copy_data(datum/reagent/current_reagent) if(!current_reagent || !current_reagent.data) return null @@ -1493,8 +1512,12 @@ return trans_data -/// Get a reference to the reagent if it exists -/datum/reagents/proc/get_reagent(type) +/** + * Get a reference to the reagent if it exists + * Arguments + * * [type][datum/reagent] - the typepath of the reagent to look up + */ +/datum/reagents/proc/get_reagent(datum/reagent/type) var/list/cached_reagents = reagent_list . = locate(type) in cached_reagents @@ -1560,8 +1583,14 @@ return // no div/0 please set_temperature(clamp(chem_temp + (delta_energy / heat_capacity), min_temp, max_temp)) -/// Applies heat to this holder -/datum/reagents/proc/expose_temperature(temperature, coeff=0.02) +/** + * Applies heat to this holder + * Arguments + * + * * temperature - the temperature we to heat/cool by + * * coeff - multiplier to be applied on temp diff between param temp and current temp + */ +/datum/reagents/proc/expose_temperature(temperature, coeff = 0.02) if(istype(my_atom,/obj/item/reagent_containers)) var/obj/item/reagent_containers/RCs = my_atom if(RCs.reagent_flags & NO_REACT) //stasis holders IE cryobeaker @@ -1601,21 +1630,6 @@ for(var/datum/reagent/reagent as anything in reagent_list) reagent.ph = clamp(reagent.ph + value, lower_limit, upper_limit) -/* -* Adjusts the base pH of all of the listed types -* -* - moves it towards acidic -* + moves it towards basic -* Arguments: -* * input_reagents_list - list of reagent objects to adjust -* * value - How much to adjust the base pH by -*/ -/datum/reagents/proc/adjust_specific_reagent_list_ph(list/input_reagents_list, value, lower_limit = 0, upper_limit = 14) - for(var/datum/reagent/reagent as anything in input_reagents_list) - if(!reagent) //We can call this with missing reagents. - continue - reagent.ph = clamp(reagent.ph + value, lower_limit, upper_limit) - /* * Adjusts the base pH of a specific type * @@ -1647,16 +1661,11 @@ for(var/reagent_type in external_list) var/list/qualities = external_list[reagent_type] - data += "[reagent_type] ([round(qualities[REAGENT_TRANSFER_AMOUNT], 0.1)]u, [qualities[REAGENT_PURITY]] purity)" + data += "[reagent_type] ([FLOOR(qualities[REAGENT_TRANSFER_AMOUNT], CHEMICAL_QUANTISATION_LEVEL)]u, [qualities[REAGENT_PURITY]] purity)" return english_list(data) -/** - * Outputs a log-friendly list of reagents based on the internal reagent_list. - * - * Arguments: - * * external_list - Assoc list of (reagent_type) = list(REAGENT_TRANSFER_AMOUNT = amounts, REAGENT_PURITY = purity) - */ +/// Outputs a log-friendly list of reagents based on the internal reagent_list. /datum/reagents/proc/get_reagent_log_string() if(!length(reagent_list)) return "no reagents" @@ -1664,7 +1673,7 @@ var/list/data = list() for(var/datum/reagent/reagent as anything in reagent_list) - data += "[reagent.type] ([round(reagent.volume, 0.1)]u, [reagent.purity] purity)" + data += "[reagent.type] ([FLOOR(reagent.volume, CHEMICAL_QUANTISATION_LEVEL)]u, [reagent.purity] purity)" return english_list(data) @@ -2015,7 +2024,7 @@ ui_reaction_id = text2path(params["id"]) return TRUE if("search_reagents") - var/input_reagent = tgui_input_list(usr, "Select reagent", "Reagent", GLOB.chemical_name_list) + var/input_reagent = tgui_input_list(usr, "Select reagent", "Reagent", GLOB.name2reagent) input_reagent = get_reagent_type_from_product_string(input_reagent) //from string to type var/datum/reagent/reagent = find_reagent_object_from_type(input_reagent) if(!reagent) @@ -2133,13 +2142,5 @@ reagents = new /datum/reagents(max_vol, flags) reagents.my_atom = src -/atom/movable/chem_holder - name = "This atom exists to hold chems. If you can see this, make an issue report" - desc = "God this is stupid" - #undef REAGENT_TRANSFER_AMOUNT #undef REAGENT_PURITY - -#undef REAGENTS_UI_MODE_LOOKUP -#undef REAGENTS_UI_MODE_REAGENT -#undef REAGENTS_UI_MODE_RECIPE diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 0a49fd1beb1374..9d33cccd56c6ce 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -46,9 +46,10 @@ GLOBAL_LIST_INIT(chem_master_containers, list( /obj/item/reagent_containers/pill/patch/style )), // SKYRAT EDIT ADDITION START - CAT_HYPOS = typecacheof(list( - /obj/item/reagent_containers/cup/vial - )), + CAT_HYPOS = list( + /obj/item/reagent_containers/cup/vial/small, + /obj/item/reagent_containers/cup/vial/large, + ), CAT_DARTS = typecacheof(list( /obj/item/reagent_containers/syringe/smartdart )) diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 110107d103fc04..f62cf8a86be55c 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -1,21 +1,3 @@ -GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) - -/proc/build_name2reagent() - . = list() - for (var/t in subtypesof(/datum/reagent)) - var/datum/reagent/R = t - if (length(initial(R.name))) - .[ckey(initial(R.name))] = t - -GLOBAL_LIST_INIT(blacklisted_metalgen_types, typecacheof(list( - /turf/closed/indestructible, //indestructible turfs should be indestructible, metalgen transmutation to plasma allows them to be destroyed - /turf/open/indestructible -))) - -//Various reagents -//Toxin & acid reagents -//Hydroponics stuff - /// A single reagent /datum/reagent /// datums don't have names by default @@ -50,8 +32,6 @@ GLOBAL_LIST_INIT(blacklisted_metalgen_types, typecacheof(list( var/color = "#000000" // rgb: 0, 0, 0 ///how fast the reagent is metabolized by the mob var/metabolization_rate = REAGENTS_METABOLISM - /// appears unused - var/overrides_metab = 0 /// above this overdoses happen var/overdose_threshold = 0 /// You fucked up and this is now triggering its overdose effects, purge that shit quick. @@ -62,8 +42,6 @@ GLOBAL_LIST_INIT(blacklisted_metalgen_types, typecacheof(list( var/reagent_weight = 1 ///is it currently metabolizing var/metabolizing = FALSE - /// is it bad for you? Currently only used for borghypo. C2s and Toxins have it TRUE by default. - var/harmful = FALSE /// Are we from a material? We might wanna know that for special stuff. Like metalgen. Is replaced with a ref of the material on New() var/datum/material/material ///A list of causes why this chem should skip being removed, if the length is 0 it will be removed from holder naturally, if this is >0 it will not be removed from the holder. @@ -121,7 +99,8 @@ GLOBAL_LIST_INIT(blacklisted_metalgen_types, typecacheof(list( if(!mass) mass = rand(10, 800) -/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references +/// This should only be called by the holder, so it's already handled clearing its references +/datum/reagent/Destroy() . = ..() holder = null @@ -159,12 +138,27 @@ GLOBAL_LIST_INIT(blacklisted_metalgen_types, typecacheof(list( /datum/reagent/proc/burn(datum/reagents/holder) return -/// Called from [/datum/reagents/proc/metabolize] -/datum/reagent/proc/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) +/** + * Ticks on mob Life() for as long as the reagent remains in the mob's reagents. + * + * Usage: Parent should be called first using . = ..() + * + * Exceptions: If the holder var needs to be accessed, call the parent afterward that as it can become null if the reagent is fully removed. + * + * Returns: UPDATE_MOB_HEALTH only if you need to update the health of a mob (this is only needed when damage is dealt to the mob) + * + * Arguments + * * mob/living/carbon/affected_mob - the mob which the reagent currently is inside of + * * seconds_per_tick - the time in server seconds between proc calls (when performing normally it will be 2) + * * times_fired - the number of times the owner's Life() tick has been called aka The number of times SSmobs has fired + * + */ +/datum/reagent/proc/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) current_cycle++ if(length(reagent_removal_skip_list)) return - holder.remove_reagent(type, metabolization_rate * M.metabolism_efficiency * seconds_per_tick) //By default it slowly disappears. + if(holder) + holder.remove_reagent(type, metabolization_rate * affected_mob.metabolism_efficiency * seconds_per_tick) //By default it slowly disappears. /// Called in burns.dm *if* the reagent has the REAGENT_AFFECTS_WOUNDS process flag /datum/reagent/proc/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound) @@ -174,7 +168,7 @@ GLOBAL_LIST_INIT(blacklisted_metalgen_types, typecacheof(list( Used to run functions before a reagent is transferred. Returning TRUE will block the transfer attempt. Primarily used in reagents/reaction_agents */ -/datum/reagent/proc/intercept_reagents_transfer(datum/reagents/target) +/datum/reagent/proc/intercept_reagents_transfer(datum/reagents/target, amount) return FALSE ///Called after a reagent is transferred @@ -182,35 +176,32 @@ Primarily used in reagents/reaction_agents return /// Called when this reagent is first added to a mob -/datum/reagent/proc/on_mob_add(mob/living/L, amount) +/datum/reagent/proc/on_mob_add(mob/living/affected_mob, amount) overdose_threshold /= max(normalise_creation_purity(), 1) //Maybe??? Seems like it would help pure chems be even better but, if I normalised this to 1, then everything would take a 25% reduction return /// Called when this reagent is removed while inside a mob -/datum/reagent/proc/on_mob_delete(mob/living/L) - L.clear_mood_event("[type]_overdose") +/datum/reagent/proc/on_mob_delete(mob/living/affected_mob) + affected_mob.clear_mood_event("[type]_overdose") return /// Called when this reagent first starts being metabolized by a liver -/datum/reagent/proc/on_mob_metabolize(mob/living/L) +/datum/reagent/proc/on_mob_metabolize(mob/living/affected_mob) return /// Called when this reagent stops being metabolized by a liver -/datum/reagent/proc/on_mob_end_metabolize(mob/living/L) +/datum/reagent/proc/on_mob_end_metabolize(mob/living/affected_mob) return -/// Called when a reagent is inside of a mob when they are dead -/datum/reagent/proc/on_mob_dead(mob/living/carbon/C, seconds_per_tick) +/// Called when a reagent is inside of a mob when they are dead. Returning UPDATE_MOB_HEALTH will cause updatehealth() to be called on the holder mob by /datum/reagents/proc/metabolize. +/datum/reagent/proc/on_mob_dead(mob/living/carbon/affected_mob, seconds_per_tick) if(!(chemical_flags & REAGENT_DEAD_PROCESS)) return current_cycle++ if(length(reagent_removal_skip_list)) return - holder.remove_reagent(type, metabolization_rate * C.metabolism_efficiency * seconds_per_tick) - -/// Called by [/datum/reagents/proc/conditional_update_move] -/datum/reagent/proc/on_move(mob/M) - return + if(holder) + holder.remove_reagent(type, metabolization_rate * affected_mob.metabolism_efficiency * seconds_per_tick) /// Called after add_reagents creates a new reagent. /datum/reagent/proc/on_new(data) @@ -225,14 +216,14 @@ Primarily used in reagents/reaction_agents /datum/reagent/proc/on_update(atom/A) return -/// Called if the reagent has passed the overdose threshold and is set to be triggering overdose effects -/datum/reagent/proc/overdose_process(mob/living/M, seconds_per_tick, times_fired) +/// Called if the reagent has passed the overdose threshold and is set to be triggering overdose effects. Returning UPDATE_MOB_HEALTH will cause updatehealth() to be called on the holder mob by /datum/reagents/proc/metabolize. +/datum/reagent/proc/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) return -/// Called when an overdose starts -/datum/reagent/proc/overdose_start(mob/living/M) - to_chat(M, span_userdanger("You feel like you took too much of [name]!")) - M.add_mood_event("[type]_overdose", /datum/mood_event/overdose, name) +/// Called when an overdose starts. Returning UPDATE_MOB_HEALTH will cause updatehealth() to be called on the holder mob by /datum/reagents/proc/metabolize. +/datum/reagent/proc/overdose_start(mob/living/affected_mob) + to_chat(affected_mob, span_userdanger("You feel like you took too much of [name]!")) + affected_mob.add_mood_event("[type]_overdose", /datum/mood_event/overdose, name) return /** diff --git a/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm b/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm index 817e5ed98bfe55..4550edbdfdf410 100644 --- a/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/atmos_gas_reagents.dm @@ -12,8 +12,8 @@ breather.add_movespeed_modifier(/datum/movespeed_modifier/reagent/freon) /datum/reagent/freon/on_mob_end_metabolize(mob/living/breather) + . = ..() breather.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/freon) - return ..() /datum/reagent/halon name = "Halon" @@ -30,9 +30,9 @@ ADD_TRAIT(breather, TRAIT_RESISTHEAT, type) /datum/reagent/halon/on_mob_end_metabolize(mob/living/breather) + . = ..() breather.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/halon) REMOVE_TRAIT(breather, TRAIT_RESISTHEAT, type) - return ..() /datum/reagent/healium name = "Healium" @@ -44,16 +44,18 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/healium/on_mob_end_metabolize(mob/living/breather) + . = ..() breather.SetSleeping(1 SECONDS) - return ..() /datum/reagent/healium/on_mob_life(mob/living/breather, seconds_per_tick, times_fired) - breather.SetSleeping(30 SECONDS) - breather.adjustFireLoss(-2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - breather.adjustToxLoss(-5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - breather.adjustBruteLoss(-2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) . = ..() - return TRUE + breather.SetSleeping(30 SECONDS) + var/need_mob_update + need_mob_update = breather.adjustFireLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += breather.adjustToxLoss(-5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += breather.adjustBruteLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/hypernoblium name = "Hyper-Noblium" @@ -65,9 +67,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/hypernoblium/on_mob_life(mob/living/carbon/breather, seconds_per_tick, times_fired) + . = ..() if(isplasmaman(breather)) breather.set_timed_status_effect(10 SECONDS * REM * seconds_per_tick, /datum/status_effect/hypernob_protection) - ..() /datum/reagent/nitrium_high_metabolization name = "Nitrosyl plasmide" @@ -85,14 +87,16 @@ ADD_TRAIT(breather, TRAIT_SLEEPIMMUNE, type) /datum/reagent/nitrium_high_metabolization/on_mob_end_metabolize(mob/living/breather) + . = ..() REMOVE_TRAIT(breather, TRAIT_SLEEPIMMUNE, type) - return ..() /datum/reagent/nitrium_high_metabolization/on_mob_life(mob/living/carbon/breather, seconds_per_tick, times_fired) - breather.adjustStaminaLoss(-2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - breather.adjustToxLoss(0.1 * current_cycle * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) // 1 toxin damage per cycle at cycle 10 . = ..() - return TRUE + var/need_mob_update + need_mob_update = breather.adjustStaminaLoss(-2 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + need_mob_update += breather.adjustToxLoss(0.1 * (current_cycle-1) * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) // 1 toxin damage per cycle at cycle 10 + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/nitrium_low_metabolization name = "Nitrium" @@ -109,8 +113,8 @@ breather.add_movespeed_modifier(/datum/movespeed_modifier/reagent/nitrium) /datum/reagent/nitrium_low_metabolization/on_mob_end_metabolize(mob/living/breather) + . = ..() breather.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/nitrium) - return ..() /datum/reagent/pluoxium name = "Pluoxium" @@ -122,18 +126,17 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/pluoxium/on_mob_life(mob/living/carbon/breather, seconds_per_tick, times_fired) + . = ..() if(!HAS_TRAIT(breather, TRAIT_KNOCKEDOUT)) - return ..() + return . = ..() for(var/obj/item/organ/organ_being_healed as anything in breather.organs) if(!organ_being_healed.damage) continue - organ_being_healed.apply_organ_damage(-0.5 * REM * seconds_per_tick, required_organ_flag = ORGAN_ORGANIC) - . = TRUE - - return . + if(organ_being_healed.apply_organ_damage(-0.5 * REM * seconds_per_tick, required_organ_flag = ORGAN_ORGANIC)) + return UPDATE_MOB_HEALTH /datum/reagent/zauker name = "Zauker" @@ -147,9 +150,11 @@ affected_respiration_type = ALL /datum/reagent/zauker/on_mob_life(mob/living/breather, seconds_per_tick, times_fired) - breather.adjustBruteLoss(6 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - breather.adjustOxyLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - breather.adjustFireLoss(2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - breather.adjustToxLoss(2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - return TRUE + . = ..() + var/need_mob_update + need_mob_update = breather.adjustBruteLoss(6 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += breather.adjustOxyLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += breather.adjustFireLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += breather.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm index 693404431faa10..b944fdbee80ce3 100644 --- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm @@ -1,6 +1,5 @@ // Category 2 medicines are medicines that have an ill effect regardless of volume/OD to dissuade doping. Mostly used as emergency chemicals OR to convert damage (and heal a bit in the process). The type is used to prompt borgs that the medicine is harmful. /datum/reagent/medicine/c2 - harmful = TRUE metabolization_rate = 0.5 * REAGENTS_METABOLISM inverse_chem = null //Some of these use inverse chems - we're just defining them all to null here to avoid repetition, eventually this will be moved up to parent creation_purity = REAGENT_STANDARD_PURITY//All sources by default are 0.75 - reactions are primed to resolve to roughly the same with no intervention for these. @@ -27,21 +26,23 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/c2/helbital/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - . = TRUE var/death_is_coming = (affected_mob.getToxLoss() + affected_mob.getOxyLoss() + affected_mob.getFireLoss() + affected_mob.getBruteLoss())*normalise_creation_purity() var/thou_shall_heal = 0 var/good_kind_of_healing = FALSE + var/need_mob_update = FALSE switch(affected_mob.stat) if(CONSCIOUS) //bad thou_shall_heal = death_is_coming/50 - affected_mob.adjustOxyLoss(2 * REM * seconds_per_tick, TRUE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustOxyLoss(2 * REM * seconds_per_tick, TRUE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) if(SOFT_CRIT) //meh convert thou_shall_heal = round(death_is_coming/47,0.1) - affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, TRUE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, TRUE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) else //no convert thou_shall_heal = round(death_is_coming/45, 0.1) good_kind_of_healing = TRUE - affected_mob.adjustBruteLoss(-thou_shall_heal * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustBruteLoss(-thou_shall_heal * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + . = UPDATE_MOB_HEALTH if(good_kind_of_healing && !reaping && SPT_PROB(0.00005, seconds_per_tick)) //janken with the grim reaper! notify_ghosts("[affected_mob] has entered a game of rock-paper-scissors with death!", source = affected_mob, action = NOTIFY_ORBIT, header = "Who Will Win?") @@ -73,21 +74,18 @@ affected_mob.revive(HEAL_ALL) holder.del_reagent(type) return - - ..() - return + return ..() || . /datum/reagent/medicine/c2/helbital/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(!helbent) affected_mob.apply_necropolis_curse(CURSE_WASTING | CURSE_BLINDING) helbent = TRUE - ..() - return TRUE -/datum/reagent/medicine/c2/helbital/on_mob_delete(mob/living/L) +/datum/reagent/medicine/c2/helbital/on_mob_delete(mob/living/affected_mob) + . = ..() if(helbent) - L.remove_status_effect(/datum/status_effect/necropolis_curse) - ..() + affected_mob.remove_status_effect(/datum/status_effect/necropolis_curse) /datum/reagent/medicine/c2/libital //messes with your liber name = "Libital" @@ -99,10 +97,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/c2/libital/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - affected_mob.adjustBruteLoss(-3 * REM * normalise_creation_purity() * seconds_per_tick, required_bodytype = affected_bodytype) - ..() - return TRUE + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + need_mob_update += affected_mob.adjustBruteLoss(-3 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/c2/probital name = "Probital" @@ -116,7 +116,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/c2/probital/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustBruteLoss(-2.25 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustBruteLoss(-2.25 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) var/ooo_youaregettingsleepy = 3.5 switch(round(affected_mob.getStaminaLoss())) if(10 to 40) @@ -125,20 +127,22 @@ ooo_youaregettingsleepy = 2.5 if(61 to 200) //you really can only go to 120 ooo_youaregettingsleepy = 2 - affected_mob.adjustStaminaLoss(ooo_youaregettingsleepy * REM * seconds_per_tick) - ..() - . = TRUE + need_mob_update += affected_mob.adjustStaminaLoss(ooo_youaregettingsleepy * REM * seconds_per_tick, updating_stamina = FALSE) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/c2/probital/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustStaminaLoss(3 * REM * seconds_per_tick, updating_stamina = FALSE) + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustStaminaLoss(3 * REM * seconds_per_tick, updating_stamina = FALSE) if(affected_mob.getStaminaLoss() >= 80) affected_mob.adjust_drowsiness(2 SECONDS * REM * seconds_per_tick) if(affected_mob.getStaminaLoss() >= 100) to_chat(affected_mob,span_warning("You feel more tired than you usually do, perhaps if you rest your eyes for a bit...")) - affected_mob.adjustStaminaLoss(-100, updating_stamina = TRUE) // Don't add the biotype parameter here as it results in infinite sleep and chat spam. + need_mob_update += affected_mob.adjustStaminaLoss(-100, updating_stamina = FALSE) // Don't add the biotype parameter here as it results in infinite sleep and chat spam. affected_mob.Sleeping(10 SECONDS) - ..() - . = TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/c2/probital/on_transfer(atom/A, methods=INGEST, trans_volume) if(!(methods & INGEST) || (!iscarbon(A) && !istype(A, /obj/item/organ/internal/stomach)) ) @@ -162,10 +166,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/c2/lenturi/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustFireLoss(-3 * REM * normalise_creation_purity() * seconds_per_tick, required_bodytype = affected_bodytype) - affected_mob.adjustOrganLoss(ORGAN_SLOT_STOMACH, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - ..() - return TRUE + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustFireLoss(-3 * REM * normalise_creation_purity() * seconds_per_tick, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_STOMACH, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/c2/aiuri name = "Aiuri" @@ -178,10 +184,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/c2/aiuri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustFireLoss(-2 * REM * normalise_creation_purity() * seconds_per_tick, required_bodytype = affected_bodytype) - affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, 0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - ..() - return TRUE + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustFireLoss(-2 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, 0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/c2/hercuri name = "Hercuri" @@ -194,20 +202,27 @@ inverse_chem = /datum/reagent/inverse/hercuri inverse_chem_val = 0.3 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + process_flags = REAGENT_ORGANIC | REAGENT_SYNTHETIC // SKYRAT EDIT ADDITION - Lets hercuri process in synths /datum/reagent/medicine/c2/hercuri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - if(affected_mob.getFireLoss() > 50) - affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick * normalise_creation_purity(), FALSE, required_bodytype = affected_bodytype) - else - affected_mob.adjustFireLoss(-1.25 * REM * seconds_per_tick * normalise_creation_purity(), FALSE, required_bodytype = affected_bodytype) + . = ..() + var/need_mob_update + // SKYRAT EDIT CHANGE BEGIN -- Adds check for owner_flags; indented the getFireLoss check and everything under it, so synths can get cooled down + var/owner_flags = affected_mob.dna.species.reagent_flags + if (owner_flags & PROCESS_ORGANIC) + if(affected_mob.getFireLoss() > 50) + need_mob_update = affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_bodytype = affected_bodytype) + else + need_mob_update = affected_mob.adjustFireLoss(-1.25 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_bodytype = affected_bodytype) + // SKYRAT EDIT CHANGE END affected_mob.adjust_bodytemperature(rand(-25,-5) * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50) if(ishuman(affected_mob)) var/mob/living/carbon/human/humi = affected_mob humi.adjust_coretemperature(rand(-25,-5) * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50) affected_mob.reagents?.chem_temp += (-10 * REM * seconds_per_tick) affected_mob.adjust_fire_stacks(-1 * REM * seconds_per_tick) - ..() - . = TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/c2/hercuri/expose_mob(mob/living/carbon/exposed_mob, methods=VAPOR, reac_volume) . = ..() @@ -220,11 +235,11 @@ exposed_mob.extinguish_mob() /datum/reagent/medicine/c2/hercuri/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_bodytemperature(-10 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50) //chilly chilly if(ishuman(affected_mob)) var/mob/living/carbon/human/humi = affected_mob humi.adjust_coretemperature(-10 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50) - ..() /******OXY******/ @@ -243,20 +258,22 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/c2/convermol/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired) - var/oxycalc = 2.5 * REM * current_cycle + . = ..() + var/oxycalc = 2.5 * REM * (current_cycle-1) if(!overdosed) oxycalc = min(oxycalc, affected_mob.getOxyLoss() + 0.5) //if NOT overdosing, we lower our toxdamage to only the damage we actually healed with a minimum of 0.1*current_cycle. IE if we only heal 10 oxygen damage but we COULD have healed 20, we will only take toxdamage for the 10. We would take the toxdamage for the extra 10 if we were overdosing. - affected_mob.adjustOxyLoss(-oxycalc * seconds_per_tick * normalise_creation_purity(), FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustToxLoss(oxycalc * seconds_per_tick / CONVERMOL_RATIO, FALSE, required_biotype = affected_biotype) - if(SPT_PROB(current_cycle / 2, seconds_per_tick) && affected_mob.losebreath) + var/need_mob_update + need_mob_update = affected_mob.adjustOxyLoss(-oxycalc * seconds_per_tick * normalise_creation_purity(), FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustToxLoss(oxycalc * seconds_per_tick / CONVERMOL_RATIO, updating_health = FALSE, required_biotype = affected_biotype) + if(SPT_PROB((current_cycle-1) / 2, seconds_per_tick) && affected_mob.losebreath) affected_mob.losebreath-- - ..() - return TRUE + need_mob_update = TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/c2/convermol/overdose_process(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired) + . = ..() metabolization_rate += 2.5 * REAGENTS_METABOLISM - ..() - return TRUE #undef CONVERMOL_RATIO @@ -273,20 +290,22 @@ COOLDOWN_DECLARE(drowsycd) /datum/reagent/medicine/c2/tirimol/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick * normalise_creation_purity(), required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustStaminaLoss(2 * REM * seconds_per_tick, required_biotype = affected_biotype) + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustStaminaLoss(2 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) if(drowsycd && COOLDOWN_FINISHED(src, drowsycd)) affected_mob.adjust_drowsiness(20 SECONDS) COOLDOWN_START(src, drowsycd, 45 SECONDS) else if(!drowsycd) COOLDOWN_START(src, drowsycd, 15 SECONDS) - ..() - return TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH -/datum/reagent/medicine/c2/tirimol/on_mob_end_metabolize(mob/living/L) - if(current_cycle > 20) - L.Sleeping(10 SECONDS) - ..() +/datum/reagent/medicine/c2/tirimol/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() + if(current_cycle > 21) + affected_mob.Sleeping(10 SECONDS) /******TOXIN******/ /*Suffix: -iver*/ @@ -307,14 +326,16 @@ rads_heal_threshold = rand(rads_heal_threshold - 50, rads_heal_threshold + 50) // Basically this means 50K and below will always give the radiation heal, and upto 150K could. Calculated once. /datum/reagent/medicine/c2/seiver/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired) + . = ..() var/chemtemp = min(holder.chem_temp, 1000) chemtemp = chemtemp ? chemtemp : T0C //why do you have null sweaty var/healypoints = 0 //5 healypoints = 1 heart damage; 5 rads = 1 tox damage healed for the purpose of healypoints //you're hot var/toxcalc = min(round(5 + ((chemtemp-1000)/175), 0.1), 5) * REM * seconds_per_tick * normalise_creation_purity() //max 2.5 tox healing per second + var/need_mob_update if(toxcalc > 0) - affected_mob.adjustToxLoss(-toxcalc, required_biotype = affected_biotype) + need_mob_update = affected_mob.adjustToxLoss(-toxcalc, updating_health = FALSE, required_biotype = affected_biotype) healypoints += toxcalc //and you're cold @@ -323,16 +344,16 @@ radcalc *= normalise_creation_purity() // extra rad healing if you are SUPER cold if(chemtemp < rads_heal_threshold*0.1) - affected_mob.adjustToxLoss(-radcalc * 0.9, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustToxLoss(-radcalc * 0.9, updating_health = FALSE, required_biotype = affected_biotype) else if(chemtemp < rads_heal_threshold) - affected_mob.adjustToxLoss(-radcalc * 0.75, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustToxLoss(-radcalc * 0.75, updating_health = FALSE, required_biotype = affected_biotype) healypoints += (radcalc / 5) //you're yes and... oh no! healypoints = round(healypoints, 0.1) affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, healypoints / 5, required_organ_flag = affected_organ_flags) - ..() - return TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/c2/multiver //enhanced with MULTIple medicines name = "Multiver" @@ -343,6 +364,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/c2/multiver/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired) + . = ..() var/medibonus = 0 //it will always have itself which makes it REALLY start @ 1 for(var/r in affected_mob.reagents.reagent_list) var/datum/reagent/the_reagent = r @@ -350,8 +372,9 @@ medibonus += 1 if(creation_purity >= 1) //Perfectly pure multivers gives a bonus of 2! medibonus += 1 - affected_mob.adjustToxLoss(-0.5 * min(medibonus, 3 * normalise_creation_purity()) * REM * seconds_per_tick, required_biotype = affected_biotype) //not great at healing but if you have nothing else it will work - affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) //kills at 40u + var/need_mob_update + need_mob_update = affected_mob.adjustToxLoss(-0.5 * min(medibonus, 3 * normalise_creation_purity()) * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) //not great at healing but if you have nothing else it will work + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) //kills at 40u for(var/r2 in affected_mob.reagents.reagent_list) var/datum/reagent/the_reagent2 = r2 if(the_reagent2 == src) @@ -360,8 +383,8 @@ if(medibonus >= 3 && istype(the_reagent2, /datum/reagent/medicine)) //3 unique meds (2+multiver) | (1 + pure multiver) will make it not purge medicines continue affected_mob.reagents.remove_reagent(the_reagent2.type, amount2purge * REM * seconds_per_tick) - ..() - return TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH // Antitoxin binds plants pretty well. So the tox goes significantly down /datum/reagent/medicine/c2/multiver/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user) @@ -385,7 +408,7 @@ return var/mob/living/carbon/C = A if(trans_volume >= 0.6) //prevents cheesing with ultralow doses. - C.adjustToxLoss((-1.5 * min(2, trans_volume) * REM) * normalise_creation_purity(), FALSE, required_biotype = affected_biotype) //This is to promote iv pole use for that chemotherapy feel. + C.adjustToxLoss((-1.5 * min(2, trans_volume) * REM) * normalise_creation_purity(), required_biotype = affected_biotype) //This is to promote iv pole use for that chemotherapy feel. var/obj/item/organ/internal/liver/L = C.organs_slot[ORGAN_SLOT_LIVER] if(!L || L.organ_flags & ORGAN_FAILING) return @@ -395,22 +418,24 @@ ..() /datum/reagent/medicine/c2/syriniver/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.8 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.8 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + need_mob_update += affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) for(var/datum/reagent/R in affected_mob.reagents.reagent_list) if(issyrinormusc(R)) continue affected_mob.reagents.remove_reagent(R.type, 0.4 * REM * seconds_per_tick) - ..() - . = TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/c2/syriniver/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + . = ..() + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + . = UPDATE_MOB_HEALTH affected_mob.adjust_disgust(3 * REM * seconds_per_tick) affected_mob.reagents.add_reagent(/datum/reagent/medicine/c2/musiver, 0.225 * REM * seconds_per_tick) - ..() - . = TRUE /datum/reagent/medicine/c2/musiver //MUScles name = "Musiver" @@ -424,30 +449,32 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/c2/musiver/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.1 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick * normalise_creation_purity(), FALSE, required_biotype = affected_biotype) + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.1 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + need_mob_update += affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_biotype = affected_biotype) for(var/datum/reagent/R in affected_mob.reagents.reagent_list) if(issyrinormusc(R)) continue affected_mob.reagents.remove_reagent(R.type, 0.2 * REM * seconds_per_tick) - ..() - . = TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/c2/musiver/overdose_start(mob/living/carbon/affected_mob) + . = ..() trauma = new() affected_mob.gain_trauma(trauma, TRAUMA_RESILIENCE_ABSOLUTE) - ..() -/datum/reagent/medicine/c2/musiver/on_mob_delete(mob/living/carbon/affected_mob) +/datum/reagent/medicine/c2/musiver/on_mob_delete(mob/living/affected_mob) + . = ..() if(trauma) QDEL_NULL(trauma) - return ..() /datum/reagent/medicine/c2/musiver/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + . = ..() + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + . = UPDATE_MOB_HEALTH affected_mob.adjust_disgust(3 * REM * seconds_per_tick) - ..() - . = TRUE #undef issyrinormusc /******COMBOS******/ @@ -469,14 +496,19 @@ show_message = 0 if(!(methods & (PATCH|TOUCH|VAPOR))) return - var/harmies = min(carbies.getBruteLoss(), carbies.adjustBruteLoss(-1.25 * reac_volume, required_bodytype = affected_bodytype)*-1) - var/burnies = min(carbies.getFireLoss(), carbies.adjustFireLoss(-1.25 * reac_volume, required_bodytype = affected_bodytype)*-1) + var/harmies = min(carbies.getBruteLoss(), carbies.adjustBruteLoss(-1.25 * reac_volume, updating_health = FALSE, required_bodytype = affected_bodytype)*-1) + var/burnies = min(carbies.getFireLoss(), carbies.adjustFireLoss(-1.25 * reac_volume, updating_health = FALSE, required_bodytype = affected_bodytype)*-1) for(var/i in carbies.all_wounds) var/datum/wound/iter_wound = i iter_wound.on_synthflesh(reac_volume) - carbies.adjustToxLoss((harmies+burnies)*(0.5 + (0.25*(1-creation_purity))), required_biotype = affected_biotype) //0.5 - 0.75 + var/need_mob_update = harmies + burnies + need_mob_update += carbies.adjustToxLoss((harmies+burnies)*(0.5 + (0.25*(1-creation_purity))), updating_health = FALSE, required_biotype = affected_biotype) //0.5 - 0.75 + + if(need_mob_update) + carbies.updatehealth() if(show_message) to_chat(carbies, span_danger("You feel your burns and bruises healing! It stings like hell!")) + carbies.add_mood_event("painful_medicine", /datum/mood_event/painful_medicine) if(HAS_TRAIT_FROM(exposed_mob, TRAIT_HUSK, BURN) && carbies.getFireLoss() < UNHUSK_DAMAGE_THRESHOLD && (carbies.reagents.get_reagent_amount(/datum/reagent/medicine/c2/synthflesh) + reac_volume >= SYNTHFLESH_UNHUSK_AMOUNT)) carbies.cure_husk(BURN) @@ -526,45 +558,51 @@ user.throw_alert("penthrite", /atom/movable/screen/alert/penthrite) user.add_traits(subject_traits, type) -/datum/reagent/medicine/c2/penthrite/on_mob_life(mob/living/carbon/human/H, seconds_per_tick, times_fired) - H.adjustStaminaLoss(-25 * REM) //SKYRAT EDIT ADDITION - COMBAT - makes your heart beat faster, fills you with energy. For miners - H.adjustOrganLoss(ORGAN_SLOT_STOMACH, 0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - if(H.health <= HEALTH_THRESHOLD_CRIT && H.health > (H.crit_threshold + HEALTH_THRESHOLD_FULLCRIT * (2 * normalise_creation_purity()))) //we cannot save someone below our lowered crit threshold. +/datum/reagent/medicine/c2/penthrite/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustStaminaLoss(-12.5 * REM * seconds_per_tick, updating_stamina = FALSE) //SKYRAT EDIT ADDITION - COMBAT - makes your heart beat faster, fills you with energy. For miners + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_STOMACH, 0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(affected_mob.health <= HEALTH_THRESHOLD_CRIT && affected_mob.health > (affected_mob.crit_threshold + HEALTH_THRESHOLD_FULLCRIT * (2 * normalise_creation_purity()))) //we cannot save someone below our lowered crit threshold. - H.adjustToxLoss(-2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - H.adjustBruteLoss(-2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - H.adjustFireLoss(-2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - H.adjustOxyLoss(-6 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustBruteLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustOxyLoss(-6 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - H.losebreath = 0 + affected_mob.losebreath = 0 - H.adjustOrganLoss(ORGAN_SLOT_HEART, max(volume/10, 1) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) // your heart is barely keeping up! + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, max(volume/10, 1) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) // your heart is barely keeping up! - H.set_jitter_if_lower(rand(0 SECONDS, 4 SECONDS) * REM * seconds_per_tick) - H.set_dizzy_if_lower(rand(0 SECONDS, 4 SECONDS) * REM * seconds_per_tick) + affected_mob.set_jitter_if_lower(rand(0 SECONDS, 4 SECONDS) * REM * seconds_per_tick) + affected_mob.set_dizzy_if_lower(rand(0 SECONDS, 4 SECONDS) * REM * seconds_per_tick) if(SPT_PROB(18, seconds_per_tick)) - to_chat(H,span_danger("Your body is trying to give up, but your heart is still beating!")) + to_chat(affected_mob,span_danger("Your body is trying to give up, but your heart is still beating!")) - if(H.health <= (H.crit_threshold + HEALTH_THRESHOLD_FULLCRIT*(2*normalise_creation_purity()))) //certain death below this threshold - REMOVE_TRAIT(H, TRAIT_STABLEHEART, type) //we have to remove the stable heart trait before we give them a heart attack - to_chat(H,span_danger("You feel something rupturing inside your chest!")) - H.emote("scream") - H.set_heartattack(TRUE) + if(affected_mob.health <= (affected_mob.crit_threshold + HEALTH_THRESHOLD_FULLCRIT*(2*normalise_creation_purity()))) //certain death below this threshold + REMOVE_TRAIT(affected_mob, TRAIT_STABLEHEART, type) //we have to remove the stable heart trait before we give them a heart attack + to_chat(affected_mob,span_danger("You feel something rupturing inside your chest!")) + affected_mob.emote("scream") + affected_mob.set_heartattack(TRUE) volume = 0 - . = ..() - return TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH -/datum/reagent/medicine/c2/penthrite/on_mob_end_metabolize(mob/living/user) - user.clear_alert("penthrite") - user.remove_traits(subject_traits, type) +/datum/reagent/medicine/c2/penthrite/on_mob_end_metabolize(mob/living/affected_mob) . = ..() + affected_mob.clear_alert("penthrite") + affected_mob.remove_traits(subject_traits, type) -/datum/reagent/medicine/c2/penthrite/overdose_process(mob/living/carbon/human/H, seconds_per_tick, times_fired) - REMOVE_TRAIT(H, TRAIT_STABLEHEART, type) - H.adjustStaminaLoss(10 * REM * seconds_per_tick, required_biotype = affected_biotype) - H.adjustOrganLoss(ORGAN_SLOT_HEART, 10 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - H.set_heartattack(TRUE) +/datum/reagent/medicine/c2/penthrite/overdose_process(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired) + . = ..() + REMOVE_TRAIT(affected_mob, TRAIT_STABLEHEART, type) + var/need_mob_update + need_mob_update = affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, 10 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + need_mob_update += affected_mob.set_heartattack(TRUE) + if(need_mob_update) + return UPDATE_MOB_HEALTH /******NICHE******/ diff --git a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm index b81e1600bbfc47..07335fe728feb9 100644 --- a/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drinks/alcohol_reagents.dm @@ -51,9 +51,10 @@ return ..() /datum/reagent/consumable/ethanol/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(drinker.get_drunk_amount() < volume * boozepwr * ALCOHOL_THRESHOLD_MODIFIER || boozepwr < 0) var/booze_power = boozepwr - if(HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE)) //we're an accomplished drinker + if(HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE)) // we're an accomplished drinker booze_power *= 0.7 if(HAS_TRAIT(drinker, TRAIT_LIGHT_DRINKER)) booze_power *= 2 @@ -77,8 +78,8 @@ var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER) var/heavy_drinker_multiplier = (HAS_TRAIT(drinker, TRAIT_HEAVY_DRINKER) ? 0.5 : 1) if (istype(liver)) - liver.apply_organ_damage(((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * liver.alcohol_tolerance * heavy_drinker_multiplier * seconds_per_tick, 0))/300)) // SKYRAT EDIT CHANGE - Alcohol Tolerance - Original: (((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * liver.alcohol_tolerance * heavy_drinker_multiplier * seconds_per_tick, 0))/150)) - return ..() + if(liver.apply_organ_damage(((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * liver.alcohol_tolerance * heavy_drinker_multiplier * seconds_per_tick, 0))/300))) // SKYRAT EDIT CHANGE - Alcohol Tolerance - Original: if((((max(sqrt(volume) * (boozepwr ** ALCOHOL_EXPONENT) * liver.alcohol_tolerance * heavy_drinker_multiplier * seconds_per_tick, 0))/150))) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/expose_obj(obj/exposed_obj, reac_volume) if(istype(exposed_obj, /obj/item/paper)) @@ -151,9 +152,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/beer/green/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(drinker.color != color) drinker.add_atom_colour(color, TEMPORARY_COLOUR_PRIORITY) - return ..() /datum/reagent/consumable/ethanol/beer/green/on_mob_end_metabolize(mob/living/drinker) drinker.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, color) @@ -167,13 +168,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/kahlua/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.set_dizzy_if_lower(10 SECONDS * REM * seconds_per_tick) drinker.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick) drinker.AdjustSleeping(-40 * REM * seconds_per_tick) if(!HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE)) drinker.set_jitter_if_lower(10 SECONDS) - ..() - . = TRUE /datum/reagent/consumable/ethanol/whiskey name = "Whiskey" @@ -200,9 +200,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/whiskey/candycorn/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(5, seconds_per_tick)) drinker.adjust_hallucinations(4 SECONDS * REM * seconds_per_tick) - ..() /datum/reagent/consumable/ethanol/thirteenloko name = "Thirteen Loko" @@ -216,20 +216,21 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/thirteenloko/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.adjust_drowsiness(-14 SECONDS * REM * seconds_per_tick) drinker.AdjustSleeping(-40 * REM * seconds_per_tick) drinker.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, drinker.get_body_temp_normal()) if(!HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE)) drinker.set_jitter_if_lower(10 SECONDS) - ..() - return TRUE /datum/reagent/consumable/ethanol/thirteenloko/overdose_start(mob/living/drinker) + . = ..() to_chat(drinker, span_userdanger("Your entire body violently jitters as you start to feel queasy. You really shouldn't have drank all of that [name]!")) drinker.set_jitter_if_lower(40 SECONDS) drinker.Stun(1.5 SECONDS) /datum/reagent/consumable/ethanol/thirteenloko/overdose_process(mob/living/drinker, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(3.5, seconds_per_tick) && iscarbon(drinker)) var/obj/item/held_item = drinker.get_active_held_item() if(held_item) @@ -248,15 +249,18 @@ eyes.forceMove(get_turf(drinker)) to_chat(drinker, span_userdanger("You double over in pain as you feel your eyeballs liquify in your head!")) drinker.emote("scream") - drinker.adjustBruteLoss(15, required_bodytype = affected_bodytype) + if(drinker.adjustBruteLoss(15 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)) + . = UPDATE_MOB_HEALTH else to_chat(drinker, span_userdanger("You scream in terror as you go blind!")) - eyes.apply_organ_damage(eyes.maxHealth) + if(eyes.apply_organ_damage(eyes.maxHealth)) + . = UPDATE_MOB_HEALTH drinker.emote("scream") if(SPT_PROB(1.5, seconds_per_tick) && iscarbon(drinker)) drinker.visible_message(span_danger("[drinker] starts having a seizure!"), span_userdanger("You have a seizure!")) - drinker.Unconscious(10 SECONDS) + if(drinker.Unconscious(10 SECONDS)) + . = UPDATE_MOB_HEALTH drinker.set_jitter_if_lower(700 SECONDS) if(SPT_PROB(0.5, seconds_per_tick) && iscarbon(drinker)) @@ -285,10 +289,10 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/bilk/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(drinker.getBruteLoss() && SPT_PROB(5, seconds_per_tick)) - drinker.heal_bodypart_damage(brute = 1) - . = TRUE - return ..() || . + if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/threemileisland name = "Three Mile Island Iced Tea" @@ -301,8 +305,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/threemileisland/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.set_drugginess(100 SECONDS * REM * seconds_per_tick) - return ..() /datum/reagent/consumable/ethanol/gin name = "Gin" @@ -415,9 +419,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/absinthe/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(5, seconds_per_tick) && !HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE)) - drinker.adjust_hallucinations(8 SECONDS) - ..() + drinker.adjust_hallucinations(8 SECONDS * REM * seconds_per_tick) /datum/reagent/consumable/ethanol/hooch name = "Hooch" @@ -513,13 +517,15 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/cuba_libre/on_mob_life(mob/living/carbon/cubano, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update if(cubano.mind && cubano.mind.has_antag_datum(/datum/antagonist/rev)) //Cuba Libre, the traditional drink of revolutions! Heals revolutionaries. - cubano.adjustBruteLoss(-1 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - cubano.adjustFireLoss(-1 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - cubano.adjustToxLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - cubano.adjustOxyLoss(-5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - . = TRUE - return ..() || . + need_mob_update = cubano.adjustBruteLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += cubano.adjustFireLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += cubano.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += cubano.adjustOxyLoss(-5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/whiskey_cola name = "Whiskey Cola" @@ -602,17 +608,17 @@ )) /datum/reagent/consumable/ethanol/screwdrivercocktail/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER) if(HAS_TRAIT(liver, TRAIT_ENGINEER_METABOLISM)) ADD_TRAIT(drinker, TRAIT_HALT_RADIATION_EFFECTS, "[type]") if (HAS_TRAIT(drinker, TRAIT_IRRADIATED)) - drinker.adjustToxLoss(-2 * REM * seconds_per_tick, required_biotype = affected_biotype) - - return ..() + if(drinker.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/screwdrivercocktail/on_mob_end_metabolize(mob/living/drinker) + . = ..() REMOVE_TRAIT(drinker, TRAIT_HALT_RADIATION_EFFECTS, "[type]") - return ..() /datum/reagent/consumable/ethanol/booger name = "Booger" @@ -648,6 +654,7 @@ var/tough_text /datum/reagent/consumable/ethanol/brave_bull/on_mob_metabolize(mob/living/drinker) + . = ..() tough_text = pick("brawny", "tenacious", "tough", "hardy", "sturdy") //Tuff stuff to_chat(drinker, span_notice("You feel [tough_text]!")) drinker.maxHealth += 10 //Brave Bull makes you sturdier, and thus capable of withstanding a tiny bit more punishment. @@ -655,6 +662,7 @@ ADD_TRAIT(drinker, TRAIT_FEARLESS, type) /datum/reagent/consumable/ethanol/brave_bull/on_mob_end_metabolize(mob/living/drinker) + . = ..() to_chat(drinker, span_notice("You no longer feel [tough_text].")) drinker.maxHealth -= 10 drinker.health = min(drinker.health - 10, drinker.maxHealth) //This can indeed crit you if you're alive solely based on alchol ingestion @@ -672,6 +680,7 @@ var/obj/effect/light_holder /datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_metabolize(mob/living/drinker) + . = ..() to_chat(drinker, span_notice("You feel gentle warmth spread through your body!")) light_holder = new(drinker) light_holder.set_light(3, 0.7, "#FFCC00") //Tequila Sunrise makes you radiate dim light, like a sunrise! @@ -684,6 +693,7 @@ return ..() /datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_end_metabolize(mob/living/drinker) + . = ..() to_chat(drinker, span_notice("The warmth in your body fades.")) QDEL_NULL(light_holder) @@ -697,8 +707,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/toxins_special/on_mob_life(mob/living/drinker, seconds_per_tick, times_fired) + . = ..() drinker.adjust_bodytemperature(15 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, drinker.get_body_temp_normal() + 20) //310.15 is the normal bodytemp. - return ..() /datum/reagent/consumable/ethanol/beepsky_smash name = "Beepsky Smash" @@ -714,6 +724,7 @@ var/datum/brain_trauma/special/beepsky/beepsky_hallucination /datum/reagent/consumable/ethanol/beepsky_smash/on_mob_metabolize(mob/living/carbon/drinker) + . = ..() if(HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE)) metabolization_rate = 0.8 // if you don't have a liver, or your liver isn't an officer's liver @@ -721,28 +732,27 @@ if(!liver || !HAS_TRAIT(liver, TRAIT_LAW_ENFORCEMENT_METABOLISM)) beepsky_hallucination = new() drinker.gain_trauma(beepsky_hallucination, TRAUMA_RESILIENCE_ABSOLUTE) - ..() /datum/reagent/consumable/ethanol/beepsky_smash/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.set_jitter_if_lower(4 SECONDS) var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER) // if you have a liver and that liver is an officer's liver if(liver && HAS_TRAIT(liver, TRAIT_LAW_ENFORCEMENT_METABOLISM)) - . = TRUE - drinker.adjustStaminaLoss(-10 * REM * seconds_per_tick, required_biotype = affected_biotype) + if(drinker.adjustStaminaLoss(-10 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH if(SPT_PROB(10, seconds_per_tick)) drinker.cause_hallucination(get_random_valid_hallucination_subtype(/datum/hallucination/nearby_fake_item), name) if(SPT_PROB(5, seconds_per_tick)) drinker.cause_hallucination(/datum/hallucination/stray_bullet, name) - ..() - /datum/reagent/consumable/ethanol/beepsky_smash/on_mob_end_metabolize(mob/living/carbon/drinker) + . = ..() if(beepsky_hallucination) QDEL_NULL(beepsky_hallucination) - return ..() /datum/reagent/consumable/ethanol/beepsky_smash/overdose_start(mob/living/carbon/drinker) + . = ..() var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER) // if you don't have a liver, or your liver isn't an officer's liver if(!liver || !HAS_TRAIT(liver, TRAIT_LAW_ENFORCEMENT_METABOLISM)) @@ -768,6 +778,7 @@ var/dorf_mode = FALSE /datum/reagent/consumable/ethanol/manly_dorf/on_mob_metabolize(mob/living/drinker) + . = ..() if(ishuman(drinker)) var/mob/living/carbon/human/potential_dwarf = drinker if(HAS_TRAIT(potential_dwarf, TRAIT_DWARF)) @@ -776,10 +787,13 @@ dorf_mode = TRUE /datum/reagent/consumable/ethanol/manly_dorf/on_mob_life(mob/living/carbon/dwarf, seconds_per_tick, times_fired) + . = ..() if(dorf_mode) - dwarf.adjustBruteLoss(-2 * REM * seconds_per_tick, required_bodytype = affected_bodytype) - dwarf.adjustFireLoss(-2 * REM * seconds_per_tick, required_bodytype = affected_bodytype) - return ..() + var/need_mob_update + need_mob_update = dwarf.adjustBruteLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += dwarf.adjustFireLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/longislandicedtea name = "Long Island Iced Tea" @@ -809,6 +823,7 @@ glass_price = DRINK_PRICE_EASY /datum/reagent/consumable/ethanol/b52/on_mob_metabolize(mob/living/drinker) + . = ..() playsound(drinker, 'sound/effects/explosion_distant.ogg', 100, FALSE) /datum/reagent/consumable/ethanol/irishcoffee @@ -859,8 +874,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/manhattan_proj/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.set_drugginess(1 MINUTES * REM * seconds_per_tick) - return ..() /datum/reagent/consumable/ethanol/whiskeysoda name = "Whiskey Soda" @@ -881,8 +896,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/antifreeze/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.adjust_bodytemperature(20 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, drinker.get_body_temp_normal() + 20) //310.15 is the normal bodytemp. - return ..() /datum/reagent/consumable/ethanol/barefoot name = "Barefoot" @@ -894,12 +909,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/barefoot/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(ishuman(drinker)) //Barefoot causes the imbiber to quickly regenerate brute trauma if they're not wearing shoes. var/mob/living/carbon/human/unshoed = drinker if(!unshoed.shoes) - unshoed.adjustBruteLoss(-3 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - . = TRUE - return ..() || . + if(unshoed.adjustBruteLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/snowwhite name = "Snow White" @@ -1028,13 +1043,16 @@ var/static/list/ray_filter = list(type = "rays", size = 40, density = 15, color = SUPERMATTER_SINGULARITY_RAYS_COLOUR, factor = 15) /datum/reagent/consumable/ethanol/singulo/on_mob_metabolize(mob/living/drinker) + . = ..() ADD_TRAIT(drinker, TRAIT_MADNESS_IMMUNE, type) /datum/reagent/consumable/ethanol/singulo/on_mob_end_metabolize(mob/living/drinker) + . = ..() REMOVE_TRAIT(drinker, TRAIT_MADNESS_IMMUNE, type) drinker.remove_filter("singulo_rays") /datum/reagent/consumable/ethanol/singulo/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(2.5, seconds_per_tick)) // 20u = 1x1, 45u = 2x2, 80u = 3x3 var/volume_to_radius = FLOOR(sqrt(volume/5), 1) - 1 @@ -1050,7 +1068,6 @@ animate(drinker.get_filter("singulo_rays"), offset = 10, time = 1.5 SECONDS, loop = -1) addtimer(CALLBACK(drinker, TYPE_PROC_REF(/datum, remove_filter), "singulo_rays"), 1.5 SECONDS) drinker.emote("burp") - return ..() /datum/reagent/consumable/ethanol/sbiten name = "Sbiten" @@ -1062,8 +1079,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/sbiten/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.adjust_bodytemperature(50 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, BODYTEMP_HEAT_DAMAGE_LIMIT) //310.15 is the normal bodytemp. - return ..() /datum/reagent/consumable/ethanol/red_mead name = "Red Mead" @@ -1093,8 +1110,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/iced_beer/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.adjust_bodytemperature(-20 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, T0C) //310.15 is the normal bodytemp. - return ..() /datum/reagent/consumable/ethanol/grog name = "Grog" @@ -1162,9 +1179,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/changelingsting/on_mob_life(mob/living/carbon/target, seconds_per_tick, times_fired) + . = ..() var/datum/antagonist/changeling/changeling = target.mind?.has_antag_datum(/datum/antagonist/changeling) changeling?.adjust_chemicals(metabolization_rate * REM * seconds_per_tick) - return ..() /datum/reagent/consumable/ethanol/irishcarbomb name = "Irish Car Bomb" @@ -1185,9 +1202,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/syndicatebomb/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(2.5, seconds_per_tick)) playsound(get_turf(drinker), 'sound/effects/explosionfar.ogg', 100, TRUE) - return ..() /datum/reagent/consumable/ethanol/hiveminderaser name = "Hivemind Eraser" @@ -1228,11 +1245,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/bananahonk/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER) if((liver && HAS_TRAIT(liver, TRAIT_COMEDY_METABOLISM)) || ismonkey(drinker)) - drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick) - . = TRUE - return ..() || . + if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/silencer name = "Silencer" @@ -1245,11 +1262,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/silencer/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(ishuman(drinker) && HAS_MIND_TRAIT(drinker, TRAIT_MIMING)) drinker.set_silence_if_lower(MIMEDRINK_SILENCE_DURATION) - drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick) - . = TRUE - return ..() || . + if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/drunkenblumpkin name = "Drunken Blumpkin" @@ -1289,9 +1306,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/fetching_fizz/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() for(var/obj/item/stack/ore/O in orange(3, drinker)) step_towards(O, get_turf(drinker)) - return ..() //Another reference. Heals those in critical condition extremely quickly. /datum/reagent/consumable/ethanol/hearty_punch @@ -1305,14 +1322,16 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/hearty_punch/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(drinker.health <= 0) - drinker.adjustBruteLoss(-3 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - drinker.adjustFireLoss(-3 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - drinker.adjustCloneLoss(-5 * REM * seconds_per_tick, 0) - drinker.adjustOxyLoss(-4 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - drinker.adjustToxLoss(-3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - . = TRUE - return ..() || . + var/need_mob_update + need_mob_update = drinker.adjustBruteLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += drinker.adjustFireLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += drinker.adjustCloneLoss(-5 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += drinker.adjustOxyLoss(-4 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += drinker.adjustToxLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/bacchus_blessing //An EXTREMELY powerful drink. Smashed in seconds, dead in minutes. name = "Bacchus' Blessing" @@ -1333,20 +1352,19 @@ glass_price = DRINK_PRICE_HIGH /datum/reagent/consumable/ethanol/atomicbomb/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.set_drugginess(100 SECONDS * REM * seconds_per_tick) if(!HAS_TRAIT(drinker, TRAIT_ALCOHOL_TOLERANCE)) drinker.adjust_confusion(2 SECONDS * REM * seconds_per_tick) drinker.set_dizzy_if_lower(20 SECONDS * REM * seconds_per_tick) drinker.adjust_slurring(6 SECONDS * REM * seconds_per_tick) switch(current_cycle) - if(51 to 200) + if(52 to 201) drinker.Sleeping(100 * REM * seconds_per_tick) - . = TRUE - if(201 to INFINITY) + if(202 to INFINITY) drinker.AdjustSleeping(40 * REM * seconds_per_tick) - drinker.adjustToxLoss(2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() + if(drinker.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/gargle_blaster name = "Pan-Galactic Gargle Blaster" @@ -1358,20 +1376,19 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/gargle_blaster/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.adjust_dizzy(3 SECONDS * REM * seconds_per_tick) switch(current_cycle) - if(15 to 45) + if(16 to 46) drinker.adjust_slurring(3 SECONDS * REM * seconds_per_tick) - - if(45 to 55) + if(46 to 56) if(SPT_PROB(30, seconds_per_tick)) drinker.adjust_confusion(3 SECONDS * REM * seconds_per_tick) - if(55 to 200) + if(56 to 201) drinker.set_drugginess(110 SECONDS * REM * seconds_per_tick) - if(200 to INFINITY) - drinker.adjustToxLoss(2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() + if(201 to INFINITY) + if(drinker.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/neurotoxin name = "Neurotoxin" @@ -1387,35 +1404,37 @@ return (pick(TRAIT_PARALYSIS_L_ARM,TRAIT_PARALYSIS_R_ARM,TRAIT_PARALYSIS_R_LEG,TRAIT_PARALYSIS_L_LEG)) /datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.set_drugginess(100 SECONDS * REM * seconds_per_tick) drinker.adjust_dizzy(4 SECONDS * REM * seconds_per_tick) - drinker.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick, 150, required_organ_flag = affected_organ_flags) + var/need_mob_update + need_mob_update = drinker.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick, 150, required_organ_flag = affected_organ_flags) if(SPT_PROB(10, seconds_per_tick)) - drinker.adjustStaminaLoss(10, required_biotype = affected_biotype) + need_mob_update += drinker.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) drinker.drop_all_held_items() to_chat(drinker, span_notice("You cant feel your hands!")) - if(current_cycle > 5) + if(current_cycle > 6) if(SPT_PROB(10, seconds_per_tick)) var/paralyzed_limb = pick_paralyzed_limb() ADD_TRAIT(drinker, paralyzed_limb, type) - drinker.adjustStaminaLoss(10, required_biotype = affected_biotype) - if(current_cycle > 30) - drinker.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - if(current_cycle > 50 && SPT_PROB(7.5, seconds_per_tick)) + need_mob_update += drinker.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + if(current_cycle > 31) + need_mob_update += drinker.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(current_cycle > 51 && SPT_PROB(7.5, seconds_per_tick)) if(!drinker.undergoing_cardiac_arrest() && drinker.can_heartattack()) drinker.set_heartattack(TRUE) if(drinker.stat == CONSCIOUS) drinker.visible_message(span_userdanger("[drinker] clutches at [drinker.p_their()] chest as if [drinker.p_their()] heart stopped!")) - . = TRUE - ..() + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/neurotoxin/on_mob_end_metabolize(mob/living/carbon/drinker) + . = ..() REMOVE_TRAIT(drinker, TRAIT_PARALYSIS_L_ARM, type) REMOVE_TRAIT(drinker, TRAIT_PARALYSIS_R_ARM, type) REMOVE_TRAIT(drinker, TRAIT_PARALYSIS_R_LEG, type) REMOVE_TRAIT(drinker, TRAIT_PARALYSIS_L_LEG, type) drinker.adjustStaminaLoss(10, required_biotype = affected_biotype) - ..() /datum/reagent/consumable/ethanol/hippies_delight name = "Hippie's Delight" @@ -1429,36 +1448,36 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/hippies_delight/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.set_slurring_if_lower(1 SECONDS * REM * seconds_per_tick) switch(current_cycle) - if(1 to 5) + if(2 to 6) drinker.set_dizzy_if_lower(20 SECONDS * REM * seconds_per_tick) drinker.set_drugginess(1 MINUTES * REM * seconds_per_tick) if(SPT_PROB(5, seconds_per_tick)) drinker.emote(pick("twitch","giggle")) - if(5 to 10) + if(6 to 11) drinker.set_jitter_if_lower(40 SECONDS * REM * seconds_per_tick) drinker.set_dizzy_if_lower(40 SECONDS * REM * seconds_per_tick) drinker.set_drugginess(1.5 MINUTES * REM * seconds_per_tick) if(SPT_PROB(10, seconds_per_tick)) drinker.emote(pick("twitch","giggle")) - if (10 to 200) + if (11 to 201) drinker.set_jitter_if_lower(80 SECONDS * REM * seconds_per_tick) drinker.set_dizzy_if_lower(80 SECONDS * REM * seconds_per_tick) drinker.set_drugginess(2 MINUTES * REM * seconds_per_tick) if(SPT_PROB(16, seconds_per_tick)) drinker.emote(pick("twitch","giggle")) - if(200 to INFINITY) + if(201 to INFINITY) drinker.set_jitter_if_lower(120 SECONDS * REM * seconds_per_tick) drinker.set_dizzy_if_lower(120 SECONDS * REM * seconds_per_tick) drinker.set_drugginess(2.5 MINUTES * REM * seconds_per_tick) if(SPT_PROB(23, seconds_per_tick)) drinker.emote(pick("twitch","giggle")) if(SPT_PROB(16, seconds_per_tick)) - drinker.adjustToxLoss(2, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() + if(drinker.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/eggnog name = "Eggnog" @@ -1490,9 +1509,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/narsour/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.adjust_timed_status_effect(6 SECONDS * REM * seconds_per_tick, /datum/status_effect/speech/slurring/cult, max_duration = 6 SECONDS) drinker.adjust_stutter_up_to(6 SECONDS * REM * seconds_per_tick, 6 SECONDS) - return ..() /datum/reagent/consumable/ethanol/triple_sec name = "Triple Sec" @@ -1536,12 +1555,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/quadruple_sec/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() //Securidrink in line with the Screwdriver for engineers or Nothing for mimes var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER) if(liver && HAS_TRAIT(liver, TRAIT_LAW_ENFORCEMENT_METABOLISM)) - drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick) - . = TRUE - return ..() + if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/quintuple_sec name = "Quintuple Sec" @@ -1553,13 +1572,15 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/quintuple_sec/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() //Securidrink in line with the Screwdriver for engineers or Nothing for mimes but STRONG.. var/obj/item/organ/internal/liver/liver = drinker.get_organ_slot(ORGAN_SLOT_LIVER) if(liver && HAS_TRAIT(liver, TRAIT_LAW_ENFORCEMENT_METABOLISM)) - drinker.heal_bodypart_damage(2 * REM * seconds_per_tick, 2 * REM * seconds_per_tick) - drinker.adjustStaminaLoss(-2 * REM * seconds_per_tick, required_biotype = affected_biotype) - . = TRUE - return ..() + var/need_mob_update + need_mob_update = drinker.heal_bodypart_damage(2 * REM * seconds_per_tick, 2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += drinker.adjustStaminaLoss(-2 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/grasshopper name = "Grasshopper" @@ -1592,28 +1613,34 @@ glass_price = DRINK_PRICE_HIGH /datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_metabolize(mob/living/drinker) + . = ..() var/heal_points = 10 if(drinker.health <= 0) heal_points = 20 //heal more if we're in softcrit - for(var/counter in 1 to min(volume, heal_points)) //only heals 1 point of damage per unit on add, for balance reasons - drinker.adjustBruteLoss(-1, required_bodytype = affected_bodytype) - drinker.adjustFireLoss(-1, required_bodytype = affected_bodytype) - drinker.adjustToxLoss(-1, required_biotype = affected_biotype) - drinker.adjustOxyLoss(-1, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - drinker.adjustStaminaLoss(-1, required_biotype = affected_biotype) + var/need_mob_update + var/heal_amt = min(volume, heal_points) //only heals 1 point of damage per unit on add, for balance reasons + need_mob_update = drinker.adjustBruteLoss(-heal_amt, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += drinker.adjustFireLoss(-heal_amt, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += drinker.adjustToxLoss(-heal_amt, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += drinker.adjustOxyLoss(-heal_amt, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += drinker.adjustStaminaLoss(-heal_amt, updating_stamina = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + drinker.updatehealth() drinker.visible_message(span_warning("[drinker] shivers with renewed vigor!"), span_notice("One taste of [lowertext(name)] fills you with energy!")) if(!drinker.stat && heal_points == 20) //brought us out of softcrit drinker.visible_message(span_danger("[drinker] lurches to [drinker.p_their()] feet!"), span_boldnotice("Up and at 'em, kid.")) /datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_life(mob/living/drinker, seconds_per_tick, times_fired) + . = ..() if(drinker.health > 0) - drinker.adjustBruteLoss(-1 * REM * seconds_per_tick, required_bodytype = affected_bodytype) - drinker.adjustFireLoss(-1 * REM * seconds_per_tick, required_bodytype = affected_bodytype) - drinker.adjustToxLoss(-0.5 * REM * seconds_per_tick, required_biotype = affected_biotype) - drinker.adjustOxyLoss(-3 * REM * seconds_per_tick, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - drinker.adjustStaminaLoss(-5 * REM * seconds_per_tick, required_biotype = affected_biotype) - . = TRUE - ..() + var/need_mob_update + need_mob_update = drinker.adjustBruteLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += drinker.adjustFireLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += drinker.adjustToxLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += drinker.adjustOxyLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += drinker.adjustStaminaLoss(-5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/squirt_cider name = "Squirt Cider" @@ -1625,9 +1652,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/squirt_cider/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.satiety += 5 * REM * seconds_per_tick //for context, vitamins give 15 satiety per second - ..() - . = TRUE /datum/reagent/consumable/ethanol/fringe_weaver name = "Fringe Weaver" @@ -1649,9 +1675,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/sugar_rush/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.satiety -= 10 * REM * seconds_per_tick //junky as hell! a whole glass will keep you from being able to eat junk food - ..() - . = TRUE /datum/reagent/consumable/ethanol/crevice_spike name = "Crevice Spike" @@ -1663,6 +1688,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/crevice_spike/on_mob_metabolize(mob/living/drinker) //damage only applies when drink first enters system and won't again until drink metabolizes out + . = ..() drinker.adjustBruteLoss(3 * min(5,volume), required_bodytype = affected_bodytype) //minimum 3 brute damage on ingestion to limit non-drink means of injury - a full 5 unit gulp of the drink trucks you for the full 15 /datum/reagent/consumable/ethanol/sake @@ -1684,9 +1710,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/peppermint_patty/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.apply_status_effect(/datum/status_effect/throat_soothed) drinker.adjust_bodytemperature(5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, drinker.get_body_temp_normal()) - ..() /datum/reagent/consumable/ethanol/alexander name = "Alexander" @@ -1699,24 +1725,24 @@ var/obj/item/shield/mighty_shield /datum/reagent/consumable/ethanol/alexander/on_mob_metabolize(mob/living/drinker) + . = ..() if(ishuman(drinker)) var/mob/living/carbon/human/the_human = drinker for(var/obj/item/shield/the_shield in the_human.contents) mighty_shield = the_shield mighty_shield.block_chance += 10 to_chat(the_human, span_notice("[the_shield] appears polished, although you don't recall polishing it.")) - return TRUE /datum/reagent/consumable/ethanol/alexander/on_mob_life(mob/living/drinker, seconds_per_tick, times_fired) - ..() if(mighty_shield && !(mighty_shield in drinker.contents)) //If you had a shield and lose it, you lose the reagent as well. Otherwise this is just a normal drink. holder.remove_reagent(type, volume) + return ..() /datum/reagent/consumable/ethanol/alexander/on_mob_end_metabolize(mob/living/drinker) + . = ..() if(mighty_shield) mighty_shield.block_chance -= 10 to_chat(drinker,span_notice("You notice [mighty_shield] looks worn again. Weird.")) - ..() /datum/reagent/consumable/ethanol/amaretto_alexander name = "Amaretto Alexander" @@ -1748,7 +1774,7 @@ glass_price = DRINK_PRICE_MEDIUM /datum/reagent/consumable/ethanol/between_the_sheets/on_mob_life(mob/living/drinker, seconds_per_tick, times_fired) - ..() + . = ..() var/is_between_the_sheets = FALSE for(var/obj/item/bedsheet/bedsheet in range(drinker.loc, 0)) if(bedsheet.loc != drinker.loc) // bedsheets in your backpack/neck don't count @@ -1759,15 +1785,18 @@ if(!drinker.IsSleeping() || !is_between_the_sheets) return + var/need_mob_update if(drinker.getBruteLoss() && drinker.getFireLoss()) //If you are damaged by both types, slightly increased healing but it only heals one. The more the merrier wink wink. if(prob(50)) - drinker.adjustBruteLoss(-0.25 * REM * seconds_per_tick, required_bodytype = affected_bodytype) + need_mob_update = drinker.adjustBruteLoss(-0.25 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) else - drinker.adjustFireLoss(-0.25 * REM * seconds_per_tick, required_bodytype = affected_bodytype) + need_mob_update = drinker.adjustFireLoss(-0.25 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) else if(drinker.getBruteLoss()) //If you have only one, it still heals but not as well. - drinker.adjustBruteLoss(-0.2 * REM * seconds_per_tick, required_bodytype = affected_bodytype) + need_mob_update = drinker.adjustBruteLoss(-0.2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) else if(drinker.getFireLoss()) - drinker.adjustFireLoss(-0.2 * REM * seconds_per_tick, required_bodytype = affected_bodytype) + need_mob_update = drinker.adjustFireLoss(-0.2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/kamikaze name = "Kamikaze" @@ -1806,11 +1835,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/fernet/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(drinker.nutrition <= NUTRITION_LEVEL_STARVING) - drinker.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + if(drinker.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH drinker.adjust_nutrition(-5 * REM * seconds_per_tick) drinker.overeatduration = 0 - return ..() /datum/reagent/consumable/ethanol/fernet_cola name = "Fernet Cola" @@ -1822,11 +1852,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/fernet_cola/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(drinker.nutrition <= NUTRITION_LEVEL_STARVING) - drinker.adjustToxLoss(0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + if(drinker.adjustToxLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH drinker.adjust_nutrition(-3 * REM * seconds_per_tick) drinker.overeatduration = 0 - return ..() /datum/reagent/consumable/ethanol/fanciulli name = "Fanciulli" @@ -1839,15 +1870,14 @@ glass_price = DRINK_PRICE_HIGH /datum/reagent/consumable/ethanol/fanciulli/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.adjust_nutrition(-5 * REM * seconds_per_tick) drinker.overeatduration = 0 - return ..() /datum/reagent/consumable/ethanol/fanciulli/on_mob_metabolize(mob/living/drinker) + . = ..() if(drinker.health > 0) drinker.adjustStaminaLoss(20, required_biotype = affected_biotype) - . = TRUE - ..() /datum/reagent/consumable/ethanol/branca_menta name = "Branca Menta" @@ -1860,14 +1890,13 @@ glass_price = DRINK_PRICE_MEDIUM /datum/reagent/consumable/ethanol/branca_menta/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.adjust_bodytemperature(-20 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, T0C) - return ..() /datum/reagent/consumable/ethanol/branca_menta/on_mob_metabolize(mob/living/drinker) + . = ..() if(drinker.health > 0) drinker.adjustStaminaLoss(35, required_biotype = affected_biotype) - . = TRUE - ..() /datum/reagent/consumable/ethanol/blank_paper name = "Blank Paper" @@ -1880,11 +1909,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/blank_paper/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(ishuman(drinker) && HAS_MIND_TRAIT(drinker, TRAIT_MIMING)) drinker.set_silence_if_lower(MIMEDRINK_SILENCE_DURATION) - drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick) - . = TRUE - return ..() + if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/fruit_wine name = "Fruit Wine" @@ -2011,13 +2040,16 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/wizz_fizz/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() //A healing drink similar to Quadruple Sec, Ling Stings, and Screwdrivers for the Wizznerds; the check is consistent with the changeling sting if(drinker?.mind?.has_antag_datum(/datum/antagonist/wizard)) - drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick) - drinker.adjustOxyLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - drinker.adjustToxLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - drinker.adjustStaminaLoss(-1 * REM * seconds_per_tick, required_biotype = affected_biotype) - return ..() + var/need_mob_update + need_mob_update = drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += drinker.adjustOxyLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += drinker.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += drinker.adjustStaminaLoss(-1 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/bug_spray name = "Bug Spray" @@ -2027,19 +2059,20 @@ quality = DRINK_GOOD taste_description = "the pain of ten thousand slain mosquitos" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED + affected_biotype = MOB_BUG /datum/reagent/consumable/ethanol/bug_spray/on_new(data) . = ..() AddElement(/datum/element/bugkiller_reagent) /datum/reagent/consumable/ethanol/bug_spray/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() // Does some damage to bug biotypes - var/did_damage = drinker.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = MOB_BUG) - // Random chance of causing a screm if we did some damage - if(did_damage && SPT_PROB(2, seconds_per_tick)) - drinker.emote("scream") - - return ..() || did_damage + if(drinker.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH + // Random chance of causing a screm if we did some damage + if(SPT_PROB(2, seconds_per_tick)) + drinker.emote("scream") /datum/reagent/consumable/ethanol/applejack name = "Applejack" @@ -2068,10 +2101,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/turbo/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(2, seconds_per_tick)) to_chat(drinker, span_notice("[pick("You feel disregard for the rule of law.", "You feel pumped!", "Your head is pounding.", "Your thoughts are racing..")]")) - drinker.adjustStaminaLoss(-0.25 * drinker.get_drunk_amount() * REM * seconds_per_tick, required_biotype = affected_biotype) - return ..() + if(drinker.adjustStaminaLoss(-0.25 * drinker.get_drunk_amount() * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/old_timer name = "Old Timer" @@ -2083,6 +2117,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/old_timer/on_mob_life(mob/living/carbon/human/metabolizer, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(10, seconds_per_tick) && istype(metabolizer)) metabolizer.age += 1 if(metabolizer.age > 70) @@ -2097,8 +2132,6 @@ metabolizer.visible_message(span_notice("[metabolizer] becomes older than any man should be.. and crumbles into dust!")) metabolizer.dust(just_ash = FALSE, drop_items = TRUE, force = FALSE) - return ..() - /datum/reagent/consumable/ethanol/rubberneck name = "Rubberneck" description = "A quality rubberneck should not contain any gross natural ingredients." @@ -2135,11 +2168,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/trappist/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(drinker.mind?.holy_role) - drinker.adjustFireLoss(-2.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) + if(drinker.adjustFireLoss(-2.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)) + . = UPDATE_MOB_HEALTH drinker.adjust_jitter(-2 SECONDS * REM * seconds_per_tick) drinker.adjust_stutter(-2 SECONDS * REM * seconds_per_tick) - return ..() /datum/reagent/consumable/ethanol/blazaam name = "Blazaam" @@ -2150,6 +2184,7 @@ var/stored_teleports = 0 /datum/reagent/consumable/ethanol/blazaam/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(drinker.get_drunk_amount() > 40) if(stored_teleports) do_teleport(drinker, get_turf(drinker), rand(1,3), channel = TELEPORT_CHANNEL_WORMHOLE) @@ -2159,7 +2194,6 @@ stored_teleports += rand(2, 6) if(prob(70)) drinker.vomit(vomit_flags = VOMIT_CATEGORY_DEFAULT, vomit_type = /obj/effect/decal/cleanable/vomit/purple) - return ..() /datum/reagent/consumable/ethanol/planet_cracker name = "Planet Cracker" @@ -2181,9 +2215,8 @@ // Heats the user up while the reagent is in the body. Occasionally makes you burst into flames. drinker.adjust_bodytemperature(25 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick) if (SPT_PROB(2.5, seconds_per_tick)) - drinker.adjust_fire_stacks(1) + drinker.adjust_fire_stacks(1 * REM * seconds_per_tick) drinker.ignite_mob() - ..() /datum/reagent/consumable/ethanol/painkiller name = "Painkiller" @@ -2211,6 +2244,7 @@ taste_description = "a horrible emulsion of pineapple and olive oil" /datum/reagent/consumable/ethanol/pina_olivada/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(8, seconds_per_tick)) drinker.manual_emote(pick("coughs up some oil", "swallows the lump in [drinker.p_their()] throat", "gags", "chokes up a bit")) if(SPT_PROB(3, seconds_per_tick)) @@ -2222,7 +2256,6 @@ "Your throat feels horrible.", ) to_chat(drinker, span_notice(pick(messages))) - return ..() /datum/reagent/consumable/ethanol/pruno // pruno mix is in drink_reagents name = "Pruno" @@ -2233,8 +2266,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/pruno/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.adjust_disgust(5 * REM * seconds_per_tick) - ..() /datum/reagent/consumable/ethanol/ginger_amaretto name = "Ginger Amaretto" @@ -2274,9 +2307,10 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/kortara/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(drinker.getBruteLoss() && SPT_PROB(10, seconds_per_tick)) - drinker.heal_bodypart_damage(1,0) - . = TRUE + if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 0, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/ethanol/sea_breeze name = "Sea Breeze" @@ -2288,8 +2322,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/sea_breeze/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.apply_status_effect(/datum/status_effect/throat_soothed) - ..() /datum/reagent/consumable/ethanol/white_tiziran name = "White Tiziran" @@ -2310,8 +2344,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/drunken_espatier/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.add_mood_event("numb", /datum/mood_event/narcotic_medium, name) //comfortably numb - ..() /datum/reagent/consumable/ethanol/drunken_espatier/on_mob_metabolize(mob/living/drinker) . = ..() @@ -2332,12 +2366,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/protein_blend/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() drinker.adjust_nutrition(2 * REM * seconds_per_tick) if(!islizard(drinker)) drinker.adjust_disgust(5 * REM * seconds_per_tick) else drinker.adjust_disgust(2 * REM * seconds_per_tick) - ..() /datum/reagent/consumable/ethanol/mushi_kombucha name = "Mushi Kombucha" @@ -2358,9 +2392,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/triumphal_arch/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(islizard(drinker)) drinker.add_mood_event("triumph", /datum/mood_event/memories_of_home, name) - ..() /datum/reagent/consumable/ethanol/the_juice name = "The Juice" @@ -2378,9 +2412,9 @@ drinker.gain_trauma(prophet_trauma, TRAUMA_RESILIENCE_ABSOLUTE) /datum/reagent/consumable/ethanol/the_juice/on_mob_end_metabolize(mob/living/carbon/drinker) + . = ..() if(prophet_trauma) QDEL_NULL(prophet_trauma) - return ..() //a jacked up absinthe that causes hallucinations to the game master controller basically, used in smuggling objectives /datum/reagent/consumable/ethanol/ritual_wine @@ -2517,11 +2551,10 @@ var/hal_cap = 24 /datum/reagent/consumable/ethanol/helianthus/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(5, seconds_per_tick)) drinker.adjust_hallucinations_up_to(4 SECONDS * REM * seconds_per_tick, 48 SECONDS) - ..() - /datum/reagent/consumable/ethanol/plumwine name = "Plum wine" description = "Plums turned into wine." @@ -2552,8 +2585,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/gin_garden/on_mob_life(mob/living/carbon/doll, seconds_per_tick, times_fired) + . = ..() doll.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, doll.get_body_temp_normal()) - ..() /datum/reagent/consumable/ethanol/wine_voltaic name = "Voltaic Yellow Wine" @@ -2587,8 +2620,8 @@ ADD_TRAIT(affected_mob, TRAIT_SHOCKIMMUNE, type) /datum/reagent/consumable/ethanol/telepole/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_SHOCKIMMUNE, type) - return ..() /datum/reagent/consumable/ethanol/telepole/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) //can't be on life because of the way blood works. . = ..() @@ -2610,11 +2643,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/ethanol/pod_tesla/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() affected_mob.add_traits(list(TRAIT_SHOCKIMMUNE,TRAIT_TESLA_SHOCKIMMUNE,TRAIT_FEARLESS), type) - /datum/reagent/consumable/ethanol/pod_tesla/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() affected_mob.remove_traits(list(TRAIT_SHOCKIMMUNE,TRAIT_TESLA_SHOCKIMMUNE,TRAIT_FEARLESS), type) /datum/reagent/consumable/ethanol/pod_tesla/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) //can't be on life because of the way blood works. diff --git a/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm index 36444d6229b812..8270b42f502d08 100644 --- a/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drinks/drink_reagents.dm @@ -8,10 +8,10 @@ default_container = /obj/item/reagent_containers/cup/glass/bottle/juice/orangejuice /datum/reagent/consumable/orangejuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.getOxyLoss() && SPT_PROB(16, seconds_per_tick)) - affected_mob.adjustOxyLoss(-1, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - . = TRUE - ..() + if(affected_mob.adjustOxyLoss(-1 * REM * seconds_per_tick, FALSE, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/tomatojuice name = "Tomato Juice" @@ -22,10 +22,10 @@ default_container = /obj/item/reagent_containers/cup/glass/bottle/juice/tomatojuice /datum/reagent/consumable/tomatojuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.getFireLoss() && SPT_PROB(10, seconds_per_tick)) - affected_mob.heal_bodypart_damage(0, 1) - . = TRUE - ..() + if(affected_mob.heal_bodypart_damage(brute = 0, burn = 1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/limejuice name = "Lime Juice" @@ -37,10 +37,10 @@ default_container = /obj/item/reagent_containers/cup/glass/bottle/juice/limejuice /datum/reagent/consumable/limejuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.getToxLoss() && SPT_PROB(10, seconds_per_tick)) - affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() + if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/carrotjuice name = "Carrot Juice" @@ -50,17 +50,20 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/carrotjuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_eye_blur(-2 SECONDS * REM * seconds_per_tick) affected_mob.adjust_temp_blindness(-2 SECONDS * REM * seconds_per_tick) + var/need_mob_update switch(current_cycle) if(1 to 20) //nothing if(21 to 110) if(SPT_PROB(100 * (1 - (sqrt(110 - current_cycle) / 10)), seconds_per_tick)) - affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, -2) + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, -2 * REM * seconds_per_tick) if(110 to INFINITY) - affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, -2) - return ..() + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_EYES, -2 * REM * seconds_per_tick) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/berryjuice name = "Berry Juice" @@ -84,9 +87,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/poisonberryjuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() + . = ..() + if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/watermelonjuice name = "Watermelon Juice" @@ -111,11 +114,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/banana/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER) if((liver && HAS_TRAIT(liver, TRAIT_COMEDY_METABOLISM)) || ismonkey(affected_mob)) - affected_mob.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick) - . = TRUE - ..() + if(affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/nothing name = "Nothing" @@ -128,11 +131,11 @@ icon_state = "shotglass" /datum/reagent/consumable/nothing/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() if(ishuman(drinker) && HAS_MIND_TRAIT(drinker, TRAIT_MIMING)) drinker.set_silence_if_lower(MIMEDRINK_SILENCE_DURATION) - drinker.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick) - . = TRUE - ..() + if(drinker.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/laughter name = "Laughter" @@ -143,9 +146,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/laughter/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.emote("laugh") affected_mob.add_mood_event("chemical_laughter", /datum/mood_event/chemical_laughter) - ..() /datum/reagent/consumable/superlaughter name = "Super Laughter" @@ -156,11 +159,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/superlaughter/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(16, seconds_per_tick)) affected_mob.visible_message(span_danger("[affected_mob] bursts out into a fit of uncontrollable laughter!"), span_userdanger("You burst out in a fit of uncontrollable laughter!")) affected_mob.Stun(5) affected_mob.add_mood_event("chemical_laughter", /datum/mood_event/chemical_superlaughter) - ..() /datum/reagent/consumable/potato_juice name = "Potato Juice" @@ -179,11 +182,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/pickle/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER) if((liver && HAS_TRAIT(liver, TRAIT_CORONER_METABOLISM))) - affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() + if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/grapejuice name = "Grape Juice" @@ -219,11 +222,11 @@ /datum/reagent/consumable/milk/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) if(affected_mob.getBruteLoss() && SPT_PROB(10, seconds_per_tick)) - affected_mob.heal_bodypart_damage(1,0) - . = TRUE + if(affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 0, updating_health = FALSE)) + . = UPDATE_MOB_HEALTH if(holder.has_reagent(/datum/reagent/consumable/capsaicin)) holder.remove_reagent(/datum/reagent/consumable/capsaicin, 1 * seconds_per_tick) - ..() + return ..() || . /datum/reagent/consumable/soymilk name = "Soy Milk" @@ -234,10 +237,10 @@ default_container = /obj/item/reagent_containers/condiment/soymilk /datum/reagent/consumable/soymilk/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.getBruteLoss() && SPT_PROB(10, seconds_per_tick)) - affected_mob.heal_bodypart_damage(1, 0) - . = TRUE - ..() + if(affected_mob.heal_bodypart_damage(1, 0)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/cream name = "Cream" @@ -265,8 +268,8 @@ /datum/reagent/consumable/coffee/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick) - ..() /datum/reagent/consumable/coffee/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick) @@ -276,8 +279,7 @@ affected_mob.adjust_bodytemperature(25 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal()) if(holder.has_reagent(/datum/reagent/consumable/frostoil)) holder.remove_reagent(/datum/reagent/consumable/frostoil, 5 * REM * seconds_per_tick) - ..() - . = TRUE + return ..() || . /datum/reagent/consumable/tea name = "Tea" @@ -290,12 +292,16 @@ default_container = /obj/item/reagent_containers/cup/glass/mug/tea /datum/reagent/consumable/tea/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_dizzy(-4 SECONDS * REM * seconds_per_tick) affected_mob.adjust_drowsiness(-2 SECONDS * REM * seconds_per_tick) affected_mob.adjust_jitter(-6 SECONDS * REM * seconds_per_tick) affected_mob.AdjustSleeping(-20 * REM * seconds_per_tick) if(affected_mob.getToxLoss() && SPT_PROB(10, seconds_per_tick)) - affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype) + if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH + affected_mob.adjust_bodytemperature(20 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal()) + var/to_chatted = FALSE for(var/datum/wound/iter_wound as anything in affected_mob.all_wounds) if(SPT_PROB(10, seconds_per_tick)) @@ -303,9 +309,6 @@ if(!to_chatted && helped) to_chat(affected_mob, span_notice("A calm, relaxed feeling suffuses you. Your wounds feel a little healthier.")) to_chatted = TRUE - affected_mob.adjust_bodytemperature(20 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal()) - ..() - . = TRUE // Different handling, different name. // Returns FALSE by default so broken bones and 'loss' wounds don't give a false message @@ -348,10 +351,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/tea/arnold_palmer/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(2.5, seconds_per_tick)) to_chat(affected_mob, span_notice("[pick("You remember to square your shoulders.","You remember to keep your head down.","You can't decide between squaring your shoulders and keeping your head down.","You remember to relax.","You think about how someday you'll get two strokes off your golf game.")]")) - ..() - . = TRUE /datum/reagent/consumable/icecoffee name = "Iced Coffee" @@ -362,13 +364,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/icecoffee/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick) affected_mob.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick) affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick) affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick) - ..() - . = TRUE /datum/reagent/consumable/hot_ice_coffee name = "Hot Ice Coffee" @@ -379,14 +380,14 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/hot_ice_coffee/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick) affected_mob.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick) affected_mob.AdjustSleeping(-60 * REM * seconds_per_tick) affected_mob.adjust_bodytemperature(-7 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick) - affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - . = TRUE + if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/icetea name = "Iced Tea" @@ -397,14 +398,14 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/icetea/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_dizzy(-4 SECONDS * REM * seconds_per_tick) affected_mob.adjust_drowsiness(-2 SECONDS * REM * seconds_per_tick) affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick) if(affected_mob.getToxLoss() && SPT_PROB(10, seconds_per_tick)) - affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype) + if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() - . = TRUE /datum/reagent/consumable/space_cola name = "Cola" @@ -414,9 +415,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/space_cola/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_drowsiness(-10 SECONDS * REM * seconds_per_tick) affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() /datum/reagent/consumable/roy_rogers name = "Roy Rogers" @@ -441,22 +442,21 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/nuka_cola/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/nuka_cola) /datum/reagent/consumable/nuka_cola/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/nuka_cola) - ..() /datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.set_jitter_if_lower(40 SECONDS * REM * seconds_per_tick) affected_mob.set_drugginess(1 MINUTES * REM * seconds_per_tick) affected_mob.adjust_dizzy(3 SECONDS * REM * seconds_per_tick) affected_mob.remove_status_effect(/datum/status_effect/drowsiness) affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick) affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() - . = TRUE /datum/reagent/consumable/rootbeer name = "root beer" @@ -471,15 +471,16 @@ var/effect_enabled = FALSE /datum/reagent/consumable/rootbeer/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_DOUBLE_TAP, type) if(current_cycle > 10) to_chat(affected_mob, span_warning("You feel kinda tired as your sugar rush wears off...")) affected_mob.adjustStaminaLoss(min(80, current_cycle * 3), required_biotype = affected_biotype) - affected_mob.adjust_drowsiness(current_cycle * 2 SECONDS) - ..() + affected_mob.adjust_drowsiness((current_cycle-1) * 2 SECONDS) /datum/reagent/consumable/rootbeer/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - if(current_cycle >= 3 && !effect_enabled) // takes a few seconds for the bonus to kick in to prevent microdosing + . = ..() + if(current_cycle > 3 && !effect_enabled) // takes a few seconds for the bonus to kick in to prevent microdosing to_chat(affected_mob, span_notice("You feel your trigger finger getting itchy...")) ADD_TRAIT(affected_mob, TRAIT_DOUBLE_TAP, type) effect_enabled = TRUE @@ -490,9 +491,6 @@ if(current_cycle > 10) affected_mob.adjust_dizzy(3 SECONDS * REM * seconds_per_tick) - ..() - . = TRUE - /datum/reagent/consumable/grey_bull name = "Grey Bull" description = "Grey Bull, it gives you gloves!" @@ -502,7 +500,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/grey_bull/on_mob_metabolize(mob/living/carbon/affected_atom) - ..() + . = ..() ADD_TRAIT(affected_atom, TRAIT_SHOCKIMMUNE, type) var/obj/item/organ/internal/liver/liver = affected_atom.get_organ_slot(ORGAN_SLOT_LIVER) if(HAS_TRAIT(liver, TRAIT_MAINTENANCE_METABOLISM)) @@ -510,16 +508,16 @@ metabolization_rate *= 0.8 /datum/reagent/consumable/grey_bull/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_SHOCKIMMUNE, type) - ..() /datum/reagent/consumable/grey_bull/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.set_jitter_if_lower(40 SECONDS * REM * seconds_per_tick) affected_mob.adjust_dizzy(2 SECONDS * REM * seconds_per_tick) affected_mob.remove_status_effect(/datum/status_effect/drowsiness) affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick) affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() /datum/reagent/consumable/spacemountainwind name = "SM Wind" @@ -529,12 +527,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/spacemountainwind/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_drowsiness(-14 SECONDS * REM * seconds_per_tick) affected_mob.AdjustSleeping(-20 * REM * seconds_per_tick) affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick) - ..() - . = TRUE /datum/reagent/consumable/dr_gibb name = "Dr. Gibb" @@ -544,9 +541,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/dr_gibb/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_drowsiness(-12 SECONDS * REM * seconds_per_tick) affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() /datum/reagent/consumable/space_up name = "Space-Up" @@ -556,8 +553,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/space_up/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_bodytemperature(-8 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() /datum/reagent/consumable/lemon_lime name = "Lemon Lime" @@ -567,8 +564,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/lemon_lime/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_bodytemperature(-8 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() /datum/reagent/consumable/pwr_game name = "Pwr Game" @@ -585,10 +582,10 @@ You feel as though a great secret of the universe has been made known to you...") /datum/reagent/consumable/pwr_game/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_bodytemperature(-8 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) if(SPT_PROB(5, seconds_per_tick)) affected_mob.mind?.adjust_experience(/datum/skill/gaming, 5) - ..() /datum/reagent/consumable/shamblers name = "Shambler's Juice" @@ -598,8 +595,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/shamblers/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_bodytemperature(-8 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() /datum/reagent/consumable/sodawater name = "Soda Water" @@ -615,10 +612,10 @@ mytray.adjust_plant_health(round(volume * 0.1)) /datum/reagent/consumable/sodawater/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick) affected_mob.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick) affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() /datum/reagent/consumable/tonic name = "Tonic Water" @@ -628,12 +625,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/tonic/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick) affected_mob.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick) affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick) affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() - . = TRUE /datum/reagent/consumable/wellcheers name = "Wellcheers" @@ -643,15 +639,18 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/wellcheers/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_drowsiness(3 SECONDS * REM * seconds_per_tick) + var/need_mob_update switch(affected_mob.mob_mood.sanity_level) if (SANITY_INSANE to SANITY_CRAZY) - affected_mob.adjustStaminaLoss(3 * REM * seconds_per_tick, 0) + need_mob_update = affected_mob.adjustStaminaLoss(3 * REM * seconds_per_tick, updating_stamina = FALSE) if (SANITY_UNSTABLE to SANITY_DISTURBED) affected_mob.add_mood_event("wellcheers", /datum/mood_event/wellcheers) if (SANITY_NEUTRAL to SANITY_GREAT) - affected_mob.adjustBruteLoss(-1.5 * REM * seconds_per_tick, 0) - return ..() + need_mob_update = affected_mob.adjustBruteLoss(-1.5 * REM * seconds_per_tick, updating_health = FALSE) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/monkey_energy name = "Monkey Energy" @@ -662,26 +661,26 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/monkey_energy/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.set_jitter_if_lower(80 SECONDS * REM * seconds_per_tick) affected_mob.adjust_dizzy(2 SECONDS * REM * seconds_per_tick) affected_mob.remove_status_effect(/datum/status_effect/drowsiness) affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick) affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() /datum/reagent/consumable/monkey_energy/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() if(ismonkey(affected_mob)) affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/monkey_energy) /datum/reagent/consumable/monkey_energy/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/monkey_energy) - ..() /datum/reagent/consumable/monkey_energy/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(7.5, seconds_per_tick)) affected_mob.say(pick_list_replacements(BOOMER_FILE, "boomer"), forced = /datum/reagent/consumable/monkey_energy) - ..() /datum/reagent/consumable/ice name = "Ice" @@ -693,8 +692,9 @@ default_container = /obj/item/reagent_containers/cup/glass/ice /datum/reagent/consumable/ice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() + . = ..() + if(affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, FALSE, affected_mob.get_body_temp_normal())) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/soy_latte name = "Soy Latte" @@ -706,15 +706,17 @@ glass_price = DRINK_PRICE_EASY /datum/reagent/consumable/soy_latte/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick) affected_mob.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick) - affected_mob.SetSleeping(0) + var/need_mob_update + need_mob_update = affected_mob.SetSleeping(0) affected_mob.adjust_bodytemperature(5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal()) affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick) if(affected_mob.getBruteLoss() && SPT_PROB(10, seconds_per_tick)) - affected_mob.heal_bodypart_damage(1,0) - ..() - . = TRUE + need_mob_update += affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 0, updating_health = FALSE) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/cafe_latte name = "Cafe Latte" @@ -726,15 +728,17 @@ glass_price = DRINK_PRICE_EASY /datum/reagent/consumable/cafe_latte/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_dizzy(-10 SECONDS * REM * seconds_per_tick) affected_mob.adjust_drowsiness(-12 SECONDS * REM * seconds_per_tick) - affected_mob.SetSleeping(0) + var/need_mob_update + need_mob_update = affected_mob.SetSleeping(0) affected_mob.adjust_bodytemperature(5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal()) affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick) if(affected_mob.getBruteLoss() && SPT_PROB(10, seconds_per_tick)) - affected_mob.heal_bodypart_damage(1, 0) - ..() - . = TRUE + need_mob_update += affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 0, updating_health = FALSE) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/doctor_delight name = "The Doctor's Delight" @@ -745,17 +749,19 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/doctor_delight/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) if(affected_mob.nutrition && (affected_mob.nutrition - 2 > 0)) var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER) if(!(HAS_TRAIT(liver, TRAIT_MEDICAL_METABOLISM))) // Drains the nutrition of the holder. Not medical doctors though, since it's the Doctor's Delight! affected_mob.adjust_nutrition(-2 * REM * seconds_per_tick) - ..() - . = TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/cinderella name = "Cinderella" @@ -766,8 +772,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/cinderella/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_disgust(-5 * REM * seconds_per_tick) - return ..() /datum/reagent/consumable/cherryshake name = "Cherry Shake" @@ -886,8 +892,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/grape_soda/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() /datum/reagent/consumable/milk/chocolate_milk name = "Chocolate Milk" @@ -908,11 +914,11 @@ /datum/reagent/consumable/hot_coco/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) affected_mob.adjust_bodytemperature(5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal()) if(affected_mob.getBruteLoss() && SPT_PROB(10, seconds_per_tick)) - affected_mob.heal_bodypart_damage(1, 0) - . = TRUE + if(affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 0, updating_health = FALSE)) + . = UPDATE_MOB_HEALTH if(holder.has_reagent(/datum/reagent/consumable/capsaicin)) holder.remove_reagent(/datum/reagent/consumable/capsaicin, 2 * REM * seconds_per_tick) - ..() + return ..() || . /datum/reagent/consumable/italian_coco name = "Italian Hot Chocolate" @@ -924,8 +930,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/italian_coco/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_bodytemperature(5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, 0, affected_mob.get_body_temp_normal()) - return ..() /datum/reagent/consumable/menthol name = "Menthol" @@ -936,8 +942,8 @@ default_container = /obj/item/reagent_containers/cup/glass/bottle/juice/menthol /datum/reagent/consumable/menthol/on_mob_life(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.apply_status_effect(/datum/status_effect/throat_soothed) - ..() /datum/reagent/consumable/grenadine name = "Grenadine" @@ -977,8 +983,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/cream_soda/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_bodytemperature(-5 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - ..() /datum/reagent/consumable/sol_dry name = "Sol Dry" @@ -989,8 +995,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/sol_dry/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_disgust(-5 * REM * seconds_per_tick) - ..() /datum/reagent/consumable/shirley_temple name = "Shirley Temple" @@ -1014,8 +1020,9 @@ var/current_size = RESIZE_DEFAULT_SIZE /datum/reagent/consumable/red_queen/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(50, seconds_per_tick)) - return ..() + return var/newsize = pick(0.5, 0.75, 1, 1.50, 2) newsize *= RESIZE_DEFAULT_SIZE @@ -1023,12 +1030,11 @@ current_size = newsize if(SPT_PROB(23, seconds_per_tick)) affected_mob.emote("sneeze") - ..() /datum/reagent/consumable/red_queen/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() affected_mob.update_transform(RESIZE_DEFAULT_SIZE/current_size) current_size = RESIZE_DEFAULT_SIZE - ..() /datum/reagent/consumable/bungojuice name = "Bungo Juice" @@ -1052,10 +1058,10 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/aloejuice/on_mob_life(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.getToxLoss() && SPT_PROB(16, seconds_per_tick)) - affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype) - ..() - . = TRUE + if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/agua_fresca name = "Agua Fresca" @@ -1066,10 +1072,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/agua_fresca/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_bodytemperature(-8 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) if(affected_mob.getToxLoss() && SPT_PROB(10, seconds_per_tick)) - affected_mob.adjustToxLoss(-0.5, FALSE, required_biotype = affected_biotype) - return ..() + if(affected_mob.adjustToxLoss(-0.5, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/mushroom_tea name = "Mushroom Tea" @@ -1080,10 +1087,10 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/mushroom_tea/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(islizard(affected_mob)) - affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - ..() - . = TRUE + if(affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)) + return UPDATE_MOB_HEALTH //Moth Stuff /datum/reagent/consumable/toechtauese_juice @@ -1166,10 +1173,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/cucumberlemonade/on_mob_life(mob/living/carbon/doll, seconds_per_tick, times_fired) + . = ..() doll.adjust_bodytemperature(-8 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, doll.get_body_temp_normal()) if(doll.getToxLoss() && SPT_PROB(10, seconds_per_tick)) - doll.adjustToxLoss(-0.5, FALSE, required_biotype = affected_biotype) - return ..() + if(doll.adjustToxLoss(-0.5, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/mississippi_queen name = "Mississippi Queen" @@ -1179,17 +1187,16 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/mississippi_queen/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() switch(current_cycle) - if(10 to 20) + if(11 to 21) drinker.adjust_dizzy(4 SECONDS * REM * seconds_per_tick) - if(20 to 30) + if(21 to 31) if(SPT_PROB(15, seconds_per_tick)) drinker.adjust_confusion(4 SECONDS * REM * seconds_per_tick) - if(30 to 200) + if(31 to 201) drinker.adjust_hallucinations(60 SECONDS * REM * seconds_per_tick) - return ..() - /datum/reagent/consumable/t_letter name = "T" description = "You expected to find this in a soup, but this is fine too." @@ -1198,14 +1205,15 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/t_letter/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(!HAS_MIND_TRAIT(affected_mob, TRAIT_MIMING)) - return ..() + return affected_mob.set_silence_if_lower(MIMEDRINK_SILENCE_DURATION) affected_mob.adjust_drowsiness(-6 SECONDS * REM * seconds_per_tick) affected_mob.AdjustSleeping(-40 * REM * seconds_per_tick) if(affected_mob.getToxLoss() && SPT_PROB(25, seconds_per_tick)) - affected_mob.adjustToxLoss(-2, FALSE, required_biotype = affected_biotype) - return ..() + if(affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/hakka_mate name = "Hakka-Mate" diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index 23d6010f1a94bb..95dcf4995287c5 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -18,22 +18,23 @@ addiction_types = list(/datum/addiction/hallucinogens = 10) //4 per 2 seconds /datum/reagent/drug/space_drugs/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.set_drugginess(30 SECONDS * REM * seconds_per_tick) if(isturf(affected_mob.loc) && !isspaceturf(affected_mob.loc) && !HAS_TRAIT(affected_mob, TRAIT_IMMOBILIZED) && SPT_PROB(5, seconds_per_tick)) step(affected_mob, pick(GLOB.cardinals)) if(SPT_PROB(3.5, seconds_per_tick)) affected_mob.emote(pick("twitch","drool","moan","giggle")) - ..() /datum/reagent/drug/space_drugs/overdose_start(mob/living/affected_mob) + . = ..() to_chat(affected_mob, span_userdanger("You start tripping hard!")) affected_mob.add_mood_event("[type]_overdose", /datum/mood_event/overdose, name) /datum/reagent/drug/space_drugs/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() var/hallucination_duration_in_seconds = (affected_mob.get_timed_status_effect_duration(/datum/status_effect/hallucination) / 10) if(hallucination_duration_in_seconds < volume && SPT_PROB(10, seconds_per_tick)) affected_mob.adjust_hallucinations(10 SECONDS) - ..() /datum/reagent/drug/cannabis name = "Cannabis" @@ -45,6 +46,7 @@ metabolization_rate = 0.125 * REAGENTS_METABOLISM /datum/reagent/drug/cannabis/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.apply_status_effect(/datum/status_effect/stoned) if(SPT_PROB(1, seconds_per_tick)) var/smoke_message = pick("You feel relaxed.","You feel calmed.","Your mouth feels dry.","You could use some water.","Your heart beats quickly.","You feel clumsy.","You crave junk food.","You notice you've been moving more slowly.") @@ -58,7 +60,6 @@ if(SPT_PROB(4, seconds_per_tick) && affected_mob.buckled && affected_mob.body_position != LYING_DOWN && !affected_mob.IsParalyzed()) //chance to be couchlocked if sitting to_chat(affected_mob, "It's too comfy to move...") affected_mob.Paralyze(10 SECONDS) - return ..() /datum/reagent/drug/nicotine name = "Nicotine" @@ -79,6 +80,7 @@ mytray.adjust_pestlevel(-rand(1, 2)) /datum/reagent/drug/nicotine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(0.5, seconds_per_tick)) var/smoke_message = pick("You feel relaxed.", "You feel calmed.","You feel alert.","You feel rugged.") to_chat(affected_mob, span_notice("[smoke_message]")) @@ -89,14 +91,15 @@ affected_mob.AdjustUnconscious(-50 * REM * seconds_per_tick) affected_mob.AdjustParalyzed(-50 * REM * seconds_per_tick) affected_mob.AdjustImmobilized(-50 * REM * seconds_per_tick) - ..() - . = TRUE + return UPDATE_MOB_HEALTH /datum/reagent/drug/nicotine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustToxLoss(0.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustOxyLoss(1.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - ..() - . = TRUE + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustToxLoss(0.1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustOxyLoss(1.1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/drug/krokodil name = "Krokodil" @@ -110,28 +113,28 @@ /datum/reagent/drug/krokodil/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/high_message = pick("You feel calm.", "You feel collected.", "You feel like you need to relax.") if(SPT_PROB(2.5, seconds_per_tick)) to_chat(affected_mob, span_notice("[high_message]")) affected_mob.add_mood_event("smacked out", /datum/mood_event/narcotic_heavy, name) - if(current_cycle == 35 && creation_purity <= 0.6) + if(current_cycle == 36 && creation_purity <= 0.6) if(!istype(affected_mob.dna.species, /datum/species/human/krokodil_addict)) to_chat(affected_mob, span_userdanger("Your skin falls off easily!")) var/mob/living/carbon/human/affected_human = affected_mob affected_human.set_facial_hairstyle("Shaved", update = FALSE) affected_human.set_hairstyle("Bald", update = FALSE) affected_mob.set_species(/datum/species/human/krokodil_addict) - affected_mob.adjustBruteLoss(50 * REM, FALSE, required_bodytype = affected_bodytype) // holy shit your skin just FELL THE FUCK OFF - . = TRUE - ..() + if(affected_mob.adjustBruteLoss(50 * REM, updating_health = FALSE, required_bodytype = affected_bodytype)) // holy shit your skin just FELL THE FUCK OFF + return UPDATE_MOB_HEALTH /datum/reagent/drug/krokodil/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - affected_mob.adjustToxLoss(0.25 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - . = TRUE - - + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + need_mob_update = affected_mob.adjustToxLoss(0.25 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/drug/methamphetamine name = "Methamphetamine" @@ -159,15 +162,16 @@ var/effective_impurity = min(1, (1 - creation_purity)/0.5) color = BlendRGB(initial(color), "#FAFAFA", effective_impurity) -/datum/reagent/drug/methamphetamine/on_mob_metabolize(mob/living/L) - ..() - L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/methamphetamine) +/datum/reagent/drug/methamphetamine/on_mob_metabolize(mob/living/affected_mob) + . = ..() + affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/methamphetamine) -/datum/reagent/drug/methamphetamine/on_mob_end_metabolize(mob/living/L) - L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/methamphetamine) - ..() +/datum/reagent/drug/methamphetamine/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() + affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/methamphetamine) /datum/reagent/drug/methamphetamine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/high_message = pick("You feel hyper.", "You feel like you need to go faster.", "You feel like you can run the world.") if(SPT_PROB(2.5, seconds_per_tick)) to_chat(affected_mob, span_notice("[high_message]")) @@ -177,15 +181,17 @@ affected_mob.AdjustUnconscious(-40 * REM * seconds_per_tick) affected_mob.AdjustParalyzed(-40 * REM * seconds_per_tick) affected_mob.AdjustImmobilized(-40 * REM * seconds_per_tick) - affected_mob.adjustStaminaLoss(-2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + var/need_mob_update + need_mob_update = affected_mob.adjustStaminaLoss(-2 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) affected_mob.set_jitter_if_lower(4 SECONDS * REM * seconds_per_tick) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, rand(1, 4) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, rand(1, 4) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(need_mob_update) + . = UPDATE_MOB_HEALTH if(SPT_PROB(2.5, seconds_per_tick)) affected_mob.emote(pick("twitch", "shiver")) - ..() - . = TRUE /datum/reagent/drug/methamphetamine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(!HAS_TRAIT(affected_mob, TRAIT_IMMOBILIZED) && !ismovable(affected_mob.loc)) for(var/i in 1 to round(4 * REM * seconds_per_tick, 1)) step(affected_mob, pick(GLOB.cardinals)) @@ -194,10 +200,11 @@ if(SPT_PROB(18, seconds_per_tick)) affected_mob.visible_message(span_danger("[affected_mob]'s hands flip out and flail everywhere!")) affected_mob.drop_all_held_items() - ..() - affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, (rand(5, 10) / 10) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - . = TRUE + var/need_mob_update + need_mob_update = affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, (rand(5, 10) / 10) * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/drug/bath_salts name = "Bath Salts" @@ -211,35 +218,38 @@ ph = 8.2 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/drug/bath_salts/on_mob_metabolize(mob/living/L) - ..() - L.add_traits(list(TRAIT_STUNIMMUNE, TRAIT_SLEEPIMMUNE), type) - if(iscarbon(L)) - var/mob/living/carbon/C = L +/datum/reagent/drug/bath_salts/on_mob_metabolize(mob/living/affected_mob) + . = ..() + affected_mob.add_traits(list(TRAIT_STUNIMMUNE, TRAIT_SLEEPIMMUNE), type) + if(iscarbon(affected_mob)) + var/mob/living/carbon/carbon_mob = affected_mob rage = new() - C.gain_trauma(rage, TRAUMA_RESILIENCE_ABSOLUTE) + carbon_mob.gain_trauma(rage, TRAUMA_RESILIENCE_ABSOLUTE) -/datum/reagent/drug/bath_salts/on_mob_end_metabolize(mob/living/L) - L.remove_traits(list(TRAIT_STUNIMMUNE, TRAIT_SLEEPIMMUNE), type) +/datum/reagent/drug/bath_salts/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() + affected_mob.remove_traits(list(TRAIT_STUNIMMUNE, TRAIT_SLEEPIMMUNE), type) if(rage) QDEL_NULL(rage) - ..() /datum/reagent/drug/bath_salts/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/high_message = pick("You feel amped up.", "You feel ready.", "You feel like you can push it to the limit.") if(SPT_PROB(2.5, seconds_per_tick)) to_chat(affected_mob, span_notice("[high_message]")) affected_mob.add_mood_event("salted", /datum/mood_event/stimulant_heavy, name) - affected_mob.adjustStaminaLoss(-5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + var/need_mob_update + need_mob_update = affected_mob.adjustStaminaLoss(-5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) affected_mob.adjust_hallucinations(10 SECONDS * REM * seconds_per_tick) + if(need_mob_update) + . = UPDATE_MOB_HEALTH if(!HAS_TRAIT(affected_mob, TRAIT_IMMOBILIZED) && !ismovable(affected_mob.loc)) step(affected_mob, pick(GLOB.cardinals)) step(affected_mob, pick(GLOB.cardinals)) - ..() - . = TRUE /datum/reagent/drug/bath_salts/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_hallucinations(10 SECONDS * REM * seconds_per_tick) if(!HAS_TRAIT(affected_mob, TRAIT_IMMOBILIZED) && !ismovable(affected_mob.loc)) for(var/i in 1 to round(8 * REM * seconds_per_tick, 1)) @@ -248,7 +258,6 @@ affected_mob.emote(pick("twitch","drool","moan")) if(SPT_PROB(28, seconds_per_tick)) affected_mob.drop_all_held_items() - ..() /datum/reagent/drug/aranesp name = "Aranesp" @@ -259,16 +268,18 @@ addiction_types = list(/datum/addiction/stimulants = 8) /datum/reagent/drug/aranesp/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/high_message = pick("You feel amped up.", "You feel ready.", "You feel like you can push it to the limit.") if(SPT_PROB(2.5, seconds_per_tick)) to_chat(affected_mob, span_notice("[high_message]")) - affected_mob.adjustStaminaLoss(-18 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + var/need_mob_update + need_mob_update = affected_mob.adjustStaminaLoss(-18 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) if(SPT_PROB(30, seconds_per_tick)) affected_mob.losebreath++ - affected_mob.adjustOxyLoss(1, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - ..() - . = TRUE + need_mob_update += affected_mob.adjustOxyLoss(1, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/drug/happiness name = "Happiness" @@ -280,25 +291,26 @@ taste_description = "paint thinner" addiction_types = list(/datum/addiction/hallucinogens = 18) -/datum/reagent/drug/happiness/on_mob_metabolize(mob/living/L) - ..() - ADD_TRAIT(L, TRAIT_FEARLESS, type) - L.add_mood_event("happiness_drug", /datum/mood_event/happiness_drug) +/datum/reagent/drug/happiness/on_mob_metabolize(mob/living/affected_mob) + . = ..() + ADD_TRAIT(affected_mob, TRAIT_FEARLESS, type) + affected_mob.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, type) - L.clear_mood_event("happiness_drug") - ..() +/datum/reagent/drug/happiness/on_mob_delete(mob/living/affected_mob) + . = ..() + REMOVE_TRAIT(affected_mob, TRAIT_FEARLESS, type) + affected_mob.clear_mood_event("happiness_drug") /datum/reagent/drug/happiness/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.remove_status_effect(/datum/status_effect/jitter) affected_mob.remove_status_effect(/datum/status_effect/confusion) affected_mob.disgust = 0 - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - ..() - . = TRUE + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + return UPDATE_MOB_HEALTH /datum/reagent/drug/happiness/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(16, seconds_per_tick)) var/reaction = rand(1,3) switch(reaction) @@ -311,9 +323,8 @@ if(3) affected_mob.emote("frown") affected_mob.add_mood_event("happiness_drug", /datum/mood_event/happiness_drug_bad_od) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - ..() - . = TRUE + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + return UPDATE_MOB_HEALTH /datum/reagent/drug/pumpup name = "Pump-Up" @@ -334,45 +345,54 @@ metabolization_rate *= 0.8 /datum/reagent/drug/pumpup/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_BATON_RESISTANCE, type) - return ..() /datum/reagent/drug/pumpup/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick) if(SPT_PROB(2.5, seconds_per_tick)) to_chat(affected_mob, span_notice("[pick("Go! Go! GO!", "You feel ready...", "You feel invincible...")]")) if(SPT_PROB(7.5, seconds_per_tick)) affected_mob.losebreath++ - affected_mob.adjustToxLoss(2, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() - + affected_mob.adjustToxLoss(2, updating_health = FALSE, required_biotype = affected_biotype) + return UPDATE_MOB_HEALTH /datum/reagent/drug/pumpup/overdose_start(mob/living/affected_mob) + . = ..() to_chat(affected_mob, span_userdanger("You can't stop shaking, your heart beats faster and faster...")) /datum/reagent/drug/pumpup/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick) + var/need_mob_update if(SPT_PROB(2.5, seconds_per_tick)) affected_mob.drop_all_held_items() if(SPT_PROB(7.5, seconds_per_tick)) affected_mob.emote(pick("twitch","drool")) if(SPT_PROB(10, seconds_per_tick)) affected_mob.losebreath++ - affected_mob.adjustStaminaLoss(4, FALSE, required_biotype = affected_biotype) + affected_mob.adjustStaminaLoss(4, updating_stamina = FALSE, required_biotype = affected_biotype) + need_mob_update = TRUE if(SPT_PROB(7.5, seconds_per_tick)) - affected_mob.adjustToxLoss(2, FALSE, required_biotype = affected_biotype) - ..() + need_mob_update += affected_mob.adjustToxLoss(2, updating_health = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/drug/maint name = "Maintenance Drugs" chemical_flags = NONE -/datum/reagent/drug/maint/on_mob_metabolize(mob/living/carbon/L) - var/obj/item/organ/internal/liver/liver = L.get_organ_slot(ORGAN_SLOT_LIVER) +/datum/reagent/drug/maint/on_mob_metabolize(mob/living/affected_mob) + . = ..() + if(!iscarbon(affected_mob)) + return + + var/mob/living/carbon/carbon_mob = affected_mob + var/obj/item/organ/internal/liver/liver = carbon_mob.get_organ_slot(ORGAN_SLOT_LIVER) if(HAS_TRAIT(liver, TRAIT_MAINTENANCE_METABOLISM)) - L.add_mood_event("maintenance_fun", /datum/mood_event/maintenance_high) + carbon_mob.add_mood_event("maintenance_fun", /datum/mood_event/maintenance_high) metabolization_rate *= 0.8 /datum/reagent/drug/maint/powder @@ -400,7 +420,8 @@ /datum/reagent/drug/maint/powder/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) . = ..() - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 6 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 6 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + return UPDATE_MOB_HEALTH /datum/reagent/drug/maint/sludge name = "Maintenance Sludge" @@ -412,15 +433,14 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED addiction_types = list(/datum/addiction/maintenance_drugs = 8) -/datum/reagent/drug/maint/sludge/on_mob_metabolize(mob/living/L) - +/datum/reagent/drug/maint/sludge/on_mob_metabolize(mob/living/affected_mob) . = ..() - ADD_TRAIT(L,TRAIT_HARDLY_WOUNDED,type) + ADD_TRAIT(affected_mob,TRAIT_HARDLY_WOUNDED,type) /datum/reagent/drug/maint/sludge/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() - affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, required_biotype = affected_biotype) - return TRUE + if(affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/drug/maint/sludge/on_mob_end_metabolize(mob/living/affected_mob) . = ..() @@ -432,10 +452,13 @@ return var/mob/living/carbon/carbie = affected_mob //You will be vomiting so the damage is really for a few ticks before you flush it out of your system - carbie.adjustToxLoss(1 * REM * seconds_per_tick, required_biotype = affected_biotype) + var/need_mob_update + need_mob_update = carbie.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) if(SPT_PROB(5, seconds_per_tick)) - carbie.adjustToxLoss(5, required_biotype = affected_biotype) + need_mob_update += carbie.adjustToxLoss(5, required_biotype = affected_biotype, updating_health = FALSE) carbie.vomit(VOMIT_CATEGORY_DEFAULT) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/drug/maint/tar name = "Maintenance Tar" @@ -454,13 +477,15 @@ affected_mob.AdjustParalyzed(-10 * REM * seconds_per_tick) affected_mob.AdjustImmobilized(-10 * REM * seconds_per_tick) affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 1.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - return TRUE + return UPDATE_MOB_HEALTH /datum/reagent/drug/maint/tar/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) . = ..() - - affected_mob.adjustToxLoss(5 * REM * seconds_per_tick, required_biotype = affected_biotype) - affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + var/need_update + need_update = affected_mob.adjustToxLoss(5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(need_update) + return UPDATE_MOB_HEALTH /datum/reagent/drug/mushroomhallucinogen name = "Mushroom Hallucinogen" @@ -474,21 +499,21 @@ addiction_types = list(/datum/addiction/hallucinogens = 12) /datum/reagent/drug/mushroomhallucinogen/on_mob_life(mob/living/carbon/psychonaut, seconds_per_tick, times_fired) + . = ..() psychonaut.set_slurring_if_lower(1 SECONDS * REM * seconds_per_tick) switch(current_cycle) - if(1 to 5) + if(2 to 6) if(SPT_PROB(5, seconds_per_tick)) psychonaut.emote(pick("twitch","giggle")) - if(5 to 10) + if(6 to 11) psychonaut.set_jitter_if_lower(20 SECONDS * REM * seconds_per_tick) if(SPT_PROB(10, seconds_per_tick)) psychonaut.emote(pick("twitch","giggle")) - if (10 to INFINITY) + if (11 to INFINITY) psychonaut.set_jitter_if_lower(40 SECONDS * REM * seconds_per_tick) if(SPT_PROB(16, seconds_per_tick)) psychonaut.emote(pick("twitch","giggle")) - ..() /datum/reagent/drug/mushroomhallucinogen/on_mob_metabolize(mob/living/psychonaut) . = ..() @@ -601,16 +626,17 @@ /datum/reagent/drug/blastoff/on_mob_life(mob/living/carbon/dancer, seconds_per_tick, times_fired) . = ..() - dancer.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(dancer.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + . = UPDATE_MOB_HEALTH dancer.AdjustKnockdown(-20) if(SPT_PROB(BLASTOFF_DANCE_MOVE_CHANCE_PER_UNIT * volume, seconds_per_tick)) dancer.emote("flip") - return TRUE /datum/reagent/drug/blastoff/overdose_process(mob/living/dancer, seconds_per_tick, times_fired) . = ..() - dancer.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(dancer.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + . = UPDATE_MOB_HEALTH if(SPT_PROB(BLASTOFF_DANCE_MOVE_CHANCE_PER_UNIT * volume, seconds_per_tick)) dancer.emote("spin") @@ -673,8 +699,8 @@ /datum/reagent/drug/saturnx/on_mob_life(mob/living/carbon/invisible_man, seconds_per_tick, times_fired) . = ..() - invisible_man.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - return TRUE + if(invisible_man.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.3 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + return UPDATE_MOB_HEALTH /datum/reagent/drug/saturnx/on_mob_metabolize(mob/living/invisible_man) . = ..() @@ -750,7 +776,8 @@ invisible_man.emote("giggle") if(SPT_PROB(5, seconds_per_tick)) invisible_man.emote("laugh") - invisible_man.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(invisible_man.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + return UPDATE_MOB_HEALTH /datum/reagent/drug/saturnx/stable name = "Stabilized Saturn-X" @@ -772,27 +799,29 @@ addiction_types = list(/datum/addiction/stimulants = 20) /datum/reagent/drug/kronkaine/on_mob_metabolize(mob/living/kronkaine_fiend) - ..() + . = ..() kronkaine_fiend.add_actionspeed_modifier(/datum/actionspeed_modifier/kronkaine) kronkaine_fiend.sound_environment_override = SOUND_ENVIRONMENT_HANGAR /datum/reagent/drug/kronkaine/on_mob_end_metabolize(mob/living/kronkaine_fiend) + . = ..() kronkaine_fiend.remove_actionspeed_modifier(/datum/actionspeed_modifier/kronkaine) kronkaine_fiend.sound_environment_override = NONE - . = ..() /datum/reagent/drug/kronkaine/on_transfer(atom/kronkaine_receptacle, methods, trans_volume) . = ..() if(!iscarbon(kronkaine_receptacle)) return var/mob/living/carbon/druggo = kronkaine_receptacle - druggo.adjustStaminaLoss(-4 * trans_volume, 0) + if(druggo.adjustStaminaLoss(-4 * trans_volume, updating_stamina = FALSE)) + return UPDATE_MOB_HEALTH //I wish i could give it some kind of bonus when smoked, but we don't have an INHALE method. /datum/reagent/drug/kronkaine/on_mob_life(mob/living/carbon/kronkaine_fiend, seconds_per_tick, times_fired) . = ..() || TRUE kronkaine_fiend.add_mood_event("tweaking", /datum/mood_event/stimulant_medium, name) - kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + . = UPDATE_MOB_HEALTH kronkaine_fiend.set_jitter_if_lower(20 SECONDS * REM * seconds_per_tick) kronkaine_fiend.AdjustSleeping(-20 * REM * seconds_per_tick) kronkaine_fiend.adjust_drowsiness(-10 SECONDS * REM * seconds_per_tick) @@ -805,7 +834,8 @@ /datum/reagent/drug/kronkaine/overdose_process(mob/living/kronkaine_fiend, seconds_per_tick, times_fired) . = ..() - kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, 1 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + if(kronkaine_fiend.adjustOrganLoss(ORGAN_SLOT_HEART, 1 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + . = UPDATE_MOB_HEALTH kronkaine_fiend.set_jitter_if_lower(20 SECONDS * REM * seconds_per_tick) if(SPT_PROB(10, seconds_per_tick)) to_chat(kronkaine_fiend, span_danger(pick("You feel like your heart is going to explode!", "Your ears are ringing!", "You sweat like a pig!", "You clench your jaw and grind your teeth.", "You feel prickles of pain in your chest."))) @@ -819,9 +849,10 @@ chemical_flags = NONE /datum/reagent/drug/kronkaine/gore/overdose_start(mob/living/gored) + . = ..() gored.visible_message( span_danger("[gored] explodes in a shower of gore!"), span_userdanger("GORE! GORE! GORE! YOU'RE GORE! TOO MUCH GORE! YOU'RE GORE! GORE! IT'S OVER! GORE! GORE! YOU'RE GORE! TOO MUCH G-"), ) new /obj/structure/bouncy_castle(gored.loc, gored) - gored.gib(TRUE, TRUE, TRUE) //no brain, no organs, no bodyparts + gored.gib() diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 17867389c3dc19..af75cc46db291c 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -19,15 +19,16 @@ /// affects mood, typically higher for mixed drinks with more complex recipes' var/quality = 0 -/datum/reagent/consumable/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) +/datum/reagent/consumable/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) current_cycle++ - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if(!HAS_TRAIT(H, TRAIT_NOHUNGER)) - H.adjust_nutrition(get_nutriment_factor() * REM * seconds_per_tick) + if(ishuman(affected_mob)) + var/mob/living/carbon/human/affected_human = affected_mob + if(!HAS_TRAIT(affected_human, TRAIT_NOHUNGER)) + affected_human.adjust_nutrition(get_nutriment_factor() * REM * seconds_per_tick) if(length(reagent_removal_skip_list)) return - holder.remove_reagent(type, metabolization_rate * seconds_per_tick) + if(holder) + holder.remove_reagent(type, metabolization_rate * seconds_per_tick) /datum/reagent/consumable/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) . = ..() @@ -73,11 +74,11 @@ /datum/reagent/consumable/nutriment/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user) mytray.adjust_plant_health(round(volume * 0.2)) -/datum/reagent/consumable/nutriment/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) +/datum/reagent/consumable/nutriment/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(30, seconds_per_tick)) - M.heal_bodypart_damage(brute = brute_heal, burn = burn_heal, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC) - . = TRUE - ..() + if(affected_mob.heal_bodypart_damage(brute = brute_heal * REM * seconds_per_tick, burn = burn_heal * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/nutriment/on_new(list/supplied_data) . = ..() @@ -128,10 +129,10 @@ brute_heal = 1 burn_heal = 1 -/datum/reagent/consumable/nutriment/vitamin/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) - if(M.satiety < MAX_SATIETY) - M.satiety += 30 * REM * seconds_per_tick +/datum/reagent/consumable/nutriment/vitamin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() + if(affected_mob.satiety < MAX_SATIETY) + affected_mob.satiety += 30 * REM * seconds_per_tick /// The basic resource of vat growing. /datum/reagent/consumable/nutriment/protein @@ -238,15 +239,19 @@ ///Amount of satiety that will be drained when the cloth_fibers is fully metabolized var/delayed_satiety_drain = 2 * CLOTHING_NUTRITION_GAIN -/datum/reagent/consumable/nutriment/cloth_fibers/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) - if(M.satiety < MAX_SATIETY) - M.adjust_nutrition(CLOTHING_NUTRITION_GAIN) +/datum/reagent/consumable/nutriment/cloth_fibers/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + if(affected_mob.satiety < MAX_SATIETY) + affected_mob.adjust_nutrition(CLOTHING_NUTRITION_GAIN) delayed_satiety_drain += CLOTHING_NUTRITION_GAIN - return ..() -/datum/reagent/consumable/nutriment/cloth_fibers/on_mob_delete(mob/living/carbon/M) - M.adjust_nutrition(-delayed_satiety_drain) - return ..() +/datum/reagent/consumable/nutriment/cloth_fibers/on_mob_delete(mob/living/carbon/affected_mob) + . = ..() + if(!iscarbon(affected_mob)) + return + + var/mob/living/carbon/carbon_mob = affected_mob + carbon_mob.adjust_nutrition(-delayed_satiety_drain) /datum/reagent/consumable/nutriment/mineral name = "Mineral Slurry" @@ -256,14 +261,15 @@ brute_heal = 0 burn_heal = 0 -/datum/reagent/consumable/nutriment/mineral/on_mob_life(mob/living/carbon/eater, delta_time, times_fired) - current_cycle++ - if (HAS_TRAIT(eater, TRAIT_ROCK_EATER) && !HAS_TRAIT(eater, TRAIT_NOHUNGER) && ishuman(eater)) - var/mob/living/carbon/human/golem_eater = eater - golem_eater.adjust_nutrition(get_nutriment_factor() * REM * delta_time) - if(length(reagent_removal_skip_list)) - return - holder.remove_reagent(type, metabolization_rate * delta_time) +/datum/reagent/consumable/nutriment/mineral/on_mob_life(mob/living/carbon/eater, seconds_per_tick, times_fired) + if(HAS_TRAIT(eater, TRAIT_ROCK_EATER)) // allow mobs who can eat rocks to do so + return ..() + else // otherwise just let them pass through the system + current_cycle++ + if(length(reagent_removal_skip_list)) + return + if(holder) + holder.remove_reagent(type, metabolization_rate * seconds_per_tick) /datum/reagent/consumable/sugar name = "Sugar" @@ -284,15 +290,14 @@ mytray.adjust_weedlevel(rand(1, 2)) mytray.adjust_pestlevel(rand(1, 2)) -/datum/reagent/consumable/sugar/overdose_start(mob/living/M) - to_chat(M, span_userdanger("You go into hyperglycaemic shock! Lay off the twinkies!")) - M.AdjustSleeping(20 SECONDS) - . = TRUE +/datum/reagent/consumable/sugar/overdose_start(mob/living/affected_mob) + . = ..() + to_chat(affected_mob, span_userdanger("You go into hyperglycemic shock! Lay off the twinkies!")) + affected_mob.AdjustSleeping(20 SECONDS) -/datum/reagent/consumable/sugar/overdose_process(mob/living/M, seconds_per_tick, times_fired) - M.adjust_drowsiness_up_to((5 SECONDS * REM * seconds_per_tick), 60 SECONDS) - ..() - . = TRUE +/datum/reagent/consumable/sugar/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() + affected_mob.adjust_drowsiness_up_to((5 SECONDS * REM * seconds_per_tick), 60 SECONDS) /datum/reagent/consumable/virus_food name = "Virus Food" @@ -332,29 +337,29 @@ taste_mult = 1.5 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/consumable/capsaicin/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) +/datum/reagent/consumable/capsaicin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) var/heating = 0 switch(current_cycle) if(1 to 15) heating = 5 if(holder.has_reagent(/datum/reagent/cryostylane)) holder.remove_reagent(/datum/reagent/cryostylane, 5 * REM * seconds_per_tick) - if(isslime(M)) + if(isslime(affected_mob)) heating = rand(5, 20) if(15 to 25) heating = 10 - if(isslime(M)) + if(isslime(affected_mob)) heating = rand(10, 20) if(25 to 35) heating = 15 - if(isslime(M)) + if(isslime(affected_mob)) heating = rand(15, 20) if(35 to INFINITY) heating = 20 - if(isslime(M)) + if(isslime(affected_mob)) heating = rand(20, 25) - M.adjust_bodytemperature(heating * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick) - ..() + affected_mob.adjust_bodytemperature(heating * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick) + return ..() /datum/reagent/consumable/frostoil name = "Frost Oil" @@ -367,33 +372,33 @@ specific_heat = 40 default_container = /obj/item/reagent_containers/cup/bottle/frostoil -/datum/reagent/consumable/frostoil/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) +/datum/reagent/consumable/frostoil/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) var/cooling = 0 switch(current_cycle) if(1 to 15) cooling = -10 if(holder.has_reagent(/datum/reagent/consumable/capsaicin)) holder.remove_reagent(/datum/reagent/consumable/capsaicin, 5 * REM * seconds_per_tick) - if(isslime(M)) + if(isslime(affected_mob)) cooling = -rand(5, 20) if(15 to 25) cooling = -20 - if(isslime(M)) + if(isslime(affected_mob)) cooling = -rand(10, 20) if(25 to 35) cooling = -30 if(prob(1)) - M.emote("shiver") - if(isslime(M)) + affected_mob.emote("shiver") + if(isslime(affected_mob)) cooling = -rand(15, 20) if(35 to INFINITY) cooling = -40 if(prob(5)) - M.emote("shiver") - if(isslime(M)) + affected_mob.emote("shiver") + if(isslime(affected_mob)) cooling = -rand(20, 25) - M.adjust_bodytemperature(cooling * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50) - ..() + affected_mob.adjust_bodytemperature(cooling * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50) + return ..() /datum/reagent/consumable/frostoil/expose_turf(turf/exposed_turf, reac_volume) . = ..() @@ -421,7 +426,6 @@ default_container = /obj/item/reagent_containers/cup/bottle/capsaicin /datum/reagent/consumable/condensedcapsaicin/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) - . = ..() if(!ishuman(exposed_mob)) return @@ -450,12 +454,13 @@ victim.set_dizzy_if_lower(2 SECONDS) if(prob(5)) victim.vomit(VOMIT_CATEGORY_DEFAULT) + return ..() -/datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) +/datum/reagent/consumable/condensedcapsaicin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) if(!holder.has_reagent(/datum/reagent/consumable/milk)) if(SPT_PROB(5, seconds_per_tick)) - M.visible_message(span_warning("[M] [pick("dry heaves!","coughs!","splutters!")]")) - ..() + affected_mob.visible_message(span_warning("[affected_mob] [pick("dry heaves!","coughs!","splutters!")]")) + return ..() /datum/reagent/consumable/salt name = "Table Salt" @@ -475,6 +480,8 @@ /datum/reagent/consumable/salt/expose_mob(mob/living/exposed_mob, methods, reac_volume) . = ..() + if(!iscarbon(exposed_mob)) + return var/mob/living/carbon/carbies = exposed_mob if(!(methods & (PATCH|TOUCH|VAPOR))) return @@ -506,7 +513,6 @@ flesh_healing -= max(VALUE_PER(5, 30) * reac_volume, 0) to_chat(victim, span_notice("The salt bits seep in and stick to [lowertext(src)], painfully irritating the skin! After a few moments, it feels marginally better.")) - /datum/reagent/consumable/blackpepper name = "Black Pepper" description = "A powder ground from peppercorns. *AAAACHOOO*" @@ -533,27 +539,27 @@ metabolization_rate = 0.15 * REAGENTS_METABOLISM chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/consumable/garlic/on_mob_add(mob/living/L, amount) +/datum/reagent/consumable/garlic/on_mob_add(mob/living/affected_mob, amount) + . = ..() + ADD_TRAIT(affected_mob, TRAIT_GARLIC_BREATH, type) + +/datum/reagent/consumable/garlic/on_mob_delete(mob/living/affected_mob) . = ..() - ADD_TRAIT(L, TRAIT_GARLIC_BREATH, type) + REMOVE_TRAIT(affected_mob, TRAIT_GARLIC_BREATH, type) -/datum/reagent/consumable/garlic/on_mob_delete(mob/living/L) +/datum/reagent/consumable/garlic/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() - REMOVE_TRAIT(L, TRAIT_GARLIC_BREATH, type) - -/datum/reagent/consumable/garlic/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) - if(isvampire(M)) //incapacitating but not lethal. Unfortunately, vampires cannot vomit. - if(SPT_PROB(min(current_cycle/2, 12.5), seconds_per_tick)) - to_chat(M, span_danger("You can't get the scent of garlic out of your nose! You can barely think...")) - M.Paralyze(10) - M.set_jitter_if_lower(20 SECONDS) + if(isvampire(affected_mob)) //incapacitating but not lethal. Unfortunately, vampires cannot vomit. + if(SPT_PROB(min((current_cycle-1)/2, 12.5), seconds_per_tick)) + to_chat(affected_mob, span_danger("You can't get the scent of garlic out of your nose! You can barely think...")) + affected_mob.Paralyze(10) + affected_mob.set_jitter_if_lower(20 SECONDS) else - var/obj/item/organ/internal/liver/liver = M.get_organ_slot(ORGAN_SLOT_LIVER) + var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER) if(liver && HAS_TRAIT(liver, TRAIT_CULINARY_METABOLISM)) if(SPT_PROB(10, seconds_per_tick)) //stays in the system much longer than sprinkles/banana juice, so heals slower to partially compensate - M.heal_bodypart_damage(brute = 1, burn = 1) - . = TRUE - ..() + if(affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/tearjuice name = "Tear Juice" @@ -582,12 +588,12 @@ taste_description = "childhood whimsy" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/consumable/sprinkles/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) - var/obj/item/organ/internal/liver/liver = M.get_organ_slot(ORGAN_SLOT_LIVER) +/datum/reagent/consumable/sprinkles/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER) if(liver && HAS_TRAIT(liver, TRAIT_LAW_ENFORCEMENT_METABOLISM)) - M.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick, 0) - . = TRUE - ..() + if(affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/enzyme name = "Universal Enzyme" @@ -623,9 +629,9 @@ taste_description = "your imprisonment" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/consumable/hot_ramen/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) - M.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 0, M.get_body_temp_normal()) - ..() +/datum/reagent/consumable/hot_ramen/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + affected_mob.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 0, affected_mob.get_body_temp_normal()) /datum/reagent/consumable/hell_ramen name = "Hell Ramen" @@ -635,9 +641,9 @@ taste_description = "wet and cheap noodles on fire" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/consumable/hell_ramen/on_mob_life(mob/living/carbon/target_mob, seconds_per_tick, times_fired) - target_mob.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick) - ..() +/datum/reagent/consumable/hell_ramen/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + affected_mob.adjust_bodytemperature(10 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick) /datum/reagent/consumable/flour name = "Flour" @@ -650,6 +656,8 @@ /datum/reagent/consumable/flour/expose_mob(mob/living/exposed_mob, methods, reac_volume) . = ..() + if(!iscarbon(exposed_mob)) + return var/mob/living/carbon/carbies = exposed_mob if(!(methods & (PATCH|TOUCH|VAPOR))) return @@ -718,7 +726,7 @@ color = "#FFFFFF" // rgb: 0, 0, 0 taste_description = "chalky wheat with rice" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED - + /datum/reagent/consumable/vanilla name = "Vanilla Powder" description = "A fatty, bitter paste made from vanilla pods." @@ -754,6 +762,8 @@ // Starch has similar absorbing properties to flour (Stronger here because it's rarer) /datum/reagent/consumable/corn_starch/expose_mob(mob/living/exposed_mob, methods, reac_volume) . = ..() + if(!iscarbon(exposed_mob)) + return var/mob/living/carbon/carbies = exposed_mob if(!(methods & (PATCH|TOUCH|VAPOR))) return @@ -789,9 +799,9 @@ taste_description = "sweet slime" chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/consumable/corn_syrup/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) +/datum/reagent/consumable/corn_syrup/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) holder.add_reagent(/datum/reagent/consumable/sugar, 3 * REM * seconds_per_tick) - ..() + return ..() /datum/reagent/consumable/honey name = "Honey" @@ -812,15 +822,17 @@ mytray.adjust_weedlevel(rand(1, 2)) mytray.adjust_pestlevel(rand(1, 2)) -/datum/reagent/consumable/honey/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) +/datum/reagent/consumable/honey/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) holder.add_reagent(/datum/reagent/consumable/sugar, 3 * REM * seconds_per_tick) + . = ..() + var/need_mob_update if(SPT_PROB(33, seconds_per_tick)) - M.adjustBruteLoss(-1, FALSE, required_bodytype = affected_bodytype) - M.adjustFireLoss(-1, FALSE, required_bodytype = affected_bodytype) - M.adjustOxyLoss(-1, FALSE, required_biotype = affected_biotype) - M.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() + need_mob_update = affected_mob.adjustBruteLoss(-1, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-1, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustOxyLoss(-1, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustToxLoss(-1, updating_health = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/honey/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) . = ..() @@ -861,10 +873,10 @@ color = "#664330" // rgb: 102, 67, 48 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/consumable/nutriment/stabilized/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) - if(M.nutrition > NUTRITION_LEVEL_FULL - 25) - M.adjust_nutrition(-3 * REM * get_nutriment_factor() * seconds_per_tick) - ..() +/datum/reagent/consumable/nutriment/stabilized/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + if(affected_mob.nutrition > NUTRITION_LEVEL_FULL - 25) + affected_mob.adjust_nutrition(-3 * REM * get_nutriment_factor() * seconds_per_tick) ////Lavaland Flora Reagents//// @@ -877,19 +889,20 @@ ph = 12 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/consumable/entpoly/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) - if(current_cycle >= 10) - M.Unconscious(40 * REM * seconds_per_tick, FALSE) - . = TRUE +/datum/reagent/consumable/entpoly/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update + if(current_cycle > 10) + affected_mob.Unconscious(40 * REM * seconds_per_tick, FALSE) if(SPT_PROB(10, seconds_per_tick)) - M.losebreath += 4 - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM, 150, affected_biotype) - M.adjustToxLoss(3*REM, FALSE, required_biotype = affected_biotype) - M.adjustStaminaLoss(10*REM, FALSE, required_biotype = affected_biotype) - M.set_eye_blur_if_lower(10 SECONDS) - . = TRUE - ..() - + affected_mob.losebreath += 4 + affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM, 150, affected_biotype) + affected_mob.adjustToxLoss(3*REM, updating_health = FALSE, required_biotype = affected_biotype) + affected_mob.adjustStaminaLoss(10*REM, updating_stamina = FALSE, required_biotype = affected_biotype) + affected_mob.set_eye_blur_if_lower(10 SECONDS) + need_mob_update = TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/tinlux name = "Tinea Luxor" @@ -925,12 +938,14 @@ ph = 10.4 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/consumable/vitfro/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) +/datum/reagent/consumable/vitfro/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update if(SPT_PROB(55, seconds_per_tick)) - M.adjustBruteLoss(-1, FALSE, required_bodytype = affected_bodytype) - M.adjustFireLoss(-1, FALSE, required_bodytype = affected_bodytype) - . = TRUE - ..() + need_mob_update = affected_mob.adjustBruteLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/consumable/liquidelectricity name = "Liquid Electricity" @@ -953,13 +968,13 @@ if(istype(stomach)) stomach.adjust_charge(reac_volume * 30) -/datum/reagent/consumable/liquidelectricity/enriched/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) - if(isethereal(M)) - M.blood_volume += 1 * seconds_per_tick +/datum/reagent/consumable/liquidelectricity/enriched/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + if(isethereal(affected_mob)) + affected_mob.blood_volume += 1 * seconds_per_tick else if(SPT_PROB(10, seconds_per_tick)) //lmao at the newbs who eat energy bars - M.electrocute_act(rand(5,10), "Liquid Electricity in their body", 1, SHOCK_NOGLOVES) //the shock is coming from inside the house - playsound(M, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - return ..() + affected_mob.electrocute_act(rand(5,10), "Liquid Electricity in their body", 1, SHOCK_NOGLOVES) //the shock is coming from inside the house + playsound(affected_mob, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) /datum/reagent/consumable/astrotame name = "Astrotame" @@ -973,11 +988,10 @@ overdose_threshold = 17 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/consumable/astrotame/overdose_process(mob/living/carbon/M, seconds_per_tick, times_fired) - if(M.disgust < 80) - M.adjust_disgust(10 * REM * seconds_per_tick) - ..() - . = TRUE +/datum/reagent/consumable/astrotame/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + if(affected_mob.disgust < 80) + affected_mob.adjust_disgust(10 * REM * seconds_per_tick) /datum/reagent/consumable/secretsauce name = "Secret Sauce" @@ -1022,11 +1036,10 @@ overdose_threshold = 15 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/consumable/char/overdose_process(mob/living/M, seconds_per_tick, times_fired) +/datum/reagent/consumable/char/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(13, seconds_per_tick)) - M.say(pick_list_replacements(BOOMER_FILE, "boomer"), forced = /datum/reagent/consumable/char) - ..() - return + affected_mob.say(pick_list_replacements(BOOMER_FILE, "boomer"), forced = /datum/reagent/consumable/char) /datum/reagent/consumable/bbqsauce name = "BBQ Sauce" @@ -1136,11 +1149,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED default_container = /obj/item/reagent_containers/condiment/peanut_butter -/datum/reagent/consumable/peanut_butter/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) //ET loves peanut butter - if(isabductor(M)) - M.add_mood_event("ET_pieces", /datum/mood_event/et_pieces, name) - M.set_drugginess(30 SECONDS * REM * seconds_per_tick) - ..() +/datum/reagent/consumable/peanut_butter/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) //ET loves peanut butter + . = ..() + if(isabductor(affected_mob)) + affected_mob.add_mood_event("ET_pieces", /datum/mood_event/et_pieces, name) + affected_mob.set_drugginess(30 SECONDS * REM * seconds_per_tick) /datum/reagent/consumable/vinegar name = "Vinegar" @@ -1198,10 +1211,10 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/consumable/mintextract/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(HAS_TRAIT(affected_mob, TRAIT_FAT)) affected_mob.investigate_log("has been gibbed by consuming [src] while fat.", INVESTIGATE_DEATHS) affected_mob.inflate_gib() - return ..() /datum/reagent/consumable/worcestershire name = "Worcestershire Sauce" diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents.dm index f7eaba3c211bac..1a06ae11cd9606 100644 --- a/code/modules/reagents/chemistry/reagents/impure_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/impure_reagents.dm @@ -17,10 +17,15 @@ /datum/reagent/impurity/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER) - if(isnull(liver)) //Though, lets be safe - return affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) //Incase of no liver! - affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, liver_damage * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - return TRUE + var/need_mob_update + + if(liver)//Though, lets be safe + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, liver_damage * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + else + need_mob_update = affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)//Incase of no liver! + + if(need_mob_update) + return UPDATE_MOB_HEALTH //Basically just so people don't forget to adjust metabolization_rate /datum/reagent/inverse @@ -36,7 +41,8 @@ /datum/reagent/inverse/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() - return affected_mob.adjustToxLoss(tox_damage * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + if(affected_mob.adjustToxLoss(tox_damage * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH //Failed chems - generally use inverse if you want to use a impure subtype for it //technically not a impure chem, but it's here because it can only be made with a failed impure reaction @@ -96,6 +102,7 @@ var/atom/movable/screen/alert/status_effect/freon/cryostylane_alert /datum/reagent/inverse/cryostylane/on_mob_add(mob/living/carbon/affected_mob, amount) + . = ..() cube = new /obj/structure/ice_stasis(get_turf(affected_mob)) cube.color = COLOR_CYAN cube.set_anchored(TRUE) @@ -103,17 +110,21 @@ affected_mob.apply_status_effect(/datum/status_effect/grouped/stasis, STASIS_CHEMICAL_EFFECT) cryostylane_alert = affected_mob.throw_alert("cryostylane_alert", /atom/movable/screen/alert/status_effect/freon/cryostylane) cryostylane_alert.attached_effect = src //so the alert can reference us, if it needs to - ..() /datum/reagent/inverse/cryostylane/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + if(current_cycle >= 60) + holder.remove_reagent(type, volume) // remove it all if we're past 60 cycles + return ..() if(!cube || affected_mob.loc != cube) - affected_mob.reagents.remove_reagent(type, volume) //remove it all if we're past 60s - if(current_cycle > 60) metabolization_rate += 0.01 - ..() + return ..() /datum/reagent/inverse/cryostylane/on_mob_delete(mob/living/carbon/affected_mob, amount) + . = ..() QDEL_NULL(cube) - affected_mob.remove_status_effect(/datum/status_effect/grouped/stasis, STASIS_CHEMICAL_EFFECT) - affected_mob.clear_alert("cryostylane_alert") - ..() + if(!iscarbon(affected_mob)) + return + + var/mob/living/carbon/carbon_mob = affected_mob + carbon_mob.remove_status_effect(/datum/status_effect/grouped/stasis, STASIS_CHEMICAL_EFFECT) + carbon_mob.clear_alert("cryostylane_alert") diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm index db98ed9d622573..23e8537358c489 100644 --- a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_medicine_reagents.dm @@ -35,19 +35,21 @@ affected_respiration_type = ALL //Random healing of the 4 main groups -/datum/reagent/impurity/healing/medicine_failure/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired) +/datum/reagent/impurity/healing/medicine_failure/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update var/pick = pick("brute", "burn", "tox", "oxy") switch(pick) if("brute") - owner.adjustBruteLoss(-0.5, required_bodytype = affected_bodytype) + need_mob_update = affected_mob.adjustBruteLoss(-0.5, updating_health = FALSE, required_bodytype = affected_bodytype) if("burn") - owner.adjustFireLoss(-0.5, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-0.5, updating_health = FALSE, required_bodytype = affected_bodytype) if("tox") - owner.adjustToxLoss(-0.5, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustToxLoss(-0.5, updating_health = FALSE, required_biotype = affected_biotype) if("oxy") - owner.adjustOxyLoss(-0.5, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - ..() - return TRUE + need_mob_update += affected_mob.adjustOxyLoss(-0.5, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + if(need_mob_update) + return UPDATE_MOB_HEALTH // C2 medications // Helbital @@ -64,10 +66,10 @@ var/list/timer_ids //Warns you about the impenting hands -/datum/reagent/inverse/helgrasp/on_mob_add(mob/living/L, amount) - to_chat(L, span_hierophant("You hear laughter as malevolent hands apparate before you, eager to drag you down to hell...! Look out!")) - playsound(L.loc, 'sound/chemistry/ahaha.ogg', 80, TRUE, -1) //Very obvious tell so people can be ready +/datum/reagent/inverse/helgrasp/on_mob_add(mob/living/affected_mob, amount) . = ..() + to_chat(affected_mob, span_hierophant("You hear laughter as malevolent hands apparate before you, eager to drag you down to hell...! Look out!")) + playsound(affected_mob.loc, 'sound/chemistry/ahaha.ogg', 80, TRUE, -1) //Very obvious tell so people can be ready //Sends hands after you for your hubris /* @@ -81,8 +83,9 @@ Then I attempt to calculate the how many hands to created based off the current I take the 2s interval period and divide it by the number of hands I want to make (i.e. the current seconds_per_tick) and I keep track of how many hands I'm creating (since I always create one on a tick, then I start at 1 hand). For each hand I then use this time value multiplied by the number of hands. Since we're spawning one now, and it checks to see if hands is less than, but not less than or equal to, seconds_per_tick, no hands will be created on the next expected tick. Basically, we fill the time between now and 2s from now with hands based off the current lag. */ -/datum/reagent/inverse/helgrasp/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired) - spawn_hands(owner) +/datum/reagent/inverse/helgrasp/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + spawn_hands(affected_mob) lag_remainder += seconds_per_tick - FLOOR(seconds_per_tick, 1) seconds_per_tick = FLOOR(seconds_per_tick, 1) if(lag_remainder >= 1) @@ -91,36 +94,35 @@ Basically, we fill the time between now and 2s from now with hands based off the var/hands = 1 var/time = 2 / seconds_per_tick while(hands < seconds_per_tick) //we already made a hand now so start from 1 - LAZYADD(timer_ids, addtimer(CALLBACK(src, PROC_REF(spawn_hands), owner), (time*hands) SECONDS, TIMER_STOPPABLE)) //keep track of all the timers we set up + LAZYADD(timer_ids, addtimer(CALLBACK(src, PROC_REF(spawn_hands), affected_mob), (time*hands) SECONDS, TIMER_STOPPABLE)) //keep track of all the timers we set up hands += time - return ..() -/datum/reagent/inverse/helgrasp/proc/spawn_hands(mob/living/carbon/owner) - if(!owner && iscarbon(holder.my_atom))//Catch timer - owner = holder.my_atom +/datum/reagent/inverse/helgrasp/proc/spawn_hands(mob/living/carbon/affected_mob) + if(!affected_mob && iscarbon(holder.my_atom))//Catch timer + affected_mob = holder.my_atom //Adapted from the end of the curse - but lasts a short time - var/grab_dir = turn(owner.dir, pick(-90, 90, 180, 180)) //grab them from a random direction other than the one faced, favoring grabbing from behind - var/turf/spawn_turf = get_ranged_target_turf(owner, grab_dir, 8)//Larger range so you have more time to dodge + var/grab_dir = turn(affected_mob.dir, pick(-90, 90, 180, 180)) //grab them from a random direction other than the one faced, favoring grabbing from behind + var/turf/spawn_turf = get_ranged_target_turf(affected_mob, grab_dir, 8)//Larger range so you have more time to dodge if(!spawn_turf) return - new/obj/effect/temp_visual/dir_setting/curse/grasp_portal(spawn_turf, owner.dir) + new/obj/effect/temp_visual/dir_setting/curse/grasp_portal(spawn_turf, affected_mob.dir) playsound(spawn_turf, 'sound/effects/curse2.ogg', 80, TRUE, -1) var/obj/projectile/curse_hand/hel/hand = new (spawn_turf) - hand.preparePixelProjectile(owner, spawn_turf) + hand.preparePixelProjectile(affected_mob, spawn_turf) if(QDELETED(hand)) //safety check if above fails - above has a stack trace if it does fail return hand.fire() //At the end, we clear up any loose hanging timers just in case and spawn any remaining lag_remaining hands all at once. -/datum/reagent/inverse/helgrasp/on_mob_delete(mob/living/owner) +/datum/reagent/inverse/helgrasp/on_mob_delete(mob/living/affected_mob) + . = ..() var/hands = 0 while(lag_remainder > hands) - spawn_hands(owner) + spawn_hands(affected_mob) hands++ for(var/id in timer_ids) // So that we can be certain that all timers are deleted at the end. deltimer(id) timer_ids.Cut() - return ..() /datum/reagent/inverse/helgrasp/heretic name = "Grasp of the Mansus" @@ -139,9 +141,9 @@ Basically, we fill the time between now and 2s from now with hands based off the liver_damage = 0.1 addiction_types = list(/datum/addiction/medicine = 4) -/datum/reagent/impurity/libitoil/on_mob_add(mob/living/L, amount) +/datum/reagent/impurity/libitoil/on_mob_add(mob/living/affected_mob, amount) . = ..() - var/mob/living/carbon/consumer = L + var/mob/living/carbon/consumer = affected_mob if(!consumer) return RegisterSignal(consumer, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_gained_organ)) @@ -163,9 +165,9 @@ Basically, we fill the time between now and 2s from now with hands based off the var/obj/item/organ/internal/liver/this_liver = organ this_liver.alcohol_tolerance /= 2 -/datum/reagent/impurity/libitoil/on_mob_delete(mob/living/L) +/datum/reagent/impurity/libitoil/on_mob_delete(mob/living/affected_mob) . = ..() - var/mob/living/carbon/consumer = L + var/mob/living/carbon/consumer = affected_mob UnregisterSignal(consumer, COMSIG_CARBON_LOSE_ORGAN) UnregisterSignal(consumer, COMSIG_CARBON_GAIN_ORGAN) var/obj/item/organ/internal/liver/this_liver = consumer.get_organ_slot(ORGAN_SLOT_LIVER) @@ -187,8 +189,8 @@ Basically, we fill the time between now and 2s from now with hands based off the liver_damage = 0 /datum/reagent/impurity/probital_failed/overdose_start(mob/living/carbon/M) + . = ..() metabolization_rate = 4 * REAGENTS_METABOLISM - ..() /datum/reagent/peptides_failed name = "Prion Peptides" @@ -196,11 +198,11 @@ Basically, we fill the time between now and 2s from now with hands based off the description = "These inhibitory peptides drains nutrition and causes brain damage in the patient!" ph = 2.1 -/datum/reagent/peptides_failed/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired) - owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25 * seconds_per_tick, 170) - owner.adjust_nutrition(-5 * REAGENTS_METABOLISM * seconds_per_tick) - ..() - return TRUE +/datum/reagent/peptides_failed/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25 * seconds_per_tick, 170)) + . = UPDATE_MOB_HEALTH + affected_mob.adjust_nutrition(-5 * REAGENTS_METABOLISM * seconds_per_tick) //Lenturi //impure @@ -210,13 +212,13 @@ Basically, we fill the time between now and 2s from now with hands based off the addiction_types = list(/datum/addiction/medicine = 8) liver_damage = 0 -/datum/reagent/impurity/lentslurri/on_mob_metabolize(mob/living/carbon/owner) - owner.add_movespeed_modifier(/datum/movespeed_modifier/reagent/lenturi) - return ..() +/datum/reagent/impurity/lentslurri/on_mob_metabolize(mob/living/carbon/affected_mob) + . = ..() + affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/lenturi) -/datum/reagent/impurity/lentslurri/on_mob_end_metabolize(mob/living/carbon/owner) - owner.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/lenturi) - return ..() +/datum/reagent/impurity/lentslurri/on_mob_end_metabolize(mob/living/carbon/affected_mob) + . = ..() + affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/lenturi) //failed /datum/reagent/inverse/ichiyuri @@ -233,19 +235,19 @@ Basically, we fill the time between now and 2s from now with hands based off the var/spammer = 0 //Just the removed itching mechanism - omage to it's origins. -/datum/reagent/inverse/ichiyuri/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired) - if(prob(resetting_probability) && !(HAS_TRAIT(owner, TRAIT_RESTRAINED) || owner.incapacitated())) +/datum/reagent/inverse/ichiyuri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + if(prob(resetting_probability) && !(HAS_TRAIT(affected_mob, TRAIT_RESTRAINED) || affected_mob.incapacitated())) . = TRUE if(spammer < world.time) - to_chat(owner,span_warning("You can't help but itch yourself.")) + to_chat(affected_mob,span_warning("You can't help but itch yourself.")) spammer = world.time + (10 SECONDS) var/scab = rand(1,7) - owner.adjustBruteLoss(scab*REM) - owner.bleed(scab) + if(affected_mob.adjustBruteLoss(scab*REM, updating_health = FALSE)) + . = UPDATE_MOB_HEALTH + affected_mob.bleed(scab) resetting_probability = 0 - resetting_probability += (5*(current_cycle/10) * seconds_per_tick) // 10 iterations = >51% to itch - ..() - return . + resetting_probability += (5*((current_cycle-1)/10) * seconds_per_tick) // 10 iterations = >51% to itch //Aiuri //impure @@ -258,14 +260,14 @@ Basically, we fill the time between now and 2s from now with hands based off the /// blurriness at the start of taking the med var/amount_of_blur_applied = 0 SECONDS -/datum/reagent/impurity/aiuri/on_mob_add(mob/living/owner, amount) +/datum/reagent/impurity/aiuri/on_mob_add(mob/living/affected_mob, amount) . = ..() amount_of_blur_applied = creation_purity * (volume / metabolization_rate) * 2 SECONDS - owner.adjust_eye_blur(amount_of_blur_applied) + affected_mob.adjust_eye_blur(amount_of_blur_applied) -/datum/reagent/impurity/aiuri/on_mob_delete(mob/living/owner, amount) +/datum/reagent/impurity/aiuri/on_mob_delete(mob/living/affected_mob, amount) . = ..() - owner.adjust_eye_blur(-amount_of_blur_applied) + affected_mob.adjust_eye_blur(-amount_of_blur_applied) //Hercuri //inverse @@ -280,14 +282,14 @@ Basically, we fill the time between now and 2s from now with hands based off the taste_description = "heat! Ouch!" addiction_types = list(/datum/addiction/medicine = 2.5) -/datum/reagent/inverse/hercuri/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired) +/datum/reagent/inverse/hercuri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() var/heating = rand(5, 25) * creation_purity * REM * seconds_per_tick - owner.reagents?.chem_temp += heating - owner.adjust_bodytemperature(heating * TEMPERATURE_DAMAGE_COEFFICIENT) - if(!ishuman(owner)) + affected_mob.reagents?.chem_temp += heating + affected_mob.adjust_bodytemperature(heating * TEMPERATURE_DAMAGE_COEFFICIENT) + if(!ishuman(affected_mob)) return - var/mob/living/carbon/human/human = owner + var/mob/living/carbon/human/human = affected_mob human.adjust_coretemperature(heating * TEMPERATURE_DAMAGE_COEFFICIENT) /datum/reagent/inverse/hercuri/expose_mob(mob/living/carbon/exposed_mob, methods=VAPOR, reac_volume) @@ -298,13 +300,14 @@ Basically, we fill the time between now and 2s from now with hands based off the exposed_mob.adjust_bodytemperature(reac_volume * TEMPERATURE_DAMAGE_COEFFICIENT) exposed_mob.adjust_fire_stacks(reac_volume / 2) -/datum/reagent/inverse/hercuri/overdose_process(mob/living/carbon/owner, seconds_per_tick, times_fired) +/datum/reagent/inverse/hercuri/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() - owner.adjustOrganLoss(ORGAN_SLOT_LIVER, 2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) //Makes it so you can't abuse it with pyroxadone very easily (liver dies from 25u unless it's fully upgraded) + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) //Makes it so you can't abuse it with pyroxadone very easily (liver dies from 25u unless it's fully upgraded) + . = UPDATE_MOB_HEALTH var/heating = 10 * creation_purity * REM * seconds_per_tick * TEMPERATURE_DAMAGE_COEFFICIENT - owner.adjust_bodytemperature(heating) //hot hot - if(ishuman(owner)) - var/mob/living/carbon/human/human = owner + affected_mob.adjust_bodytemperature(heating) //hot hot + if(ishuman(affected_mob)) + var/mob/living/carbon/human/human = affected_mob human.adjust_coretemperature(heating) /datum/reagent/inverse/healing/tirimol @@ -317,16 +320,17 @@ Basically, we fill the time between now and 2s from now with hands based off the addiction_types = list(/datum/addiction/medicine = 5) //Makes patients fall asleep, then boosts the purirty of their medicine reagents if they're asleep -/datum/reagent/inverse/healing/tirimol/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired) +/datum/reagent/inverse/healing/tirimol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() switch(current_cycle) - if(1 to 10)//same delay as chloral hydrate + if(2 to 11)//same delay as chloral hydrate if(prob(50)) - owner.emote("yawn") - if(10 to INFINITY) - owner.Sleeping(40) + affected_mob.emote("yawn") + if(11 to INFINITY) + affected_mob.Sleeping(40) . = 1 - if(owner.IsSleeping()) - for(var/datum/reagent/reagent as anything in owner.reagents.reagent_list) + if(affected_mob.IsSleeping()) + for(var/datum/reagent/reagent as anything in affected_mob.reagents.reagent_list) if(reagent in cached_reagent_list) continue if(!istype(reagent, /datum/reagent/medicine)) @@ -334,23 +338,22 @@ Basically, we fill the time between now and 2s from now with hands based off the reagent.creation_purity *= 1.25 cached_reagent_list += reagent - else if(!owner.IsSleeping() && length(cached_reagent_list)) + else if(!affected_mob.IsSleeping() && length(cached_reagent_list)) for(var/datum/reagent/reagent as anything in cached_reagent_list) if(!reagent) continue reagent.creation_purity *= 0.8 cached_reagent_list = list() - ..() -/datum/reagent/inverse/healing/tirimol/on_mob_delete(mob/living/owner) - if(owner.IsSleeping()) - owner.visible_message(span_notice("[icon2html(owner, viewers(DEFAULT_MESSAGE_RANGE, src))] [owner] lets out a hearty snore!"))//small way of letting people know the supersnooze is ended +/datum/reagent/inverse/healing/tirimol/on_mob_delete(mob/living/affected_mob) + . = ..() + if(affected_mob.IsSleeping()) + affected_mob.visible_message(span_notice("[icon2html(affected_mob, viewers(DEFAULT_MESSAGE_RANGE, src))] [affected_mob] lets out a hearty snore!"))//small way of letting people know the supersnooze is ended for(var/datum/reagent/reagent as anything in cached_reagent_list) if(!reagent) continue reagent.creation_purity *= 0.8 cached_reagent_list = list() - ..() //convermol //inverse @@ -369,11 +372,11 @@ Basically, we fill the time between now and 2s from now with hands based off the var/cached_cold_level_2 var/cached_cold_level_3 -/datum/reagent/inverse/healing/convermol/on_mob_add(mob/living/owner, amount) +/datum/reagent/inverse/healing/convermol/on_mob_add(mob/living/affected_mob, amount) . = ..() - RegisterSignal(owner, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_gained_organ)) - RegisterSignal(owner, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_removed_organ)) - var/obj/item/organ/internal/lungs/lungs = owner.get_organ_slot(ORGAN_SLOT_LUNGS) + RegisterSignal(affected_mob, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_gained_organ)) + RegisterSignal(affected_mob, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_removed_organ)) + var/obj/item/organ/internal/lungs/lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS) if(!lungs) return apply_lung_levels(lungs) @@ -416,11 +419,11 @@ Basically, we fill the time between now and 2s from now with hands based off the lungs.cold_level_2_threshold = cached_cold_level_2 lungs.cold_level_3_threshold = cached_cold_level_3 -/datum/reagent/inverse/healing/convermol/on_mob_delete(mob/living/owner) +/datum/reagent/inverse/healing/convermol/on_mob_delete(mob/living/affected_mob) . = ..() - UnregisterSignal(owner, COMSIG_CARBON_LOSE_ORGAN) - UnregisterSignal(owner, COMSIG_CARBON_GAIN_ORGAN) - var/obj/item/organ/internal/lungs/lungs = owner.get_organ_slot(ORGAN_SLOT_LUNGS) + UnregisterSignal(affected_mob, COMSIG_CARBON_LOSE_ORGAN) + UnregisterSignal(affected_mob, COMSIG_CARBON_GAIN_ORGAN) + var/obj/item/organ/internal/lungs/lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS) if(!lungs) return restore_lung_levels(lungs) @@ -439,13 +442,13 @@ Basically, we fill the time between now and 2s from now with hands based off the var/poison_interval = (9 SECONDS) -/datum/reagent/inverse/technetium/on_mob_life(mob/living/carbon/owner, seconds_per_tick, times_fired) +/datum/reagent/inverse/technetium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() time_until_next_poison -= seconds_per_tick * (1 SECONDS) if (time_until_next_poison <= 0) time_until_next_poison = poison_interval - owner.adjustToxLoss(creation_purity * 1, required_biotype = affected_biotype) - . = TRUE - ..() + if(affected_mob.adjustToxLoss(creation_purity * 1, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH //Kind of a healing effect, Presumably you're using syrinver to purge so this helps that /datum/reagent/inverse/healing/syriniver @@ -457,7 +460,7 @@ Basically, we fill the time between now and 2s from now with hands based off the var/cached_reagent_list = list() addiction_types = list(/datum/addiction/medicine = 1.75) -/datum/reagent/inverse/healing/syriniver/on_mob_add(mob/living/affected_mob) +/datum/reagent/inverse/healing/syriniver/on_mob_add(mob/living/affected_mob, amount) if(!(iscarbon(affected_mob))) return ..() var/mob/living/carbon/affected_carbon = affected_mob @@ -493,12 +496,13 @@ Basically, we fill the time between now and 2s from now with hands based off the //Heals toxins if it's the only thing present - kinda the oposite of multiver! Maybe that's why it's inverse! /datum/reagent/inverse/healing/monover/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + var/need_mob_update if(length(affected_mob.reagents.reagent_list) > 1) - affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * seconds_per_tick, required_organ_flag = affected_organ_flags) //Hey! It's everyone's favourite drawback from multiver! - return ..() - affected_mob.adjustToxLoss(-2 * REM * creation_purity * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - return TRUE + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * seconds_per_tick, required_organ_flag = affected_organ_flags) //Hey! It's everyone's favourite drawback from multiver! + else + need_mob_update = affected_mob.adjustToxLoss(-2 * REM * creation_purity * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH ///Can bring a corpse back to life temporarily (if heart is intact) ///Makes wounds bleed more, if it brought someone back, they take additional brute and heart damage @@ -527,9 +531,10 @@ Basically, we fill the time between now and 2s from now with hands based off the ) /datum/reagent/inverse/penthrite/on_mob_dead(mob/living/carbon/affected_mob, seconds_per_tick) + . = ..() var/obj/item/organ/internal/heart/heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART) if(!heart || heart.organ_flags & ORGAN_FAILING) - return ..() + return metabolization_rate = 0.2 * REM affected_mob.add_traits(trait_buffs, type) affected_mob.set_stat(CONSCIOUS) //This doesn't touch knocked out @@ -544,18 +549,19 @@ Basically, we fill the time between now and 2s from now with hands based off the back_from_the_dead = TRUE affected_mob.emote("gasp") affected_mob.playsound_local(affected_mob, 'sound/health/fastbeat.ogg', 65) - ..() /datum/reagent/inverse/penthrite/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(!back_from_the_dead) - return ..() + return //Following is for those brought back from the dead only REMOVE_TRAIT(affected_mob, TRAIT_KNOCKEDOUT, CRIT_HEALTH_TRAIT) REMOVE_TRAIT(affected_mob, TRAIT_KNOCKEDOUT, OXYLOSS_TRAIT) for(var/datum/wound/iter_wound as anything in affected_mob.all_wounds) iter_wound.adjust_blood_flow(1-creation_purity) - affected_mob.adjustBruteLoss(5 * (1-creation_purity) * seconds_per_tick, required_bodytype = affected_bodytype) - affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, (1 + (1-creation_purity)) * seconds_per_tick, required_organ_flag = affected_organ_flags) + var/need_mob_update + need_mob_update = affected_mob.adjustBruteLoss(5 * (1-creation_purity) * seconds_per_tick, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, (1 + (1-creation_purity)) * seconds_per_tick, required_organ_flag = affected_organ_flags) if(affected_mob.health < HEALTH_THRESHOLD_CRIT) affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/nooartrium) if(affected_mob.health < HEALTH_THRESHOLD_FULLCRIT) @@ -563,19 +569,20 @@ Basically, we fill the time between now and 2s from now with hands based off the var/obj/item/organ/internal/heart/heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART) if(!heart || heart.organ_flags & ORGAN_FAILING) remove_buffs(affected_mob) - ..() - return TRUE - + if(need_mob_update) + return UPDATE_MOB_HEALTH + /datum/reagent/inverse/penthrite/on_mob_delete(mob/living/carbon/affected_mob) + . = ..() remove_buffs(affected_mob) var/obj/item/organ/internal/heart/heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART) if(affected_mob.health < -500 || heart.organ_flags & ORGAN_FAILING)//Honestly commendable if you get -500 explosion(affected_mob, light_impact_range = 1, explosion_cause = src) qdel(heart) affected_mob.visible_message(span_boldwarning("[affected_mob]'s heart explodes!")) - return ..() /datum/reagent/inverse/penthrite/overdose_start(mob/living/carbon/affected_mob) + . = ..() if(!back_from_the_dead) return ..() var/obj/item/organ/internal/heart/heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART) @@ -650,7 +657,7 @@ Basically, we fill the time between now and 2s from now with hands based off the var/datum/brain_trauma/temp_trauma /datum/reagent/inverse/neurine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - .=..() + . = ..() if(temp_trauma) return if(!(SPT_PROB(creation_purity*10, seconds_per_tick))) @@ -658,7 +665,7 @@ Basically, we fill the time between now and 2s from now with hands based off the var/traumalist = subtypesof(/datum/brain_trauma) var/list/forbiddentraumas = list( /datum/brain_trauma/severe/split_personality, // Split personality uses a ghost, I don't want to use a ghost for a temp thing - /datum/brain_trauma/special/obsessed, // Obsessed sets the owner as an antag - I presume this will lead to problems, so we'll remove it + /datum/brain_trauma/special/obsessed, // Obsessed sets the affected_mob as an antag - I presume this will lead to problems, so we'll remove it /datum/brain_trauma/hypnosis, // Hypnosis, same reason as obsessed, plus a bug makes it remain even after the neurowhine purges and then turn into "nothing" on the med reading upon a second application /datum/brain_trauma/special/honorbound, // Designed to be chaplain exclusive ) @@ -672,7 +679,7 @@ Basically, we fill the time between now and 2s from now with hands based off the return /datum/reagent/inverse/neurine/on_mob_delete(mob/living/carbon/affected_mob) - .=..() + . = ..() if(!temp_trauma) return if(istype(temp_trauma, /datum/brain_trauma/special/imaginary_friend))//Good friends stay by you, no matter what @@ -680,7 +687,7 @@ Basically, we fill the time between now and 2s from now with hands based off the affected_mob.cure_trauma_type(temp_trauma, resilience = TRAUMA_RESILIENCE_MAGIC) /datum/reagent/inverse/corazargh - name = "Corazargh" //It's what you yell! Though, if you've a better name feel free. Also an omage to an older chem + name = "Corazargh" //It's what you yell! Though, if you've a better name feel free. Also an homage to an older chem description = "Interferes with the body's natural pacemaker, forcing the patient to manually beat their heart." color = "#5F5F5F" self_consuming = TRUE @@ -689,82 +696,22 @@ Basically, we fill the time between now and 2s from now with hands based off the metabolization_rate = REM chemical_flags = REAGENT_DEAD_PROCESS tox_damage = 0 - ///Weakref to the old heart we're swapping for - var/datum/weakref/original_heart_ref - ///Weakref to the new heart that's temp added - var/datum/weakref/manual_heart_ref -///Creates a new cursed heart and puts the old inside of it, then replaces the position of the old +///Give the victim the manual heart beating component. /datum/reagent/inverse/corazargh/on_mob_metabolize(mob/living/affected_mob) + . = ..() if(!iscarbon(affected_mob)) return var/mob/living/carbon/carbon_mob = affected_mob - var/obj/item/organ/internal/heart/original_heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART) - if(!original_heart) - return - original_heart_ref = WEAKREF(original_heart) - - var/obj/item/organ/internal/heart/cursed/manual_heart = new(null, src) - manual_heart_ref = WEAKREF(manual_heart) - original_heart.Remove(carbon_mob, special = TRUE) //So we don't suddenly die - original_heart.forceMove(manual_heart) - original_heart.organ_flags |= ORGAN_FROZEN //Not actually frozen, but we want to pause decay - manual_heart.Insert(carbon_mob, special = TRUE) - //these last so instert doesn't call them - RegisterSignal(carbon_mob, COMSIG_CARBON_GAIN_ORGAN, PROC_REF(on_gained_organ)) - RegisterSignal(carbon_mob, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_removed_organ)) - to_chat(affected_mob, span_userdanger("You feel your heart suddenly stop beating on it's own - you'll have to manually beat it!")) - ..() - -///Intercepts the new heart and creates a new cursed heart - putting the old inside of it -/datum/reagent/inverse/corazargh/proc/on_gained_organ(mob/affected_mob, obj/item/organ/organ) - SIGNAL_HANDLER - if(!istype(organ, /obj/item/organ/internal/heart)) - return - // DO NOT REACT TO YOUR OWN HEART ADDITION I SWEAR TO CHRIST - var/obj/item/organ/internal/heart/cursed/manual_heart = manual_heart_ref?.resolve() - if(organ == manual_heart) - return - - var/mob/living/carbon/affected_carbon = affected_mob - var/obj/item/organ/internal/heart/original_heart = organ - original_heart_ref = WEAKREF(original_heart) - original_heart.Remove(affected_carbon, special = TRUE) - if(!manual_heart) - manual_heart = new(null, src) - manual_heart_ref = WEAKREF(manual_heart) - original_heart.forceMove(manual_heart) - original_heart.organ_flags |= ORGAN_FROZEN //Not actually frozen, but we want to pause decay - manual_heart.Insert(affected_carbon, special = TRUE) - -///If we're ejecting out the organ - replace it with the original -/datum/reagent/inverse/corazargh/proc/on_removed_organ(mob/prev_owner, obj/item/organ/organ) - SIGNAL_HANDLER - var/obj/item/organ/internal/heart/cursed/manual_heart = manual_heart_ref?.resolve() - if(organ != manual_heart) - return - var/obj/item/organ/internal/heart/original_heart = original_heart_ref?.resolve() - if(!original_heart) + var/obj/item/organ/internal/heart/affected_heart = carbon_mob.get_organ_slot(ORGAN_SLOT_HEART) + if(isnull(affected_heart)) return + carbon_mob.AddComponent(/datum/component/manual_heart) + return ..() - original_heart.forceMove(manual_heart.loc) - original_heart.organ_flags &= ~ORGAN_FROZEN //enable decay again - QDEL_NULL(manual_heart_ref) - -///We're done - remove the curse and restore the old one +///We're done - remove the curse /datum/reagent/inverse/corazargh/on_mob_end_metabolize(mob/living/affected_mob) - //Do these first so Insert doesn't call them - UnregisterSignal(affected_mob, COMSIG_CARBON_LOSE_ORGAN) - UnregisterSignal(affected_mob, COMSIG_CARBON_GAIN_ORGAN) - if(!iscarbon(affected_mob)) - return - var/mob/living/carbon/affected_carbon = affected_mob - var/obj/item/organ/internal/heart/original_heart = original_heart_ref?.resolve() - if(original_heart) //Mostly a just in case - original_heart.organ_flags &= ~ORGAN_FROZEN //enable decay again - original_heart.Insert(affected_carbon, special = TRUE) - QDEL_NULL(manual_heart_ref) - to_chat(affected_mob, span_userdanger("You feel your heart start beating normally again!")) + qdel(affected_mob.GetComponent(/datum/component/manual_heart)) ..() /datum/reagent/inverse/antihol @@ -778,9 +725,9 @@ Basically, we fill the time between now and 2s from now with hands based off the tox_damage = 0 /datum/reagent/inverse/antihol/on_mob_life(mob/living/carbon/C, seconds_per_tick, times_fired) + . = ..() for(var/datum/reagent/consumable/ethanol/alcohol in C.reagents.reagent_list) alcohol.boozepwr += seconds_per_tick - ..() /datum/reagent/inverse/oculine name = "Oculater" @@ -797,19 +744,19 @@ Basically, we fill the time between now and 2s from now with hands based off the var/headache = FALSE /datum/reagent/inverse/oculine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(headache) return ..() if(SPT_PROB(100 * creation_purity, seconds_per_tick)) affected_mob.become_blind(IMPURE_OCULINE) to_chat(affected_mob, span_danger("You suddenly develop a pounding headache as your vision fluxuates.")) headache = TRUE - ..() /datum/reagent/inverse/oculine/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() affected_mob.cure_blind(IMPURE_OCULINE) if(headache) to_chat(affected_mob, span_notice("Your headache clears up!")) - ..() /datum/reagent/impurity/inacusiate name = "Tinacusiate" @@ -825,15 +772,15 @@ Basically, we fill the time between now and 2s from now with hands based off the var/randomSpan /datum/reagent/impurity/inacusiate/on_mob_metabolize(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() randomSpan = pick(list("clown", "small", "big", "hypnophrase", "alien", "cult", "alert", "danger", "emote", "yell", "brass", "sans", "papyrus", "robot", "his_grace", "phobia")) RegisterSignal(affected_mob, COMSIG_MOVABLE_HEAR, PROC_REF(owner_hear)) to_chat(affected_mob, span_warning("Your hearing seems to be a bit off!")) - ..() /datum/reagent/impurity/inacusiate/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() UnregisterSignal(affected_mob, COMSIG_MOVABLE_HEAR) to_chat(affected_mob, span_notice("You start hearing things normally again.")) - ..() /datum/reagent/impurity/inacusiate/proc/owner_hear(mob/living/owner, list/hearing_args) SIGNAL_HANDLER diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_toxin_reagents.dm index 947c83c3166af2..0872fa6658815d 100644 --- a/code/modules/reagents/chemistry/reagents/impure_reagents/impure_toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/impure_reagents/impure_toxin_reagents.dm @@ -18,7 +18,6 @@ owner.adjust_disgust(50) ..() - //Formaldehyde - Impure Version /datum/reagent/impurity/methanol name = "Methanol" @@ -29,9 +28,10 @@ liver_damage = 0 /datum/reagent/impurity/methanol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/obj/item/organ/internal/eyes/eyes = affected_mob.get_organ_slot(ORGAN_SLOT_EYES) - eyes?.apply_organ_damage(0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - return ..() + if(eyes?.apply_organ_damage(0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + return UPDATE_MOB_HEALTH //Chloral Hydrate - Impure Version /datum/reagent/impurity/chloralax @@ -43,9 +43,9 @@ liver_damage = 0 /datum/reagent/impurity/chloralax/on_mob_life(mob/living/carbon/owner, seconds_per_tick) - owner.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - + . = ..() + if(owner.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH //Mindbreaker Toxin - Impure Version /datum/reagent/impurity/rosenol @@ -58,12 +58,12 @@ metabolization_rate = 0.5 * REAGENTS_METABOLISM /datum/reagent/impurity/rosenol/on_mob_life(mob/living/carbon/owner, seconds_per_tick) + . = ..() var/obj/item/organ/internal/tongue/tongue = owner.get_organ_slot(ORGAN_SLOT_TONGUE) if(!tongue) - return ..() + return if(SPT_PROB(4.0, seconds_per_tick)) owner.manual_emote("clicks with [owner.p_their()] tongue.") owner.say("Noice.", forced = /datum/reagent/impurity/rosenol) if(SPT_PROB(2.0, seconds_per_tick)) owner.say(pick("Ah! That was a mistake!", "Horrible.", "Watch out everybody, the potato is really hot.", "When I was six I ate a bag of plums.", "And if there is one thing I can't stand it's tomatoes.", "And if there is one thing I love it's tomatoes.", "We had a captain who was so strict, you weren't allowed to breathe in their station.", "The unrobust ones just used to keel over and die, you'd hear them going down behind you."), forced = /datum/reagent/impurity/rosenol) - ..() diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 30fae4db9c7df7..a28e47703df4d3 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -13,7 +13,8 @@ current_cycle++ if(length(reagent_removal_skip_list)) return - holder.remove_reagent(type, metabolization_rate * seconds_per_tick / affected_mob.metabolism_efficiency) //medicine reagents stay longer if you have a better metabolism + if(holder) + holder.remove_reagent(type, metabolization_rate * seconds_per_tick / affected_mob.metabolism_efficiency) //medicine reagents stay longer if you have a better metabolism /datum/reagent/medicine/leporazine name = "Leporazine" @@ -23,6 +24,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/leporazine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/target_temp = affected_mob.get_body_temp_normal(apply_change = FALSE) if(affected_mob.bodytemperature > target_temp) affected_mob.adjust_bodytemperature(-40 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, target_temp) @@ -34,7 +36,6 @@ affected_human.adjust_coretemperature(-40 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, target_temp) else if(affected_human.coretemperature < (target_temp + 1)) affected_human.adjust_coretemperature(40 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 0, target_temp) - ..() /datum/reagent/medicine/adminordrazine //An OP chemical for admins name = "Adminordrazine" @@ -66,12 +67,11 @@ mytray.visible_message(span_warning("Nothing happens...")) /datum/reagent/medicine/adminordrazine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.heal_bodypart_damage(5 * REM * seconds_per_tick, 5 * REM * seconds_per_tick, 0, FALSE, affected_bodytype) - affected_mob.adjustToxLoss(-5 * REM * seconds_per_tick, FALSE, TRUE, affected_biotype) + . = ..() + affected_mob.heal_bodypart_damage(brute = 5 * REM * seconds_per_tick, burn = 5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + affected_mob.adjustToxLoss(-5 * REM * seconds_per_tick, updating_health = FALSE, forced = TRUE, required_biotype = affected_biotype) // Heal everything! That we want to. But really don't heal reagents. Otherwise we'll lose ... us. - affected_mob.fully_heal(full_heal_flags & ~HEAL_ALL_REAGENTS) - ..() - return TRUE + affected_mob.fully_heal(full_heal_flags & ~HEAL_ALL_REAGENTS) // there is no need to return UPDATE_MOB_HEALTH because this proc calls updatehealth() /datum/reagent/medicine/adminordrazine/quantum_heal name = "Quantum Medicine" @@ -95,11 +95,11 @@ affected_mob.AdjustParalyzed(-20 * REM * seconds_per_tick) if(holder.has_reagent(/datum/reagent/toxin/mindbreaker)) holder.remove_reagent(/datum/reagent/toxin/mindbreaker, 5 * REM * seconds_per_tick) + . = ..() affected_mob.adjust_hallucinations(-20 SECONDS * REM * seconds_per_tick) if(SPT_PROB(16, seconds_per_tick)) - affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() + if(affected_mob.adjustToxLoss(1, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/synaphydramine name = "Diphen-Synaptizine" @@ -114,11 +114,11 @@ holder.remove_reagent(/datum/reagent/toxin/mindbreaker, 5 * REM * seconds_per_tick) if(holder.has_reagent(/datum/reagent/toxin/histamine)) holder.remove_reagent(/datum/reagent/toxin/histamine, 5 * REM * seconds_per_tick) + . = ..() affected_mob.adjust_hallucinations(-20 SECONDS * REM * seconds_per_tick) if(SPT_PROB(16, seconds_per_tick)) - affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() + if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/sansufentanyl name = "Sansufentanyl" @@ -128,16 +128,16 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/sansufentanyl/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_confusion_up_to(3 SECONDS * REM * seconds_per_tick, 5 SECONDS) affected_mob.adjust_dizzy_up_to(6 SECONDS * REM * seconds_per_tick, 12 SECONDS) - affected_mob.adjustStaminaLoss(1 * REM * seconds_per_tick) + if(affected_mob.adjustStaminaLoss(1 * REM * seconds_per_tick, updating_stamina = FALSE)) + . = UPDATE_MOB_HEALTH if(SPT_PROB(10, seconds_per_tick)) to_chat(affected_mob, "You feel confused and disoriented.") if(prob(30)) SEND_SOUND(affected_mob, sound('sound/weapons/flash_ring.ogg')) - ..() - return TRUE /datum/reagent/medicine/cryoxadone name = "Cryoxadone" @@ -150,22 +150,23 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/cryoxadone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() metabolization_rate = REAGENTS_METABOLISM * (0.00001 * (affected_mob.bodytemperature ** 2) + 0.5) if(affected_mob.bodytemperature >= T0C || !HAS_TRAIT(affected_mob, TRAIT_KNOCKEDOUT)) - ..() return var/power = -0.00003 * (affected_mob.bodytemperature ** 2) + 3 - affected_mob.adjustOxyLoss(-3 * power * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustBruteLoss(-power * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(-power * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustToxLoss(-power * REM * seconds_per_tick, FALSE, TRUE, affected_biotype) //heals TOXINLOVERs - affected_mob.adjustCloneLoss(-power * REM * seconds_per_tick, FALSE, affected_biotype) + var/need_mob_update + need_mob_update = affected_mob.adjustOxyLoss(-3 * power * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustBruteLoss(-power * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-power * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustToxLoss(-power * REM * seconds_per_tick, updating_health = FALSE, forced = TRUE, required_biotype = affected_biotype) //heals TOXINLOVERs + need_mob_update += affected_mob.adjustCloneLoss(-power * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) for(var/i in affected_mob.all_wounds) var/datum/wound/iter_wound = i iter_wound.on_xadone(power * REM * seconds_per_tick) REMOVE_TRAIT(affected_mob, TRAIT_DISFIGURED, TRAIT_GENERIC) //fixes common causes for disfiguration - ..() - return TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH // Healing /datum/reagent/medicine/cryoxadone/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user) @@ -181,12 +182,12 @@ metabolization_rate = 1.5 * REAGENTS_METABOLISM /datum/reagent/medicine/clonexadone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.bodytemperature < T0C) - affected_mob.adjustCloneLoss((0.00006 * (affected_mob.bodytemperature ** 2) - 6) * REM * seconds_per_tick, FALSE) + if(affected_mob.adjustCloneLoss((0.00006 * (affected_mob.bodytemperature ** 2) - 6) * REM * seconds_per_tick, updating_health = FALSE)) + . = UPDATE_MOB_HEALTH REMOVE_TRAIT(affected_mob, TRAIT_DISFIGURED, TRAIT_GENERIC) - . = TRUE metabolization_rate = REAGENTS_METABOLISM * (0.000015 * (affected_mob.bodytemperature ** 2) + 0.75) - ..() /datum/reagent/medicine/pyroxadone name = "Pyroxadone" @@ -197,6 +198,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/pyroxadone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT) var/power = 0 switch(affected_mob.bodytemperature) @@ -209,17 +211,18 @@ if(affected_mob.on_fire) power *= 2 - affected_mob.adjustOxyLoss(-2 * power * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustBruteLoss(-power * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(-1.5 * power * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustToxLoss(-power * REM * seconds_per_tick, FALSE, TRUE, affected_biotype) - affected_mob.adjustCloneLoss(-power * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + var/need_mob_update + need_mob_update = affected_mob.adjustOxyLoss(-2 * power * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustBruteLoss(-power * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-1.5 * power * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustToxLoss(-power * REM * seconds_per_tick, updating_health = FALSE, forced = TRUE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustCloneLoss(-power * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + . = UPDATE_MOB_HEALTH for(var/i in affected_mob.all_wounds) var/datum/wound/iter_wound = i iter_wound.on_xadone(power * REM * seconds_per_tick) REMOVE_TRAIT(affected_mob, TRAIT_DISFIGURED, TRAIT_GENERIC) - . = TRUE - ..() /datum/reagent/medicine/rezadone name = "Rezadone" @@ -232,18 +235,20 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/rezadone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.setCloneLoss(0) //Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that. // No such luck so far - affected_mob.heal_bodypart_damage(1 * REM * seconds_per_tick, 1 * REM * seconds_per_tick) + . = ..() + var/need_mob_update + need_mob_update = affected_mob.setCloneLoss(0) //Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that. // No such luck so far + need_mob_update += affected_mob.heal_bodypart_damage(brute = 1 * REM * seconds_per_tick, burn = 1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_biotype) + if(need_mob_update) + . = UPDATE_MOB_HEALTH REMOVE_TRAIT(affected_mob, TRAIT_DISFIGURED, TRAIT_GENERIC) - ..() - . = TRUE /datum/reagent/medicine/rezadone/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + . = ..() + if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH affected_mob.set_dizzy_if_lower(10 SECONDS * REM * seconds_per_tick) affected_mob.set_jitter_if_lower(10 SECONDS * REM * seconds_per_tick) - ..() - . = TRUE /datum/reagent/medicine/rezadone/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) . = ..() @@ -263,13 +268,13 @@ ph = 8.1 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/medicine/spaceacillin/on_mob_add(mob/living/L) +/datum/reagent/medicine/spaceacillin/on_mob_add(mob/living/affected_mob) . = ..() - ADD_TRAIT(L, TRAIT_VIRUS_RESISTANCE, type) + ADD_TRAIT(affected_mob, TRAIT_VIRUS_RESISTANCE, type) -/datum/reagent/medicine/spaceacillin/on_mob_delete(mob/living/L) +/datum/reagent/medicine/spaceacillin/on_mob_delete(mob/living/affected_mob) . = ..() - REMOVE_TRAIT(L, TRAIT_VIRUS_RESISTANCE, type) + REMOVE_TRAIT(affected_mob, TRAIT_VIRUS_RESISTANCE, type) //Goon Chems. Ported mainly from Goonstation. Easily mixable (or not so easily) and provide a variety of effects. @@ -284,18 +289,20 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/oxandrolone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update if(affected_mob.getFireLoss() > 25) - affected_mob.adjustFireLoss(-4 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) //Twice as effective as AIURI for severe burns + need_mob_update = affected_mob.adjustFireLoss(-4 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) //Twice as effective as AIURI for severe burns else - affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) //But only a quarter as effective for more minor ones - ..() - . = TRUE + need_mob_update = affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) //But only a quarter as effective for more minor ones + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/oxandrolone/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.getFireLoss()) //It only makes existing burns worse - affected_mob.adjustFireLoss(4.5 * REM * seconds_per_tick, FALSE, FALSE, BODYTYPE_ORGANIC) // it's going to be healing either 4 or 0.5 - . = TRUE - ..() + if(affected_mob.adjustFireLoss(4.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_biotype)) // it's going to be healing either 4 or 0.5 + return UPDATE_MOB_HEALTH /datum/reagent/medicine/salglu_solution name = "Saline-Glucose Solution" @@ -312,6 +319,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/salglu_solution/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update if(last_added) affected_mob.blood_volume -= last_added last_added = 0 @@ -321,25 +330,29 @@ last_added = new_blood_level - affected_mob.blood_volume affected_mob.blood_volume = new_blood_level + (extra_regen * REM * seconds_per_tick) if(SPT_PROB(18, seconds_per_tick)) - affected_mob.adjustBruteLoss(-0.5, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(-0.5, FALSE, required_bodytype = affected_bodytype) - . = TRUE - ..() + need_mob_update = affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_biotype) + need_mob_update += affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/salglu_solution/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update if(SPT_PROB(1.5, seconds_per_tick)) - to_chat(affected_mob, span_warning("You feel salty.")) - holder.add_reagent(/datum/reagent/consumable/salt, 1) - holder.remove_reagent(/datum/reagent/medicine/salglu_solution, 0.5) + if(holder) + to_chat(affected_mob, span_warning("You feel salty.")) + holder.add_reagent(/datum/reagent/consumable/salt, 1) + holder.remove_reagent(/datum/reagent/medicine/salglu_solution, 0.5) else if(SPT_PROB(1.5, seconds_per_tick)) - to_chat(affected_mob, span_warning("You feel sweet.")) - holder.add_reagent(/datum/reagent/consumable/sugar, 1) - holder.remove_reagent(/datum/reagent/medicine/salglu_solution, 0.5) + if(holder) + to_chat(affected_mob, span_warning("You feel sweet.")) + holder.add_reagent(/datum/reagent/consumable/sugar, 1) + holder.remove_reagent(/datum/reagent/medicine/salglu_solution, 0.5) if(SPT_PROB(18, seconds_per_tick)) - affected_mob.adjustBruteLoss(0.5, FALSE, FALSE, BODYTYPE_ORGANIC) - affected_mob.adjustFireLoss(0.5, FALSE, FALSE, BODYTYPE_ORGANIC) - . = TRUE - ..() + need_mob_update = affected_mob.adjustBruteLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_biotype) + need_mob_update += affected_mob.adjustFireLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/mine_salve name = "Miner's Salve" @@ -351,10 +364,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_AFFECTS_WOUNDS /datum/reagent/medicine/mine_salve/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustBruteLoss(-0.25 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(-0.25 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - ..() - return TRUE + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustBruteLoss(-0.25 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-0.25 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/mine_salve/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE) . = ..() @@ -374,13 +389,13 @@ if(show_message) to_chat(exposed_carbon, span_danger("You feel your injuries fade away to nothing!") ) -/datum/reagent/medicine/mine_salve/on_mob_metabolize(mob/living/metabolizer) +/datum/reagent/medicine/mine_salve/on_mob_metabolize(mob/living/affected_mob) . = ..() - metabolizer.apply_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type) + affected_mob.apply_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type) -/datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/metabolizer) +/datum/reagent/medicine/mine_salve/on_mob_end_metabolize(mob/living/affected_mob) . = ..() - metabolizer.remove_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type) + affected_mob.remove_status_effect(/datum/status_effect/grouped/screwy_hud/fake_healthy, type) /datum/reagent/medicine/mine_salve/on_burn_wound_processing(datum/wound/burn/flesh/burn_wound) burn_wound.sanitization += 0.3 @@ -398,20 +413,24 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/omnizine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustToxLoss(-healing * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustOxyLoss(-healing * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustBruteLoss(-healing * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(-healing * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - ..() - . = TRUE + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustToxLoss(-healing * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustOxyLoss(-healing * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustBruteLoss(-healing * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-healing * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/omnizine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustToxLoss(1.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustOxyLoss(1.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustBruteLoss(1.5 * REM * seconds_per_tick, FALSE, FALSE, BODYTYPE_ORGANIC) - affected_mob.adjustFireLoss(1.5 * REM * seconds_per_tick, FALSE, FALSE, BODYTYPE_ORGANIC) - ..() - . = TRUE + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustToxLoss(1.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustOxyLoss(1.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustBruteLoss(1.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(1.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/omnizine/protozine name = "Protozine" @@ -433,21 +452,21 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/calomel/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() for(var/datum/reagent/target_reagent in affected_mob.reagents.reagent_list) if(istype(target_reagent, /datum/reagent/medicine/calomel)) continue affected_mob.reagents.remove_reagent(target_reagent.type, 3 * REM * seconds_per_tick) var/toxin_amount = round(affected_mob.health / 40, 0.1) - affected_mob.adjustToxLoss(toxin_amount * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - return TRUE + if(affected_mob.adjustToxLoss(toxin_amount * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/calomel/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() for(var/datum/reagent/medicine/calomel/target_reagent in affected_mob.reagents.reagent_list) affected_mob.reagents.remove_reagent(target_reagent.type, 2 * REM * seconds_per_tick) - affected_mob.adjustToxLoss(2.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - return TRUE + if(affected_mob.adjustToxLoss(2.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/ammoniated_mercury name = "Ammoniated Mercury" @@ -463,22 +482,22 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/ammoniated_mercury/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/toxin_chem_amount = 0 for(var/datum/reagent/toxin/target_reagent in affected_mob.reagents.reagent_list) toxin_chem_amount += 1 affected_mob.reagents.remove_reagent(target_reagent.type, 5 * REM * seconds_per_tick) var/toxin_amount = round(affected_mob.getBruteLoss() / 15, 0.1) + round(affected_mob.getFireLoss() / 30, 0.1) - 3 - affected_mob.adjustToxLoss(toxin_amount * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + if(affected_mob.adjustToxLoss(toxin_amount * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH if(toxin_chem_amount == 0) for(var/datum/reagent/medicine/ammoniated_mercury/target_reagent in affected_mob.reagents.reagent_list) affected_mob.reagents.remove_reagent(target_reagent.type, 1 * REM * seconds_per_tick) - ..() - return TRUE /datum/reagent/medicine/ammoniated_mercury/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustToxLoss(3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - return TRUE + . = ..() + if(affected_mob.adjustToxLoss(3 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/potass_iodide name = "Potassium Iodide" @@ -494,15 +513,14 @@ ADD_TRAIT(affected_mob, TRAIT_HALT_RADIATION_EFFECTS, "[type]") /datum/reagent/medicine/potass_iodide/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_HALT_RADIATION_EFFECTS, "[type]") - return ..() /datum/reagent/medicine/potass_iodide/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - if (HAS_TRAIT(affected_mob, TRAIT_IRRADIATED)) - affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, required_biotype = affected_biotype) - - ..() - return TRUE + . = ..() + if(HAS_TRAIT(affected_mob, TRAIT_IRRADIATED)) + if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/pen_acid name = "Pentetic Acid" @@ -518,16 +536,16 @@ ADD_TRAIT(affected_mob, TRAIT_HALT_RADIATION_EFFECTS, "[type]") /datum/reagent/medicine/pen_acid/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_HALT_RADIATION_EFFECTS, "[type]") - return ..() /datum/reagent/medicine/pen_acid/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + . = ..() + if(affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH for(var/datum/reagent/R in affected_mob.reagents.reagent_list) if(R != src) affected_mob.reagents.remove_reagent(R.type, 2 * REM * seconds_per_tick) - ..() - . = TRUE /datum/reagent/medicine/sal_acid name = "Salicylic Acid" @@ -540,18 +558,20 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/sal_acid/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update if(affected_mob.getBruteLoss() > 25) - affected_mob.adjustBruteLoss(-4 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) + need_mob_update = affected_mob.adjustBruteLoss(-4 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) else - affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - ..() - . = TRUE + need_mob_update = affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/sal_acid/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.getBruteLoss()) //It only makes existing bruises worse - affected_mob.adjustBruteLoss(4.5 * REM * seconds_per_tick, FALSE, FALSE, BODYTYPE_ORGANIC) // it's going to be healing either 4 or 0.5 - . = TRUE - ..() + if(affected_mob.adjustBruteLoss(4.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = BODYTYPE_ORGANIC)) // it's going to be healing either 4 or 0.5 + return UPDATE_MOB_HEALTH /datum/reagent/medicine/salbutamol name = "Salbutamol" @@ -563,14 +583,17 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/salbutamol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) if(affected_mob.losebreath >= 4) var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS) var/our_respiration_type = affected_lungs ? affected_lungs.respiration_type : affected_mob.mob_respiration_type // use lungs' respiration type or mob_respiration_type if no lungs if(our_respiration_type & affected_respiration_type) affected_mob.losebreath -= 2 * REM * seconds_per_tick - ..() - . = TRUE + need_mob_update = TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/ephedrine name = "Ephedrine" @@ -587,16 +610,17 @@ inverse_chem_val = 0.4 /datum/reagent/medicine/ephedrine/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/ephedrine) ADD_TRAIT(affected_mob, TRAIT_BATON_RESISTANCE, type) /datum/reagent/medicine/ephedrine/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/ephedrine) REMOVE_TRAIT(affected_mob, TRAIT_BATON_RESISTANCE, type) - ..() /datum/reagent/medicine/ephedrine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(10 * (1.5-creation_purity), seconds_per_tick) && iscarbon(affected_mob)) var/obj/item/I = affected_mob.get_active_held_item() if(I && affected_mob.dropItemToGround(I)) @@ -604,11 +628,11 @@ affected_mob.set_jitter_if_lower(20 SECONDS) affected_mob.AdjustAllImmobility(-20 * REM * seconds_per_tick * normalise_creation_purity()) - affected_mob.adjustStaminaLoss(-1 * REM * seconds_per_tick * normalise_creation_purity(), FALSE) - ..() - return TRUE + affected_mob.adjustStaminaLoss(-1 * REM * seconds_per_tick * normalise_creation_purity(), updating_stamina = FALSE) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/ephedrine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(1 * (1 + (1-normalise_creation_purity())), seconds_per_tick) && iscarbon(affected_mob)) var/datum/disease/D = new /datum/disease/heart_failure affected_mob.ForceContractDisease(D) @@ -619,10 +643,9 @@ to_chat(affected_mob, span_notice("[pick("Your head pounds.", "You feel a tight pain in your chest.", "You find it hard to stay still.", "You feel your heart practically beating out of your chest.")]")) if(SPT_PROB(18 * (1 + (1-normalise_creation_purity())), seconds_per_tick)) - affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype) + affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) affected_mob.losebreath++ - . = TRUE - return TRUE + return UPDATE_MOB_HEALTH /datum/reagent/medicine/diphenhydramine name = "Diphenhydramine" @@ -638,7 +661,7 @@ affected_mob.adjust_drowsiness(2 SECONDS) affected_mob.adjust_jitter(-2 SECONDS * REM * seconds_per_tick) holder.remove_reagent(/datum/reagent/toxin/histamine, 3 * REM * seconds_per_tick) - ..() + return ..() /datum/reagent/medicine/morphine name = "Morphine" @@ -652,32 +675,31 @@ addiction_types = list(/datum/addiction/opioids = 10) /datum/reagent/medicine/morphine/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() affected_mob.add_movespeed_mod_immunities(type, /datum/movespeed_modifier/damage_slowdown) /datum/reagent/medicine/morphine/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() affected_mob.remove_movespeed_mod_immunities(type, /datum/movespeed_modifier/damage_slowdown) - ..() /datum/reagent/medicine/morphine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - if(current_cycle >= 5) + . = ..() + if(current_cycle > 5) affected_mob.add_mood_event("numb", /datum/mood_event/narcotic_medium, name) switch(current_cycle) - if(11) + if(12) to_chat(affected_mob, span_warning("You start to feel tired...") ) - if(12 to 24) + if(13 to 25) affected_mob.adjust_drowsiness(2 SECONDS * REM * seconds_per_tick) - if(24 to INFINITY) + if(25 to INFINITY) affected_mob.Sleeping(40 * REM * seconds_per_tick) - . = TRUE - ..() /datum/reagent/medicine/morphine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(18, seconds_per_tick)) affected_mob.drop_all_held_items() affected_mob.set_dizzy_if_lower(4 SECONDS) affected_mob.set_jitter_if_lower(4 SECONDS) - ..() /datum/reagent/medicine/oculine @@ -729,33 +751,31 @@ restore_eyesight(prev_affected_mob, eyes) /datum/reagent/medicine/oculine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/normalized_purity = normalise_creation_purity() affected_mob.adjust_temp_blindness(-4 SECONDS * REM * seconds_per_tick * normalized_purity) affected_mob.adjust_eye_blur(-4 SECONDS * REM * seconds_per_tick * normalized_purity) var/obj/item/organ/internal/eyes/eyes = affected_mob.get_organ_slot(ORGAN_SLOT_EYES) - if(isnull(eyes)) - return ..() - - // Healing eye damage will cure nearsightedness and blindness from ... eye damage - eyes.apply_organ_damage(-2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags) - // If our eyes are seriously damaged, we have a probability of causing eye blur while healing depending on purity - if(eyes.damaged && IS_ORGANIC_ORGAN(eyes) && SPT_PROB(16 - min(normalized_purity * 6, 12), seconds_per_tick)) - // While healing, gives some eye blur - if(affected_mob.is_blind_from(EYE_DAMAGE)) - to_chat(affected_mob, span_warning("Your vision slowly returns...")) - affected_mob.adjust_eye_blur(20 SECONDS) - else if(affected_mob.is_nearsighted_from(EYE_DAMAGE)) - to_chat(affected_mob, span_warning("The blackness in your peripheral vision begins to fade.")) - affected_mob.adjust_eye_blur(5 SECONDS) - - return ..() || TRUE + if(eyes) + // Healing eye damage will cure nearsightedness and blindness from ... eye damage + if(eyes.apply_organ_damage(-2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags)) + . = UPDATE_MOB_HEALTH + // If our eyes are seriously damaged, we have a probability of causing eye blur while healing depending on purity + if(eyes.damaged && IS_ORGANIC_ORGAN(eyes) && SPT_PROB(16 - min(normalized_purity * 6, 12), seconds_per_tick)) + // While healing, gives some eye blur + if(affected_mob.is_blind_from(EYE_DAMAGE)) + to_chat(affected_mob, span_warning("Your vision slowly returns...")) + affected_mob.adjust_eye_blur(20 SECONDS) + else if(affected_mob.is_nearsighted_from(EYE_DAMAGE)) + to_chat(affected_mob, span_warning("The blackness in your peripheral vision begins to fade.")) + affected_mob.adjust_eye_blur(5 SECONDS) /datum/reagent/medicine/oculine/on_mob_delete(mob/living/affected_mob) + . = ..() var/obj/item/organ/internal/eyes/eyes = affected_mob.get_organ_slot(ORGAN_SLOT_EYES) if(!eyes) return restore_eyesight(affected_mob, eyes) - ..() /datum/reagent/medicine/inacusiate name = "Inacusiate" @@ -783,12 +803,12 @@ message = composer.compose_message(affected_mob, message_language, message, null, spans, message_mods) /datum/reagent/medicine/inacusiate/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/obj/item/organ/internal/ears/ears = affected_mob.get_organ_slot(ORGAN_SLOT_EARS) if(!ears) - return ..() + return ears.adjustEarDamage(-4 * REM * seconds_per_tick * normalise_creation_purity(), -4 * REM * seconds_per_tick * normalise_creation_purity()) - ..() - return TRUE + return UPDATE_MOB_HEALTH /datum/reagent/medicine/inacusiate/on_mob_delete(mob/living/affected_mob) . = ..() @@ -809,16 +829,19 @@ ADD_TRAIT(affected_mob, TRAIT_PREVENT_IMPLANT_AUTO_EXPLOSION, "[type]") /datum/reagent/medicine/atropine/on_mob_delete(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_PREVENT_IMPLANT_AUTO_EXPLOSION, "[type]") - return ..() /datum/reagent/medicine/atropine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.health <= affected_mob.crit_threshold) - affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustBruteLoss(-2* REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustOxyLoss(-5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - . = TRUE + var/need_mob_update + need_mob_update = affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustBruteLoss(-2* REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustOxyLoss(-5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + if(need_mob_update) + . = UPDATE_MOB_HEALTH var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS) var/our_respiration_type = affected_lungs ? affected_lungs.respiration_type : affected_mob.mob_respiration_type if(our_respiration_type & affected_respiration_type) @@ -826,14 +849,13 @@ if(SPT_PROB(10, seconds_per_tick)) affected_mob.set_dizzy_if_lower(10 SECONDS) affected_mob.set_jitter_if_lower(10 SECONDS) - ..() /datum/reagent/medicine/atropine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - . = TRUE + . = ..() + if(affected_mob.adjustToxLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH affected_mob.set_dizzy_if_lower(2 SECONDS * REM * seconds_per_tick) affected_mob.set_jitter_if_lower(2 SECONDS * REM * seconds_per_tick) - ..() /datum/reagent/medicine/epinephrine name = "Epinephrine" @@ -845,13 +867,13 @@ ph = 10.2 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/medicine/epinephrine/on_mob_metabolize(mob/living/carbon/affected_mob) - ..() +/datum/reagent/medicine/epinephrine/on_mob_metabolize(mob/living/affected_mob) + . = ..() ADD_TRAIT(affected_mob, TRAIT_NOCRITDAMAGE, type) -/datum/reagent/medicine/epinephrine/on_mob_end_metabolize(mob/living/carbon/affected_mob) +/datum/reagent/medicine/epinephrine/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_NOCRITDAMAGE, type) - ..() /datum/reagent/medicine/epinephrine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) if(holder.has_reagent(/datum/reagent/toxin/lexorin)) @@ -859,36 +881,45 @@ holder.remove_reagent(/datum/reagent/medicine/epinephrine, 1 * REM * seconds_per_tick) if(SPT_PROB(10, seconds_per_tick)) holder.add_reagent(/datum/reagent/toxin/histamine, 4) - ..() - return FALSE + return ..() + + . = ..() + + var/need_mob_update if(affected_mob.health <= affected_mob.crit_threshold) - affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update = affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustBruteLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) if(affected_mob.losebreath >= 4) var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS) var/our_respiration_type = affected_lungs ? affected_lungs.respiration_type : affected_mob.mob_respiration_type if(our_respiration_type & affected_respiration_type) affected_mob.losebreath -= 2 * REM * seconds_per_tick + need_mob_update = TRUE if(affected_mob.losebreath < 0) affected_mob.losebreath = 0 - affected_mob.adjustStaminaLoss(-0.5 * REM * seconds_per_tick, 0) + need_mob_update = TRUE + need_mob_update += affected_mob.adjustStaminaLoss(-0.5 * REM * seconds_per_tick, updating_stamina = FALSE) if(SPT_PROB(10, seconds_per_tick)) affected_mob.AdjustAllImmobility(-20) - ..() - return TRUE + need_mob_update = TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/epinephrine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(18, REM * seconds_per_tick)) - affected_mob.adjustStaminaLoss(2.5, 0) - affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype) + var/need_mob_update + need_mob_update = affected_mob.adjustStaminaLoss(2.5 * REM * seconds_per_tick, updating_stamina = FALSE) + need_mob_update += affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) var/obj/item/organ/internal/lungs/affected_lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS) var/our_respiration_type = affected_lungs ? affected_lungs.respiration_type : affected_mob.mob_respiration_type if(our_respiration_type & affected_respiration_type) affected_mob.losebreath++ - . = TRUE - ..() + need_mob_update = TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/strange_reagent name = "Strange Reagent" @@ -897,7 +928,6 @@ color = "#A0E85E" metabolization_rate = 1.25 * REAGENTS_METABOLISM taste_description = "magnets" - harmful = TRUE ph = 0.5 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /// The amount of damage a single unit of this will heal @@ -990,11 +1020,13 @@ return ..() /datum/reagent/medicine/strange_reagent/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/damage_at_random = rand(0, 250)/100 //0 to 2.5 - affected_mob.adjustBruteLoss(damage_at_random * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(damage_at_random * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - ..() - return TRUE + var/need_mob_update + need_mob_update = affected_mob.adjustBruteLoss(damage_at_random * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(damage_at_random * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/mannitol name = "Mannitol" @@ -1009,9 +1041,9 @@ inverse_chem_val = 0.45 /datum/reagent/medicine/mannitol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags) - ..() - return TRUE + . = ..() + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags)) + return UPDATE_MOB_HEALTH //Having mannitol in you will pause the brain damage from brain tumor (so it heals an even 2 brain damage instead of 1.8) /datum/reagent/medicine/mannitol/on_mob_metabolize(mob/living/carbon/affected_mob) @@ -1019,13 +1051,15 @@ ADD_TRAIT(affected_mob, TRAIT_TUMOR_SUPPRESSED, TRAIT_GENERIC) /datum/reagent/medicine/mannitol/on_mob_end_metabolize(mob/living/carbon/affected_mob) - REMOVE_TRAIT(affected_mob, TRAIT_TUMOR_SUPPRESSED, TRAIT_GENERIC) . = ..() + REMOVE_TRAIT(affected_mob, TRAIT_TUMOR_SUPPRESSED, TRAIT_GENERIC) /datum/reagent/medicine/mannitol/overdose_start(mob/living/affected_mob) + . = ..() to_chat(affected_mob, span_notice("You suddenly feel E N L I G H T E N E D!")) /datum/reagent/medicine/mannitol/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(65, seconds_per_tick)) return var/list/tips @@ -1037,7 +1071,6 @@ tips = world.file2list("strings/chemistrytips.txt") var/message = pick(tips) send_tip_of_the_round(affected_mob, message) - return ..() /datum/reagent/medicine/neurine name = "Neurine" @@ -1073,11 +1106,12 @@ holder.remove_reagent(/datum/reagent/consumable/ethanol/neurotoxin, 5 * REM * seconds_per_tick * normalise_creation_purity()) if(SPT_PROB(8 * normalise_creation_purity(), seconds_per_tick)) affected_mob.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC) - ..() + return ..() /datum/reagent/medicine/neurine/on_mob_dead(mob/living/carbon/affected_mob, seconds_per_tick) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags) - ..() + . = ..() + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags)) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/mutadone name = "Mutadone" @@ -1088,11 +1122,10 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/mutadone/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.remove_status_effect(/datum/status_effect/jitter) if(affected_mob.has_dna()) affected_mob.dna.remove_all_mutations(list(MUT_NORMAL, MUT_EXTRA), TRUE) - if(!QDELETED(affected_mob)) //We were a monkey, now a human - ..() /datum/reagent/medicine/antihol name = "Antihol" @@ -1114,13 +1147,13 @@ ) /datum/reagent/medicine/antihol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() for(var/effect in status_effects_to_clear) affected_mob.remove_status_effect(effect) affected_mob.reagents.remove_all_type(/datum/reagent/consumable/ethanol, 3 * REM * seconds_per_tick * normalise_creation_purity(), FALSE, TRUE) - affected_mob.adjustToxLoss(-0.2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + if(affected_mob.adjustToxLoss(-0.2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH affected_mob.adjust_drunk_effect(-10 * REM * seconds_per_tick * normalise_creation_purity()) - ..() - . = TRUE /datum/reagent/medicine/antihol/expose_mob(mob/living/carbon/exposed_carbon, methods=TOUCH, reac_volume) . = ..() @@ -1141,33 +1174,35 @@ addiction_types = list(/datum/addiction/stimulants = 4) //0.8 per 2 seconds /datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/stimulants) ADD_TRAIT(affected_mob, TRAIT_BATON_RESISTANCE, type) /datum/reagent/medicine/stimulants/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/stimulants) REMOVE_TRAIT(affected_mob, TRAIT_BATON_RESISTANCE, type) - ..() /datum/reagent/medicine/stimulants/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.health < 50 && affected_mob.health > 0) - affected_mob.adjustOxyLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustBruteLoss(-1 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(-1 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) + var/need_mob_update + need_mob_update += affected_mob.adjustOxyLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustBruteLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + . = UPDATE_MOB_HEALTH affected_mob.AdjustAllImmobility(-60 * REM * seconds_per_tick) - affected_mob.adjustStaminaLoss(-5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - . = TRUE + affected_mob.adjustStaminaLoss(-5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) /datum/reagent/medicine/stimulants/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(18, seconds_per_tick)) - affected_mob.adjustStaminaLoss(2.5, FALSE, required_biotype = affected_biotype) - affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype) + affected_mob.adjustStaminaLoss(2.5, updating_stamina = FALSE, required_biotype = affected_biotype) + affected_mob.adjustToxLoss(1, updating_health = FALSE, required_biotype = affected_biotype) affected_mob.losebreath++ - . = TRUE - ..() + return UPDATE_MOB_HEALTH /datum/reagent/medicine/insulin name = "Insulin" @@ -1179,10 +1214,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/insulin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - if(affected_mob.AdjustSleeping(-20 * REM * seconds_per_tick)) - . = TRUE + affected_mob.AdjustSleeping(-20 * REM * seconds_per_tick) holder.remove_reagent(/datum/reagent/consumable/sugar, 3 * REM * seconds_per_tick) - ..() + return ..() //Trek Chems, used primarily by medibots. Only heals a specific damage type, but is very efficient. @@ -1195,9 +1229,10 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/medicine/inaprovaline/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.losebreath >= 5) affected_mob.losebreath -= 5 * REM * seconds_per_tick - ..() + return UPDATE_MOB_HEALTH /datum/reagent/medicine/regen_jelly name = "Regenerative Jelly" @@ -1219,12 +1254,14 @@ exposed_human.set_haircolor(color, update = TRUE) /datum/reagent/medicine/regen_jelly/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustBruteLoss(-1.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(-1.5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustOxyLoss(-1.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustToxLoss(-1.5 * REM * seconds_per_tick, FALSE, TRUE, affected_biotype) //heals TOXINLOVERs - ..() - . = TRUE + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustBruteLoss(-1.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-1.5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustOxyLoss(-1.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustToxLoss(-1.5 * REM * seconds_per_tick, updating_health = FALSE, forced = TRUE, required_biotype = affected_biotype) //heals TOXINLOVERs + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/syndicate_nanites //Used exclusively by Syndicate medical cyborgs name = "Restorative Nanites" @@ -1236,21 +1273,22 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/medicine/syndicate_nanites/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustBruteLoss(-5 * REM * seconds_per_tick, FALSE) //A ton of healing - this is a 50 telecrystal investment. - affected_mob.adjustFireLoss(-5 * REM * seconds_per_tick, FALSE) - affected_mob.adjustOxyLoss(-15 * REM * seconds_per_tick, FALSE) - affected_mob.adjustToxLoss(-5 * REM * seconds_per_tick, FALSE) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -15 * REM * seconds_per_tick) - affected_mob.adjustCloneLoss(-3 * REM * seconds_per_tick, FALSE) - ..() - . = TRUE + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustBruteLoss(-5 * REM * seconds_per_tick, updating_health = FALSE) //A ton of healing - this is a 50 telecrystal investment. + need_mob_update += affected_mob.adjustFireLoss(-5 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += affected_mob.adjustOxyLoss(-15 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += affected_mob.adjustToxLoss(-5 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -15 * REM * seconds_per_tick) + need_mob_update += affected_mob.adjustCloneLoss(-3 * REM * seconds_per_tick, updating_health = FALSE) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/syndicate_nanites/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) //wtb flavortext messages that hint that you're vomitting up robots + . = ..() if(SPT_PROB(13, seconds_per_tick)) affected_mob.reagents.remove_reagent(type, metabolization_rate*15) // ~5 units at a rate of 0.4 but i wanted a nice number in code affected_mob.vomit(vomit_flags = VOMIT_CATEGORY_DEFAULT, vomit_type = /obj/effect/decal/cleanable/vomit/nanites, lost_nutrition = 20) // nanite safety protocols make your body expel them to prevent harmies - ..() - . = TRUE /datum/reagent/medicine/earthsblood //Created by ambrosia gaia plants name = "Earthsblood" @@ -1263,48 +1301,53 @@ addiction_types = list(/datum/addiction/hallucinogens = 14) /datum/reagent/medicine/earthsblood/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - if(current_cycle <= 25) //10u has to be processed before u get into THE FUN ZONE - affected_mob.adjustBruteLoss(-1 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(-1 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustCloneLoss(-0.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustStaminaLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick, 150, affected_organ_flags) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that! + . = ..() + var/need_mob_update + if(current_cycle < 25) //10u has to be processed before u get into THE FUN ZONE + need_mob_update = affected_mob.adjustBruteLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustOxyLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustToxLoss(-0.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustCloneLoss(-0.1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustStaminaLoss(-0.5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick, 150, affected_organ_flags) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that! else - affected_mob.adjustBruteLoss(-5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) //slow to start, but very quick healing once it gets going - affected_mob.adjustFireLoss(-5 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustToxLoss(-3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustCloneLoss(-1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - affected_mob.adjustStaminaLoss(-3 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + need_mob_update = affected_mob.adjustBruteLoss(-5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) //slow to start, but very quick healing once it gets going + need_mob_update += affected_mob.adjustFireLoss(-5 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustToxLoss(-3 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustCloneLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustStaminaLoss(-3 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM * seconds_per_tick, 150, affected_organ_flags) affected_mob.adjust_jitter_up_to(6 SECONDS * REM * seconds_per_tick, 1 MINUTES) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM * seconds_per_tick, 150, affected_organ_flags) if(SPT_PROB(5, seconds_per_tick)) affected_mob.say(return_hippie_line(), forced = /datum/reagent/medicine/earthsblood) affected_mob.adjust_drugginess_up_to(20 SECONDS * REM * seconds_per_tick, 30 SECONDS * REM * seconds_per_tick) - ..() - . = TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/earthsblood/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() ADD_TRAIT(affected_mob, TRAIT_PACIFISM, type) /datum/reagent/medicine/earthsblood/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_PACIFISM, type) - ..() /datum/reagent/medicine/earthsblood/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_hallucinations_up_to(10 SECONDS * REM * seconds_per_tick, 120 SECONDS) - if(current_cycle > 25) - affected_mob.adjustToxLoss(4 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - if(current_cycle > 100) //podpeople get out reeeeeeeeeeeeeeeeeeeee - affected_mob.adjustToxLoss(6 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + var/need_mob_update + if(current_cycle > 26) + need_mob_update = affected_mob.adjustToxLoss(4 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + if(current_cycle > 101) //podpeople get out reeeeeeeeeeeeeeeeeeeee + need_mob_update += affected_mob.adjustToxLoss(6 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) if(iscarbon(affected_mob)) var/mob/living/carbon/hippie = affected_mob hippie.gain_trauma(/datum/brain_trauma/severe/pacifism) - ..() - . = TRUE + + if(need_mob_update) + return UPDATE_MOB_HEALTH /// Returns a hippie-esque string for the person affected by the reagent to say. /datum/reagent/medicine/earthsblood/proc/return_hippie_line() @@ -1327,9 +1370,9 @@ metabolization_rate = 0.4 * REAGENTS_METABOLISM ph = 4.3 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED - harmful = TRUE /datum/reagent/medicine/haloperidol/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() for(var/datum/reagent/drug/R in affected_mob.reagents.reagent_list) affected_mob.reagents.remove_reagent(R.type, 5 * REM * seconds_per_tick) affected_mob.adjust_drowsiness(4 SECONDS * REM * seconds_per_tick) @@ -1340,11 +1383,12 @@ if (affected_mob.get_timed_status_effect_duration(/datum/status_effect/hallucination) >= 10 SECONDS) affected_mob.adjust_hallucinations(-10 SECONDS * REM * seconds_per_tick) + var/need_mob_update = FALSE if(SPT_PROB(10, seconds_per_tick)) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, 50, affected_organ_flags) - affected_mob.adjustStaminaLoss(2.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - return TRUE + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, 50, affected_organ_flags) + need_mob_update += affected_mob.adjustStaminaLoss(2.5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH //used for changeling's adrenaline power /datum/reagent/medicine/changelingadrenaline @@ -1355,29 +1399,29 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/medicine/changelingadrenaline/on_mob_life(mob/living/carbon/metabolizer, seconds_per_tick, times_fired) - ..() + . = ..() metabolizer.AdjustAllImmobility(-20 * REM * seconds_per_tick) - metabolizer.adjustStaminaLoss(-10 * REM * seconds_per_tick, 0) + if(metabolizer.adjustStaminaLoss(-10 * REM * seconds_per_tick, updating_stamina = FALSE)) + . = UPDATE_MOB_HEALTH metabolizer.set_jitter_if_lower(20 SECONDS * REM * seconds_per_tick) metabolizer.set_dizzy_if_lower(20 SECONDS * REM * seconds_per_tick) - return TRUE /datum/reagent/medicine/changelingadrenaline/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() affected_mob.add_traits(list(TRAIT_SLEEPIMMUNE, TRAIT_BATON_RESISTANCE), type) affected_mob.add_movespeed_mod_immunities(type, /datum/movespeed_modifier/damage_slowdown) /datum/reagent/medicine/changelingadrenaline/on_mob_end_metabolize(mob/living/affected_mob) - ..() + . = ..() affected_mob.remove_traits(list(TRAIT_SLEEPIMMUNE, TRAIT_BATON_RESISTANCE), type) affected_mob.remove_movespeed_mod_immunities(type, /datum/movespeed_modifier/damage_slowdown) affected_mob.remove_status_effect(/datum/status_effect/dizziness) affected_mob.remove_status_effect(/datum/status_effect/jitter) /datum/reagent/medicine/changelingadrenaline/overdose_process(mob/living/metabolizer, seconds_per_tick, times_fired) - metabolizer.adjustToxLoss(1 * REM * seconds_per_tick, FALSE) - ..() - return TRUE + . = ..() + if(metabolizer.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/changelinghaste name = "Changeling Haste" @@ -1387,17 +1431,17 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/medicine/changelinghaste/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() affected_mob.add_movespeed_modifier(/datum/movespeed_modifier/reagent/changelinghaste) /datum/reagent/medicine/changelinghaste/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() affected_mob.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/changelinghaste) - ..() /datum/reagent/medicine/changelinghaste/on_mob_life(mob/living/carbon/metabolizer, seconds_per_tick, times_fired) - metabolizer.adjustToxLoss(2 * REM * seconds_per_tick, FALSE) - ..() - return TRUE + . = ..() + if(metabolizer.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/higadrite name = "Higadrite" @@ -1411,7 +1455,7 @@ ADD_TRAIT(affected_mob, TRAIT_STABLELIVER, type) /datum/reagent/medicine/higadrite/on_mob_end_metabolize(mob/living/affected_mob) - ..() + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_STABLELIVER, type) /datum/reagent/medicine/cordiolis_hepatico @@ -1422,11 +1466,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/medicine/cordiolis_hepatico/on_mob_add(mob/living/affected_mob) - ..() + . = ..() affected_mob.add_traits(list(TRAIT_STABLELIVER, TRAIT_STABLEHEART), type) /datum/reagent/medicine/cordiolis_hepatico/on_mob_end_metabolize(mob/living/affected_mob) - ..() + . = ..() affected_mob.remove_traits(list(TRAIT_STABLELIVER, TRAIT_STABLEHEART), type) /datum/reagent/medicine/muscle_stimulant @@ -1455,29 +1499,32 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/modafinil/on_mob_metabolize(mob/living/affected_mob) + . = ..() ADD_TRAIT(affected_mob, TRAIT_SLEEPIMMUNE, type) - ..() /datum/reagent/medicine/modafinil/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_SLEEPIMMUNE, type) - ..() /datum/reagent/medicine/modafinil/on_mob_life(mob/living/carbon/metabolizer, seconds_per_tick, times_fired) + . = ..() if(!overdosed) // We do not want any effects on OD overdose_threshold = overdose_threshold + ((rand(-10, 10) / 10) * REM * seconds_per_tick) // for extra fun metabolizer.AdjustAllImmobility(-5 * REM * seconds_per_tick) - metabolizer.adjustStaminaLoss(-0.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + metabolizer.adjustStaminaLoss(-0.5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) metabolizer.set_jitter_if_lower(1 SECONDS * REM * seconds_per_tick) metabolization_rate = 0.005 * REAGENTS_METABOLISM * rand(5, 20) // randomizes metabolism between 0.02 and 0.08 per second - . = TRUE - ..() + return UPDATE_MOB_HEALTH /datum/reagent/medicine/modafinil/overdose_start(mob/living/affected_mob) + . = ..() to_chat(affected_mob, span_userdanger("You feel awfully out of breath and jittery!")) metabolization_rate = 0.025 * REAGENTS_METABOLISM // sets metabolism to 0.005 per second on overdose /datum/reagent/medicine/modafinil/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() overdose_progress++ + var/need_mob_update switch(overdose_progress) if(1 to 40) affected_mob.adjust_jitter_up_to(2 SECONDS * REM * seconds_per_tick, 20 SECONDS) @@ -1485,29 +1532,31 @@ affected_mob.set_dizzy_if_lower(10 SECONDS * REM * seconds_per_tick) if(SPT_PROB(30, seconds_per_tick)) affected_mob.losebreath++ + need_mob_update = TRUE if(41 to 80) - affected_mob.adjustOxyLoss(0.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustStaminaLoss(0.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + need_mob_update = affected_mob.adjustOxyLoss(0.1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustStaminaLoss(0.1 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) affected_mob.adjust_jitter_up_to(2 SECONDS * REM * seconds_per_tick, 40 SECONDS) affected_mob.adjust_stutter_up_to(2 SECONDS * REM * seconds_per_tick, 40 SECONDS) affected_mob.set_dizzy_if_lower(20 SECONDS * REM * seconds_per_tick) if(SPT_PROB(30, seconds_per_tick)) affected_mob.losebreath++ + need_mob_update = TRUE if(SPT_PROB(10, seconds_per_tick)) to_chat(affected_mob, span_userdanger("You have a sudden fit!")) affected_mob.emote("moan") affected_mob.Paralyze(20) // you should be in a bad spot at this point unless epipen has been used if(81) to_chat(affected_mob, span_userdanger("You feel too exhausted to continue!")) // at this point you will eventually die unless you get charcoal - affected_mob.adjustOxyLoss(0.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustStaminaLoss(0.1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + need_mob_update = affected_mob.adjustOxyLoss(0.1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustStaminaLoss(0.1 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) if(82 to INFINITY) REMOVE_TRAIT(affected_mob, TRAIT_SLEEPIMMUNE, type) affected_mob.Sleeping(100 * REM * seconds_per_tick) - affected_mob.adjustOxyLoss(1.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustStaminaLoss(1.5 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - return TRUE + need_mob_update += affected_mob.adjustOxyLoss(1.5 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustStaminaLoss(1.5 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/psicodine name = "Psicodine" @@ -1520,28 +1569,27 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/psicodine/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() ADD_TRAIT(affected_mob, TRAIT_FEARLESS, type) /datum/reagent/medicine/psicodine/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_FEARLESS, type) - ..() /datum/reagent/medicine/psicodine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_jitter(-12 SECONDS * REM * seconds_per_tick) affected_mob.adjust_dizzy(-12 SECONDS * REM * seconds_per_tick) affected_mob.adjust_confusion(-6 SECONDS * REM * seconds_per_tick) affected_mob.disgust = max(affected_mob.disgust - (6 * REM * seconds_per_tick), 0) if(affected_mob.mob_mood != null && affected_mob.mob_mood.sanity <= SANITY_NEUTRAL) // only take effect if in negative sanity and then... affected_mob.mob_mood.set_sanity(min(affected_mob.mob_mood.sanity + (5 * REM * seconds_per_tick), SANITY_NEUTRAL)) // set minimum to prevent unwanted spiking over neutral - ..() - . = TRUE /datum/reagent/medicine/psicodine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_hallucinations_up_to(10 SECONDS * REM * seconds_per_tick, 120 SECONDS) - affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - . = TRUE + if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/metafactor name = "Mitogen Metabolism Factor" @@ -1555,12 +1603,13 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/metafactor/overdose_start(mob/living/carbon/affected_mob) + . = ..() metabolization_rate = 2 * REAGENTS_METABOLISM /datum/reagent/medicine/metafactor/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(13, seconds_per_tick)) affected_mob.vomit(VOMIT_CATEGORY_DEFAULT) - ..() /datum/reagent/medicine/silibinin name = "Silibinin" @@ -1571,9 +1620,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/silibinin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, -2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)//Add a chance to cure liver trauma once implemented. - ..() - . = TRUE + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, -2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) // Add a chance to cure liver trauma once implemented. + return UPDATE_MOB_HEALTH /datum/reagent/medicine/polypyr //This is intended to be an ingredient in advanced chems. name = "Polypyrylium Oligomers" @@ -1587,9 +1635,11 @@ /datum/reagent/medicine/polypyr/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) //I wanted a collection of small positive effects, this is as hard to obtain as coniine after all. . = ..() - affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, -0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - affected_mob.adjustBruteLoss(-0.35 * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - return TRUE + var/need_mob_update + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, -0.25 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + need_mob_update += affected_mob.adjustBruteLoss(-0.35 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/polypyr/expose_mob(mob/living/carbon/human/exposed_human, methods=TOUCH, reac_volume) . = ..() @@ -1600,9 +1650,9 @@ exposed_human.update_body_parts() /datum/reagent/medicine/polypyr/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - ..() - . = TRUE + . = ..() + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_LUNGS, 0.5 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags)) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/granibitaluri name = "Granibitaluri" //achieve "GRANular" amounts of C2 @@ -1615,16 +1665,19 @@ /datum/reagent/medicine/granibitaluri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) var/healamount = max(0.5 - round(0.01 * (affected_mob.getBruteLoss() + affected_mob.getFireLoss()), 0.1), 0) //base of 0.5 healing per cycle and loses 0.1 healing for every 10 combined brute/burn damage you have - affected_mob.adjustBruteLoss(-healamount * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - affected_mob.adjustFireLoss(-healamount * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - ..() - . = TRUE + var/need_mob_update + need_mob_update = affected_mob.adjustBruteLoss(-healamount * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustFireLoss(-healamount * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/granibitaluri/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) - . = TRUE - affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - affected_mob.adjustToxLoss(0.2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) //Only really deadly if you eat over 100u - ..() + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.2 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) + need_mob_update += affected_mob.adjustToxLoss(0.2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) //Only really deadly if you eat over 100u + if(need_mob_update) + return UPDATE_MOB_HEALTH // helps bleeding wounds clot faster /datum/reagent/medicine/coagulant @@ -1643,15 +1696,15 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/medicine/coagulant/on_mob_metabolize(mob/living/affected_mob) + . = ..() ADD_TRAIT(affected_mob, TRAIT_COAGULATING, /datum/reagent/medicine/coagulant) if(ishuman(affected_mob)) var/mob/living/carbon/human/blood_boy = affected_mob blood_boy.physiology?.bleed_mod *= passive_bleed_modifier - return ..() - /datum/reagent/medicine/coagulant/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_COAGULATING, /datum/reagent/medicine/coagulant) if(was_working) @@ -1660,8 +1713,6 @@ var/mob/living/carbon/human/blood_boy = affected_mob blood_boy.physiology?.bleed_mod /= passive_bleed_modifier - return ..() - /datum/reagent/medicine/coagulant/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() if(!affected_mob.blood_volume || !affected_mob.all_wounds) @@ -1690,19 +1741,21 @@ if(SPT_PROB(7.5, seconds_per_tick)) affected_mob.losebreath += rand(2, 4) - affected_mob.adjustOxyLoss(rand(1, 3), required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + affected_mob.adjustOxyLoss(rand(1, 3), updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) if(prob(30)) to_chat(affected_mob, span_danger("You can feel your blood clotting up in your veins!")) else if(prob(10)) to_chat(affected_mob, span_userdanger("You feel like your blood has stopped moving!")) - affected_mob.adjustOxyLoss(rand(3, 4), required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + affected_mob.adjustOxyLoss(rand(3, 4) * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) if(prob(50)) var/obj/item/organ/internal/lungs/our_lungs = affected_mob.get_organ_slot(ORGAN_SLOT_LUNGS) - our_lungs.apply_organ_damage(1) + our_lungs.apply_organ_damage(1 * REM * seconds_per_tick) else var/obj/item/organ/internal/heart/our_heart = affected_mob.get_organ_slot(ORGAN_SLOT_HEART) - our_heart.apply_organ_damage(1) + our_heart.apply_organ_damage(1 * REM * seconds_per_tick) + + return UPDATE_MOB_HEALTH // i googled "natural coagulant" and a couple of results came up for banana peels, so after precisely 30 more seconds of research, i now dub grinding banana peels good for your blood /datum/reagent/medicine/coagulant/banana_peel @@ -1745,11 +1798,11 @@ ph = 10.6 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED -/datum/reagent/medicine/ondansetron/on_mob_life(mob/living/carbon/M, seconds_per_tick, times_fired) +/datum/reagent/medicine/ondansetron/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() if(SPT_PROB(8, seconds_per_tick)) - M.adjust_drowsiness(2 SECONDS * REM * seconds_per_tick) - if(SPT_PROB(15, seconds_per_tick) && !M.getStaminaLoss()) - M.adjustStaminaLoss(10) - . = TRUE - M.adjust_disgust(-10 * REM * seconds_per_tick) + affected_mob.adjust_drowsiness(2 SECONDS * REM * seconds_per_tick) + if(SPT_PROB(15, seconds_per_tick) && !affected_mob.getStaminaLoss()) + if(affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE)) + . = UPDATE_MOB_HEALTH + affected_mob.adjust_disgust(-10 * REM * seconds_per_tick) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index dddf966be72c07..be5df37ffdb483 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -321,6 +321,8 @@ /datum/reagent/water/salt/expose_mob(mob/living/exposed_mob, methods, reac_volume) . = ..() + if(!iscarbon(exposed_mob)) + return var/mob/living/carbon/carbies = exposed_mob if(!(methods & (PATCH|TOUCH|VAPOR))) return @@ -369,7 +371,7 @@ mytray.myseed?.adjust_instability(round(volume * 0.15)) /datum/reagent/water/holywater/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() ADD_TRAIT(affected_mob, TRAIT_HOLY, type) /datum/reagent/water/holywater/on_mob_add(mob/living/affected_mob, amount) @@ -378,8 +380,8 @@ data["misc"] = 0 /datum/reagent/water/holywater/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_HOLY, type) - ..() /datum/reagent/water/holywater/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) . = ..() @@ -387,8 +389,7 @@ to_chat(exposed_mob, span_userdanger("A vile holiness begins to spread its shining tendrils through your mind, purging the Geometer of Blood's influence!")) /datum/reagent/water/holywater/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - if(affected_mob.blood_volume) - affected_mob.blood_volume += 0.1 * REM * seconds_per_tick // water is good for you! + . = ..() if(!data) data = list("misc" = 0) @@ -415,9 +416,11 @@ affected_mob.Unconscious(100) affected_mob.remove_status_effect(/datum/status_effect/jitter) affected_mob.remove_status_effect(/datum/status_effect/speech/stutter) - holder.remove_reagent(type, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better?? + if(holder) + holder.remove_reagent(type, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better?? return - holder.remove_reagent(type, 1 * REAGENTS_METABOLISM * seconds_per_tick) //fixed consumption to prevent balancing going out of whack + if(holder) + holder.remove_reagent(type, 1 * REAGENTS_METABOLISM * seconds_per_tick) //fixed consumption to prevent balancing going out of whack /datum/reagent/water/holywater/expose_turf(turf/exposed_turf, reac_volume) . = ..() @@ -483,25 +486,47 @@ ph = 6.5 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED +/datum/reagent/fuel/unholywater/on_mob_metabolize(mob/living/affected_mob) + . = ..() + if(IS_CULTIST(affected_mob)) + ADD_TRAIT(affected_mob, TRAIT_COAGULATING, type) + /datum/reagent/fuel/unholywater/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update = FALSE if(IS_CULTIST(affected_mob)) affected_mob.adjust_drowsiness(-10 SECONDS * REM * seconds_per_tick) affected_mob.AdjustAllImmobility(-40 * REM * seconds_per_tick) - affected_mob.adjustStaminaLoss(-10 * REM * seconds_per_tick, 0) - affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, 0) - affected_mob.adjustOxyLoss(-2 * REM * seconds_per_tick, 0) - affected_mob.adjustBruteLoss(-2 * REM * seconds_per_tick, 0) - affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick, 0) + need_mob_update += affected_mob.adjustStaminaLoss(-10 * REM * seconds_per_tick, updating_stamina = FALSE) + need_mob_update += affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += affected_mob.adjustOxyLoss(-2 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += affected_mob.adjustBruteLoss(-2 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update = TRUE if(ishuman(affected_mob) && affected_mob.blood_volume < BLOOD_VOLUME_NORMAL) affected_mob.blood_volume += 3 * REM * seconds_per_tick + + var/datum/wound/bloodiest_wound + + for(var/datum/wound/iter_wound as anything in affected_mob.all_wounds) + if(iter_wound.blood_flow && iter_wound.blood_flow > bloodiest_wound?.blood_flow) + bloodiest_wound = iter_wound + + if(bloodiest_wound) + bloodiest_wound.adjust_blood_flow(-2 * REM * seconds_per_tick) + else // Will deal about 90 damage when 50 units are thrown - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * REM * seconds_per_tick, 150) - affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, 0) - affected_mob.adjustFireLoss(1 * REM * seconds_per_tick, 0) - affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, 0) - affected_mob.adjustBruteLoss(1 * REM * seconds_per_tick, 0) - ..() - return TRUE + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * REM * seconds_per_tick, 150) + need_mob_update += affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += affected_mob.adjustFireLoss(1 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += affected_mob.adjustBruteLoss(1 * REM * seconds_per_tick, updating_health = FALSE) + if(need_mob_update) + return UPDATE_MOB_HEALTH + +/datum/reagent/fuel/unholywater/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() + REMOVE_TRAIT(affected_mob, TRAIT_COAGULATING, type) //We don't cult check here because potentially our imbiber may no longer be a cultist for whatever reason! It doesn't purge holy water, after all! /datum/reagent/hellwater //if someone has this in their system they've really pissed off an eldrich god name = "Hell Water" @@ -511,13 +536,17 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/hellwater/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.set_fire_stacks(min(affected_mob.fire_stacks + (1.5 * seconds_per_tick), 5)) affected_mob.ignite_mob() //Only problem with igniting people is currently the commonly available fire suits make you immune to being on fire - affected_mob.adjustToxLoss(0.5*seconds_per_tick, 0) - affected_mob.adjustFireLoss(0.5*seconds_per_tick, 0) //Hence the other damages... ain't I a bastard? + var/need_mob_update + need_mob_update = affected_mob.adjustToxLoss(0.5*seconds_per_tick, updating_health = FALSE) + need_mob_update += affected_mob.adjustFireLoss(0.5*seconds_per_tick, updating_health = FALSE) //Hence the other damages... ain't I a bastard? affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2.5*seconds_per_tick, 150) - holder.remove_reagent(type, 0.5*seconds_per_tick) - return TRUE + if(holder) + holder.remove_reagent(type, 0.5*seconds_per_tick) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/medicine/omnizine/godblood name = "Godblood" @@ -629,8 +658,8 @@ if((methods & INGEST) && show_message) to_chat(exposed_mob, span_notice("That tasted horrible.")) - /datum/reagent/spraytan/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() metabolization_rate = 1 * REAGENTS_METABOLISM if(ishuman(affected_mob)) @@ -656,13 +685,18 @@ affected_mob.visible_message("[affected_mob] flexes [affected_mob.p_their()] arms.") if(SPT_PROB(5, seconds_per_tick)) affected_mob.say(pick("Shit was SO cash.", "You are everything bad in the world.", "What sports do you play, other than 'jack off to naked drawn Japanese people?'", "Don???t be a stranger. Just hit me with your best shot.", "My name is John and I hate every single one of you."), forced = /datum/reagent/spraytan) - ..() - return #define MUT_MSG_IMMEDIATE 1 #define MUT_MSG_EXTENDED 2 #define MUT_MSG_ABOUT2TURN 3 +/// the current_cycle threshold / iterations needed before one can transform +#define CYCLES_TO_TURN 20 +/// the cycle at which 'immediate' mutation text begins displaying +#define CYCLES_MSG_IMMEDIATE 6 +/// the cycle at which 'extended' mutation text begins displaying +#define CYCLES_MSG_EXTENDED 16 + /datum/reagent/mutationtoxin name = "Stable Mutation Toxin" description = "A humanizing toxin." @@ -675,21 +709,20 @@ "Your limbs begin to take on a different shape." = MUT_MSG_EXTENDED, "Your appendages begin morphing." = MUT_MSG_EXTENDED, "You feel as though you're about to change at any moment!" = MUT_MSG_ABOUT2TURN) - var/cycles_to_turn = 20 //the current_cycle threshold / iterations needed before one can transform /datum/reagent/mutationtoxin/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired) - . = TRUE + . = ..() if(!istype(affected_mob)) return - if(!(affected_mob.dna?.species) || !(affected_mob.mob_biotypes & MOB_ORGANIC)) + if(!(affected_mob.dna?.species) || !(affected_mob.mob_biotypes & affected_biotype)) return if(SPT_PROB(5, seconds_per_tick)) var/list/pick_ur_fav = list() var/filter = NONE - if(current_cycle <= (cycles_to_turn*0.3)) + if(current_cycle <= CYCLES_MSG_IMMEDIATE) filter = MUT_MSG_IMMEDIATE - else if(current_cycle <= (cycles_to_turn*0.8)) + else if(current_cycle <= CYCLES_MSG_EXTENDED) filter = MUT_MSG_EXTENDED else filter = MUT_MSG_ABOUT2TURN @@ -699,14 +732,15 @@ pick_ur_fav += i to_chat(affected_mob, span_warning("[pick(pick_ur_fav)]")) - if(current_cycle >= cycles_to_turn) + if(current_cycle >= CYCLES_TO_TURN) var/datum/species/species_type = race //affected_mob.set_species(species_type) //ORIGINAL affected_mob.set_species(species_type, TRUE, FALSE, null, null, null, null, TRUE) //SKYRAT EDIT CHANGE - CUSTOMIZATION holder.del_reagent(type) to_chat(affected_mob, span_warning("You've become \a [lowertext(initial(species_type.name))]!")) return - ..() + + return ..() /datum/reagent/mutationtoxin/classic //The one from plasma on green slimes name = "Mutation Toxin" @@ -769,14 +803,14 @@ //affected_mob.set_species(species_type) //ORIGINAL affected_mob.set_species(species_type, TRUE, FALSE, null, null, null, null, TRUE, TRUE) //SKYRAT EDIT CHANGE - CUSTOMIZATION holder.del_reagent(type) - return TRUE - if(current_cycle >= cycles_to_turn) //overwrite since we want subtypes of jelly + return UPDATE_MOB_HEALTH + if(current_cycle >= CYCLES_TO_TURN) //overwrite since we want subtypes of jelly var/datum/species/species_type = pick(subtypesof(race)) //affected_mob.set_species(species_type) //ORIGINAL affected_mob.set_species(species_type, TRUE, FALSE, null, null, null, null, TRUE, TRUE) //SKYRAT EDIT CHANGE - CUSTOMIZATION holder.del_reagent(type) to_chat(affected_mob, span_warning("You've become \a [initial(species_type.name)]!")) - return TRUE + return UPDATE_MOB_HEALTH return ..() /datum/reagent/mutationtoxin/golem @@ -849,6 +883,10 @@ #undef MUT_MSG_EXTENDED #undef MUT_MSG_ABOUT2TURN +#undef CYCLES_TO_TURN +#undef CYCLES_MSG_IMMEDIATE +#undef CYCLES_MSG_EXTENDED + /datum/reagent/mulligan name = "Mulligan Toxin" description = "This toxin will rapidly change the DNA of humanoid beings. Commonly used by Syndicate spies and assassins in need of an emergency ID change." @@ -858,7 +896,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/mulligan/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired) - ..() + . = ..() if (!istype(affected_mob)) return to_chat(affected_mob, span_warning("You grit your teeth in pain as your body rapidly mutates!")) @@ -900,10 +938,10 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/serotrotium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(ishuman(affected_mob)) if(SPT_PROB(3.5, seconds_per_tick)) affected_mob.emote(pick("twitch","drool","moan","gasp")) - ..() /datum/reagent/oxygen name = "Oxygen" @@ -978,13 +1016,13 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/mercury/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(!HAS_TRAIT(src, TRAIT_IMMOBILIZED) && !isspaceturf(affected_mob.loc)) step(affected_mob, pick(GLOB.cardinals)) if(SPT_PROB(3.5, seconds_per_tick)) affected_mob.emote(pick("twitch","drool","moan")) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5*seconds_per_tick) - ..() - return TRUE + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5*seconds_per_tick)) + return UPDATE_MOB_HEALTH /datum/reagent/sulfur name = "Sulfur" @@ -1052,9 +1090,9 @@ mytray.adjust_weedlevel(-rand(1, 4)) /datum/reagent/fluorine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustToxLoss(0.5*REM*seconds_per_tick, 0) - . = TRUE - ..() + . = ..() + if(affected_mob.adjustToxLoss(0.5*REM*seconds_per_tick, updating_health = FALSE)) + . = TRUE /datum/reagent/sodium name = "Sodium" @@ -1090,11 +1128,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/lithium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(!HAS_TRAIT(affected_mob, TRAIT_IMMOBILIZED) && !isspaceturf(affected_mob.loc) && isturf(affected_mob.loc)) step(affected_mob, pick(GLOB.cardinals)) if(SPT_PROB(2.5, seconds_per_tick)) affected_mob.emote(pick("twitch","drool","moan")) - ..() /datum/reagent/glycerol name = "Glycerol" @@ -1134,9 +1172,9 @@ ph = 6 /datum/reagent/iron/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.blood_volume < BLOOD_VOLUME_NORMAL) affected_mob.blood_volume += 0.25 * seconds_per_tick - ..() /datum/reagent/gold name = "Gold" @@ -1170,9 +1208,9 @@ var/tox_damage = 0.5 /datum/reagent/uranium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustToxLoss(tox_damage * seconds_per_tick * REM) - ..() - return TRUE + . = ..() + if(affected_mob.adjustToxLoss(tox_damage * seconds_per_tick * REM, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/uranium/expose_turf(turf/exposed_turf, reac_volume) . = ..() @@ -1216,12 +1254,12 @@ do_teleport(exposed_mob, get_turf(exposed_mob), (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/affected_mob, seconds_per_tick, times_fired) + . = ..() if(current_cycle > 10 && SPT_PROB(7.5, seconds_per_tick)) to_chat(affected_mob, span_warning("You feel unstable...")) affected_mob.set_jitter_if_lower(2 SECONDS) current_cycle = 1 addtimer(CALLBACK(affected_mob, TYPE_PROC_REF(/mob/living, bluespace_shuffle)), 30) - ..() /mob/living/proc/bluespace_shuffle() do_teleport(src, get_turf(src), 5, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE) @@ -1268,9 +1306,9 @@ exposed_mob.adjust_fire_stacks(reac_volume / 10) /datum/reagent/fuel/on_mob_life(mob/living/carbon/victim, seconds_per_tick, times_fired) - victim.adjustToxLoss(0.5 * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - return TRUE + . = ..() + if(victim.adjustToxLoss(0.5 * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/fuel/expose_turf(turf/exposed_turf, reac_volume) . = ..() @@ -1337,11 +1375,13 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/space_cleaner/ez_clean/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustBruteLoss(1.665*seconds_per_tick) - affected_mob.adjustFireLoss(1.665*seconds_per_tick) - affected_mob.adjustToxLoss(1.665*seconds_per_tick) - ..() - return TRUE + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustBruteLoss(1.665*seconds_per_tick, updating_health = FALSE) + need_mob_update += affected_mob.adjustFireLoss(1.665*seconds_per_tick, updating_health = FALSE) + need_mob_update += affected_mob.adjustToxLoss(1.665*seconds_per_tick, updating_health = FALSE) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/space_cleaner/ez_clean/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) . = ..() @@ -1359,6 +1399,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/cryptobiolin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.set_dizzy_if_lower(2 SECONDS) // Cryptobiolin adjusts the mob's confusion down to 20 seconds if it's higher, @@ -1370,8 +1411,6 @@ else if(confusion_left > 20 SECONDS) affected_mob.set_confusion(20 SECONDS) - ..() - /datum/reagent/impedrezene name = "Impedrezene" description = "Impedrezene is a narcotic that impedes one's ability by slowing down the higher brain cell functions." @@ -1382,6 +1421,7 @@ addiction_types = list(/datum/addiction/opioids = 10) /datum/reagent/impedrezene/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_jitter(-5 SECONDS * seconds_per_tick) . = FALSE if(SPT_PROB(55, seconds_per_tick)) @@ -1391,7 +1431,6 @@ affected_mob.adjust_drowsiness(6 SECONDS) if(SPT_PROB(5, seconds_per_tick)) affected_mob.emote("drool") - ..() /datum/reagent/cyborg_mutation_nanomachines name = "Nanomachines" @@ -1542,13 +1581,13 @@ exposed_mob.adjust_drowsiness(drowsiness_to_apply) /datum/reagent/nitrous_oxide/on_mob_metabolize(mob/living/affected_mob) + . = ..() if(!HAS_TRAIT(affected_mob, TRAIT_COAGULATING)) //IF the mob does not have a coagulant in them, we add the blood mess trait to make the bleed quicker ADD_TRAIT(affected_mob, TRAIT_BLOODY_MESS, type) - return ..() /datum/reagent/nitrous_oxide/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_BLOODY_MESS, type) - return ..() /datum/reagent/nitrous_oxide/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) affected_mob.adjust_drowsiness(4 SECONDS * REM * seconds_per_tick) @@ -1706,10 +1745,10 @@ ph = 3 /datum/reagent/plantnutriment/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(tox_prob, seconds_per_tick)) - affected_mob.adjustToxLoss(1, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() + if(affected_mob.adjustToxLoss(1, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/plantnutriment/eznutriment name = "E-Z Nutrient" @@ -2183,15 +2222,17 @@ /datum/reagent/barbers_aid/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=FALSE) . = ..() - if(!(methods & (TOUCH|VAPOR)) || !ishuman(exposed_mob) || HAS_TRAIT(exposed_mob, TRAIT_BALD) || HAS_TRAIT(exposed_mob, TRAIT_SHAVED)) + if(!(methods & (TOUCH|VAPOR)) || !ishuman(exposed_mob) || (HAS_TRAIT(exposed_mob, TRAIT_BALD) && HAS_TRAIT(exposed_mob, TRAIT_SHAVED))) return var/mob/living/carbon/human/exposed_human = exposed_mob - var/datum/sprite_accessory/hair/picked_hair = pick(GLOB.hairstyles_list) - var/datum/sprite_accessory/facial_hair/picked_beard = pick(GLOB.facial_hairstyles_list) - to_chat(exposed_human, span_notice("Hair starts sprouting from your scalp.")) - exposed_human.set_facial_hairstyle(picked_beard, update = FALSE) - exposed_human.set_hairstyle(picked_hair, update = TRUE) + if(!HAS_TRAIT(exposed_human, TRAIT_SHAVED)) + var/datum/sprite_accessory/facial_hair/picked_beard = pick(GLOB.facial_hairstyles_list) + exposed_human.set_facial_hairstyle(picked_beard, update = FALSE) + if(!HAS_TRAIT(exposed_human, TRAIT_BALD)) + var/datum/sprite_accessory/hair/picked_hair = pick(GLOB.hairstyles_list) + exposed_human.set_hairstyle(picked_hair, update = TRUE) + to_chat(exposed_human, span_notice("Hair starts sprouting from your [HAS_TRAIT(exposed_human, TRAIT_BALD) ? "face" : "scalp"].")) /datum/reagent/concentrated_barbers_aid name = "Concentrated Barber's Aid" @@ -2204,17 +2245,19 @@ /datum/reagent/concentrated_barbers_aid/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message=TRUE, touch_protection=FALSE) . = ..() - if(!(methods & (TOUCH|VAPOR)) || !ishuman(exposed_mob) || HAS_TRAIT(exposed_mob, TRAIT_BALD) || HAS_TRAIT(exposed_mob, TRAIT_SHAVED)) + if(!(methods & (TOUCH|VAPOR)) || !ishuman(exposed_mob) || (HAS_TRAIT(exposed_mob, TRAIT_BALD) && HAS_TRAIT(exposed_mob, TRAIT_SHAVED))) return var/mob/living/carbon/human/exposed_human = exposed_mob - to_chat(exposed_human, span_notice("Your hair starts growing at an incredible speed!")) - exposed_human.set_facial_hairstyle("Beard (Very Long)", update = FALSE) - exposed_human.set_hairstyle("Very Long Hair", update = TRUE) + if(!HAS_TRAIT(exposed_human, TRAIT_SHAVED)) + exposed_human.set_facial_hairstyle("Beard (Very Long)", update = FALSE) + if(!HAS_TRAIT(exposed_human, TRAIT_BALD)) + exposed_human.set_hairstyle("Very Long Hair", update = TRUE) + to_chat(exposed_human, span_notice("Your[HAS_TRAIT(exposed_human, TRAIT_BALD) ? " facial" : ""] hair starts growing at an incredible speed!")) /datum/reagent/concentrated_barbers_aid/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() - if(current_cycle > 20 / creation_purity) + if(current_cycle > 21 / creation_purity) if(!ishuman(affected_mob)) return var/mob/living/carbon/human/human_mob = affected_mob @@ -2362,9 +2405,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/royal_bee_jelly/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(1, seconds_per_tick)) affected_mob.say(pick("Bzzz...","BZZ BZZ","Bzzzzzzzzzzz..."), forced = "royal bee jelly") - ..() //Misc reagents @@ -2396,8 +2439,8 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/magillitis/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - ..() - if((ishuman(affected_mob)) && current_cycle >= 10) + . = ..() + if((ishuman(affected_mob)) && current_cycle > 10) affected_mob.gorillize() /datum/reagent/growthserum @@ -2409,6 +2452,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/growthserum/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/newsize = current_size switch(volume) if(0 to 19) @@ -2424,12 +2468,11 @@ affected_mob.update_transform(newsize/current_size) current_size = newsize - ..() /datum/reagent/growthserum/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() affected_mob.update_transform(RESIZE_DEFAULT_SIZE/current_size) current_size = RESIZE_DEFAULT_SIZE - ..() /datum/reagent/plastic_polymers name = "Plastic Polymers" @@ -2491,12 +2534,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/pax/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() ADD_TRAIT(affected_mob, TRAIT_PACIFISM, type) /datum/reagent/pax/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_PACIFISM, type) - ..() /datum/reagent/bz_metabolites name = "BZ Metabolites" @@ -2507,19 +2550,19 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/bz_metabolites/on_mob_metabolize(mob/living/ling) - ..() + . = ..() ADD_TRAIT(ling, CHANGELING_HIVEMIND_MUTE, type) /datum/reagent/bz_metabolites/on_mob_end_metabolize(mob/living/ling) - ..() + . = ..() REMOVE_TRAIT(ling, CHANGELING_HIVEMIND_MUTE, type) /datum/reagent/bz_metabolites/on_mob_life(mob/living/carbon/target, seconds_per_tick, times_fired) + . = ..() if(target.mind) var/datum/antagonist/changeling/changeling = target.mind.has_antag_datum(/datum/antagonist/changeling) if(changeling) - changeling.adjust_chemicals(-4 * REM * seconds_per_tick) //SKYRAT EDIT - BZ-BUFF-VS-LING - ORIGINAL: changeling.adjust_chemicals(-2 * REM * delta_time) - return ..() + changeling.adjust_chemicals(-4 * REM * seconds_per_tick) //SKYRAT EDIT - BZ-BUFF-VS-LING - ORIGINAL: changeling.adjust_chemicals(-2 * REM * seconds_per_tick) /datum/reagent/pax/peaceborg name = "Synthpax" @@ -2550,14 +2593,14 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/peaceborg/tire/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() var/healthcomp = (100 - affected_mob.health) //DOES NOT ACCOUNT FOR ADMINBUS THINGS THAT MAKE YOU HAVE MORE THAN 200/210 HEALTH, OR SOMETHING OTHER THAN A HUMAN PROCESSING THIS. . = FALSE if(affected_mob.getStaminaLoss() < (45 - healthcomp)) //At 50 health you would have 200 - 150 health meaning 50 compensation. 60 - 50 = 10, so would only do 10-19 stamina.) - affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick) - . = TRUE + if(affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE)) + . = UPDATE_MOB_HEALTH if(SPT_PROB(16, seconds_per_tick)) to_chat(affected_mob, "You should sit down and take a rest...") - ..() /datum/reagent/gondola_mutation_toxin name = "Tranquility" @@ -2565,11 +2608,12 @@ color = "#9A6750" //RGB: 154, 103, 80 taste_description = "inner peace" penetrates_skin = NONE + var/datum/disease/transformation/gondola_disease = /datum/disease/transformation/gondola /datum/reagent/gondola_mutation_toxin/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume, show_message = TRUE, touch_protection = 0) . = ..() if((methods & (PATCH|INGEST|INJECT)) || ((methods & VAPOR) && prob(min(reac_volume,100)*(1 - touch_protection)))) - exposed_mob.ForceContractDisease(new /datum/disease/transformation/gondola(), FALSE, TRUE) + exposed_mob.ForceContractDisease(new gondola_disease, FALSE, TRUE) /datum/reagent/spider_extract @@ -2595,13 +2639,14 @@ desc = "It smells like a carcass, and doesn't look much better." /datum/reagent/yuck/on_mob_add(mob/living/affected_mob) - . = ..() if(HAS_TRAIT(affected_mob, TRAIT_NOHUNGER)) //they can't puke holder.del_reagent(type) + return ..() #define YUCK_PUKE_CYCLES 3 // every X cycle is a puke #define YUCK_PUKES_TO_STUN 3 // hit this amount of pukes in a row to start stunning /datum/reagent/yuck/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(!yuck_cycle) if(SPT_PROB(4, seconds_per_tick)) var/dread = pick("Something is moving in your stomach...", \ @@ -2613,19 +2658,19 @@ var/yuck_cycles = current_cycle - yuck_cycle if(yuck_cycles % YUCK_PUKE_CYCLES == 0) if(yuck_cycles >= YUCK_PUKE_CYCLES * YUCK_PUKES_TO_STUN) - holder.remove_reagent(type, 5) + if(holder) + holder.remove_reagent(type, 5) var/passable_flags = (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM) if(yuck_cycles >= (YUCK_PUKE_CYCLES * YUCK_PUKES_TO_STUN)) passable_flags |= MOB_VOMIT_STUN affected_mob.vomit(vomit_flags = passable_flags, lost_nutrition = rand(14, 26)) - if(holder) - return ..() + #undef YUCK_PUKE_CYCLES #undef YUCK_PUKES_TO_STUN /datum/reagent/yuck/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() yuck_cycle = 0 // reset vomiting - return ..() /datum/reagent/yuck/on_transfer(atom/A, methods=TOUCH, trans_volume) if((methods & INGEST) || !iscarbon(A)) @@ -2724,10 +2769,11 @@ addtimer(CALLBACK(exposed_obj, PROC_REF(_RemoveElement), list(/datum/element/forced_gravity, 0)), volume * time_multiplier, TIMER_UNIQUE|TIMER_OVERRIDE) /datum/reagent/gravitum/on_mob_metabolize(mob/living/affected_mob) + . = ..() affected_mob.AddElement(/datum/element/forced_gravity, 0) //0 is the gravity, and in this case weightless - return ..() /datum/reagent/gravitum/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() affected_mob.RemoveElement(/datum/element/forced_gravity, 0) /datum/reagent/cellulose @@ -2751,6 +2797,7 @@ var/significant = FALSE /datum/reagent/determination/on_mob_end_metabolize(mob/living/carbon/affected_mob) + . = ..() if(significant) var/stam_crash = 0 for(var/thing in affected_mob.all_wounds) @@ -2758,9 +2805,9 @@ stam_crash += (W.severity + 1) * 3 // spike of 3 stam damage per wound severity (moderate = 6, severe = 9, critical = 12) when the determination wears off if it was a combat rush affected_mob.adjustStaminaLoss(stam_crash) affected_mob.remove_status_effect(/datum/status_effect/determined) - ..() /datum/reagent/determination/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(!significant && volume >= WOUND_DETERMINATION_SEVERE) significant = TRUE affected_mob.apply_status_effect(/datum/status_effect/determined) // in addition to the slight healing, limping cooldowns are divided by 4 during the combat high @@ -2772,8 +2819,8 @@ var/obj/item/bodypart/wounded_part = W.limb if(wounded_part) wounded_part.heal_damage(0.25 * REM * seconds_per_tick, 0.25 * REM * seconds_per_tick) - affected_mob.adjustStaminaLoss(-0.25 * REM * seconds_per_tick) // the more wounds, the more stamina regen - ..() + if(affected_mob.adjustStaminaLoss(-0.25 * REM * seconds_per_tick, updating_stamina = FALSE)) // the more wounds, the more stamina regen + return UPDATE_MOB_HEALTH // unholy water, but for heretics. // why couldn't they have both just used the same reagent? @@ -2791,24 +2838,26 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/eldritch/on_mob_life(mob/living/carbon/drinker, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update = FALSE if(IS_HERETIC(drinker)) drinker.adjust_drowsiness(-10 * REM * seconds_per_tick) drinker.AdjustAllImmobility(-40 * REM * seconds_per_tick) - drinker.adjustStaminaLoss(-10 * REM * seconds_per_tick, FALSE) - drinker.adjustToxLoss(-2 * REM * seconds_per_tick, FALSE, forced = TRUE) - drinker.adjustOxyLoss(-2 * REM * seconds_per_tick, FALSE) - drinker.adjustBruteLoss(-2 * REM * seconds_per_tick, FALSE) - drinker.adjustFireLoss(-2 * REM * seconds_per_tick, FALSE) + need_mob_update += drinker.adjustStaminaLoss(-10 * REM * seconds_per_tick, updating_stamina = FALSE) + need_mob_update += drinker.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, forced = TRUE) + need_mob_update += drinker.adjustOxyLoss(-2 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += drinker.adjustBruteLoss(-2 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += drinker.adjustFireLoss(-2 * REM * seconds_per_tick, updating_health = FALSE) if(drinker.blood_volume < BLOOD_VOLUME_NORMAL) drinker.blood_volume += 3 * REM * seconds_per_tick else - drinker.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * REM * seconds_per_tick, 150) - drinker.adjustToxLoss(2 * REM * seconds_per_tick, FALSE) - drinker.adjustFireLoss(2 * REM * seconds_per_tick, FALSE) - drinker.adjustOxyLoss(2 * REM * seconds_per_tick, FALSE) - drinker.adjustBruteLoss(2 * REM * seconds_per_tick, FALSE) - ..() - return TRUE + need_mob_update = drinker.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * REM * seconds_per_tick, 150) + need_mob_update += drinker.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += drinker.adjustFireLoss(2 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += drinker.adjustOxyLoss(2 * REM * seconds_per_tick, updating_health = FALSE) + need_mob_update += drinker.adjustBruteLoss(2 * REM * seconds_per_tick, updating_health = FALSE) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/universal_indicator name = "Universal Indicator" @@ -2854,10 +2903,11 @@ desc = "Bottoms up...?" /datum/reagent/ants/on_mob_life(mob/living/carbon/victim, seconds_per_tick) + . = ..() victim.adjustBruteLoss(max(0.1, round((ant_damage * 0.025),0.1))) //Scales with time. Roughly 32 brute with 100u. ant_damage++ if(ant_damage < 5) // Makes ant food a little more appetizing, since you won't be screaming as much. - return ..() + return if(SPT_PROB(5, seconds_per_tick)) if(SPT_PROB(5, seconds_per_tick)) //Super rare statement victim.say("AUGH NO NOT THE ANTS! NOT THE ANTS! AAAAUUGH THEY'RE IN MY EYES! MY EYES! AUUGH!!", forced = /datum/reagent/ants) @@ -2866,14 +2916,12 @@ if(SPT_PROB(15, seconds_per_tick)) victim.emote("scream") if(SPT_PROB(2, seconds_per_tick)) // Stuns, but purges ants. - victim.vomit(rand(5,10), FALSE, TRUE, 1, TRUE, FALSE, purge_ratio = 1) - ..() - return TRUE + victim.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = rand(5,10), purge_ratio = 1) /datum/reagent/ants/on_mob_end_metabolize(mob/living/living_anthill) + . = ..() ant_damage = 0 to_chat(living_anthill, "You feel like the last of the ants are out of your system.") - return ..() /datum/reagent/ants/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) . = ..() @@ -2918,9 +2966,9 @@ metabolization_rate = 0.4 * REAGENTS_METABOLISM /datum/reagent/lead/on_mob_life(mob/living/carbon/victim) - victim.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5) - ..() - return TRUE + . = ..() + if(victim.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5)) + return UPDATE_MOB_HEALTH //The main feedstock for kronkaine production, also a shitty stamina healer. /datum/reagent/kronkus_extract @@ -2932,10 +2980,12 @@ addiction_types = list(/datum/addiction/stimulants = 5) /datum/reagent/kronkus_extract/on_mob_life(mob/living/carbon/kronkus_enjoyer) - ..() - kronkus_enjoyer.adjustOrganLoss(ORGAN_SLOT_HEART, 0.1) - kronkus_enjoyer.adjustStaminaLoss(-2, FALSE) - return TRUE + . = ..() + var/need_mob_update + need_mob_update = kronkus_enjoyer.adjustOrganLoss(ORGAN_SLOT_HEART, 0.1) + need_mob_update += kronkus_enjoyer.adjustStaminaLoss(-2, updating_stamina = FALSE) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/brimdust name = "Brimdust" @@ -2947,7 +2997,8 @@ /datum/reagent/brimdust/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() - return affected_mob.adjustFireLoss((ispodperson(affected_mob) ? -1 : 1) * seconds_per_tick) + if(affected_mob.adjustFireLoss((ispodperson(affected_mob) ? -1 : 1 * seconds_per_tick), updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/brimdust/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user) mytray.adjust_weedlevel(-1) @@ -2975,14 +3026,15 @@ . = ..() metabolizer.add_mood_event(name, /datum/mood_event/love_reagent) -/datum/reagent/love/on_mob_delete(mob/living/deleted_from) +/datum/reagent/love/on_mob_delete(mob/living/affected_mob) . = ..() // When we exit the system we'll leave the moodlet based on the amount we had var/duration_of_moodlet = current_cycle * 20 SECONDS - deleted_from.clear_mood_event(name) - deleted_from.add_mood_event(name, /datum/mood_event/love_reagent, duration_of_moodlet) + affected_mob.clear_mood_event(name) + affected_mob.add_mood_event(name, /datum/mood_event/love_reagent, duration_of_moodlet) /datum/reagent/love/overdose_process(mob/living/metabolizer, seconds_per_tick, times_fired) + . = ..() var/mob/living/carbon/carbon_metabolizer = metabolizer if(!istype(carbon_metabolizer) || !carbon_metabolizer.can_heartattack() || carbon_metabolizer.undergoing_cardiac_arrest()) metabolizer.reagents.del_reagent(type) @@ -3016,6 +3068,8 @@ affected_mob.add_mood_event("hauntium_spirits", /datum/mood_event/hauntium_spirits, name) //8 minutes of mood debuff /datum/reagent/hauntium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + if(affected_mob.mob_biotypes & MOB_UNDEAD || HAS_MIND_TRAIT(affected_mob, TRAIT_MORBID)) //if morbid or undead,acts like an addiction-less drug affected_mob.remove_status_effect(/datum/status_effect/jitter) affected_mob.AdjustStun(-50 * REM * seconds_per_tick) @@ -3023,10 +3077,13 @@ affected_mob.AdjustUnconscious(-50 * REM * seconds_per_tick) affected_mob.AdjustParalyzed(-50 * REM * seconds_per_tick) affected_mob.AdjustImmobilized(-50 * REM * seconds_per_tick) - ..() else - affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, REM * seconds_per_tick) //1 heart damage per tick + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, REM * seconds_per_tick)) //1 heart damage per tick + . = UPDATE_MOB_HEALTH if(SPT_PROB(10, seconds_per_tick)) affected_mob.emote(pick("twitch","choke","shiver","gag")) - ..() - return TRUE + +// The same as gold just with a slower metabolism rate, to make using the Hand of Midas easier. +/datum/reagent/gold/cursed + name = "Cursed Gold" + metabolization_rate = 0.2 * REAGENTS_METABOLISM diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm index 6f99273ad4e937..2db3682ef21850 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm @@ -13,9 +13,9 @@ exposed_turf.AddComponent(/datum/component/thermite, reac_volume) /datum/reagent/thermite/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustFireLoss(1 * REM * seconds_per_tick, 0) - ..() - return TRUE + . = ..() + if(affected_mob.adjustFireLoss(1 * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/nitroglycerin name = "Nitroglycerin" @@ -47,10 +47,10 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/clf3/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_fire_stacks(2 * REM * seconds_per_tick) - affected_mob.adjustFireLoss(0.3 * max(affected_mob.fire_stacks, 1) * REM * seconds_per_tick, 0) - ..() - return TRUE + if(affected_mob.adjustFireLoss(0.3 * max(affected_mob.fire_stacks, 1) * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/clf3/expose_turf(turf/exposed_turf, reac_volume) . = ..() @@ -177,10 +177,10 @@ exposed_mob.ignite_mob() /datum/reagent/phlogiston/on_mob_life(mob/living/carbon/metabolizer, seconds_per_tick, times_fired) + . = ..() metabolizer.adjust_fire_stacks(1 * REM * seconds_per_tick) - metabolizer.adjustFireLoss(0.3 * max(metabolizer.fire_stacks, 0.15) * REM * seconds_per_tick, 0) - ..() - return TRUE + if(metabolizer.adjustFireLoss(0.3 * max(metabolizer.fire_stacks, 0.15) * REM * seconds_per_tick, updating_health = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/napalm name = "Napalm" @@ -201,9 +201,8 @@ mytray.adjust_weedlevel(-rand(5,9)) //At least give them a small reward if they bother. /datum/reagent/napalm/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_fire_stacks(1 * REM * seconds_per_tick) - ..() - return TRUE /datum/reagent/napalm/expose_mob(mob/living/exposed_mob, methods=TOUCH, reac_volume) . = ..() @@ -249,6 +248,7 @@ metabolization_rate = 0.05 * REM //slower consumption when dead /datum/reagent/cryostylane/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() metabolization_rate = 0.25 * REM//faster consumption when alive if(affected_mob.reagents.has_reagent(/datum/reagent/oxygen)) affected_mob.reagents.remove_reagent(/datum/reagent/oxygen, 0.5 * REM * seconds_per_tick) @@ -256,7 +256,6 @@ if(ishuman(affected_mob)) var/mob/living/carbon/human/humi = affected_mob humi.adjust_coretemperature(-15 * REM * seconds_per_tick) - ..() /datum/reagent/cryostylane/expose_turf(turf/exposed_turf, reac_volume) . = ..() @@ -284,9 +283,9 @@ holder.remove_reagent(/datum/reagent/oxygen, 0.5 * REM * seconds_per_tick) affected_mob.adjust_bodytemperature(15 * REM * seconds_per_tick) if(ishuman(affected_mob)) - var/mob/living/carbon/human/humi = affected_mob - humi.adjust_coretemperature(15 * REM * seconds_per_tick) - ..() + var/mob/living/carbon/human/affected_human = affected_mob + affected_human.adjust_coretemperature(15 * REM * seconds_per_tick) + return ..() /datum/reagent/pyrosium/burn(datum/reagents/holder) if(holder.has_reagent(/datum/reagent/oxygen)) @@ -306,12 +305,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/teslium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() shock_timer++ if(shock_timer >= rand(5, 30)) //Random shocks are wildly unpredictable shock_timer = 0 affected_mob.electrocute_act(rand(5, 20), "Teslium in their body", 1, SHOCK_NOGLOVES) //SHOCK_NOGLOVES because it's caused from INSIDE of you playsound(affected_mob, SFX_SPARKS, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE) - ..() /datum/reagent/teslium/on_mob_metabolize(mob/living/carbon/human/affected_mob) . = ..() @@ -334,15 +333,16 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/teslium/energized_jelly/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(isjellyperson(affected_mob)) shock_timer = 0 //immune to shocks affected_mob.AdjustAllImmobility(-40 *REM * seconds_per_tick) - affected_mob.adjustStaminaLoss(-2 * REM * seconds_per_tick, 0) + if(affected_mob.adjustStaminaLoss(-2 * REM * seconds_per_tick, updating_stamina = FALSE)) + . = UPDATE_MOB_HEALTH if(is_species(affected_mob, /datum/species/jelly/luminescent)) var/mob/living/carbon/human/affected_human = affected_mob var/datum/species/jelly/luminescent/slime_species = affected_human.dna.species slime_species.extract_cooldown = max(slime_species.extract_cooldown - (2 SECONDS * REM * seconds_per_tick), 0) - ..() /datum/reagent/firefighting_foam name = "Firefighting Foam" diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index d655698646ca28..390c3d7bfd4ddf 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -7,7 +7,6 @@ color = "#CF3600" // rgb: 207, 54, 0 taste_description = "bitterness" taste_mult = 1.2 - harmful = TRUE chemical_flags = REAGENT_CAN_BE_SYNTHESIZED ///The amount of toxin damage this will cause when metabolized (also used to calculate liver damage) var/toxpwr = 1.5 @@ -23,10 +22,10 @@ mytray.adjust_toxic(round(volume * 2)) /datum/reagent/toxin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(toxpwr && affected_mob.health > health_required) - affected_mob.adjustToxLoss(toxpwr * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() + if(affected_mob.adjustToxLoss(toxpwr * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/amatoxin name = "Amatoxin" @@ -64,8 +63,9 @@ exposed_mob.domutcheck() /datum/reagent/toxin/mutagen/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - . = affected_mob.adjustToxLoss(0.5 * seconds_per_tick * REM, required_biotype = affected_biotype) - return ..() || . + . = ..() + if(affected_mob.adjustToxLoss(0.5 * seconds_per_tick * REM, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/mutagen/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user) mytray.mutation_roll(user) @@ -100,14 +100,16 @@ /datum/reagent/toxin/plasma/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) if(holder.has_reagent(/datum/reagent/medicine/epinephrine)) holder.remove_reagent(/datum/reagent/medicine/epinephrine, 2 * REM * seconds_per_tick) + . = ..() affected_mob.adjustPlasma(20 * REM * seconds_per_tick) - return ..() /datum/reagent/toxin/plasma/on_mob_metabolize(mob/living/carbon/affected_mob) + . = ..() if(HAS_TRAIT(affected_mob, TRAIT_PLASMA_LOVER_METABOLISM)) // sometimes mobs can temporarily metabolize plasma (e.g. plasma fixation disease symptom) toxpwr = 0 /datum/reagent/toxin/plasma/on_mob_end_metabolize(mob/living/carbon/affected_mob) + . = ..() toxpwr = initial(toxpwr) /// Handles plasma boiling. @@ -154,18 +156,20 @@ /datum/reagent/toxin/hot_ice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) if(holder.has_reagent(/datum/reagent/medicine/epinephrine)) holder.remove_reagent(/datum/reagent/medicine/epinephrine, 2 * REM * seconds_per_tick) + . = ..() affected_mob.adjustPlasma(20 * REM * seconds_per_tick) affected_mob.adjust_bodytemperature(-7 * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, affected_mob.get_body_temp_normal()) if(ishuman(affected_mob)) var/mob/living/carbon/human/humi = affected_mob humi.adjust_coretemperature(-7 * REM * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick, affected_mob.get_body_temp_normal()) - return ..() /datum/reagent/toxin/hot_ice/on_mob_metabolize(mob/living/carbon/affected_mob) + . = ..() if(HAS_TRAIT(affected_mob, TRAIT_PLASMA_LOVER_METABOLISM)) toxpwr = 0 /datum/reagent/toxin/hot_ice/on_mob_end_metabolize(mob/living/carbon/affected_mob) + . = ..() toxpwr = initial(toxpwr) /datum/reagent/toxin/lexorin @@ -180,22 +184,20 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/lexorin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - . = TRUE - - if(HAS_TRAIT(affected_mob, TRAIT_NOBREATH)) - . = FALSE - - if(.) + . = ..() + if(!HAS_TRAIT(affected_mob, TRAIT_NOBREATH)) affected_mob.adjustOxyLoss(5 * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) affected_mob.losebreath += 2 * REM * normalise_creation_purity() * seconds_per_tick + . = UPDATE_MOB_HEALTH if(SPT_PROB(10, seconds_per_tick)) affected_mob.emote("gasp") - ..() /datum/reagent/toxin/lexorin/on_mob_metabolize(mob/living/affected_mob) + . = ..() RegisterSignal(affected_mob, COMSIG_CARBON_ATTEMPT_BREATHE, PROC_REF(block_breath)) /datum/reagent/toxin/lexorin/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() UnregisterSignal(affected_mob, COMSIG_CARBON_ATTEMPT_BREATHE, PROC_REF(block_breath)) /datum/reagent/toxin/lexorin/proc/block_breath(mob/living/source) @@ -213,14 +215,14 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/slimejelly/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(5, seconds_per_tick)) to_chat(affected_mob, span_danger("Your insides are burning!")) - affected_mob.adjustToxLoss(rand(20, 60), FALSE, required_biotype = affected_biotype) - . = TRUE + if(affected_mob.adjustToxLoss(rand(20, 60), updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH else if(SPT_PROB(23, seconds_per_tick)) - affected_mob.heal_bodypart_damage(5) - . = TRUE - ..() + if(affected_mob.heal_bodypart_damage(5)) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/carpotoxin name = "Carpotoxin" @@ -252,9 +254,9 @@ if((data?["method"] & INGEST) && holder_mob.stat != DEAD) holder_mob.fakedeath(type) -/datum/reagent/toxin/zombiepowder/on_mob_end_metabolize(mob/living/holder_mob) - holder_mob.cure_fakedeath(type) - return ..() +/datum/reagent/toxin/zombiepowder/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() + affected_mob.cure_fakedeath(type) /datum/reagent/toxin/zombiepowder/on_transfer(atom/target_atom, methods, trans_volume) . = ..() @@ -265,21 +267,22 @@ zombiepowder.data["method"] |= INGEST /datum/reagent/toxin/zombiepowder/on_mob_life(mob/living/affected_mob, seconds_per_tick, times_fired) + . = ..() if(HAS_TRAIT(affected_mob, TRAIT_FAKEDEATH) && HAS_TRAIT(affected_mob, TRAIT_DEATHCOMA)) - ..() - return TRUE + return + var/need_mob_update switch(current_cycle) - if(1 to 5) + if(2 to 6) affected_mob.adjust_confusion(1 SECONDS * REM * seconds_per_tick) affected_mob.adjust_drowsiness(2 SECONDS * REM * seconds_per_tick) affected_mob.adjust_slurring(6 SECONDS * REM * seconds_per_tick) - if(5 to 8) - affected_mob.adjustStaminaLoss(40 * REM * seconds_per_tick, 0) - if(9 to INFINITY) + if(6 to 9) + need_mob_update = affected_mob.adjustStaminaLoss(40 * REM * seconds_per_tick, updating_stamina = FALSE) + if(10 to INFINITY) if(affected_mob.stat != DEAD) affected_mob.fakedeath(type) - ..() - return TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/ghoulpowder name = "Ghoul Powder" @@ -294,17 +297,17 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/ghoulpowder/on_mob_metabolize(mob/living/affected_mob) - ..() + . = ..() ADD_TRAIT(affected_mob, TRAIT_FAKEDEATH, type) /datum/reagent/toxin/ghoulpowder/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_FAKEDEATH, type) - ..() /datum/reagent/toxin/ghoulpowder/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - ..() - . = TRUE + . = ..() + if(affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, FALSE, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/mindbreaker name = "Mindbreaker Toxin" @@ -319,25 +322,23 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED addiction_types = list(/datum/addiction/hallucinogens = 18) //7.2 per 2 seconds - -/datum/reagent/toxin/mindbreaker/on_mob_metabolize(mob/living/metabolizer) +/datum/reagent/toxin/mindbreaker/on_mob_metabolize(mob/living/affected_mob) . = ..() - ADD_TRAIT(metabolizer, TRAIT_RDS_SUPPRESSED, type) + ADD_TRAIT(affected_mob, TRAIT_RDS_SUPPRESSED, type) -/datum/reagent/toxin/mindbreaker/on_mob_end_metabolize(mob/living/metabolizer) +/datum/reagent/toxin/mindbreaker/on_mob_end_metabolize(mob/living/affected_mob) . = ..() - REMOVE_TRAIT(metabolizer, TRAIT_RDS_SUPPRESSED, type) + REMOVE_TRAIT(affected_mob, TRAIT_RDS_SUPPRESSED, type) -/datum/reagent/toxin/mindbreaker/on_mob_life(mob/living/carbon/metabolizer, seconds_per_tick, times_fired) +/datum/reagent/toxin/mindbreaker/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() // mindbreaker toxin assuages hallucinations in those plagued with it, mentally - if(metabolizer.has_trauma_type(/datum/brain_trauma/mild/hallucinations)) - metabolizer.remove_status_effect(/datum/status_effect/hallucination) + if(affected_mob.has_trauma_type(/datum/brain_trauma/mild/hallucinations)) + affected_mob.remove_status_effect(/datum/status_effect/hallucination) // otherwise it creates hallucinations. truly a miracle medicine. else - metabolizer.adjust_hallucinations(10 SECONDS * REM * seconds_per_tick) - - return ..() + affected_mob.adjust_hallucinations(10 SECONDS * REM * seconds_per_tick) /datum/reagent/toxin/plantbgone name = "Plant-B-Gone" @@ -374,8 +375,8 @@ var/damage = min(round(0.4 * reac_volume, 0.1), 10) if(exposed_mob.mob_biotypes & MOB_PLANT) // spray bottle emits 5u so it's dealing ~15 dmg per spray - exposed_mob.adjustToxLoss(damage * 20, required_biotype = affected_biotype) - return + if(exposed_mob.adjustToxLoss(damage * 20, required_biotype = affected_biotype)) + return if(!(methods & VAPOR) || !iscarbon(exposed_mob)) return @@ -409,8 +410,9 @@ AddElement(/datum/element/bugkiller_reagent) /datum/reagent/toxin/pestkiller/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - . = affected_mob.adjustToxLoss(2 * toxpwr * REM * seconds_per_tick, updating_health = FALSE, required_biotype = MOB_BUG) - return ..() || . + . = ..() + if(affected_mob.adjustToxLoss(2 * toxpwr * REM * seconds_per_tick, updating_health = FALSE, required_biotype = MOB_BUG)) + return UPDATE_MOB_HEALTH //Pest Spray /datum/reagent/toxin/pestkiller/on_hydroponics_apply(obj/machinery/hydroponics/mytray, mob/user) @@ -438,10 +440,10 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/toxin/spore/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.damageoverlaytemp = 60 affected_mob.update_damage_hud() affected_mob.set_eye_blur_if_lower(6 SECONDS * REM * seconds_per_tick) - return ..() /datum/reagent/toxin/spore_burning name = "Burning Spore Toxin" @@ -453,9 +455,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/toxin/spore_burning/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_fire_stacks(2 * REM * seconds_per_tick) affected_mob.ignite_mob() - return ..() /datum/reagent/toxin/chloralhydrate name = "Chloral Hydrate" @@ -472,18 +474,17 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/chloralhydrate/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() switch(current_cycle) - if(1 to 10) + if(2 to 11) affected_mob.adjust_confusion(2 SECONDS * REM * normalise_creation_purity() * seconds_per_tick) affected_mob.adjust_drowsiness(4 SECONDS * REM * normalise_creation_purity() * seconds_per_tick) - if(10 to 50) + if(11 to 51) affected_mob.Sleeping(40 * REM * normalise_creation_purity() * seconds_per_tick) - . = TRUE - if(51 to INFINITY) + if(52 to INFINITY) affected_mob.Sleeping(40 * REM * normalise_creation_purity() * seconds_per_tick) - affected_mob.adjustToxLoss(1 * (current_cycle - 50) * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_biotype = affected_biotype) - . = TRUE - ..() + if(affected_mob.adjustToxLoss(1 * (current_cycle - 51) * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/fakebeer //disguised as normal beer for use by emagged brobots name = "B33r" @@ -507,14 +508,14 @@ icon_state = initial(copy_from.icon_state) /datum/reagent/toxin/fakebeer/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() switch(current_cycle) - if(1 to 50) + if(2 to 51) affected_mob.Sleeping(40 * REM * seconds_per_tick) - if(51 to INFINITY) + if(52 to INFINITY) affected_mob.Sleeping(40 * REM * seconds_per_tick) - affected_mob.adjustToxLoss(1 * (current_cycle - 50) * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - . = TRUE - return ..() || . + if(affected_mob.adjustToxLoss(1 * (current_cycle - 50) * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/coffeepowder name = "Coffee Grounds" @@ -558,9 +559,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/mutetoxin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() // Gain approximately 12 seconds * creation purity seconds of silence every metabolism tick. affected_mob.set_silence_if_lower(6 SECONDS * REM * normalise_creation_purity() * seconds_per_tick) - return ..() /datum/reagent/toxin/staminatoxin name = "Tirizene" @@ -572,10 +573,10 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/staminatoxin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustStaminaLoss(data * REM * seconds_per_tick, 0) + . = ..() + if(affected_mob.adjustStaminaLoss(data * REM * seconds_per_tick, updating_stamina = FALSE)) + . = UPDATE_MOB_HEALTH data = max(data - 1, 3) - ..() - . = TRUE /datum/reagent/toxin/polonium name = "Polonium" @@ -587,12 +588,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/toxin/polonium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if (!HAS_TRAIT(affected_mob, TRAIT_IRRADIATED) && SSradiation.can_irradiate_basic(affected_mob)) affected_mob.AddComponent(/datum/component/irradiated) else - affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, required_biotype = affected_biotype) - . = TRUE - return ..() || . + if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/histamine name = "Histamine" @@ -606,6 +607,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/toxin/histamine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(30, seconds_per_tick)) switch(pick(1, 2, 3, 4)) if(1) @@ -618,16 +620,17 @@ if(4) if(prob(75)) to_chat(affected_mob, span_danger("You scratch at an itch.")) - affected_mob.adjustBruteLoss(2*REM, FALSE, required_bodytype = affected_bodytype) - . = TRUE - ..() + if(affected_mob.adjustBruteLoss(2* REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/histamine/overdose_process(mob/living/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOxyLoss(2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - affected_mob.adjustBruteLoss(2 * REM * seconds_per_tick, FALSE, FALSE, BODYTYPE_ORGANIC) - affected_mob.adjustToxLoss(2 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - ..() - . = TRUE + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustOxyLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update += affected_mob.adjustBruteLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update += affected_mob.adjustToxLoss(2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/formaldehyde name = "Formaldehyde" @@ -646,14 +649,13 @@ /datum/reagent/toxin/formaldehyde/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) var/obj/item/organ/internal/liver/liver = affected_mob.get_organ_slot(ORGAN_SLOT_LIVER) if(liver && HAS_TRAIT(liver, TRAIT_CORONER_METABOLISM)) //mmmm, the forbidden pickle juice - affected_mob.adjustToxLoss(-1, FALSE, required_biotype = affected_biotype) //it counteracts its own toxin damage. - . = TRUE - return ..() + if(affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) //it counteracts its own toxin damage. + return UPDATE_MOB_HEALTH + return else if(SPT_PROB(2.5, seconds_per_tick)) holder.add_reagent(/datum/reagent/toxin/histamine, pick(5,15)) holder.remove_reagent(/datum/reagent/toxin/formaldehyde, 1.2) - else - return ..() + return ..() /datum/reagent/toxin/venom name = "Venom" @@ -670,20 +672,23 @@ var/newsize = 1.1 * RESIZE_DEFAULT_SIZE affected_mob.update_transform(newsize/current_size) current_size = newsize - toxpwr = 0.1 * volume - affected_mob.adjustBruteLoss((0.3 * volume) * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - . = TRUE + + if(affected_mob.adjustBruteLoss((0.3 * volume) * REM * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)) + . = UPDATE_MOB_HEALTH + + // chance to either decay into histamine or go the normal route of toxin metabolization if(SPT_PROB(8, seconds_per_tick)) + current_cycle++ holder.add_reagent(/datum/reagent/toxin/histamine, pick(5, 10)) holder.remove_reagent(/datum/reagent/toxin/venom, 1.1) else - ..() + return ..() || . /datum/reagent/toxin/venom/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() affected_mob.update_transform(RESIZE_DEFAULT_SIZE/current_size) current_size = RESIZE_DEFAULT_SIZE - ..() /datum/reagent/toxin/fentanyl name = "Fentanyl" @@ -699,15 +704,17 @@ addiction_types = list(/datum/addiction/opioids = 25) /datum/reagent/toxin/fentanyl/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * REM * normalise_creation_purity() * seconds_per_tick, 150) + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3 * REM * normalise_creation_purity() * seconds_per_tick, 150) if(affected_mob.toxloss <= 60) - affected_mob.adjustToxLoss(1 * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_biotype = affected_biotype) - if(current_cycle >= 4) + need_mob_update += affected_mob.adjustToxLoss(1 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + if(current_cycle > 4) affected_mob.add_mood_event("smacked out", /datum/mood_event/narcotic_heavy, name) - if(current_cycle >= 18) + if(current_cycle > 18) affected_mob.Sleeping(40 * REM * normalise_creation_purity() * seconds_per_tick) - ..() - return TRUE + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/cyanide name = "Cyanide" @@ -722,13 +729,17 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/cyanide/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() + var/need_mob_update = FALSE if(SPT_PROB(2.5, seconds_per_tick)) affected_mob.losebreath += 1 + need_mob_update = TRUE if(SPT_PROB(4, seconds_per_tick)) to_chat(affected_mob, span_danger("You feel horrendously weak!")) affected_mob.Stun(40) - affected_mob.adjustToxLoss(2*REM * normalise_creation_purity(), FALSE, required_biotype = affected_biotype) - return ..() + need_mob_update += affected_mob.adjustToxLoss(2*REM * normalise_creation_purity(), updating_health = FALSE, required_biotype = affected_biotype) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/bad_food name = "Bad Food" @@ -755,23 +766,26 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/itching_powder/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + var/need_mob_update = FALSE if(SPT_PROB(8, seconds_per_tick)) to_chat(affected_mob, span_danger("You scratch at your head.")) - affected_mob.adjustBruteLoss(0.2*REM, FALSE, required_bodytype = affected_bodytype) - . = TRUE + need_mob_update += affected_mob.adjustBruteLoss(0.2*REM, FALSE, required_bodytype = affected_bodytype) if(SPT_PROB(8, seconds_per_tick)) to_chat(affected_mob, span_danger("You scratch at your leg.")) - affected_mob.adjustBruteLoss(0.2*REM, FALSE, required_bodytype = affected_bodytype) - . = TRUE + need_mob_update += affected_mob.adjustBruteLoss(0.2*REM, FALSE, required_bodytype = affected_bodytype) if(SPT_PROB(8, seconds_per_tick)) to_chat(affected_mob, span_danger("You scratch at your arm.")) - affected_mob.adjustBruteLoss(0.2*REM, FALSE, required_bodytype = affected_bodytype) - . = TRUE + need_mob_update += affected_mob.adjustBruteLoss(0.2*REM, FALSE, required_bodytype = affected_bodytype) + + if(need_mob_update) + . = UPDATE_MOB_HEALTH + if(SPT_PROB(1.5, seconds_per_tick)) holder.add_reagent(/datum/reagent/toxin/histamine,rand(1,3)) holder.remove_reagent(/datum/reagent/toxin/itching_powder,1.2) return - ..() + else + return ..() || . /datum/reagent/toxin/initropidril name = "Initropidril" @@ -784,16 +798,17 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/toxin/initropidril/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(13, seconds_per_tick)) var/picked_option = rand(1,3) + var/need_mob_update switch(picked_option) if(1) affected_mob.Paralyze(60) - . = TRUE if(2) affected_mob.losebreath += 10 - affected_mob.adjustOxyLoss(rand(5,25), FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - . = TRUE + affected_mob.adjustOxyLoss(rand(5,25), updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update = TRUE if(3) if(!affected_mob.undergoing_cardiac_arrest() && affected_mob.can_heartattack()) affected_mob.set_heartattack(TRUE) @@ -801,9 +816,9 @@ affected_mob.visible_message(span_userdanger("[affected_mob] clutches at [affected_mob.p_their()] chest as if [affected_mob.p_their()] heart stopped!")) else affected_mob.losebreath += 10 - affected_mob.adjustOxyLoss(rand(5,25), FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - . = TRUE - return ..() || . + need_mob_update = affected_mob.adjustOxyLoss(rand(5,25), updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/pancuronium name = "Pancuronium" @@ -817,12 +832,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/toxin/pancuronium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - if(current_cycle >= 10) + . = ..() + if(current_cycle > 10) affected_mob.Stun(40 * REM * seconds_per_tick) - . = TRUE if(SPT_PROB(10, seconds_per_tick)) affected_mob.losebreath += 4 - ..() + return UPDATE_MOB_HEALTH /datum/reagent/toxin/sodium_thiopental name = "Sodium Thiopental" @@ -843,11 +858,11 @@ REMOVE_TRAIT(affected_mob, TRAIT_ANTICONVULSANT, name) /datum/reagent/toxin/sodium_thiopental/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - if(current_cycle >= 10) + . = ..() + if(current_cycle > 10) affected_mob.Sleeping(40 * REM * seconds_per_tick) - affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick, 0) - ..() - return TRUE + if(affected_mob.adjustStaminaLoss(10 * REM * seconds_per_tick, updating_stamina = FALSE)) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/sulfonal name = "Sulfonal" @@ -863,9 +878,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/sulfonal/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - if(current_cycle >= 22) + . = ..() + if(current_cycle > 22) affected_mob.Sleeping(40 * REM * normalise_creation_purity() * seconds_per_tick) - return ..() /datum/reagent/toxin/amanitin name = "Amanitin" @@ -879,13 +894,13 @@ var/delayed_toxin_damage = 0 /datum/reagent/toxin/amanitin/on_mob_life(mob/living/affected_mob, seconds_per_tick, times_fired) - delayed_toxin_damage += (seconds_per_tick * 3) . = ..() + delayed_toxin_damage += (seconds_per_tick * 3) /datum/reagent/toxin/amanitin/on_mob_delete(mob/living/affected_mob) + . = ..() affected_mob.log_message("has taken [delayed_toxin_damage] toxin damage from amanitin toxin", LOG_ATTACK) affected_mob.adjustToxLoss(delayed_toxin_damage, required_biotype = affected_biotype) - . = ..() /datum/reagent/toxin/lipolicide name = "Lipolicide" @@ -903,12 +918,12 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/lipolicide/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.nutrition <= NUTRITION_LEVEL_STARVING) - affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) - . = TRUE + if(affected_mob.adjustToxLoss(1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH affected_mob.adjust_nutrition(-3 * REM * normalise_creation_purity() * seconds_per_tick) // making the chef more valuable, one meme trap at a time affected_mob.overeatduration = 0 - return ..() || . /datum/reagent/toxin/coniine name = "Coniine" @@ -920,9 +935,10 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/coniine/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.losebreath < 5) affected_mob.losebreath = min(affected_mob.losebreath + 5 * REM * seconds_per_tick, 5) - return ..() + return UPDATE_MOB_HEALTH /datum/reagent/toxin/spewium name = "Spewium" @@ -936,8 +952,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/toxin/spewium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - .=..() - if(current_cycle >= 11 && SPT_PROB(min(30, current_cycle), seconds_per_tick)) + . = ..() + if(current_cycle > 11 && SPT_PROB(min(31, current_cycle), seconds_per_tick)) + affected_mob.vomit(10, prob(10), prob(50), rand(0,4), TRUE) var/constructed_flags = (MOB_VOMIT_MESSAGE | MOB_VOMIT_HARM) if(prob(10)) constructed_flags |= MOB_VOMIT_BLOOD @@ -950,7 +967,7 @@ /datum/reagent/toxin/spewium/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() - if(current_cycle >= 33 && SPT_PROB(7.5, seconds_per_tick)) + if(current_cycle > 33 && SPT_PROB(7.5, seconds_per_tick)) affected_mob.spew_organ() affected_mob.vomit(VOMIT_CATEGORY_BLOOD, lost_nutrition = 0, distance = 4) to_chat(affected_mob, span_userdanger("You feel something lumpy come up as you vomit.")) @@ -965,11 +982,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/toxin/curare/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - if(current_cycle >= 11) + . = ..() + if(current_cycle > 11) affected_mob.Paralyze(60 * REM * seconds_per_tick) - affected_mob.adjustOxyLoss(0.5*REM*seconds_per_tick, FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) - . = TRUE - ..() + if(affected_mob.adjustOxyLoss(0.5*REM*seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type)) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/heparin //Based on a real-life anticoagulant. I'm not a doctor, so this won't be realistic. name = "Heparin" @@ -990,12 +1007,12 @@ return ..() /datum/reagent/toxin/heparin/on_mob_metabolize(mob/living/affected_mob) + . = ..() ADD_TRAIT(affected_mob, TRAIT_BLOODY_MESS, /datum/reagent/toxin/heparin) - return ..() /datum/reagent/toxin/heparin/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_BLOODY_MESS, /datum/reagent/toxin/heparin) - return ..() /datum/reagent/toxin/rotatium //Rotatium. Fucks up your rotation and is hilarious name = "Rotatium" @@ -1012,6 +1029,7 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/rotatium/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(affected_mob.hud_used) if(current_cycle >= 20 && (current_cycle % 20) == 0) var/atom/movable/plane_master_controller/pm_controller = affected_mob.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] @@ -1020,14 +1038,13 @@ for(var/atom/movable/screen/plane_master/plane as anything in pm_controller.get_planes()) animate(plane, transform = matrix(rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING, loop = -1) animate(transform = matrix(-rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING) - return ..() /datum/reagent/toxin/rotatium/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() if(affected_mob?.hud_used) var/atom/movable/plane_master_controller/pm_controller = affected_mob.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] for(var/atom/movable/screen/plane_master/plane as anything in pm_controller.get_planes()) animate(plane, transform = matrix(), time = 5, easing = QUAD_EASING) - ..() /datum/reagent/toxin/anacea name = "Anacea" @@ -1045,13 +1062,12 @@ var/remove_amt = 5 if(holder.has_reagent(/datum/reagent/medicine/calomel) || holder.has_reagent(/datum/reagent/medicine/pen_acid)) remove_amt = 0.5 + . = ..() for(var/datum/reagent/medicine/R in affected_mob.reagents.reagent_list) affected_mob.reagents.remove_reagent(R.type, remove_amt * REM * normalise_creation_purity() * seconds_per_tick) - return ..() //ACID - /datum/reagent/toxin/acid name = "Sulfuric Acid" description = "A strong mineral acid with the molecular formula H2SO4." @@ -1115,9 +1131,9 @@ mytray.adjust_weedlevel(-rand(1,4)) /datum/reagent/toxin/acid/fluacid/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustFireLoss((current_cycle/15) * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) - . = TRUE - ..() + . = ..() + if(affected_mob.adjustFireLoss(((current_cycle-1)/15) * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/acid/nitracid name = "Nitric Acid" @@ -1131,9 +1147,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/acid/nitracid/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustFireLoss((volume/10) * REM * normalise_creation_purity() * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) //here you go nervar - . = TRUE - ..() + . = ..() + if(affected_mob.adjustFireLoss((volume/10) * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype)) //here you go nervar + return UPDATE_MOB_HEALTH /datum/reagent/toxin/delayed name = "Toxin Microcapsules" @@ -1143,17 +1159,18 @@ var/actual_metaboliztion_rate = REAGENTS_METABOLISM toxpwr = 0 var/actual_toxpwr = 5 - var/delay = 30 + var/delay = 31 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED|REAGENT_NO_RANDOM_RECIPE /datum/reagent/toxin/delayed/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(current_cycle > delay) - holder.remove_reagent(type, actual_metaboliztion_rate * affected_mob.metabolism_efficiency * seconds_per_tick) - affected_mob.adjustToxLoss(actual_toxpwr * REM * seconds_per_tick, FALSE, required_biotype = affected_biotype) + if(holder) + holder.remove_reagent(type, actual_metaboliztion_rate * affected_mob.metabolism_efficiency * seconds_per_tick) + if(affected_mob.adjustToxLoss(actual_toxpwr * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype)) + . = UPDATE_MOB_HEALTH if(SPT_PROB(5, seconds_per_tick)) affected_mob.Paralyze(20) - . = TRUE - ..() /datum/reagent/toxin/mimesbane name = "Mime's Bane" @@ -1168,9 +1185,11 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/mimesbane/on_mob_metabolize(mob/living/affected_mob) + . = ..() ADD_TRAIT(affected_mob, TRAIT_EMOTEMUTE, type) /datum/reagent/toxin/mimesbane/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() REMOVE_TRAIT(affected_mob, TRAIT_EMOTEMUTE, type) /datum/reagent/toxin/bonehurtingjuice //oof ouch @@ -1187,11 +1206,13 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/bonehurtingjuice/on_mob_add(mob/living/carbon/affected_mob) + . = ..() affected_mob.say("oof ouch my bones", forced = /datum/reagent/toxin/bonehurtingjuice) - return ..() /datum/reagent/toxin/bonehurtingjuice/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustStaminaLoss(7.5 * REM * seconds_per_tick, 0) + . = ..() + if(affected_mob.adjustStaminaLoss(7.5 * REM * seconds_per_tick, updating_stamina = FALSE)) + . = UPDATE_MOB_HEALTH if(SPT_PROB(10, seconds_per_tick)) switch(rand(1, 3)) if(1) @@ -1200,9 +1221,9 @@ affected_mob.manual_emote(pick("oofs silently.", "looks like [affected_mob.p_their()] bones hurt.", "grimaces, as though [affected_mob.p_their()] bones hurt.")) if(3) to_chat(affected_mob, span_warning("Your bones hurt!")) - return ..() || TRUE /datum/reagent/toxin/bonehurtingjuice/overdose_process(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() if(SPT_PROB(2, seconds_per_tick) && iscarbon(affected_mob)) //big oof var/selected_part = pick(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) //God help you if the same limb gets picked twice quickly. var/obj/item/bodypart/BP = affected_mob.get_bodypart(selected_part) @@ -1210,11 +1231,11 @@ playsound(affected_mob, get_sfx(SFX_DESECRATION), 50, TRUE, -1) affected_mob.visible_message(span_warning("[affected_mob]'s bones hurt too much!!"), span_danger("Your bones hurt too much!!")) affected_mob.say("OOF!!", forced = /datum/reagent/toxin/bonehurtingjuice) - BP.receive_damage(20, 0, 200, wound_bonus = rand(30, 130)) + if(BP.receive_damage(brute = 20 * REM * seconds_per_tick, burn = 0, blocked = 200, updating_health = FALSE, wound_bonus = rand(30, 130))) + . = UPDATE_MOB_HEALTH else //SUCH A LUST FOR REVENGE!!! to_chat(affected_mob, span_warning("A phantom limb hurts!")) affected_mob.say("Why are we still here, just to suffer?", forced = /datum/reagent/toxin/bonehurtingjuice) - return ..() /datum/reagent/toxin/bungotoxin name = "Bungotoxin" @@ -1227,7 +1248,9 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/bungotoxin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, 3 * REM * seconds_per_tick) + . = ..() + if(affected_mob.adjustOrganLoss(ORGAN_SLOT_HEART, 3 * REM * seconds_per_tick)) + . = UPDATE_MOB_HEALTH // If our mob's currently dizzy from anything else, we will also gain confusion var/mob_dizziness = affected_mob.get_timed_status_effect_duration(/datum/status_effect/confusion) @@ -1235,11 +1258,9 @@ // Gain confusion equal to about half the duration of our current dizziness affected_mob.set_confusion(mob_dizziness / 2) - if(current_cycle >= 12 && SPT_PROB(4, seconds_per_tick)) + if(current_cycle >= 13 && SPT_PROB(4, seconds_per_tick)) var/tox_message = pick("You feel your heart spasm in your chest.", "You feel faint.","You feel you need to catch your breath.","You feel a prickle of pain in your chest.") to_chat(affected_mob, span_notice("[tox_message]")) - . = TRUE - ..() /datum/reagent/toxin/leadacetate name = "Lead Acetate" @@ -1252,13 +1273,16 @@ chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /datum/reagent/toxin/leadacetate/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) - affected_mob.adjustOrganLoss(ORGAN_SLOT_EARS, 1 * REM * seconds_per_tick) - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick) - . = TRUE + . = ..() + var/need_mob_update + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_EARS, 1 * REM * seconds_per_tick) + need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1 * REM * seconds_per_tick) + if(need_mob_update) + . = UPDATE_MOB_HEALTH if(SPT_PROB(0.5, seconds_per_tick)) to_chat(affected_mob, span_notice("Ah, what was that? You thought you heard something...")) affected_mob.adjust_confusion(5 SECONDS) - return ..() || . + /datum/reagent/toxin/hunterspider name = "Spider Toxin" description = "A toxic chemical produced by spiders to weaken prey." @@ -1273,8 +1297,8 @@ liver_damage_multiplier = 0 /datum/reagent/toxin/viperspider/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() affected_mob.adjust_hallucinations(10 SECONDS * REM * seconds_per_tick) - return ..() /datum/reagent/toxin/tetrodotoxin name = "Tetrodotoxin" @@ -1294,10 +1318,12 @@ ) /datum/reagent/toxin/tetrodotoxin/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) + . = ..() //be ready for a cocktail of symptoms, including: //numbness, nausea, vomit, breath loss, weakness, paralysis and nerve damage/impairment and eventually a heart attack if enough time passes. + var/need_mob_update switch(current_cycle) - if(6 to 12) + if(7 to 13) if(SPT_PROB(20, seconds_per_tick)) affected_mob.set_jitter_if_lower(rand(2 SECONDS, 3 SECONDS) * REM * seconds_per_tick) if(SPT_PROB(5, seconds_per_tick)) @@ -1306,51 +1332,57 @@ to_chat(affected_mob, span_warning("your [tongue.name] feels numb...")) affected_mob.set_slurring_if_lower(5 SECONDS * REM * seconds_per_tick) affected_mob.adjust_disgust(3.5 * REM * seconds_per_tick) - if(12 to 20) + if(13 to 21) silent_toxin = FALSE toxpwr = 0.5 - affected_mob.adjustStaminaLoss(2.5 * REM * seconds_per_tick, 0) + need_mob_update = affected_mob.adjustStaminaLoss(2.5 * REM * seconds_per_tick, updating_stamina = FALSE) if(SPT_PROB(20, seconds_per_tick)) affected_mob.losebreath += 1 * REM * seconds_per_tick + need_mob_update = TRUE if(SPT_PROB(40, seconds_per_tick)) affected_mob.set_jitter_if_lower(rand(2 SECONDS, 3 SECONDS) * REM * seconds_per_tick) affected_mob.adjust_disgust(3 * REM * seconds_per_tick) affected_mob.set_slurring_if_lower(1 SECONDS * REM * seconds_per_tick) - affected_mob.adjustStaminaLoss(2 * REM * seconds_per_tick, 0) + affected_mob.adjustStaminaLoss(2 * REM * seconds_per_tick, updating_stamina = FALSE) if(SPT_PROB(4, seconds_per_tick)) paralyze_limb(affected_mob) + need_mob_update = TRUE if(SPT_PROB(10, seconds_per_tick)) affected_mob.adjust_confusion(rand(6 SECONDS, 8 SECONDS)) - if(20 to 28) + if(21 to 29) toxpwr = 1 - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5) + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5) if(SPT_PROB(40, seconds_per_tick)) affected_mob.losebreath += 2 * REM * seconds_per_tick + need_mob_update = TRUE affected_mob.adjust_disgust(3 * REM * seconds_per_tick) affected_mob.set_slurring_if_lower(3 SECONDS * REM * seconds_per_tick) if(SPT_PROB(5, seconds_per_tick)) to_chat(affected_mob, span_danger("you feel horribly weak.")) - affected_mob.adjustStaminaLoss(5 * REM * seconds_per_tick, 0) + need_mob_update += affected_mob.adjustStaminaLoss(5 * REM * seconds_per_tick, updating_stamina = FALSE) if(SPT_PROB(8, seconds_per_tick)) paralyze_limb(affected_mob) + need_mob_update = TRUE if(SPT_PROB(10, seconds_per_tick)) affected_mob.adjust_confusion(rand(6 SECONDS, 8 SECONDS)) - if(28 to INFINITY) + if(29 to INFINITY) toxpwr = 1.5 - affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, BRAIN_DAMAGE_DEATH) + need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1, BRAIN_DAMAGE_DEATH) affected_mob.set_silence_if_lower(3 SECONDS * REM * seconds_per_tick) - affected_mob.adjustStaminaLoss(5 * REM * seconds_per_tick, 0) + need_mob_update += affected_mob.adjustStaminaLoss(5 * REM * seconds_per_tick, updating_stamina = FALSE) affected_mob.adjust_disgust(2 * REM * seconds_per_tick) if(SPT_PROB(15, seconds_per_tick)) paralyze_limb(affected_mob) + need_mob_update = TRUE if(SPT_PROB(10, seconds_per_tick)) affected_mob.adjust_confusion(rand(6 SECONDS, 8 SECONDS)) - if(current_cycle >= 38 && !length(traits_not_applied) && SPT_PROB(5, seconds_per_tick) && !affected_mob.undergoing_cardiac_arrest()) + if(current_cycle > 38 && !length(traits_not_applied) && SPT_PROB(5, seconds_per_tick) && !affected_mob.undergoing_cardiac_arrest()) affected_mob.set_heartattack(TRUE) to_chat(affected_mob, span_danger("you feel a burning pain spread throughout your chest, oh no...")) - return ..() + if(need_mob_update) + return UPDATE_MOB_HEALTH /datum/reagent/toxin/tetrodotoxin/proc/paralyze_limb(mob/living/affected_mob) if(!length(traits_not_applied)) @@ -1360,9 +1392,11 @@ traits_not_applied -= added_trait /datum/reagent/toxin/tetrodotoxin/on_mob_metabolize(mob/living/affected_mob) + . = ..() RegisterSignal(affected_mob, COMSIG_CARBON_ATTEMPT_BREATHE, PROC_REF(block_breath)) /datum/reagent/toxin/tetrodotoxin/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() UnregisterSignal(affected_mob, COMSIG_CARBON_ATTEMPT_BREATHE, PROC_REF(block_breath)) // the initial() proc doesn't work for lists. var/list/initial_list = list( @@ -1376,5 +1410,5 @@ /datum/reagent/toxin/tetrodotoxin/proc/block_breath(mob/living/source) SIGNAL_HANDLER - if(current_cycle >= 28) + if(current_cycle > 28) return COMSIG_CARBON_BLOCK_BREATH diff --git a/code/modules/reagents/chemistry/reagents/unique/eigenstasium.dm b/code/modules/reagents/chemistry/reagents/unique/eigenstasium.dm index 70db34460601f1..73dcf8aa60b482 100644 --- a/code/modules/reagents/chemistry/reagents/unique/eigenstasium.dm +++ b/code/modules/reagents/chemistry/reagents/unique/eigenstasium.dm @@ -77,21 +77,21 @@ return ..() /datum/reagent/eigenstate/on_mob_life(mob/living/carbon/living_mob) + . = ..() if(prob(20)) do_sparks(5,FALSE,living_mob) - return ..() - /datum/reagent/eigenstate/on_mob_delete(mob/living/living_mob) //returns back to original location + . = ..() do_sparks(5,FALSE,living_mob) to_chat(living_mob, span_userdanger("You feel strangely whole again.")) if(!living_mob.reagents.has_reagent(/datum/reagent/stabilizing_agent)) do_teleport(living_mob, location_return, 0, asoundin = 'sound/effects/phasein.ogg') //Teleports home do_sparks(5,FALSE,living_mob) qdel(eigenstate) - return ..() /datum/reagent/eigenstate/overdose_start(mob/living/living_mob) //Overdose, makes you teleport randomly + . = ..() to_chat(living_mob, span_userdanger("You feel like your perspective is being ripped apart as you begin flitting in and out of reality!")) living_mob.set_jitter_if_lower(40 SECONDS) metabolization_rate += 0.5 //So you're not stuck forever teleporting. @@ -101,10 +101,10 @@ return ..() /datum/reagent/eigenstate/overdose_process(mob/living/living_mob) //Overdose, makes you teleport randomly + . = ..() do_sparks(5, FALSE, living_mob) do_teleport(living_mob, get_turf(living_mob), 10, asoundin = 'sound/effects/phasein.ogg') do_sparks(5, FALSE, living_mob) - return ..() //FOR ADDICTION-LIKE EFFECTS, SEE datum/status_effect/eigenstasium diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index b632bc7b6c86e9..7afd69182619b8 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -584,7 +584,7 @@ var/location = get_turf(M) if(iscarbon(M)) if(ismonkey(M)) - M.gib() + M.gib(DROP_ALL_REMAINS) else M.vomit(VOMIT_CATEGORY_BLOOD) new /mob/living/carbon/human/species/monkey(location, TRUE) diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 9083de70902e76..d49976ac10eed2 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -125,16 +125,16 @@ ///special size for anti cult effect var/effective_size = round(created_volume/48) playsound(T, 'sound/effects/pray.ogg', 80, FALSE, effective_size) - for(var/mob/living/simple_animal/revenant/R in get_hearers_in_view(7,T)) + for(var/mob/living/basic/revenant/ghostie in get_hearers_in_view(7,T)) var/deity if(GLOB.deity) deity = GLOB.deity else deity = "Christ" - to_chat(R, span_userdanger("The power of [deity] compels you!")) - R.stun(20) - R.reveal(100) - R.adjustHealth(50) + to_chat(ghostie, span_userdanger("The power of [deity] compels you!")) + ghostie.apply_status_effect(/datum/status_effect/incapacitating/paralyzed/revenant, 2 SECONDS) + ghostie.apply_status_effect(/datum/status_effect/revenant/revealed, 10 SECONDS) + ghostie.adjust_health(50) for(var/mob/living/carbon/C in get_hearers_in_view(effective_size,T)) if(IS_CULTIST(C)) to_chat(C, span_userdanger("The divine explosion sears you!")) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 49ef6980142aa0..5234018bbd9fa7 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -144,7 +144,7 @@ span_danger("You splash the contents of [src] onto [target][punctuation]"), ignored_mobs = target, ) - + SEND_SIGNAL(target, COMSIG_ATOM_SPLASHED) if (ismob(target)) var/mob/target_mob = target target_mob.show_message( diff --git a/code/modules/reagents/reagent_containers/cups/_cup.dm b/code/modules/reagents/reagent_containers/cups/_cup.dm index b5930955a3143e..5caec9de68168c 100644 --- a/code/modules/reagents/reagent_containers/cups/_cup.dm +++ b/code/modules/reagents/reagent_containers/cups/_cup.dm @@ -125,7 +125,7 @@ return var/trans = reagents.trans_to(target, amount_per_transfer_from_this, transferred_by = user) - to_chat(user, span_notice("You transfer [trans] unit\s of the solution to [target].")) + to_chat(user, span_notice("You transfer [round(trans, 0.01)] unit\s of the solution to [target].")) else if(target.is_drainable()) //A dispenser. Transfer FROM it TO us. if(!target.reagents.total_volume) @@ -137,7 +137,7 @@ return var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transferred_by = user) - to_chat(user, span_notice("You fill [src] with [trans] unit\s of the contents of [target].")) + to_chat(user, span_notice("You fill [src] with [round(trans, 0.01)] unit\s of the contents of [target].")) target.update_appearance() @@ -158,7 +158,7 @@ return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transferred_by = user) - to_chat(user, span_notice("You fill [src] with [trans] unit\s of the contents of [target].")) + to_chat(user, span_notice("You fill [src] with [round(trans, 0.01)] unit\s of the contents of [target].")) target.update_appearance() return SECONDARY_ATTACK_CONTINUE_CHAIN diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm index cf01c2cd4c2a0e..ac8d0af0d1c6b9 100644 --- a/code/modules/reagents/reagent_containers/dropper.dm +++ b/code/modules/reagents/reagent_containers/dropper.dm @@ -20,7 +20,7 @@ return if(reagents.total_volume > 0) - if(target.reagents.total_volume >= target.reagents.maximum_volume) + if(target.reagents.holder_full()) to_chat(user, span_notice("[target] is full.")) return @@ -29,7 +29,7 @@ return var/trans = 0 - var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1) + var/fraction = min(amount_per_transfer_from_this / reagents.total_volume, 1) if(ismob(target)) if(ishuman(target)) @@ -46,7 +46,7 @@ target.visible_message(span_danger("[user] tries to squirt something into [target]'s eyes, but fails!"), \ span_userdanger("[user] tries to squirt something into your eyes, but fails!")) - to_chat(user, span_notice("You transfer [trans] unit\s of the solution.")) + to_chat(user, span_notice("You transfer [round(trans, 0.01)] unit\s of the solution.")) update_appearance() return else if(isalien(target)) //hiss-hiss has no eyes! @@ -66,7 +66,7 @@ log_combat(user, M, "squirted", R) trans = src.reagents.trans_to(target, amount_per_transfer_from_this, transferred_by = user) - to_chat(user, span_notice("You transfer [trans] unit\s of the solution.")) + to_chat(user, span_notice("You transfer [round(trans, 0.01)] unit\s of the solution.")) update_appearance() target.update_appearance() @@ -82,7 +82,7 @@ var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this, transferred_by = user) - to_chat(user, span_notice("You fill [src] with [trans] unit\s of the solution.")) + to_chat(user, span_notice("You fill [src] with [round(trans, 0.01)] unit\s of the solution.")) update_appearance() target.update_appearance() diff --git a/code/modules/religion/burdened/psyker.dm b/code/modules/religion/burdened/psyker.dm index 4499030642d93b..d4c752751b8bc2 100644 --- a/code/modules/religion/burdened/psyker.dm +++ b/code/modules/religion/burdened/psyker.dm @@ -183,7 +183,7 @@ on_clear_callback = CALLBACK(src, PROC_REF(on_cult_rune_removed)), \ effects_we_clear = list(/obj/effect/rune, /obj/effect/heretic_rune, /obj/effect/cosmic_rune), \ ) - AddElement(/datum/element/bane, target_type = /mob/living/simple_animal/revenant, damage_multiplier = 0, added_damage = 25) + AddElement(/datum/element/bane, target_type = /mob/living/basic/revenant, damage_multiplier = 0, added_damage = 25) name = pick(possible_names) desc = possible_names[name] diff --git a/code/modules/religion/honorbound/honorbound_rites.dm b/code/modules/religion/honorbound/honorbound_rites.dm index 6ba557d5a30e2c..c9c9e71135404a 100644 --- a/code/modules/religion/honorbound/honorbound_rites.dm +++ b/code/modules/religion/honorbound/honorbound_rites.dm @@ -59,7 +59,7 @@ if(joining_now.mind.has_antag_datum(/datum/antagonist/cult))//what the fuck?! to_chat(user, span_warning("[GLOB.deity] has seen a true, dark evil in [joining_now]'s heart, and they have been smitten!")) playsound(get_turf(religious_tool), 'sound/effects/pray.ogg', 50, TRUE) - joining_now.gib(TRUE) + joining_now.gib(DROP_ORGANS|DROP_BODYPARTS) return FALSE var/datum/brain_trauma/special/honorbound/honor = user.has_trauma_type(/datum/brain_trauma/special/honorbound) if(joining_now in honor.guilty) diff --git a/code/modules/religion/religion_sects.dm b/code/modules/religion/religion_sects.dm index 9075a656ae9d79..ebd90388fda64c 100644 --- a/code/modules/religion/religion_sects.dm +++ b/code/modules/religion/religion_sects.dm @@ -115,7 +115,7 @@ if(hurt_limbs.len) for(var/X in hurt_limbs) var/obj/item/bodypart/affecting = X - if(affecting.heal_damage(heal_amt, heal_amt, BODYTYPE_ORGANIC)) + if(affecting.heal_damage(heal_amt, heal_amt, required_bodytype = BODYTYPE_ORGANIC)) blessed.update_damage_overlays() blessed.visible_message(span_notice("[chap] heals [blessed] with the power of [GLOB.deity]!")) to_chat(blessed, span_boldnotice("May the power of [GLOB.deity] compel you to be healed!")) @@ -272,7 +272,7 @@ var/list/hurt_limbs = blessed.get_damaged_bodyparts(1, 1, BODYTYPE_ORGANIC) if(hurt_limbs.len) for(var/obj/item/bodypart/affecting as anything in hurt_limbs) - if(affecting.heal_damage(heal_amt, heal_amt, BODYTYPE_ORGANIC)) + if(affecting.heal_damage(heal_amt, heal_amt, required_bodytype = BODYTYPE_ORGANIC)) blessed.update_damage_overlays() blessed.visible_message(span_notice("[chap] barters a heal for [blessed] from [GLOB.deity]!")) to_chat(blessed, span_boldnotice("May the power of [GLOB.deity] compel you to be healed! Thank you for choosing [GLOB.deity]!")) diff --git a/code/modules/research/anomaly/anomaly_core.dm b/code/modules/research/anomaly/anomaly_core.dm index 56220956182b57..febb25add5301e 100644 --- a/code/modules/research/anomaly/anomaly_core.dm +++ b/code/modules/research/anomaly/anomaly_core.dm @@ -23,7 +23,7 @@ /obj/item/assembly/signaler/anomaly/manual_suicide(mob/living/carbon/user) user.visible_message(span_suicide("[user]'s [src] is reacting to the radio signal, warping [user.p_their()] body!")) user.set_suicide(TRUE) - user.gib() + user.gib(DROP_ALL_REMAINS) /obj/item/assembly/signaler/anomaly/attack_self() return diff --git a/code/modules/research/bepis.dm b/code/modules/research/bepis.dm deleted file mode 100644 index d0640ed5d1c499..00000000000000 --- a/code/modules/research/bepis.dm +++ /dev/null @@ -1,296 +0,0 @@ -//This system is designed to act as an in-between for cargo and science, and the first major money sink in the game outside of just buying things from cargo (As of 10/9/19, anyway). - -//economics defined values, subject to change should anything be too high or low in practice. - -#define MACHINE_OPERATION 100000 -#define MACHINE_OVERLOAD 500000 -#define MAJOR_THRESHOLD (6*CARGO_CRATE_VALUE) -#define MINOR_THRESHOLD (4*CARGO_CRATE_VALUE) -#define STANDARD_DEVIATION (2*CARGO_CRATE_VALUE) -#define PART_CASH_OFFSET_AMOUNT (0.5*CARGO_CRATE_VALUE) - -/obj/machinery/rnd/bepis - name = "\improper B.E.P.I.S. Chamber" - desc = "A high fidelity testing device which unlocks the secrets of the known universe using the two most powerful substances available to man: excessive amounts of electricity and capital." - icon = 'icons/obj/machines/bepis.dmi' - icon_state = "chamber" - base_icon_state = "chamber" - density = TRUE - layer = ABOVE_MOB_LAYER - plane = GAME_PLANE_UPPER - circuit = /obj/item/circuitboard/machine/bepis - - ///How much cash the UI and machine are depositing at a time. - var/banking_amount = 100 - ///How much stored player cash exists within the machine. - var/banked_cash = 0 - ///Payer's bank account. - var/datum/bank_account/account - ///Name on the payer's bank account. - var/account_name - ///When the BEPIS fails to hand out any reward, the ERROR cause will be a randomly picked string displayed on the UI. - var/error_cause = null - - //Vars related to probability and chance of success for testing, using gaussian normal distribution. - ///How much cash you will need to obtain a Major Tech Disk reward. - var/major_threshold = MAJOR_THRESHOLD - ///How much cash you will need to obtain a minor invention reward. - var/minor_threshold = MINOR_THRESHOLD - ///The standard deviation of the BEPIS's gaussian normal distribution. - var/std = STANDARD_DEVIATION - - //Stock part variables - ///Multiplier that lowers how much the BEPIS' power costs are. Maximum of 1, upgraded to a minimum of 0.7. See RefreshParts. - var/power_saver = 1 - ///Variability on the money you actively spend on the BEPIS, with higher inaccuracy making the most change, good and bad to spent cash. - var/inaccuracy_percentage = 1.5 - ///How much "cash" is added to your inserted cash efforts for free. Based on manipulator stock part level. - var/positive_cash_offset = 0 - ///How much "cost" is removed from both the minor and major threshold costs. Based on laser stock part level. - var/negative_cash_offset = 0 - ///List of objects that constitute your minor rewards. All rewards are unique or rare outside of the BEPIS. - var/minor_rewards = list( - //To add a new minor reward, add it here. - /obj/item/stack/circuit_stack/full, - /obj/item/pen/survival, - /obj/item/flashlight/flashdark,//SKYRAT EDIT - /obj/item/circuitboard/machine/sleeper/party, - /obj/item/toy/sprayoncan, - ) - -/obj/machinery/rnd/bepis/attackby(obj/item/O, mob/user, params) - if(!is_operational) - to_chat(user, span_notice("[src] can't accept money when it's not functioning.")) - return - if(istype(O, /obj/item/holochip) || istype(O, /obj/item/stack/spacecash)) - var/deposit_value = O.get_item_credit_value() - banked_cash += deposit_value - qdel(O) - say("Deposited [deposit_value] credits into storage.") - update_appearance() - return - if(isidcard(O)) - var/obj/item/card/id/Card = O - if(Card.registered_account) - account = Card.registered_account - account_name = Card.registered_name - say("New account detected. Console Updated.") - else - say("No account detected on card. Aborting.") - return - return ..() - -/obj/machinery/rnd/bepis/screwdriver_act(mob/living/user, obj/item/tool) - return default_deconstruction_screwdriver(user, "chamber_open", "chamber", tool) - -/obj/machinery/rnd/bepis/screwdriver_act_secondary(mob/living/user, obj/item/tool) - return default_deconstruction_screwdriver(user, "chamber_open", "chamber", tool) - -/obj/machinery/rnd/bepis/RefreshParts() - . = ..() - var/C = 0 - var/M = 0 - var/L = 0 - var/S = 0 - for(var/datum/stock_part/capacitor/capacitor in component_parts) - C += ((capacitor.tier - 1) * 0.1) - power_saver = 1 - C - for(var/datum/stock_part/servo/servo in component_parts) - M += ((servo.tier - 1) * PART_CASH_OFFSET_AMOUNT) - positive_cash_offset = M - for(var/datum/stock_part/micro_laser/Laser in component_parts) - L += ((Laser.tier - 1) * PART_CASH_OFFSET_AMOUNT) - negative_cash_offset = L - for(var/datum/stock_part/scanning_module/scanning_module in component_parts) - S += ((scanning_module.tier - 1) * 0.25) - inaccuracy_percentage = (1.5 - S) - -/obj/machinery/rnd/bepis/update_icon_state() - if(panel_open == TRUE) - icon_state = "[base_icon_state]_open" - return ..() - if((use_power == ACTIVE_POWER_USE) && (banked_cash > 0) && (is_operational)) - icon_state = "[base_icon_state]_active_loaded" - return ..() - if (((use_power == IDLE_POWER_USE) && (banked_cash > 0)) || (banked_cash > 0) && (!is_operational)) - icon_state = "[base_icon_state]_loaded" - return ..() - if(use_power == ACTIVE_POWER_USE && is_operational) - icon_state = "[base_icon_state]_active" - return ..() - if(((use_power == IDLE_POWER_USE) && (banked_cash == 0)) || (!is_operational)) - icon_state = base_icon_state - return ..() - return ..() - -/obj/machinery/rnd/bepis/ui_interact(mob/user, datum/tgui/ui) - ui = SStgui.try_update_ui(user, src, ui) - if(!ui) - ui = new(user, src, "Bepis", name) - ui.open() - RefreshParts() - if(isliving(user)) - var/mob/living/customer = user - account = customer.get_bank_account() - -/obj/machinery/rnd/bepis/ui_data(mob/user) - var/list/data = list() - var/powered = FALSE - var/zvalue = ((banking_amount + banked_cash) - (major_threshold - positive_cash_offset - negative_cash_offset))/(std) - var/std_success = 0 - var/prob_success = 0 - //Admittedly this is messy, but not nearly as messy as the alternative, which is jury-rigging an entire Z-table into the code, or making an adaptive z-table. - var/z = abs(zvalue) - if(z > 0 && z <= 0.5) - std_success = 19.1 - else if(z > 0.5 && z <= 1.0) - std_success = 34.1 - else if(z > 1.0 && z <= 1.5) - std_success = 43.3 - else if(z > 1.5 && z <= 2.0) - std_success = 47.7 - else if(z > 2.0 && z <= 2.5) - std_success = 49.4 - else - std_success = 50 - if(zvalue > 0) - prob_success = 50 + std_success - else if(zvalue == 0) - prob_success = 50 - else - prob_success = 50 - std_success - - if(use_power == ACTIVE_POWER_USE) - powered = TRUE - data["account_owner"] = account_name - data["amount"] = banking_amount - data["stored_cash"] = account?.account_balance - data["mean_value"] = (major_threshold - positive_cash_offset - negative_cash_offset) - data["error_name"] = error_cause - data["power_saver"] = power_saver - data["accuracy_percentage"] = inaccuracy_percentage * 100 - data["positive_cash_offset"] = positive_cash_offset - data["negative_cash_offset"] = negative_cash_offset - data["manual_power"] = powered ? FALSE : TRUE - data["silicon_check"] = issilicon(user) - data["success_estimate"] = prob_success - return data - -/obj/machinery/rnd/bepis/ui_act(action,params) - . = ..() - if(.) - return - switch(action) - if("begin_experiment") - if(use_power == IDLE_POWER_USE) - return - depositcash() - if(banked_cash == 0) - say("Please select funds to deposit to begin testing.") - return - calcsuccess() - use_power(MACHINE_OPERATION * power_saver) //This thing should eat your APC battery if you're not careful. - update_use_power(IDLE_POWER_USE) //Machine shuts off after use to prevent spam and look better visually. - update_appearance() - if("amount") - var/input = text2num(params["amount"]) - if(input) - banking_amount = input - if("toggle_power") - if(use_power == ACTIVE_POWER_USE) - update_use_power(IDLE_POWER_USE) - else - update_use_power(ACTIVE_POWER_USE) - update_appearance() - if("account_reset") - if(use_power == IDLE_POWER_USE) - return - account_name = "" - account = null - say("Account settings reset.") - . = TRUE - -/** - * Proc that handles the user's account to deposit credits for the BEPIS. - * Handles success and fail cases for transferring credits, then logs the transaction and uses small amounts of power. - **/ -/obj/machinery/rnd/bepis/proc/depositcash() - var/deposit_value = 0 - deposit_value = banking_amount - if(deposit_value == 0) - update_appearance() - say("Attempting to deposit 0 credits. Aborting.") - return - deposit_value = clamp(round(deposit_value, 1), 1, 10000) - if(!account) - say("Cannot find user account. Please swipe a valid ID.") - return - if(!account.has_money(deposit_value)) - say("You do not possess enough credits.") - return - account.adjust_money(-deposit_value, "Vending: B.E.P.I.S. Chamber") //The money vanishes, not paid to any accounts. - SSblackbox.record_feedback("amount", "BEPIS_credits_spent", deposit_value) - log_econ("[deposit_value] credits were inserted into [src] by [account.account_holder]") - banked_cash += deposit_value - use_power(1000 * power_saver) - return - -/** - * Proc used to determine the experiment math and results all in one. - * Uses banked_cash and stock part levels to determine minor, major, and real gauss values for the BEPIS to hold. - * If by the end real is larger than major, You get a tech disk. If all the disks are earned or you at least beat minor, you get a minor reward. - **/ - -/obj/machinery/rnd/bepis/proc/calcsuccess() - var/turf/dropturf = null - var/gauss_major = 0 - var/gauss_minor = 0 - var/gauss_real = 0 - - var/turf/my_turf = get_turf(src) - var/list/turfs = TURF_NEIGHBORS(my_turf) //NO MORE DISCS IN WINDOWS - while(length(turfs)) - var/turf/T = pick_n_take(turfs) - if(T.is_blocked_turf(TRUE)) - continue - else - dropturf = T - break - - if (!dropturf) - dropturf = drop_location() - gauss_major = (gaussian(major_threshold, std) - negative_cash_offset) //This is the randomized profit value that this experiment has to surpass to unlock a tech. - gauss_minor = (gaussian(minor_threshold, std) - negative_cash_offset) //And this is the threshold to instead get a minor prize. - gauss_real = (gaussian(banked_cash, std*inaccuracy_percentage) + positive_cash_offset) //this is the randomized profit value that your experiment expects to give. - say("Real: [gauss_real]. Minor: [gauss_minor]. Major: [gauss_major].") - flick("chamber_flash",src) - update_appearance() - banked_cash = 0 - if((gauss_real >= gauss_major)) //Major Success. - if(SSresearch.techweb_nodes_experimental.len > 0) - say("Experiment concluded with major success. New technology node discovered on technology disc.") - new /obj/item/disk/design_disk/bepis/remove_tech(dropturf,1) - return - say("Expended all available experimental technology nodes. Resorting to minor rewards.") - if(gauss_real >= gauss_minor) //Minor Success. - var/reward = pick(minor_rewards) - new reward(dropturf) - say("Experiment concluded with partial success. Dispensing compiled research efforts.") - return - if(gauss_real <= -1) //Critical Failure - say("ERROR: CRITICAL MACHIME MALFUNCTI- ON. CURRENCY IS NOT CRASH. CANNOT COMPUTE COMMAND: 'make bucks'") //not a typo, for once. - new /mob/living/basic/deer(dropturf, 1) - use_power(MACHINE_OVERLOAD * power_saver) //To prevent gambling at low cost and also prevent spamming for infinite deer. - return - //Minor Failure - error_cause = pick("attempted to sell grey products to American dominated market.","attempted to sell gray products to British dominated market.","placed wild assumption that PDAs would go out of style.","simulated product #76 damaged brand reputation mortally.","simulated business model resembled 'pyramid scheme' by 98.7%.","product accidently granted override access to all station doors.") - say("Experiment concluded with zero product viability. Cause of error: [error_cause]") - return - - -#undef MACHINE_OPERATION -#undef MACHINE_OVERLOAD -#undef MAJOR_THRESHOLD -#undef MINOR_THRESHOLD -#undef STANDARD_DEVIATION -#undef PART_CASH_OFFSET_AMOUNT diff --git a/code/modules/research/designs/autolathe/service_designs.dm b/code/modules/research/designs/autolathe/service_designs.dm index ea65fe3ef380e2..687e85d64361bb 100644 --- a/code/modules/research/designs/autolathe/service_designs.dm +++ b/code/modules/research/designs/autolathe/service_designs.dm @@ -142,6 +142,18 @@ ) departmental_flags = DEPARTMENT_BITFLAG_SERVICE +/datum/design/tongs + name = "Tongs" + id = "tongs" + build_type = AUTOLATHE | PROTOLATHE | AWAY_LATHE + materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT * 2) + build_path = /obj/item/kitchen/tongs + category = list( + RND_CATEGORY_INITIAL, + RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_KITCHEN, + ) + departmental_flags = DEPARTMENT_BITFLAG_SERVICE + /datum/design/tray name = "Serving Tray" id = "servingtray" diff --git a/code/modules/research/designs/machine_designs.dm b/code/modules/research/designs/machine_designs.dm index 1c44e8bc4fb268..3b0bf62c267816 100644 --- a/code/modules/research/designs/machine_designs.dm +++ b/code/modules/research/designs/machine_designs.dm @@ -358,16 +358,6 @@ ) departmental_flags = DEPARTMENT_BITFLAG_SCIENCE -/datum/design/board/bepis - name = "B.E.P.I.S. Board" - desc = "The circuit board for a B.E.P.I.S." - id = "bepis" - build_path = /obj/item/circuitboard/machine/bepis - category = list( - RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_RESEARCH - ) - departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_CARGO - /datum/design/board/protolathe name = "Protolathe Board" desc = "The circuit board for a protolathe." @@ -542,6 +532,16 @@ ) departmental_flags = DEPARTMENT_BITFLAG_SERVICE +/datum/design/board/microwave_engineering + name = "Wireless Microwave Board" + desc = "The circuit board for a cell-powered microwave." + id = "microwave_engineering" + build_path = /obj/item/circuitboard/machine/microwave/engineering + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_KITCHEN + ) + departmental_flags = DEPARTMENT_BITFLAG_SERVICE | DEPARTMENT_BITFLAG_ENGINEERING + /datum/design/board/gibber name = "Gibber Board" desc = "The circuit board for a gibber." @@ -1106,3 +1106,13 @@ RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_ROBOTICS ) departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_ENGINEERING + +/datum/design/board/fishing_portal_generator + name = "Fishing Portal Generator Board" + desc = "The circuit board for the fishing portal generator" + id = "fishing_portal_generator" + build_path = /obj/item/circuitboard/machine/fishing_portal_generator + category = list( + RND_CATEGORY_MACHINE + RND_SUBCATEGORY_MACHINE_SERVICE + ) + departmental_flags = DEPARTMENT_BITFLAG_SERVICE | DEPARTMENT_BITFLAG_CARGO | DEPARTMENT_BITFLAG_SCIENCE diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm index 521504da351d0b..8a06607ec59a84 100644 --- a/code/modules/research/techweb/_techweb.dm +++ b/code/modules/research/techweb/_techweb.dm @@ -283,7 +283,7 @@ var/datum/experiment/experiment = completed_experiment if (experiment == experiment_type) return FALSE - available_experiments += new experiment_type() + available_experiments += new experiment_type(src) /** * Adds a list of experiments to this techweb by their types, ensures that no duplicates are added. @@ -310,13 +310,21 @@ var/refund = skipped_experiment_types[completed_experiment.type] || 0 if(refund > 0) add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = refund)) - result_text += ", refunding [refund] points." + result_text += ", refunding [refund] points" // Nothing more to gain here, but we keep it in the list to prevent double dipping skipped_experiment_types[completed_experiment.type] = -1 - else - result_text += "!" - - log_research("[completed_experiment.name] ([completed_experiment.type]) has been completed on techweb [id]/[organization][refund ? ", refunding [refund] points" : ""].") + var/points_rewarded + if(completed_experiment.points_reward) + add_point_list(completed_experiment.points_reward) + points_rewarded = ",[refund > 0 ? " and" : ""] rewarding " + var/list/english_list_keys = list() + for(var/points_type in completed_experiment.points_reward) + english_list_keys += "[completed_experiment.points_reward[points_type]] [points_type]" + points_rewarded += "[english_list(english_list_keys)] points" + result_text += points_rewarded + result_text += "!" + + log_research("[completed_experiment.name] ([completed_experiment.type]) has been completed on techweb [id]/[organization][refund ? ", refunding [refund] points" : ""][points_rewarded].") return result_text /datum/techweb/proc/printout_points() diff --git a/code/modules/research/techweb/_techweb_node.dm b/code/modules/research/techweb/_techweb_node.dm index 2f01252548a21c..ae50ea7f65f9e6 100644 --- a/code/modules/research/techweb/_techweb_node.dm +++ b/code/modules/research/techweb/_techweb_node.dm @@ -16,7 +16,7 @@ var/description = "Why are you seeing this?" /// Whether it starts off hidden var/hidden = FALSE - /// If the tech can be randomly generated by the BEPIS as a reward. MEant to be fully given in tech disks, not researched + /// If the tech can be randomly generated by BEPIS tech as a reward. Meant to be fully given in tech disks, not researched var/experimental = FALSE /// Whether it's available without any research var/starting_node = FALSE diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 3f64efe851eae8..441e6f0038b5e7 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -14,7 +14,6 @@ "basic_matter_bin", "basic_micro_laser", "basic_scanning", - "bepis", "blast", "bounced_radio", "bowl", @@ -50,6 +49,7 @@ "extinguisher", "fax", "fishing_rod", + "fishing_portal_generator", "flashlight", "fluid_ducts", "foam_dart", @@ -115,6 +115,7 @@ "titaniumglass", "toner_large", "toner", + "tongs", "toy_armblade", "toy_balloon", "toygun", @@ -475,6 +476,7 @@ "gibber", "griddle", "microwave", + "microwave_engineering", "monkey_recycler", "oven", "processor", @@ -1491,6 +1493,19 @@ required_experiments = list(/datum/experiment/scanning/random/plants/wild) discount_experiments = list(/datum/experiment/scanning/random/plants/traits = 3000) +/datum/techweb_node/fishing + id = "fishing" + display_name = "Fishing Technology" + description = "Cutting edge fishing advancements." + prereq_ids = list("base") + design_ids = list( + "fishing_rod_tech", + "stabilized_hook", + "fish_analyzer", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2000) + required_experiments = list(/datum/experiment/scanning/fish) + /datum/techweb_node/exp_tools id = "exp_tools" display_name = "Experimental Tools" @@ -2355,20 +2370,6 @@ hidden = TRUE experimental = TRUE -/datum/techweb_node/fishing - id = "fishing" - display_name = "Fishing Technology" - description = "Cutting edge fishing advancements." - prereq_ids = list("base") - design_ids = list( - "fishing_rod_tech", - "stabilized_hook", - "fish_analyzer", - ) - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) - hidden = TRUE - experimental = TRUE - /datum/techweb_node/advanced_plastic_surgery id = "plastic_surgery" display_name = "Advanced Plastic Surgery" diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 5c6ff3c811a6f1..6d4d6a7b27200b 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -173,10 +173,13 @@ alert_type = /atom/movable/screen/alert/status_effect/clone_decay /datum/status_effect/slime_clone_decay/tick(seconds_between_ticks) - owner.adjustToxLoss(1, 0) - owner.adjustOxyLoss(1, 0) - owner.adjustBruteLoss(1, 0) - owner.adjustFireLoss(1, 0) + var/need_mob_update + need_mob_update = owner.adjustToxLoss(1, updating_health = FALSE) + need_mob_update += owner.adjustOxyLoss(1, updating_health = FALSE) + need_mob_update += owner.adjustBruteLoss(1, updating_health = FALSE) + need_mob_update += owner.adjustFireLoss(1, updating_health = FALSE) + if(need_mob_update) + owner.updatehealth() owner.color = "#007BA7" /atom/movable/screen/alert/status_effect/bloodchill @@ -505,20 +508,24 @@ /datum/status_effect/stabilized/purple/tick(seconds_between_ticks) healed_last_tick = FALSE + var/need_mob_update = FALSE if(owner.getBruteLoss() > 0) - owner.adjustBruteLoss(-0.2) + need_mob_update += owner.adjustBruteLoss(-0.2, updating_health = FALSE) healed_last_tick = TRUE if(owner.getFireLoss() > 0) - owner.adjustFireLoss(-0.2) + need_mob_update += owner.adjustFireLoss(-0.2, updating_health = FALSE) healed_last_tick = TRUE if(owner.getToxLoss() > 0) // Forced, so slimepeople are healed as well. - owner.adjustToxLoss(-0.2, forced = TRUE) + need_mob_update += owner.adjustToxLoss(-0.2, updating_health = FALSE, forced = TRUE) healed_last_tick = TRUE + if(need_mob_update) + owner.updatehealth() + // Technically, "healed this tick" by now. if(healed_last_tick) new /obj/effect/temp_visual/heal(get_turf(owner), "#FF0000") diff --git a/code/modules/research/xenobiology/crossbreeding/consuming.dm b/code/modules/research/xenobiology/crossbreeding/consuming.dm index 007bacf8bb785f..ec90edd6550bf3 100644 --- a/code/modules/research/xenobiology/crossbreeding/consuming.dm +++ b/code/modules/research/xenobiology/crossbreeding/consuming.dm @@ -120,12 +120,15 @@ Consuming extracts: taste = "fruit jam and cough medicine" /obj/item/slime_cookie/purple/do_effect(mob/living/M, mob/user) - M.adjustBruteLoss(-5) - M.adjustFireLoss(-5) - M.adjustToxLoss(-5, forced=1) //To heal slimepeople. - M.adjustOxyLoss(-5) - M.adjustCloneLoss(-5) - M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -5) + var/need_mob_update = FALSE + need_mob_update += M.adjustBruteLoss(-5, updating_health = FALSE) + need_mob_update += M.adjustFireLoss(-5, updating_health = FALSE) + need_mob_update += M.adjustToxLoss(-5, updating_health = FALSE, forced = TRUE) //To heal slimepeople. + need_mob_update += M.adjustOxyLoss(-5, updating_health = FALSE) + need_mob_update += M.adjustCloneLoss(-5, updating_health = FALSE) + need_mob_update += M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -5) + if(need_mob_update) + M.updatehealth() /obj/item/slimecross/consuming/blue colour = SLIME_TYPE_BLUE diff --git a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm index ece96fd41e04c1..0152b343c45dfd 100644 --- a/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm +++ b/code/modules/research/xenobiology/vatgrowing/samples/cell_lines/common.dm @@ -263,7 +263,7 @@ /datum/reagent/medicine/psicodine = -2) //Blob zombies likely wouldn't appreciate psicodine so why this is here virus_suspectibility = 0 - resulting_atoms = list(/mob/living/simple_animal/hostile/blob/blobspore/independent = 2) //These are useless so we might as well spawn 2. + resulting_atoms = list(/mob/living/basic/blob_minion/spore = 2) //These are useless so we might as well spawn 2. /datum/micro_organism/cell_line/blobbernaut desc = "Blobular myocytes" @@ -282,7 +282,7 @@ suppressive_reagents = list(/datum/reagent/consumable/tinlux = -6) virus_suspectibility = 0 - resulting_atoms = list(/mob/living/simple_animal/hostile/blob/blobbernaut/independent = 1) + resulting_atoms = list(/mob/living/basic/blob_minion/blobbernaut = 1) /datum/micro_organism/cell_line/gelatinous_cube desc = "Cubic ooze particles" diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index f81f328c0f3593..b3945fe60c437e 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -460,7 +460,7 @@ to_chat(user, span_userdanger("You explode!")) explosion(user, devastation_range = 1, heavy_impact_range = 3, light_impact_range = 6, explosion_cause = src) user.investigate_log("has been gibbed by an oil slime extract explosion.", INVESTIGATE_DEATHS) - user.gib() + user.gib(DROP_ALL_REMAINS) return to_chat(user, span_notice("You stop feeding [src], and the feeling passes.")) diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm index 21664265b6812d..33bbdd76f29c1b 100644 --- a/code/modules/security_levels/keycard_authentication.dm +++ b/code/modules/security_levels/keycard_authentication.dm @@ -59,11 +59,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/keycard_auth, 26) /obj/machinery/keycard_auth/ui_status(mob/user) if(isdrone(user)) return UI_CLOSE - if(!isanimal(user)) + if(!isanimal_or_basicmob(user)) return ..() - var/mob/living/simple_animal/A = user - if(!A.dextrous) - to_chat(user, span_warning("You are too primitive to use this device!")) + if(!HAS_TRAIT(user, TRAIT_CAN_HOLD_ITEMS)) + balloon_alert(user, "no hands!") return UI_CLOSE return ..() diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index ca49d5792725fb..7c8b26b5d16bfc 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -35,7 +35,7 @@ All ShuttleMove procs go here SSblackbox.record_feedback("tally", "shuttle_gib", 1, M.type) log_shuttle("[key_name(M)] was shuttle gibbed by [shuttle].") M.investigate_log("has been gibbed by [shuttle].", INVESTIGATE_DEATHS) - M.gib() + M.gib(DROP_ALL_REMAINS) else //non-living mobs shouldn't be affected by shuttles, which is why this is an else diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 4ae1c241d06f37..e11e6bf9156f01 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -239,6 +239,9 @@ for(var/turf/T in return_turfs()) T.turf_flags |= NO_RUINS + if(SSshuttle.initialized) + INVOKE_ASYNC(SSshuttle, TYPE_PROC_REF(/datum/controller/subsystem/shuttle, setup_shuttles), list(src)) + #ifdef DOCKING_PORT_HIGHLIGHT highlight("#f00") #endif diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 44c13e39c76c2c..cdabfdc4926407 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -322,5 +322,17 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list( new /obj/structure/closet/crate/mail/economy(pick(empty_turfs)) +/// Takes a supply pack, returns the amount we currently have on order (or OVER_ORDER_LIMIT if we are over the hardcap on orders of this type) +/obj/docking_port/mobile/supply/proc/get_order_count(datum/supply_pack/ordering) + var/similar_count = 0 + for(var/datum/supply_order/order as anything in (SSshuttle.shopping_list | SSshuttle.request_list)) + if(order.pack == ordering) + similar_count += 1 + + if(similar_count >= CARGO_MAX_ORDER) + return OVER_ORDER_LIMIT + + return similar_count + #undef GOODY_FREE_SHIPPING_MAX #undef CRATE_TAX diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm index 966f618376d781..5bc39b389b315d 100644 --- a/code/modules/spells/spell.dm +++ b/code/modules/spells/spell.dm @@ -140,7 +140,7 @@ // Where the cast chain starts /datum/action/cooldown/spell/PreActivate(atom/target) - if(SEND_SIGNAL(owner, COMSIG_MOB_ABILITY_STARTED, src) & COMPONENT_BLOCK_ABILITY_START) + if(SEND_SIGNAL(owner, COMSIG_MOB_ABILITY_STARTED, src, target) & COMPONENT_BLOCK_ABILITY_START) return FALSE if(target == owner) target = get_caster_from_target(target) @@ -180,11 +180,6 @@ to_chat(owner, span_warning("Some form of antimagic is preventing you from casting [src]!")) return FALSE - if(!(spell_requirements & SPELL_CASTABLE_WHILE_PHASED) && HAS_TRAIT(owner, TRAIT_MAGICALLY_PHASED)) - if(feedback) - to_chat(owner, span_warning("[src] cannot be cast unless you are completely manifested in the material plane!")) - return FALSE - if(!try_invoke(owner, feedback = feedback)) return FALSE diff --git a/code/modules/spells/spell_types/conjure/simian.dm b/code/modules/spells/spell_types/conjure/simian.dm index 556a78e50127c4..aa9aabc681009d 100644 --- a/code/modules/spells/spell_types/conjure/simian.dm +++ b/code/modules/spells/spell_types/conjure/simian.dm @@ -14,14 +14,18 @@ invocation_type = INVOCATION_SHOUT summon_radius = 2 - summon_type = list(/mob/living/carbon/human/species/monkey/angry, /mob/living/carbon/human/species/monkey/angry, /mob/living/simple_animal/hostile/gorilla/lesser) + summon_type = list( + /mob/living/basic/gorilla/lesser, + /mob/living/carbon/human/species/monkey/angry, + /mob/living/carbon/human/species/monkey/angry, // Listed twice so it's twice as likely, this class doesn't use pick weight + ) summon_amount = 4 /datum/action/cooldown/spell/conjure/simian/level_spell(bypass_cap) . = ..() summon_amount++ // MORE, MOOOOORE if(spell_level == spell_max_level) // We reward the faithful. - summon_type = list(/mob/living/carbon/human/species/monkey/angry, /mob/living/simple_animal/hostile/gorilla) + summon_type = list(/mob/living/carbon/human/species/monkey/angry, /mob/living/basic/gorilla) spell_requirements = SPELL_REQUIRES_NO_ANTIMAGIC // Max level lets you cast it naked, for monkey larp. to_chat(owner, span_notice("Your simian power has reached maximum capacity! You can now cast this spell naked, and you will create adult Gorillas with each cast.")) diff --git a/code/modules/spells/spell_types/jaunt/_jaunt.dm b/code/modules/spells/spell_types/jaunt/_jaunt.dm index 4a94f03c0410aa..207a7ed8b5be48 100644 --- a/code/modules/spells/spell_types/jaunt/_jaunt.dm +++ b/code/modules/spells/spell_types/jaunt/_jaunt.dm @@ -62,7 +62,7 @@ var/obj/effect/dummy/phased_mob/jaunt = new jaunt_type(loc_override || get_turf(jaunter), jaunter) RegisterSignal(jaunt, COMSIG_MOB_EJECTED_FROM_JAUNT, PROC_REF(on_jaunt_exited)) - spell_requirements |= SPELL_CASTABLE_WHILE_PHASED + check_flags &= ~AB_CHECK_PHASED jaunter.add_traits(list(TRAIT_MAGICALLY_PHASED, TRAIT_RUNECHAT_HIDDEN, TRAIT_WEATHER_IMMUNE), REF(src)) // Don't do the feedback until we have runechat hidden. // Otherwise the text will follow the jaunt holder, which reveals where our caster is travelling. @@ -106,7 +106,7 @@ */ /datum/action/cooldown/spell/jaunt/proc/on_jaunt_exited(obj/effect/dummy/phased_mob/jaunt, mob/living/unjaunter) SHOULD_CALL_PARENT(TRUE) - spell_requirements &= ~SPELL_CASTABLE_WHILE_PHASED + check_flags |= AB_CHECK_PHASED unjaunter.remove_traits(list(TRAIT_MAGICALLY_PHASED, TRAIT_RUNECHAT_HIDDEN, TRAIT_WEATHER_IMMUNE), REF(src)) // This needs to happen at the end, after all the traits and stuff is handled SEND_SIGNAL(unjaunter, COMSIG_MOB_AFTER_EXIT_JAUNT, src) diff --git a/code/modules/spells/spell_types/self/basic_heal.dm b/code/modules/spells/spell_types/self/basic_heal.dm index 135b80942062da..f68403ddeeb3f2 100644 --- a/code/modules/spells/spell_types/self/basic_heal.dm +++ b/code/modules/spells/spell_types/self/basic_heal.dm @@ -26,5 +26,8 @@ span_warning("A wreath of gentle light passes over [cast_on]!"), span_notice("You wreath yourself in healing light!"), ) - cast_on.adjustBruteLoss(-brute_to_heal, FALSE) - cast_on.adjustFireLoss(-burn_to_heal) + var/need_mob_update = FALSE + need_mob_update += cast_on.adjustBruteLoss(-brute_to_heal, updating_health = FALSE) + need_mob_update += cast_on.adjustFireLoss(-burn_to_heal, updating_health = FALSE) + if(need_mob_update) + cast_on.updatehealth() diff --git a/code/modules/spells/spell_types/self/splattercasting_spell.dm b/code/modules/spells/spell_types/self/splattercasting_spell.dm index 1af0cacd2aa741..184a2afab7ca23 100644 --- a/code/modules/spells/spell_types/self/splattercasting_spell.dm +++ b/code/modules/spells/spell_types/self/splattercasting_spell.dm @@ -29,6 +29,7 @@ merely a vessel for the arcane flow. Soon, all that is left is not pain, but hunger.")) cast_on.set_species(/datum/species/vampire) + cast_on.blood_volume = BLOOD_VOLUME_NORMAL ///for predictable blood total amounts when the spell is first cast. cast_on.AddComponent(/datum/component/splattercasting) diff --git a/code/modules/spells/spell_types/shapeshift/_shape_status.dm b/code/modules/spells/spell_types/shapeshift/_shape_status.dm index 10d42760c91b9d..94e1d549af2680 100644 --- a/code/modules/spells/spell_types/shapeshift/_shape_status.dm +++ b/code/modules/spells/spell_types/shapeshift/_shape_status.dm @@ -115,7 +115,7 @@ // Our caster inside was gibbed, mirror the gib to our mob if(gibbed) - owner.gib() + owner.gib(DROP_ALL_REMAINS) // Otherwise our caster died, just make our mob die else diff --git a/code/modules/spells/spell_types/shapeshift/_shapeshift.dm b/code/modules/spells/spell_types/shapeshift/_shapeshift.dm index 8acd6ca92475e4..5aecd863bce43c 100644 --- a/code/modules/spells/spell_types/shapeshift/_shapeshift.dm +++ b/code/modules/spells/spell_types/shapeshift/_shapeshift.dm @@ -132,7 +132,7 @@ // Gib our caster, and make sure to leave nothing behind // (If we leave something behind, it'll drop on the turf of the pipe, which is kinda wrong.) cast_on.investigate_log("has been gibbed by shapeshifting while ventcrawling.", INVESTIGATE_DEATHS) - cast_on.gib(TRUE, TRUE, TRUE) + cast_on.gib() /// Callback for the radial that allows the user to choose their species. /datum/action/cooldown/spell/shapeshift/proc/check_menu(mob/living/caster) @@ -159,6 +159,12 @@ spell_requirements &= ~(SPELL_REQUIRES_HUMAN|SPELL_REQUIRES_WIZARD_GARB) ADD_TRAIT(new_shape, TRAIT_DONT_WRITE_MEMORY, SHAPESHIFT_TRAIT) // If you shapeshift into a pet subtype we don't want to update Poly's deathcount or something when you die + // Make sure that if you shapechanged into a bot, the AI can't just turn you off. + var/mob/living/simple_animal/bot/polymorph_bot = new_shape + if (istype(polymorph_bot)) + polymorph_bot.bot_cover_flags |= BOT_COVER_EMAGGED + polymorph_bot.bot_mode_flags &= ~BOT_MODE_REMOTE_ENABLED + return new_shape /// Actually does the un-shapeshift, from the caster. (Caster is a shapeshifted mob.) diff --git a/code/modules/spells/spell_types/touch/smite.dm b/code/modules/spells/spell_types/touch/smite.dm index bcd234979c6620..f02ea8247dd227 100644 --- a/code/modules/spells/spell_types/touch/smite.dm +++ b/code/modules/spells/spell_types/touch/smite.dm @@ -48,7 +48,7 @@ return TRUE victim.investigate_log("has been gibbed by the smite spell.", INVESTIGATE_DEATHS) - victim.gib() + victim.gib(DROP_ALL_REMAINS) return TRUE /obj/item/melee/touch_attack/smite diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 4b9c0114024456..f033c081eadb92 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -152,7 +152,7 @@ /// How much generic bleedstacks we have on this bodypart var/generic_bleedstacks /// If we have a gauze wrapping currently applied (not including splints) - var/obj/item/stack/current_gauze + var/obj/item/stack/medical/gauze/current_gauze /// If something is currently grasping this bodypart and trying to staunch bleeding (see [/obj/item/hand_item/self_grasp]) var/obj/item/hand_item/self_grasp/grasped_by @@ -215,7 +215,6 @@ wound_resistance = reset_fantasy_variable("wound_resistance", wound_resistance) return ..() - /obj/item/bodypart/Initialize(mapload) . = ..() if(can_be_disabled) @@ -349,7 +348,6 @@ var/stuck_word = embedded_thing.isEmbedHarmless() ? "stuck" : "embedded" check_list += "\t There is \a [embedded_thing] [stuck_word] in your [name]!" - /obj/item/bodypart/blob_act() receive_damage(max_damage, wound_bonus = CANT_WOUND) @@ -408,10 +406,10 @@ var/atom/drop_loc = drop_location() if(IS_ORGANIC_LIMB(src)) playsound(drop_loc, 'sound/misc/splort.ogg', 50, TRUE, -1) - seep_gauze(9999) // destroy any existing gauze if any exists - for(var/obj/item/organ/bodypart_organ in get_organs()) + QDEL_NULL(current_gauze) + for(var/obj/item/organ/bodypart_organ as anything in get_organs()) bodypart_organ.transfer_to_limb(src, owner) - for(var/obj/item/organ/external/external in external_organs) + for(var/obj/item/organ/external/external as anything in external_organs) external.remove_from_limb() external.forceMove(drop_loc) for(var/obj/item/item_in_bodypart in src) @@ -456,16 +454,20 @@ * attack_direction - The direction the bodypart is attacked from, used to send blood flying in the opposite direction. * damage_source - The source of damage, typically a weapon. */ -/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, blocked = 0, updating_health = TRUE, required_bodytype = null, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, damage_source) +/obj/item/bodypart/proc/receive_damage(brute = 0, burn = 0, blocked = 0, updating_health = TRUE, forced = FALSE, required_bodytype = null, wound_bonus = 0, bare_wound_bonus = 0, sharpness = NONE, attack_direction = null, damage_source) SHOULD_CALL_PARENT(TRUE) var/hit_percent = (100-blocked)/100 if((!brute && !burn) || hit_percent <= 0) return FALSE - if(owner && (owner.status_flags & GODMODE)) - return FALSE //godmode - if(required_bodytype && !(bodytype & required_bodytype)) - return FALSE + if (!forced) + if(!isnull(owner)) + if (owner.status_flags & GODMODE) + return FALSE + if (SEND_SIGNAL(owner, COMSIG_CARBON_LIMB_DAMAGED, src, brute, burn) & COMPONENT_PREVENT_LIMB_DAMAGE) + return FALSE + if(required_bodytype && !(bodytype & required_bodytype)) + return FALSE var/dmg_multi = CONFIG_GET(number/damage_multiplier) * hit_percent brute = round(max(brute * dmg_multi * brute_modifier, 0), DAMAGE_PRECISION) @@ -649,10 +651,10 @@ //Heals brute and burn damage for the organ. Returns 1 if the damage-icon states changed at all. //Damage cannot go below zero. //Cannot remove negative damage (i.e. apply damage) -/obj/item/bodypart/proc/heal_damage(brute, burn, required_bodytype, updating_health = TRUE) +/obj/item/bodypart/proc/heal_damage(brute, burn, updating_health = TRUE, forced = FALSE, required_bodytype) SHOULD_CALL_PARENT(TRUE) - if(required_bodytype && !(bodytype & required_bodytype)) //So we can only heal certain kinds of limbs, ie robotic vs organic. + if(!forced && required_bodytype && !(bodytype & required_bodytype)) //So we can only heal certain kinds of limbs, ie robotic vs organic. return if(brute) @@ -674,7 +676,6 @@ cremation_progress = min(0, cremation_progress - ((brute_dam + burn_dam)*(100/max_damage))) return update_bodypart_damage_state() - ///Sets the damage of a bodypart when it is created. /obj/item/bodypart/proc/set_initial_damage(brute_damage, burn_damage) set_brute_dam(brute_damage) @@ -689,7 +690,6 @@ . = brute_dam brute_dam = new_value - ///Proc to hook behavior associated to the change of the burn_dam variable's value. /obj/item/bodypart/proc/set_burn_dam(new_value) PROTECTED_PROC(TRUE) @@ -701,8 +701,7 @@ //Returns total damage. /obj/item/bodypart/proc/get_damage() - var/total = brute_dam + burn_dam - return total + return brute_dam + burn_dam //Checks disabled status thresholds /obj/item/bodypart/proc/update_disabled() @@ -745,7 +744,6 @@ last_maxed = FALSE set_disabled(FALSE) - ///Proc to change the value of the `disabled` variable and react to the event of its change. /obj/item/bodypart/proc/set_disabled(new_disabled) SHOULD_CALL_PARENT(TRUE) @@ -761,7 +759,6 @@ owner.update_health_hud() //update the healthdoll owner.update_body() - ///Proc to change the value of the `owner` variable and react to the event of its change. /obj/item/bodypart/proc/set_owner(new_owner) SHOULD_CALL_PARENT(TRUE) @@ -855,7 +852,6 @@ )) set_disabled(FALSE) - ///Called when TRAIT_PARALYSIS is added to the limb. /obj/item/bodypart/proc/on_paralysis_trait_gain(obj/item/bodypart/source) PROTECTED_PROC(TRUE) @@ -864,7 +860,6 @@ if(can_be_disabled) set_disabled(TRUE) - ///Called when TRAIT_PARALYSIS is removed from the limb. /obj/item/bodypart/proc/on_paralysis_trait_loss(obj/item/bodypart/source) PROTECTED_PROC(TRUE) @@ -873,7 +868,6 @@ if(can_be_disabled) update_disabled() - ///Called when TRAIT_NOLIMBDISABLE is added to the owner. /obj/item/bodypart/proc/on_owner_nolimbdisable_trait_gain(mob/living/carbon/source) PROTECTED_PROC(TRUE) @@ -881,7 +875,6 @@ set_can_be_disabled(FALSE) - ///Called when TRAIT_NOLIMBDISABLE is removed from the owner. /obj/item/bodypart/proc/on_owner_nolimbdisable_trait_loss(mob/living/carbon/source) PROTECTED_PROC(TRUE) @@ -1308,17 +1301,18 @@ * Arguments: * * gauze- Just the gauze stack we're taking a sheet from to apply here */ -/obj/item/bodypart/proc/apply_gauze(obj/item/stack/gauze) - if(!istype(gauze) || !gauze.absorption_capacity) +/obj/item/bodypart/proc/apply_gauze(obj/item/stack/medical/gauze/new_gauze) + if(!istype(new_gauze) || !new_gauze.absorption_capacity) return var/newly_gauzed = FALSE if(!current_gauze) newly_gauzed = TRUE QDEL_NULL(current_gauze) - current_gauze = new gauze.type(src, 1) - gauze.use(1) + current_gauze = new new_gauze.type(src, 1) + new_gauze.use(1) + current_gauze.gauzed_bodypart = src if(newly_gauzed) - SEND_SIGNAL(src, COMSIG_BODYPART_GAUZED, gauze) + SEND_SIGNAL(src, COMSIG_BODYPART_GAUZED, current_gauze, new_gauze) /** * seep_gauze() is for when a gauze wrapping absorbs blood or pus from wounds, lowering its absorption capacity. @@ -1335,7 +1329,6 @@ if(current_gauze.absorption_capacity <= 0) owner.visible_message(span_danger("\The [current_gauze.name] on [owner]'s [name] falls away in rags."), span_warning("\The [current_gauze.name] on your [name] falls away in rags."), vision_distance=COMBAT_MESSAGE_RANGE) QDEL_NULL(current_gauze) - SEND_SIGNAL(src, COMSIG_BODYPART_GAUZE_DESTROYED) ///Loops through all of the bodypart's external organs and update's their color. /obj/item/bodypart/proc/recolor_external_organs() @@ -1383,9 +1376,10 @@ else update_icon_dropped() +// Note: Does NOT return EMP protection value from parent call or pass it on to subtypes /obj/item/bodypart/emp_act(severity) - . = ..() - if(. & EMP_PROTECT_WIRES || !IS_ROBOTIC_LIMB(src)) + var/protection = ..() + if((protection & EMP_PROTECT_WIRES) || !IS_ROBOTIC_LIMB(src)) return FALSE // with defines at the time of writing, this is 2 brute and 1.5 burn @@ -1402,16 +1396,14 @@ burn_damage *= 1.3 // SKYRAT EDIT : Balance - Lowers total damage from ~104 Burn to ~24 receive_damage(brute_damage, burn_damage) - do_sparks(number = 1, cardinal_only = FALSE, source = owner) - var/damage_percent_to_max = (get_damage() / max_damage) - if (time_needed && (damage_percent_to_max >= robotic_emp_paralyze_damage_percent_threshold)) - owner.visible_message(span_danger("[owner]'s [src] seems to malfunction!")) + do_sparks(number = 1, cardinal_only = FALSE, source = owner || src) + + if(can_be_disabled && (get_damage() / max_damage) >= robotic_emp_paralyze_damage_percent_threshold) ADD_TRAIT(src, TRAIT_PARALYSIS, EMP_TRAIT) - addtimer(CALLBACK(src, PROC_REF(un_paralyze)), time_needed) - return TRUE + addtimer(TRAIT_CALLBACK_REMOVE(src, TRAIT_PARALYSIS, EMP_TRAIT), time_needed) + owner?.visible_message(span_danger("[owner]'s [plaintext_zone] seems to malfunction!")) -/obj/item/bodypart/proc/un_paralyze() - REMOVE_TRAITS_IN(src, EMP_TRAIT) + return TRUE /// Returns the generic description of our BIO_EXTERNAL feature(s), prioritizing certain ones over others. Returns error on failure. /obj/item/bodypart/proc/get_external_description() diff --git a/code/modules/surgery/bodyparts/robot_bodyparts.dm b/code/modules/surgery/bodyparts/robot_bodyparts.dm index 37b6cef9897507..99591daaa4b2b2 100644 --- a/code/modules/surgery/bodyparts/robot_bodyparts.dm +++ b/code/modules/surgery/bodyparts/robot_bodyparts.dm @@ -111,15 +111,16 @@ /obj/item/bodypart/leg/left/robot/emp_act(severity) . = ..() - if(!.) + if(!. || isnull(owner)) return + var/knockdown_time = AUGGED_LEG_EMP_KNOCKDOWN_TIME if (severity == EMP_HEAVY) knockdown_time *= 2 owner.Knockdown(knockdown_time) if(owner.incapacitated(IGNORE_RESTRAINTS|IGNORE_GRAB)) // So the message isn't duplicated. If they were stunned beforehand by something else, then the message not showing makes more sense anyways. return - to_chat(owner, span_danger("As your [src] unexpectedly malfunctions, it causes you to fall to the ground!")) + to_chat(owner, span_danger("As your [plaintext_zone] unexpectedly malfunctions, it causes you to fall to the ground!")) /obj/item/bodypart/leg/right/robot name = "cyborg right leg" @@ -156,15 +157,16 @@ /obj/item/bodypart/leg/right/robot/emp_act(severity) . = ..() - if(!.) + if(!. || isnull(owner)) return + var/knockdown_time = AUGGED_LEG_EMP_KNOCKDOWN_TIME if (severity == EMP_HEAVY) knockdown_time *= 2 owner.Knockdown(knockdown_time) if(owner.incapacitated(IGNORE_RESTRAINTS|IGNORE_GRAB)) // So the message isn't duplicated. If they were stunned beforehand by something else, then the message not showing makes more sense anyways. return - to_chat(owner, span_danger("As your [src] unexpectedly malfunctions, it causes you to fall to the ground!")) + to_chat(owner, span_danger("As your [plaintext_zone] unexpectedly malfunctions, it causes you to fall to the ground!")) /obj/item/bodypart/chest/robot name = "cyborg torso" @@ -203,7 +205,7 @@ /obj/item/bodypart/chest/robot/emp_act(severity) . = ..() - if(!.) + if(!. || isnull(owner)) return var/stun_time = 0 @@ -219,7 +221,7 @@ var/damage_percent_to_max = (get_damage() / max_damage) if (stun_time && (damage_percent_to_max >= robotic_emp_paralyze_damage_percent_threshold)) - to_chat(owner, span_danger("Your [src]'s logic boards temporarily become unresponsive!")) + to_chat(owner, span_danger("Your [plaintext_zone]'s logic boards temporarily become unresponsive!")) owner.Stun(stun_time) owner.Shake(pixelshiftx = shift_x, pixelshifty = shift_y, duration = shake_duration) @@ -338,9 +340,10 @@ /obj/item/bodypart/head/robot/emp_act(severity) . = ..() - if(!.) + if(!. || isnull(owner)) return - to_chat(owner, span_danger("Your [src]'s optical transponders glitch out and malfunction!")) + + to_chat(owner, span_danger("Your [plaintext_zone]'s optical transponders glitch out and malfunction!")) var/glitch_duration = AUGGED_HEAD_EMP_GLITCH_DURATION if (severity == EMP_HEAVY) diff --git a/code/modules/surgery/organs/_organ.dm b/code/modules/surgery/organs/_organ.dm index 632e4c8b511ebf..5b78cb30796e75 100644 --- a/code/modules/surgery/organs/_organ.dm +++ b/code/modules/surgery/organs/_organ.dm @@ -6,6 +6,8 @@ throwforce = 0 /// The mob that owns this organ. var/mob/living/carbon/owner = null + /// The cached info about the blood this organ belongs to + var/list/blood_dna_info = list("Synthetic DNA" = "O+") // not every organ spawns inside a person /// The body zone this organ is supposed to inhabit. var/zone = BODY_ZONE_CHEST /** @@ -14,7 +16,7 @@ */ var/slot /// Random flags that describe this organ - var/organ_flags = ORGAN_ORGANIC | ORGAN_EDIBLE + var/organ_flags = ORGAN_ORGANIC | ORGAN_EDIBLE | ORGAN_VIRGIN /// Maximum damage the organ can take, ever. var/maxHealth = STANDARD_ORGAN_THRESHOLD /** @@ -75,6 +77,9 @@ INITIALIZE_IMMEDIATE(/obj/item/organ) volume = reagent_vol,\ after_eat = CALLBACK(src, PROC_REF(OnEatFrom))) + if(!IS_ROBOTIC_ORGAN(src)) + add_blood_DNA(blood_dna_info) + /* * Insert the organ into the select mob. * @@ -100,6 +105,14 @@ INITIALIZE_IMMEDIATE(/obj/item/organ) receiver.organs_slot[slot] = src owner = receiver + if(!IS_ROBOTIC_ORGAN(src) && (organ_flags & ORGAN_VIRGIN)) + blood_dna_info = receiver.get_blood_dna_list() + // need to remove the synethic blood DNA that is initialized + // wash also adds the blood dna again + wash(CLEAN_TYPE_BLOOD) + organ_flags &= ~ORGAN_VIRGIN + + // Apply unique side-effects. Return value does not matter. on_insert(receiver, special) @@ -168,6 +181,9 @@ INITIALIZE_IMMEDIATE(/obj/item/organ) SEND_SIGNAL(src, COMSIG_ORGAN_REMOVED, organ_owner) SEND_SIGNAL(organ_owner, COMSIG_CARBON_LOSE_ORGAN, src, special) + if(!IS_ROBOTIC_ORGAN(src) && !(item_flags & NO_BLOOD_ON_ITEM) && !QDELING(src)) + AddElement(/datum/element/decal/blood) + var/list/diseases = organ_owner.get_static_viruses() if(!LAZYLEN(diseases)) return @@ -228,6 +244,14 @@ INITIALIZE_IMMEDIATE(/obj/item/organ) /obj/item/organ/proc/on_surgical_removal(mob/living/user, mob/living/carbon/old_owner, target_zone, obj/item/tool) SHOULD_CALL_PARENT(TRUE) SEND_SIGNAL(src, COMSIG_ORGAN_SURGICALLY_REMOVED, user, old_owner, target_zone, tool) + RemoveElement(/datum/element/decal/blood) + +/obj/item/organ/wash(clean_types) + . = ..() + + // always add the original dna to the organ after it's washed + if(!IS_ROBOTIC_ORGAN(src) && (clean_types & CLEAN_TYPE_BLOOD)) + add_blood_DNA(blood_dna_info) /obj/item/organ/process(seconds_per_tick, times_fired) return @@ -267,17 +291,18 @@ INITIALIZE_IMMEDIATE(/obj/item/organ) /obj/item/organ/item_action_slot_check(slot,mob/user) return //so we don't grant the organ's action to mobs who pick up the organ. -///Adjusts an organ's damage by the amount "damage_amount", up to a maximum amount, which is by default max damage +///Adjusts an organ's damage by the amount "damage_amount", up to a maximum amount, which is by default max damage. Returns the net change in organ damage. /obj/item/organ/proc/apply_organ_damage(damage_amount, maximum = maxHealth, required_organ_flag = NONE) //use for damaging effects if(!damage_amount) //Micro-optimization. - return + return FALSE maximum = clamp(maximum, 0, maxHealth) // the logical max is, our max if(maximum < damage) - return + return FALSE if(required_organ_flag && !(organ_flags & required_organ_flag)) - return + return FALSE damage = clamp(damage + damage_amount, 0, maximum) - var/mess = check_damage_thresholds(owner) + . = (prev_damage - damage) // return net damage + var/message = check_damage_thresholds(owner) prev_damage = damage if(damage >= maxHealth) @@ -285,8 +310,8 @@ INITIALIZE_IMMEDIATE(/obj/item/organ) else organ_flags &= ~ORGAN_FAILING - if(mess && owner && owner.stat <= SOFT_CRIT) - to_chat(owner, mess) + if(message && owner && owner.stat <= SOFT_CRIT) + to_chat(owner, message) ///SETS an organ's damage to the amount "damage_amount", and in doing so clears or sets the failing flag, good for when you have an effect that should fix an organ if broken /obj/item/organ/proc/set_organ_damage(damage_amount, required_organ_flag = NONE) //use mostly for admin heals diff --git a/code/modules/surgery/organs/internal/appendix/_appendix.dm b/code/modules/surgery/organs/internal/appendix/_appendix.dm index a52479c10a7321..bb02c8b9ef9e9c 100644 --- a/code/modules/surgery/organs/internal/appendix/_appendix.dm +++ b/code/modules/surgery/organs/internal/appendix/_appendix.dm @@ -34,7 +34,7 @@ if(organ_flags & ORGAN_FAILING) // forced to ensure people don't use it to gain tox as slime person - owner.adjustToxLoss(2 * seconds_per_tick, updating_health = TRUE, forced = TRUE) + owner.adjustToxLoss(2 * seconds_per_tick, forced = TRUE) else if(inflamation_stage) inflamation(seconds_per_tick) else if(SPT_PROB(APPENDICITIS_PROB, seconds_per_tick)) @@ -62,7 +62,7 @@ to_chat(organ_owner, span_warning("You feel a stabbing pain in your abdomen!")) organ_owner.adjustOrganLoss(ORGAN_SLOT_APPENDIX, 5) organ_owner.Stun(rand(40, 60)) - organ_owner.adjustToxLoss(1, updating_health = TRUE, forced = TRUE) + organ_owner.adjustToxLoss(1, forced = TRUE) if(3) if(SPT_PROB(0.5, seconds_per_tick)) organ_owner.vomit(VOMIT_CATEGORY_DEFAULT, lost_nutrition = 95) diff --git a/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm b/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm index 60322a7f8d6a98..1ea3a1bf9c4abc 100644 --- a/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm +++ b/code/modules/surgery/organs/internal/cyberimp/augments_chest.dm @@ -52,43 +52,84 @@ slot = ORGAN_SLOT_HEART_AID var/revive_cost = 0 var/reviving = FALSE + /// revival/defibrillation possibility flag that gathered from owner's .can_defib() proc + var/can_defib_owner COOLDOWN_DECLARE(reviver_cooldown) +/obj/item/organ/internal/cyberimp/chest/reviver/on_death(seconds_per_tick, times_fired) + if(isnull(owner)) // owner can be null, on_death() gets called by /obj/item/organ/internal/process() for decay + return + try_heal() // Allows implant to work even on dead people /obj/item/organ/internal/cyberimp/chest/reviver/on_life(seconds_per_tick, times_fired) + try_heal() + +/obj/item/organ/internal/cyberimp/chest/reviver/proc/try_heal() if(reviving) - switch(owner.stat) - if(UNCONSCIOUS, HARD_CRIT, SOFT_CRIT) - addtimer(CALLBACK(src, PROC_REF(heal)), 3 SECONDS) - else - COOLDOWN_START(src, reviver_cooldown, revive_cost) - reviving = FALSE - to_chat(owner, span_notice("Your reviver implant shuts down and starts recharging. It will be ready again in [DisplayTimeText(revive_cost)].")) + if(owner.stat == CONSCIOUS) + COOLDOWN_START(src, reviver_cooldown, revive_cost) + reviving = FALSE + to_chat(owner, span_notice("Your reviver implant shuts down and starts recharging. It will be ready again in [DisplayTimeText(revive_cost)].")) + else + addtimer(CALLBACK(src, PROC_REF(heal)), 3 SECONDS) return if(!COOLDOWN_FINISHED(src, reviver_cooldown) || HAS_TRAIT(owner, TRAIT_SUICIDED)) return - switch(owner.stat) - if(UNCONSCIOUS, HARD_CRIT) - revive_cost = 0 - reviving = TRUE - to_chat(owner, span_notice("You feel a faint buzzing as your reviver implant starts patching your wounds...")) + if(owner.stat != CONSCIOUS) + revive_cost = 0 + reviving = TRUE + to_chat(owner, span_notice("You feel a faint buzzing as your reviver implant starts patching your wounds...")) /obj/item/organ/internal/cyberimp/chest/reviver/proc/heal() + if(can_defib_owner == DEFIB_POSSIBLE) + revive_dead() + can_defib_owner = null + revive_cost += 10 MINUTES // Additional 10 minutes cooldown after revival. + // this check goes after revive_dead() to delay revival a bit + if(owner.stat == DEAD) + can_defib_owner = owner.can_defib() + if(can_defib_owner == DEFIB_POSSIBLE) + owner.notify_ghost_cloning("You are being revived by [src]!") + owner.grab_ghost() + /// boolean that stands for if PHYSICAL damage being patched + var/body_damage_patched = FALSE + var/need_mob_update = FALSE if(owner.getOxyLoss()) - owner.adjustOxyLoss(-5) + need_mob_update += owner.adjustOxyLoss(-5, updating_health = FALSE) revive_cost += 5 if(owner.getBruteLoss()) - owner.adjustBruteLoss(-2) + need_mob_update += owner.adjustBruteLoss(-2, updating_health = FALSE) revive_cost += 40 + body_damage_patched = TRUE if(owner.getFireLoss()) - owner.adjustFireLoss(-2) + need_mob_update += owner.adjustFireLoss(-2, updating_health = FALSE) revive_cost += 40 + body_damage_patched = TRUE if(owner.getToxLoss()) - owner.adjustToxLoss(-1) + need_mob_update += owner.adjustToxLoss(-1, updating_health = FALSE) revive_cost += 40 + if(need_mob_update) + owner.updatehealth() + + if(body_damage_patched && prob(35)) // healing is called every few seconds, not every tick + owner.visible_message(span_warning("[owner]'s body twitches a bit."), span_notice("You feel like something is patching your injured body.")) + + +/obj/item/organ/internal/cyberimp/chest/reviver/proc/revive_dead() + owner.grab_ghost() + + owner.visible_message(span_warning("[owner]'s body convulses a bit.")) + playsound(owner, SFX_BODYFALL, 50, TRUE) + playsound(owner, 'sound/machines/defib_zap.ogg', 75, TRUE, -1) + owner.revive() + owner.emote("gasp") + owner.set_jitter_if_lower(200 SECONDS) + SEND_SIGNAL(owner, COMSIG_LIVING_MINOR_SHOCK) + log_game("[owner] been revived by [src]") + /obj/item/organ/internal/cyberimp/chest/reviver/emp_act(severity) . = ..() diff --git a/code/modules/surgery/organs/internal/eyes/_eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm index aca812a6186f58..05f532ae444f5c 100644 --- a/code/modules/surgery/organs/internal/eyes/_eyes.dm +++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm @@ -187,7 +187,7 @@ /obj/item/organ/internal/eyes/apply_organ_damage(damage_amount, maximum = maxHealth, required_organ_flag) . = ..() if(!owner) - return + return FALSE apply_damaged_eye_effects() /// Applies effects to our owner based on how damaged our eyes are diff --git a/code/modules/surgery/organs/internal/heart/_heart.dm b/code/modules/surgery/organs/internal/heart/_heart.dm index e553f8f130739e..fb97ca7eda00b7 100644 --- a/code/modules/surgery/organs/internal/heart/_heart.dm +++ b/code/modules/surgery/organs/internal/heart/_heart.dm @@ -6,7 +6,7 @@ visual = FALSE zone = BODY_ZONE_CHEST slot = ORGAN_SLOT_HEART - + item_flags = NO_BLOOD_ON_ITEM healing_factor = STANDARD_ORGAN_HEALING decay_factor = 2.5 * STANDARD_ORGAN_DECAY //designed to fail around 6 minutes after death @@ -104,20 +104,12 @@ icon_state = "cursedheart-off" base_icon_state = "cursedheart" decay_factor = 0 - actions_types = list(/datum/action/item_action/organ_action/cursed_heart) - var/last_pump = 0 - var/add_colour = TRUE //So we're not constantly recreating colour datums - /// How long between needed pumps; you can pump one second early var/pump_delay = 3 SECONDS - /// How much blood volume you lose every missed pump, this is a flat amount not a percentage! - var/blood_loss = (BLOOD_VOLUME_NORMAL / 5) // 20% of normal volume, missing five pumps is instant death - - //How much to heal per pump, negative numbers would HURT the player + var/blood_loss = BLOOD_VOLUME_NORMAL * 0.2 var/heal_brute = 0 var/heal_burn = 0 var/heal_oxy = 0 - /obj/item/organ/internal/heart/cursed/attack(mob/living/carbon/human/accursed, mob/living/carbon/human/user, obj/target) if(accursed == user && istype(accursed)) playsound(user,'sound/effects/singlebeat.ogg',40,TRUE) @@ -126,75 +118,13 @@ else return ..() -/// Worker proc that checks logic for if a pump can happen, and applies effects/notifications from doing so -/obj/item/organ/internal/heart/cursed/proc/on_pump(mob/owner) - var/next_pump = last_pump + pump_delay - (1 SECONDS) // pump a second early - if(world.time < next_pump) - to_chat(owner, span_userdanger("Too soon!")) - return - - last_pump = world.time - playsound(owner,'sound/effects/singlebeat.ogg', 40, TRUE) - to_chat(owner, span_notice("Your heart beats.")) - - if(!ishuman(owner)) - return - var/mob/living/carbon/human/accursed = owner - - if(HAS_TRAIT(accursed, TRAIT_NOBLOOD) || !accursed.dna) - return - accursed.blood_volume = min(accursed.blood_volume + (blood_loss * 0.5), BLOOD_VOLUME_MAXIMUM) - accursed.remove_client_colour(/datum/client_colour/cursed_heart_blood) - add_colour = TRUE - accursed.adjustBruteLoss(-heal_brute) - accursed.adjustFireLoss(-heal_burn) - accursed.adjustOxyLoss(-heal_oxy) - -/obj/item/organ/internal/heart/cursed/on_life(seconds_per_tick, times_fired) - if(!owner.client || !ishuman(owner)) // Let's be fair, if you're not here to pump, you're not here to suffer. - last_pump = world.time - return - - if(world.time <= (last_pump + pump_delay)) - return - - var/mob/living/carbon/human/accursed = owner - if(HAS_TRAIT(accursed, TRAIT_NOBLOOD) || !accursed.dna) - return - - accursed.blood_volume = max(accursed.blood_volume - blood_loss, 0) - to_chat(accursed, span_userdanger("You have to keep pumping your blood!")) - if(add_colour) - accursed.add_client_colour(/datum/client_colour/cursed_heart_blood) //bloody screen so real - add_colour = FALSE - /obj/item/organ/internal/heart/cursed/on_insert(mob/living/carbon/accursed) . = ..() - last_pump = world.time // give them time to react - to_chat(accursed, span_userdanger("Your heart has been replaced with a cursed one, you have to pump this one manually otherwise you'll die!")) + accursed.AddComponent(/datum/component/manual_heart, pump_delay = pump_delay, blood_loss = blood_loss, heal_brute = heal_brute, heal_burn = heal_burn, heal_oxy = heal_oxy) /obj/item/organ/internal/heart/cursed/Remove(mob/living/carbon/accursed, special = FALSE) . = ..() - accursed.remove_client_colour(/datum/client_colour/cursed_heart_blood) - -/datum/action/item_action/organ_action/cursed_heart - name = "Pump your blood" - check_flags = NONE - -//You are now brea- pumping blood manually -/datum/action/item_action/organ_action/cursed_heart/Trigger(trigger_flags) - . = ..() - if(!.) - return - - var/obj/item/organ/internal/heart/cursed/cursed_heart = target - if(!istype(cursed_heart)) - CRASH("Cursed heart pump action created on non-cursed heart!") - cursed_heart.on_pump(owner) - -/datum/client_colour/cursed_heart_blood - priority = 100 //it's an indicator you're dying, so it's very high priority - colour = "#FF0000" + qdel(accursed.GetComponent(/datum/component/manual_heart)) /obj/item/organ/internal/heart/cybernetic name = "basic cybernetic heart" diff --git a/code/modules/surgery/organs/internal/heart/heart_ethereal.dm b/code/modules/surgery/organs/internal/heart/heart_ethereal.dm index f29ee2e731df91..bb0b30ddd62869 100644 --- a/code/modules/surgery/organs/internal/heart/heart_ethereal.dm +++ b/code/modules/surgery/organs/internal/heart/heart_ethereal.dm @@ -108,7 +108,7 @@ if(!COOLDOWN_FINISHED(src, crystalize_cooldown) || ethereal.stat != DEAD) return //Should probably not happen, but lets be safe. - if(ismob(location) || isitem(location) || HAS_TRAIT_FROM(src, TRAIT_HUSK, CHANGELING_DRAIN)) //Stops crystallization if they are eaten by a dragon, turned into a legion, consumed by his grace, etc. + if(ismob(location) || isitem(location) || iseffect(location) || HAS_TRAIT_FROM(src, TRAIT_HUSK, CHANGELING_DRAIN)) //Stops crystallization if they are eaten by a dragon, turned into a legion, consumed by his grace, etc. to_chat(ethereal, span_warning("You were unable to finish your crystallization, for obvious reasons.")) stop_crystalization_process(ethereal, FALSE) return diff --git a/code/modules/surgery/organs/internal/liver/liver_skeleton.dm b/code/modules/surgery/organs/internal/liver/liver_skeleton.dm index f9b41741b4a34d..b57afd245f587a 100644 --- a/code/modules/surgery/organs/internal/liver/liver_skeleton.dm +++ b/code/modules/surgery/organs/internal/liver/liver_skeleton.dm @@ -19,8 +19,8 @@ if((. & COMSIG_MOB_STOP_REAGENT_CHECK) || (organ_flags & ORGAN_FAILING)) return if(istype(chem, /datum/reagent/toxin/bonehurtingjuice)) - organ_owner.adjustStaminaLoss(7.5 * REM * seconds_per_tick, 0) - organ_owner.adjustBruteLoss(0.5 * REM * seconds_per_tick, 0) + organ_owner.adjustStaminaLoss(7.5 * REM * seconds_per_tick, updating_stamina = FALSE) + organ_owner.adjustBruteLoss(0.5 * REM * seconds_per_tick, updating_health = FALSE) if(SPT_PROB(10, seconds_per_tick)) switch(rand(1, 3)) if(1) diff --git a/code/modules/surgery/organs/internal/tongue/_tongue.dm b/code/modules/surgery/organs/internal/tongue/_tongue.dm index e34ceb8bd617e5..0dc9a6cfb267de 100644 --- a/code/modules/surgery/organs/internal/tongue/_tongue.dm +++ b/code/modules/surgery/organs/internal/tongue/_tongue.dm @@ -148,7 +148,7 @@ /obj/item/organ/internal/tongue/apply_organ_damage(damage_amount, maximum = maxHealth, required_organ_flag) . = ..() if(!owner) - return + return FALSE apply_tongue_effects() /// Applies effects to our owner based on how damaged our tongue is diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 20ca34d52596b3..dd3a7ec9eff452 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -100,6 +100,7 @@ #include "baseturfs.dm" #include "bespoke_id.dm" #include "binary_insert.dm" +#include "bitrunning.dm" #include "blindness.dm" #include "bloody_footprints.dm" #include "breath.dm" @@ -175,6 +176,8 @@ #include "metabolizing.dm" #include "mindbound_actions.dm" #include "missing_icons.dm" +#include "mob_chains.dm" +#include "mob_damage.dm" #include "mob_faction.dm" #include "mob_spawn.dm" #include "modify_fantasy_variable.dm" diff --git a/code/modules/unit_tests/bitrunning.dm b/code/modules/unit_tests/bitrunning.dm new file mode 100644 index 00000000000000..568eeeed8c1334 --- /dev/null +++ b/code/modules/unit_tests/bitrunning.dm @@ -0,0 +1,15 @@ +/// Ensures settings on vdoms are correct +/datum/unit_test/bitrunner_vdom_settings + +/datum/unit_test/bitrunner_vdom_settings/Run() + var/obj/structure/closet/crate/secure/bitrunning/decrypted/cache = allocate(/obj/structure/closet/crate/secure/bitrunning/decrypted) + + for(var/path in subtypesof(/datum/lazy_template/virtual_domain)) + var/datum/lazy_template/virtual_domain/vdom = new path + TEST_ASSERT_NOTNULL(vdom.key, "[path] should have a key") + TEST_ASSERT_NOTNULL(vdom.map_name, "[path] should have a map name") + + if(!length(vdom.extra_loot)) + continue + + TEST_ASSERT_EQUAL(cache.spawn_loot(vdom.extra_loot), TRUE, "[path] didn't spawn loot. Extra loot should be an associative list") diff --git a/code/modules/unit_tests/fish_unit_tests.dm b/code/modules/unit_tests/fish_unit_tests.dm index 1ef15f8d0f5126..d0d39227f43b73 100644 --- a/code/modules/unit_tests/fish_unit_tests.dm +++ b/code/modules/unit_tests/fish_unit_tests.dm @@ -28,10 +28,10 @@ var/obj/structure/aquarium/traits/aquarium = allocate(/obj/structure/aquarium/traits) TEST_ASSERT(!aquarium.sterile.try_to_reproduce(), "The test aquarium's sterile fish managed to reproduce when it shouldn't have") var/obj/item/fish/crossbreeder_jr = aquarium.crossbreeder.try_to_reproduce() - TEST_ASSERT(crossbreeder_jr, "The test aquarium's crossbreeder fish didn't manage to reproduce when it should have.") + TEST_ASSERT(crossbreeder_jr, "The test aquarium's crossbreeder fish didn't manage to reproduce when it should have") TEST_ASSERT_EQUAL(crossbreeder_jr.type, aquarium.cloner.type, "The test aquarium's crossbreeder fish mated with the wrong type of fish") var/obj/item/fish/cloner_jr = aquarium.cloner.try_to_reproduce() - TEST_ASSERT(cloner_jr, "The test aquarium's cloner fish didn't manage to reproduce when it should have.") + TEST_ASSERT(cloner_jr, "The test aquarium's cloner fish didn't manage to reproduce when it should have") TEST_ASSERT_NOTEQUAL(cloner_jr.type, aquarium.sterile.type, "The test aquarium's cloner fish mated with the sterile fish") ///Checks that fish evolutions work correctly. @@ -41,11 +41,24 @@ var/obj/structure/aquarium/evolution/aquarium = allocate(/obj/structure/aquarium/evolution) var/obj/item/fish/evolve_jr = aquarium.evolve.try_to_reproduce() TEST_ASSERT(evolve_jr, "The test aquarium's evolution fish didn't manage to reproduce when it should have") - TEST_ASSERT_NOTEQUAL(evolve_jr.type, /obj/item/fish/goldfish, "The test aquarium's evolution fish managed to pass the conditions of an impossible evolution.") + TEST_ASSERT_NOTEQUAL(evolve_jr.type, /obj/item/fish/goldfish, "The test aquarium's evolution fish managed to pass the conditions of an impossible evolution") TEST_ASSERT_EQUAL(evolve_jr.type, /obj/item/fish/clownfish, "The test aquarium's evolution fish's offspring isn't of the expected type") TEST_ASSERT(!(/datum/fish_trait/dummy in evolve_jr.fish_traits), "The test aquarium's evolution fish's offspring still has the old trait that ought to be removed by the evolution datum") TEST_ASSERT(/datum/fish_trait/dummy/two in evolve_jr.fish_traits, "The test aquarium's evolution fish's offspring doesn't have the evolution trait") +/datum/unit_test/fish_scanning + +/datum/unit_test/fish_scanning/Run() + var/scannable_fishes = 0 + for(var/obj/item/fish/fish_prototype as anything in subtypesof(/obj/item/fish)) + if(initial(fish_prototype.experisci_scannable)) + scannable_fishes++ + for(var/datum/experiment/scanning/fish/fish_scan as anything in typesof(/datum/experiment/scanning/fish)) + fish_scan = new fish_scan + var/scan_key = fish_scan.required_atoms[1] + if(fish_scan.required_atoms[scan_key] > scannable_fishes) + TEST_FAIL("[fish_scan.type] has requirements higher than the number of scannable fish types in the game: [scannable_fishes]") + ///dummy fish item used for the tests, as well with related subtypes and datums. /obj/item/fish/testdummy grind_results = list() diff --git a/code/modules/unit_tests/heretic_rituals.dm b/code/modules/unit_tests/heretic_rituals.dm index 7298a16327490a..4ac5bce8d3d3a1 100644 --- a/code/modules/unit_tests/heretic_rituals.dm +++ b/code/modules/unit_tests/heretic_rituals.dm @@ -63,6 +63,8 @@ var/list/created_atoms = list() for(var/ritual_item_path in knowledge.required_atoms) var/amount_to_create = knowledge.required_atoms[ritual_item_path] + if(islist(ritual_item_path)) + ritual_item_path = pick(ritual_item_path) for(var/i in 1 to amount_to_create) created_atoms += new ritual_item_path(get_turf(our_heretic)) diff --git a/code/modules/unit_tests/mob_chains.dm b/code/modules/unit_tests/mob_chains.dm new file mode 100644 index 00000000000000..2562019958e46d --- /dev/null +++ b/code/modules/unit_tests/mob_chains.dm @@ -0,0 +1,31 @@ +/// Checks if mobs who are linked together with the mob chain component react as expected +/datum/unit_test/mob_chains + +/datum/unit_test/mob_chains/Run() + var/mob/living/centipede_head = allocate(/mob/living/basic/pet/dog) + var/list/segments = list(centipede_head) + centipede_head.AddComponent(/datum/component/mob_chain) + var/mob/living/centipede_tail = centipede_head + for (var/i in 1 to 2) + var/mob/living/new_segment = allocate(/mob/living/basic/pet/dog) + new_segment.AddComponent(/datum/component/mob_chain, front = centipede_tail) + segments += new_segment + centipede_tail = new_segment + + var/test_damage = 15 + centipede_head.apply_damage(test_damage, BRUTE) + TEST_ASSERT_EQUAL(centipede_head.bruteloss, 0, "Centipede head took damage which should have been passed to its tail.") + TEST_ASSERT_EQUAL(centipede_tail.bruteloss, test_damage, "Centipede tail did not take damage which should have originated from its head.") + + var/expected_damage = 5 + for (var/mob/living/segment as anything in segments) + segment.combat_mode = TRUE + segment.melee_damage_lower = expected_damage + segment.melee_damage_upper = expected_damage + + var/mob/living/victim = allocate(/mob/living/basic/pet/dog) + centipede_head.ClickOn(victim) + TEST_ASSERT_EQUAL(victim.bruteloss, expected_damage * 3, "Centipede failed to do damage with all of its segments.") + + centipede_head.death() + TEST_ASSERT_EQUAL(centipede_tail.stat, DEAD, "Centipede tail failed to die with head.") diff --git a/code/modules/unit_tests/mob_damage.dm b/code/modules/unit_tests/mob_damage.dm new file mode 100644 index 00000000000000..50046141a88b7f --- /dev/null +++ b/code/modules/unit_tests/mob_damage.dm @@ -0,0 +1,622 @@ +/// Tests to make sure mob damage procs are working correctly +/datum/unit_test/mob_damage + priority = TEST_LONGER + +/datum/unit_test/mob_damage/Destroy() + SSmobs.ignite() + return ..() + +/datum/unit_test/mob_damage/Run() + SSmobs.pause() + var/mob/living/carbon/human/dummy = allocate(/mob/living/carbon/human/consistent) + dummy.maxHealth = 200 // tank mode + + /* The sanity tests: here we make sure that: + 1) That damage procs are returning the expected values. They should be returning the actual amount of damage taken/healed. + (Negative values mean damage was taken, positive mean healing) + 2) Verifying that the damage has been accurately applied to the mob afterwards. */ + + test_sanity_simple(dummy) + test_sanity_complex(dummy) + + // Testing if biotypes are working as intended + test_biotypes(dummy) + + // Testing whether or not TRAIT_NOBREATH is working as intended + test_nobreath(dummy) + + // Testing whether or not TRAIT_TOXINLOVER and TRAIT_TOXIMMUNE are working as intended + test_toxintraits(dummy) + + // Testing whether or not TRAIT_NOCLONELOSS is working as intended + test_nocloneloss(dummy) + + // Testing the proc ordered_healing() + test_ordered_healing(dummy) + + // testing with godmode enabled + test_godmode(dummy) + +/** + * Test whether the adjust damage procs return the correct values and that the mob's health is the expected value afterwards. + * + * By default this calls apply_damage(amount) followed by verify_damage(amount_after) and returns TRUE if both succeeded. + * amount_after defaults to the mob's current stamina loss but can be overridden as needed. + * + * Arguments: + * * testing_mob - the mob to apply the damage to + * * amount - the amount of damage to apply to the mob + * * expected - what the expected return value of the damage proc is + * * amount_after - in case you want to specify what the damage amount on the mob should be afterwards + * * included_types - Bitflag of damage types to apply + * * biotypes - the biotypes of damage to apply + * * bodytypes - the bodytypes of damage to apply + * * forced - whether or not this is forced damage + */ +/datum/unit_test/mob_damage/proc/test_apply_damage(mob/living/testing_mob, amount, expected = -amount, amount_after, included_types, biotypes, bodytypes, forced) + if(isnull(amount_after)) + amount_after = testing_mob.getStaminaLoss() - expected // stamina loss applies to both carbon and basic mobs the same way, so that's why we're using it here + if(!apply_damage(testing_mob, amount, expected, included_types, biotypes, bodytypes, forced)) + return FALSE + if(!verify_damage(testing_mob, amount_after, included_types)) + return FALSE + return TRUE + +/** + * Test whether the set damage procs return the correct values and that the mob's health is the expected value afterwards. + * + * By default this calls set_damage(amount) followed by verify_damage(amount_after) and returns TRUE if both succeeded. + * amount_after defaults to the mob's current stamina loss but can be overridden as needed. + * + * Arguments: + * * testing_mob - the mob to apply the damage to + * * amount - the amount of damage to apply to the mob + * * expected - what the expected return value of the damage proc is + * * amount_after - in case you want to specify what the damage amount on the mob should be afterwards + * * included_types - Bitflag of damage types to apply + * * biotypes - the biotypes of damage to apply + * * bodytypes - the bodytypes of damage to apply + * * forced - whether or not this is forced damage + */ +/datum/unit_test/mob_damage/proc/test_set_damage(mob/living/testing_mob, amount, expected, amount_after, included_types, biotypes, bodytypes, forced) + if(isnull(amount_after)) + amount_after = testing_mob.getStaminaLoss() - expected + if(!set_damage(testing_mob, amount, expected, included_types, biotypes, bodytypes, forced)) + return FALSE + if(!verify_damage(testing_mob, amount_after, included_types)) + return FALSE + return TRUE + +/** + * Check that the mob has a specific amount of damage + * + * By default this checks that the mob has of every type of damage. + * Arguments: + * * testing_mob - the mob to check the damage of + * * amount - the amount of damage to verify that the mob has + * * included_types - Bitflag of damage types to check. + */ +/datum/unit_test/mob_damage/proc/verify_damage(mob/living/testing_mob, amount, included_types = ALL) + if(included_types & TOXLOSS) + TEST_ASSERT_EQUAL(testing_mob.getToxLoss(), amount, \ + "[testing_mob] should have [amount] toxin damage, instead they have [testing_mob.getToxLoss()]!") + if(included_types & CLONELOSS) + TEST_ASSERT_EQUAL(testing_mob.getCloneLoss(), amount, \ + "[testing_mob] should have [amount] clone damage, instead they have [testing_mob.getCloneLoss()]!") + if(included_types & BRUTELOSS) + TEST_ASSERT_EQUAL(round(testing_mob.getBruteLoss(), 1), amount, \ + "[testing_mob] should have [amount] brute damage, instead they have [testing_mob.getBruteLoss()]!") + if(included_types & FIRELOSS) + TEST_ASSERT_EQUAL(round(testing_mob.getFireLoss(), 1), amount, \ + "[testing_mob] should have [amount] burn damage, instead they have [testing_mob.getFireLoss()]!") + if(included_types & OXYLOSS) + TEST_ASSERT_EQUAL(testing_mob.getOxyLoss(), amount, \ + "[testing_mob] should have [amount] oxy damage, instead they have [testing_mob.getOxyLoss()]!") + if(included_types & STAMINALOSS) + TEST_ASSERT_EQUAL(testing_mob.getStaminaLoss(), amount, \ + "[testing_mob] should have [amount] stamina damage, instead they have [testing_mob.getStaminaLoss()]!") + return TRUE + +/** + * Apply a specific amount of damage to the mob using adjustBruteLoss(), adjustToxLoss(), etc. + * + * By default this applies damage of every type to the mob, and checks that the damage procs return the value + * Arguments: + * * testing_mob - the mob to apply the damage to + * * amount - the amount of damage to apply to the mob + * * expected - what the expected return value of the damage proc is + * * included_types - Bitflag of damage types to apply + * * biotypes - the biotypes of damage to apply + * * bodytypes - the bodytypes of damage to apply + * * forced - whether or not this is forced damage + */ +/datum/unit_test/mob_damage/proc/apply_damage(mob/living/testing_mob, amount, expected = -amount, included_types = ALL, biotypes = ALL, bodytypes = ALL, forced = FALSE) + var/damage_returned + if(included_types & TOXLOSS) + damage_returned = testing_mob.adjustToxLoss(amount, updating_health = FALSE, forced = forced, required_biotype = biotypes) + TEST_ASSERT_EQUAL(damage_returned, expected, \ + "adjustToxLoss() should have returned [expected], but returned [damage_returned] instead!") + if(included_types & CLONELOSS) + damage_returned = testing_mob.adjustCloneLoss(amount, updating_health = FALSE, forced = forced, required_biotype = biotypes) + TEST_ASSERT_EQUAL(damage_returned, expected, \ + "adjustCloneLoss() should have returned [expected], but returned [damage_returned] instead!") + if(included_types & BRUTELOSS) + damage_returned = round(testing_mob.adjustBruteLoss(amount, updating_health = FALSE, forced = forced, required_bodytype = bodytypes), 1) + TEST_ASSERT_EQUAL(damage_returned, expected, \ + "adjustBruteLoss() should have returned [expected], but returned [damage_returned] instead!") + if(included_types & FIRELOSS) + damage_returned = round(testing_mob.adjustFireLoss(amount, updating_health = FALSE, forced = forced, required_bodytype = bodytypes), 1) + TEST_ASSERT_EQUAL(damage_returned, expected, \ + "adjustFireLoss() should have returned [expected], but returned [damage_returned] instead!") + if(included_types & OXYLOSS) + damage_returned = testing_mob.adjustOxyLoss(amount, updating_health = FALSE, forced = forced, required_biotype = biotypes) + TEST_ASSERT_EQUAL(damage_returned, expected, \ + "adjustOxyLoss() should have returned [expected], but returned [damage_returned] instead!") + if(included_types & STAMINALOSS) + damage_returned = testing_mob.adjustStaminaLoss(amount, updating_stamina = FALSE, forced = forced, required_biotype = biotypes) + TEST_ASSERT_EQUAL(damage_returned, expected, \ + "adjustStaminaLoss() should have returned [expected], but returned [damage_returned] instead!") + return TRUE + +/** + * Set a specific amount of damage for the mob using setBruteLoss(), setToxLoss(), etc. + * + * By default this sets every type of damage to for the mob, and checks that the damage procs return the value + * Arguments: + * * testing_mob - the mob to apply the damage to + * * amount - the amount of damage to apply to the mob + * * expected - what the expected return value of the damage proc is + * * included_types - Bitflag of damage types to apply + * * biotypes - the biotypes of damage to apply + * * bodytypes - the bodytypes of damage to apply + * * forced - whether or not this is forced damage + */ +/datum/unit_test/mob_damage/proc/set_damage(mob/living/testing_mob, amount, expected = -amount, included_types = ALL, biotypes = ALL, bodytypes = ALL, forced = FALSE) + var/damage_returned + if(included_types & TOXLOSS) + damage_returned = testing_mob.setToxLoss(amount, updating_health = FALSE, forced = forced, required_biotype = biotypes) + TEST_ASSERT_EQUAL(damage_returned, expected, \ + "setToxLoss() should have returned [expected], but returned [damage_returned] instead!") + if(included_types & CLONELOSS) + damage_returned = testing_mob.setCloneLoss(amount, updating_health = FALSE, forced = forced, required_biotype = biotypes) + TEST_ASSERT_EQUAL(damage_returned, expected, \ + "setCloneLoss() should have returned [expected], but returned [damage_returned] instead!") + if(included_types & BRUTELOSS) + damage_returned = round(testing_mob.setBruteLoss(amount, updating_health = FALSE, forced = forced), 1) + TEST_ASSERT_EQUAL(damage_returned, expected, \ + "setBruteLoss() should have returned [expected], but returned [damage_returned] instead!") + if(included_types & FIRELOSS) + damage_returned = round(testing_mob.setFireLoss(amount, updating_health = FALSE, forced = forced), 1) + TEST_ASSERT_EQUAL(damage_returned, expected, \ + "setFireLoss() should have returned [expected], but returned [damage_returned] instead!") + if(included_types & OXYLOSS) + damage_returned = testing_mob.setOxyLoss(amount, updating_health = FALSE, forced = forced, required_biotype = biotypes) + TEST_ASSERT_EQUAL(damage_returned, expected, \ + "setOxyLoss() should have returned [expected], but returned [damage_returned] instead!") + if(included_types & STAMINALOSS) + damage_returned = testing_mob.setStaminaLoss(amount, updating_stamina = FALSE, forced = forced, required_biotype = biotypes) + TEST_ASSERT_EQUAL(damage_returned, expected, \ + "setStaminaLoss() should have returned [expected], but returned [damage_returned] instead!") + return TRUE + +/// Sanity tests damage and healing using adjustToxLoss, adjustBruteLoss, etc +/datum/unit_test/mob_damage/proc/test_sanity_simple(mob/living/carbon/human/consistent/dummy) + // Apply 5 damage and then heal it + if(!test_apply_damage(dummy, amount = 5)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! damage was not applied correctly") + + if(!test_apply_damage(dummy, amount = -5)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! healing was not applied correctly") + + // Apply 15 damage and heal 3 + if(!test_apply_damage(dummy, amount = 15)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! damage was not applied correctly") + + if(!test_apply_damage(dummy, amount = -3)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! underhealing was not applied correctly") + + // Now overheal by 666. It should heal for 12. + + if(!test_apply_damage(dummy, amount = -666, expected = 12)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! overhealing was not applied correctly") + + // Now test the damage setter procs + + // set all types of damage to 5 + if(!test_set_damage(dummy, amount = 5, expected = -5)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! failed to set damage to 5") + // now try healing 5 + if(!test_set_damage(dummy, amount = 0, expected = 5)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! failed to set damage to 0") + +/// Sanity tests damage and healing using the more complex procs like take_overall_damage(), heal_overall_damage(), etc +/datum/unit_test/mob_damage/proc/test_sanity_complex(mob/living/carbon/human/consistent/dummy) + // Heal up, so that errors from the previous tests we won't cause this one to fail + dummy.fully_heal(HEAL_DAMAGE) + + var/damage_returned + // take 5 brute, 2 burn + damage_returned = round(dummy.take_bodypart_damage(5, 2, updating_health = FALSE), 1) + TEST_ASSERT_EQUAL(damage_returned, -7, \ + "take_bodypart_damage() should have returned -7, but returned [damage_returned] instead!") + + TEST_ASSERT_EQUAL(round(dummy.getBruteLoss(), 1), 5, \ + "Dummy should have 5 brute damage, instead they have [dummy.getBruteLoss()]!") + TEST_ASSERT_EQUAL(round(dummy.getFireLoss(), 1), 2, \ + "Dummy should have 2 burn damage, instead they have [dummy.getFireLoss()]!") + + // heal 4 brute, 1 burn + damage_returned = round(dummy.heal_bodypart_damage(4, 1, updating_health = FALSE), 1) + TEST_ASSERT_EQUAL(damage_returned, 5, \ + "heal_bodypart_damage() should have returned 5, but returned [damage_returned] instead!") + + if(!verify_damage(dummy, 1, included_types = BRUTELOSS|FIRELOSS)) + TEST_FAIL("heal_bodypart_damage did not apply its healing correctly on the mob!") + + // heal 1 brute, 1 burn + damage_returned = round(dummy.heal_overall_damage(1, 1, updating_health = FALSE), 1) + TEST_ASSERT_EQUAL(damage_returned, 2, \ + "heal_overall_damage() should have returned 2, but returned [damage_returned] instead!") + + if(!verify_damage(dummy, 0, included_types = BRUTELOSS|FIRELOSS)) + TEST_FAIL("heal_overall_damage did not apply its healing correctly on the mob!") + + // take 50 brute, 50 burn + damage_returned = round(dummy.take_overall_damage(50, 50, updating_health = FALSE), 1) + TEST_ASSERT_EQUAL(damage_returned, -100, \ + "take_overall_damage() should have returned -100, but returned [damage_returned] instead!") + + if(!verify_damage(dummy, 50, included_types = BRUTELOSS|FIRELOSS)) + TEST_FAIL("take_overall_damage did not apply its damage correctly on the mob!") + + // testing negative damage amount args with the overall damage procs - the sign should be ignored for these procs + + damage_returned = round(dummy.take_bodypart_damage(-5, -5, updating_health = FALSE), 1) + TEST_ASSERT_EQUAL(damage_returned, -10, \ + "take_bodypart_damage() should have returned -10, but returned [damage_returned] instead!") + + damage_returned = round(dummy.heal_bodypart_damage(-5, -5, updating_health = FALSE), 1) + TEST_ASSERT_EQUAL(damage_returned, 10, \ + "heal_bodypart_damage() should have returned 10, but returned [damage_returned] instead!") + + damage_returned = round(dummy.take_overall_damage(-5, -5, updating_health = FALSE), 1) + TEST_ASSERT_EQUAL(damage_returned, -10, \ + "take_overall_damage() should have returned -10, but returned [damage_returned] instead!") + + damage_returned = round(dummy.heal_overall_damage(-5, -5, updating_health = FALSE), 1) + TEST_ASSERT_EQUAL(damage_returned, 10, \ + "heal_overall_damage() should have returned 10, but returned [damage_returned] instead!") + + if(!verify_damage(dummy, 50, included_types = BRUTELOSS|FIRELOSS)) + TEST_FAIL("heal_overall_damage did not apply its healingcorrectly on the mob!") + + // testing overhealing + + damage_returned = round(dummy.heal_overall_damage(75, 99, updating_health = FALSE), 1) + TEST_ASSERT_EQUAL(damage_returned, 100, \ + "heal_overall_damage() should have returned 100, but returned [damage_returned] instead!") + + if(!verify_damage(dummy, 0, included_types = BRUTELOSS|FIRELOSS)) + TEST_FAIL("heal_overall_damage did not apply its healing correctly on the mob!") + +/// Tests damage procs with godmode on +/datum/unit_test/mob_damage/proc/test_godmode(mob/living/carbon/human/consistent/dummy) + // Heal up, so that errors from the previous tests we won't cause this one to fail + dummy.fully_heal(HEAL_DAMAGE) + // flip godmode bit to 1 + dummy.status_flags ^= GODMODE + + // Apply 9 damage and then heal it + if(!test_apply_damage(dummy, amount = 9, expected = 0)) + TEST_FAIL("ABOVE FAILURE: failed test_godmode! mob took damage despite having godmode enabled.") + + if(!test_apply_damage(dummy, amount = -9, expected = 0)) + TEST_FAIL("ABOVE FAILURE: failed test_godmode! mob healed when they should've been at full health.") + + // Apply 11 damage and then heal it, this time with forced enabled. The damage should go through regardless of godmode. + if(!test_apply_damage(dummy, amount = 11, forced = TRUE)) + TEST_FAIL("ABOVE FAILURE: failed test_godmode! godmode did not respect forced = TRUE") + + if(!test_apply_damage(dummy, amount = -11, forced = TRUE)) + TEST_FAIL("ABOVE FAILURE: failed test_godmode! godmode did not respect forced = TRUE") + + // flip godmode bit back to 0 + dummy.status_flags ^= GODMODE + +/// Testing biotypes +/datum/unit_test/mob_damage/proc/test_biotypes(mob/living/carbon/human/consistent/dummy) + // Heal up, so that errors from the previous tests we won't cause this one to fail + dummy.fully_heal(HEAL_DAMAGE) + // Testing biotypes using a plasmaman, who is MOB_MINERAL and MOB_HUMANOID + dummy.set_species(/datum/species/plasmaman) + + // argumentless default: should default to required_biotype = ALL. The damage should be applied in that case. + if(!test_apply_damage(dummy, 1, included_types = TOXLOSS|CLONELOSS|STAMINALOSS)) + TEST_FAIL("ABOVE FAILURE: plasmaman did not take damage with biotypes = ALL") + + // If we specify MOB_ORGANIC, the damage should not get applied because plasmamen lack that biotype. + if(!test_apply_damage(dummy, 1, expected = 0, included_types = TOXLOSS|CLONELOSS|STAMINALOSS, biotypes = MOB_ORGANIC)) + TEST_FAIL("ABOVE FAILURE: plasmaman took damage with biotypes = MOB_ORGANIC") + + // Now if we specify MOB_MINERAL the damage should get applied. + if(!test_apply_damage(dummy, 1, included_types = TOXLOSS|CLONELOSS|STAMINALOSS, biotypes = MOB_MINERAL)) + TEST_FAIL("ABOVE FAILURE: plasmaman did not take damage with biotypes = MOB_MINERAL") + + // Transform back to human + dummy.set_species(/datum/species/human) + + // We have 2 damage presently. + // Try to heal it; let's specify MOB_MINERAL, which should no longer work because we have changed back to a human. + if(!test_apply_damage(dummy, -2, expected = 0, included_types = TOXLOSS|CLONELOSS|STAMINALOSS, biotypes = MOB_MINERAL)) + TEST_FAIL("ABOVE FAILURE: human took damage with biotypes = MOB_MINERAL") + + // Force heal some of the damage. When forced = TRUE the damage/healing gets applied no matter what. + if(!test_apply_damage(dummy, -1, included_types = TOXLOSS|CLONELOSS|STAMINALOSS, biotypes = MOB_MINERAL, forced = TRUE)) + TEST_FAIL("ABOVE FAILURE: human did not get healed when biotypes = MOB_MINERAL and forced = TRUE") + + // Now heal the rest of it with the correct biotype. Make sure that this works. We should have 0 damage afterwards. + if(!test_apply_damage(dummy, -1, included_types = TOXLOSS|CLONELOSS|STAMINALOSS, biotypes = MOB_ORGANIC)) + TEST_FAIL("ABOVE FAILURE: human did not get healed with biotypes = MOB_ORGANIC") + +/// Testing oxyloss with the TRAIT_NOBREATH +/datum/unit_test/mob_damage/proc/test_nobreath(mob/living/carbon/human/consistent/dummy) + // Heal up, so that errors from the previous tests we won't cause this one to fail + dummy.fully_heal(HEAL_DAMAGE) + + // TRAIT_NOBREATH is supposed to prevent oxyloss damage (but not healing). Let's make sure that's the case. + ADD_TRAIT(dummy, TRAIT_NOBREATH, TRAIT_SOURCE_UNIT_TESTS) + // force some oxyloss here + dummy.setOxyLoss(2, updating_health = FALSE, forced = TRUE) + + // Try to take more oxyloss damage with TRAIT_NOBREATH. It should not work. + if(!test_apply_damage(dummy, 2, expected = 0, amount_after = dummy.getOxyLoss(), included_types = OXYLOSS)) + TEST_FAIL("ABOVE FAILURE: failed test_nobreath! mob took oxyloss damage while having TRAIT_NOBREATH") + + // Make sure we are still be able to heal the oxyloss. This should work. + if(!test_apply_damage(dummy, -2, amount_after = dummy.getOxyLoss()-2, included_types = OXYLOSS)) + TEST_FAIL("ABOVE FAILURE: failed test_nobreath! mob could not heal oxyloss damage while having TRAIT_NOBREATH") + + REMOVE_TRAIT(dummy, TRAIT_NOBREATH, TRAIT_SOURCE_UNIT_TESTS) + +/// Testing toxloss with TRAIT_TOXINLOVER and TRAIT_TOXIMMUNE +/datum/unit_test/mob_damage/proc/test_toxintraits(mob/living/carbon/human/consistent/dummy) + // Heal up, so that errors from the previous tests we won't cause this one to fail + dummy.fully_heal(HEAL_DAMAGE) + + // TRAIT_TOXINLOVER is supposed to invert toxin damage and healing. Things that would normally cause toxloss now heal it, and vice versa. + ADD_TRAIT(dummy, TRAIT_TOXINLOVER, TRAIT_SOURCE_UNIT_TESTS) + // force some toxloss here + dummy.setToxLoss(2, updating_health = FALSE, forced = TRUE) + + // Try to take more toxloss damage with TRAIT_TOXINLOVER. It should heal instead. + if(!test_apply_damage(dummy, 2, expected = 2, amount_after = dummy.getToxLoss()-2, included_types = TOXLOSS)) + TEST_FAIL("ABOVE FAILURE: failed test_toxintraits! mob did not heal from toxin damage with TRAIT_TOXINLOVER") + + // If we try to heal the toxloss we should take damage instead + if(!test_apply_damage(dummy, -2, expected = -2, amount_after = dummy.getToxLoss()+2, included_types = TOXLOSS)) + TEST_FAIL("ABOVE FAILURE: failed test_toxintraits! mob did not take damage from toxin healing with TRAIT_TOXINLOVER") + + // TOXIMMUNE trait should prevent the damage you get from being healed by toxins medicines while having TRAIT_TOXINLOVER + ADD_TRAIT(dummy, TRAIT_TOXIMMUNE, TRAIT_SOURCE_UNIT_TESTS) + + // need to force apply some toxin damage since the TOXIMUNNE trait sets toxloss to 0 upon being added + dummy.setToxLoss(2, updating_health = FALSE, forced = TRUE) + + // try to 'heal' again - this time it should just do nothing because we should be immune to any sort of toxin damage - including from inverted healing + if(!test_apply_damage(dummy, -2, expected = 0, amount_after = dummy.getToxLoss(), included_types = TOXLOSS)) + TEST_FAIL("ABOVE FAILURE: failed test_toxintraits! mob should not have taken any damage or healing with TRAIT_TOXINLOVER + TRAIT_TOXIMMUNE") + + // ok, let's try taking 'damage'. The inverted damage should still heal mobs with the TOXIMMUNE trait. + if(!test_apply_damage(dummy, 2, expected = 2, amount_after = dummy.getToxLoss()-2, included_types = TOXLOSS)) + TEST_FAIL("ABOVE FAILURE: failed test_toxintraits! mob did not heal from taking toxin damage with TRAIT_TOXINLOVER + TRAIT_TOXIMMUNE") + + REMOVE_TRAIT(dummy, TRAIT_TOXINLOVER, TRAIT_SOURCE_UNIT_TESTS) + REMOVE_TRAIT(dummy, TRAIT_TOXIMMUNE, TRAIT_SOURCE_UNIT_TESTS) + +/// Testing cloneloss with TRAIT_NOCLONELOSS +/datum/unit_test/mob_damage/proc/test_nocloneloss(mob/living/carbon/human/consistent/dummy) + // Heal up, so that errors from the previous tests we won't cause this one to fail + dummy.fully_heal(HEAL_DAMAGE) + + // TRAIT_TRAIT_NOCLONELOSS is supposed to prevent cloneloss damage and healing. Let's make sure that's the case. + ADD_TRAIT(dummy, TRAIT_NOCLONELOSS, TRAIT_SOURCE_UNIT_TESTS) + // force some cloneloss here + dummy.setCloneLoss(2, updating_health = FALSE, forced = TRUE) + + // Try to take more cloneloss damage with TRAIT_NOCLONELOSS. It should not work. + if(!test_apply_damage(dummy, 2, expected = 0, amount_after = dummy.getCloneLoss(), included_types = CLONELOSS)) + TEST_FAIL("ABOVE FAILURE: failed test_nocloneloss! mob took cloneloss damage with TRAIT_NOCLONELOSS") + + // Healing the cloneloss should not work either, unless we force it + if(!test_apply_damage(dummy, -2, expected = 0, amount_after = dummy.getCloneLoss(), included_types = CLONELOSS)) + TEST_FAIL("ABOVE FAILURE: failed test_nocloneloss! mob healed cloneloss damage with TRAIT_NOCLONELOSS") + // so let's force it + if(!test_apply_damage(dummy, -2, expected = 2, amount_after = dummy.getCloneLoss()-2, included_types = CLONELOSS, forced = TRUE)) + TEST_FAIL("ABOVE FAILURE: failed test_nocloneloss! mob could not heal cloneloss damage with forced = TRUE and TRAIT_NOCLONELOSS") + + REMOVE_TRAIT(dummy, TRAIT_NOCLONELOSS, TRAIT_SOURCE_UNIT_TESTS) + +/// Testing heal_ordered_damage() +/datum/unit_test/mob_damage/proc/test_ordered_healing(mob/living/carbon/human/consistent/dummy) + // Heal up, so that errors from the previous tests we won't cause this one to fail + dummy.fully_heal(HEAL_DAMAGE) + var/damage_returned + + // We apply 20 brute, 20 burn, and 20 toxin damage. 60 damage total + apply_damage(dummy, 20, included_types = TOXLOSS|BRUTELOSS|FIRELOSS) + + // Heal 30 damage of that, starting from brute + damage_returned = round(dummy.heal_ordered_damage(30, list(BRUTE, BURN, TOX)), 1) + TEST_ASSERT_EQUAL(damage_returned, 30, \ + "heal_ordered_damage() should have returned 30, but returned [damage_returned] instead!") + + // Should have 10 burn damage and 20 toxins damage remaining, let's check + TEST_ASSERT_EQUAL(dummy.getBruteLoss(), 0, \ + "[src] should have 0 brute damage, but has [dummy.getBruteLoss()] instead!") + TEST_ASSERT_EQUAL(dummy.getFireLoss(), 10, \ + "[src] should have 10 burn damage, but has [dummy.getFireLoss()] instead!") + TEST_ASSERT_EQUAL(dummy.getToxLoss(), 20, \ + "[src] should have 20 toxin damage, but has [dummy.getToxLoss()] instead!") + + // Now heal the remaining 30, overhealing by 5. + damage_returned = round(dummy.heal_ordered_damage(35, list(BRUTE, BURN, TOX)), 1) + TEST_ASSERT_EQUAL(damage_returned, 30, \ + "heal_ordered_damage() should have returned 30, but returned [damage_returned] instead!") + + // Should have no damage remaining + TEST_ASSERT_EQUAL(dummy.getBruteLoss(), 0, \ + "[src] should have 0 brute damage, but has [dummy.getBruteLoss()] instead!") + TEST_ASSERT_EQUAL(dummy.getFireLoss(), 0, \ + "[src] should have 0 burn damage, but has [dummy.getFireLoss()] instead!") + TEST_ASSERT_EQUAL(dummy.getToxLoss(), 0, \ + "[src] should have 0 toxin damage, but has [dummy.getToxLoss()] instead!") + +/// Tests that mob damage procs are working as intended for basic mobs +/datum/unit_test/mob_damage/basic + +/datum/unit_test/mob_damage/basic/Run() + SSmobs.pause() + var/mob/living/basic/mouse/gray/gusgus = allocate(/mob/living/basic/mouse/gray) + // give gusgus a damage_coeff of 1 for this test + gusgus.damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 1, OXY = 1) + // tank mouse + gusgus.maxHealth = 200 + + test_sanity_simple(gusgus) + test_sanity_complex(gusgus) + +/** + * Check that the mob has a specific amount of damage. Note: basic mobs have all incoming damage types besides stam converted into brute damage. + * + * By default this checks that the mob has of every type of damage. + * Arguments: + * * testing_mob - the mob to check the damage of + * * amount - the amount of damage to verify that the mob has + * * expected - the expected return value of the damage procs, if it differs from the default of (amount * 5) + * * included_types - Bitflag of damage types to check. + */ +/datum/unit_test/mob_damage/basic/verify_damage(mob/living/testing_mob, amount, expected, included_types = ALL) + if(included_types & TOXLOSS) + TEST_ASSERT_EQUAL(testing_mob.getToxLoss(), 0, \ + "[testing_mob] should have [0] toxin damage, instead they have [testing_mob.getToxLoss()]!") + if(included_types & CLONELOSS) + TEST_ASSERT_EQUAL(testing_mob.getCloneLoss(), 0, \ + "[testing_mob] should have [0] clone damage, instead they have [testing_mob.getCloneLoss()]!") + if(included_types & BRUTELOSS) + TEST_ASSERT_EQUAL(round(testing_mob.getBruteLoss(), 1), expected || amount * 5, \ + "[testing_mob] should have [expected || amount * 5] brute damage, instead they have [testing_mob.getBruteLoss()]!") + if(included_types & FIRELOSS) + TEST_ASSERT_EQUAL(round(testing_mob.getFireLoss(), 1), 0, \ + "[testing_mob] should have [0] burn damage, instead they have [testing_mob.getFireLoss()]!") + if(included_types & OXYLOSS) + TEST_ASSERT_EQUAL(testing_mob.getOxyLoss(), 0, \ + "[testing_mob] should have [0] oxy damage, instead they have [testing_mob.getOxyLoss()]!") + if(included_types & STAMINALOSS) + TEST_ASSERT_EQUAL(testing_mob.getStaminaLoss(), amount, \ + "[testing_mob] should have [amount] stamina damage, instead they have [testing_mob.getStaminaLoss()]!") + return TRUE + +/datum/unit_test/mob_damage/basic/test_sanity_simple(mob/living/basic/mouse/gray/gusgus) + // check to see if basic mob damage works + + // Simple damage and healing + // Take 1 damage, heal for 1 + if(!test_apply_damage(gusgus, amount = 1)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! damage was not applied correctly") + + if(!test_apply_damage(gusgus, amount = -1)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! healing was not applied correctly") + + // Give 2 damage of every time (translates to 10 brute, 2 staminaloss) + if(!test_apply_damage(gusgus, amount = 2)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! damage was not applied correctly") + + // underhealing: heal 1 damage of every type (translates to 5 brute, 1 staminaloss) + if(!test_apply_damage(gusgus, amount = -1)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! healing was not applied correctly") + + // overhealing + + // heal 11 points of toxloss (should take care of all 5 brute damage remaining) + if(!apply_damage(gusgus, -11, expected = 5, included_types = TOXLOSS)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! toxloss was not applied correctly") + // heal the remaining point of staminaloss + if(!apply_damage(gusgus, -11, expected = 1, included_types = STAMINALOSS)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! failed to heal staminaloss correctly") + // heal 35 points of each type, we should already be at full health so nothing should happen + if(!test_apply_damage(gusgus, amount = -35, expected = 0)) + TEST_FAIL("ABOVE FAILURE: failed test_sanity_simple! overhealing was not applied correctly") + +/datum/unit_test/mob_damage/basic/test_sanity_complex(mob/living/basic/mouse/gray/gusgus) + // Heal up, so that errors from the previous tests we won't cause this one to fail + gusgus.fully_heal(HEAL_DAMAGE) + var/damage_returned + // overall damage procs + + // take 5 brute, 2 burn + damage_returned = gusgus.take_bodypart_damage(5, 2, updating_health = FALSE) + TEST_ASSERT_EQUAL(damage_returned, -7, \ + "take_bodypart_damage() should have returned -7, but returned [damage_returned] instead!") + + TEST_ASSERT_EQUAL(gusgus.bruteloss, 7, \ + "Mouse should have 7 brute damage, instead they have [gusgus.bruteloss]!") + TEST_ASSERT_EQUAL(gusgus.fireloss, 0, \ + "Mouse should have 0 burn damage, instead they have [gusgus.fireloss]!") + + // heal 4 brute, 1 burn + damage_returned = gusgus.heal_bodypart_damage(4, 1, updating_health = FALSE) + TEST_ASSERT_EQUAL(damage_returned, 5, \ + "heal_bodypart_damage() should have returned 5, but returned [damage_returned] instead!") + + TEST_ASSERT_EQUAL(gusgus.bruteloss, 2, \ + "Mouse should have 2 brute damage, instead they have [gusgus.bruteloss]!") + TEST_ASSERT_EQUAL(gusgus.fireloss, 0, \ + "Mouse should have 0 burn damage, instead they have [gusgus.fireloss]!") + + // heal 1 brute, 1 burn + damage_returned = gusgus.heal_overall_damage(1, 1, updating_health = FALSE) + TEST_ASSERT_EQUAL(damage_returned, 2, \ + "heal_overall_damage() should have returned 2, but returned [damage_returned] instead!") + + TEST_ASSERT_EQUAL(gusgus.bruteloss, 0, \ + "Mouse should have 0 brute damage, instead they have [gusgus.bruteloss]!") + TEST_ASSERT_EQUAL(gusgus.fireloss, 0, \ + "Mouse should have 0 burn damage, instead they have [gusgus.fireloss]!") + + // take 50 brute, 50 burn + damage_returned = gusgus.take_overall_damage(3, 3, updating_health = FALSE) + TEST_ASSERT_EQUAL(damage_returned, -6, \ + "take_overall_damage() should have returned -6, but returned [damage_returned] instead!") + + if(!verify_damage(gusgus, 1, expected = 6, included_types = BRUTELOSS)) + TEST_FAIL("take_overall_damage did not apply its damage correctly on the mouse!") + + // testing negative args with the overall damage procs + + damage_returned = gusgus.take_bodypart_damage(-1, -1, updating_health = FALSE) + TEST_ASSERT_EQUAL(damage_returned, -2, \ + "take_bodypart_damage() should have returned -2, but returned [damage_returned] instead!") + + damage_returned = gusgus.heal_bodypart_damage(-1, -1, updating_health = FALSE) + TEST_ASSERT_EQUAL(damage_returned, 2, \ + "heal_bodypart_damage() should have returned 2, but returned [damage_returned] instead!") + + damage_returned = gusgus.take_overall_damage(-1, -1, updating_health = FALSE) + TEST_ASSERT_EQUAL(damage_returned, -2, \ + "take_overall_damage() should have returned -2, but returned [damage_returned] instead!") + + damage_returned = gusgus.heal_overall_damage(-1, -1, updating_health = FALSE) + TEST_ASSERT_EQUAL(damage_returned, 2, \ + "heal_overall_damage() should have returned 2, but returned [damage_returned] instead!") + + if(!verify_damage(gusgus, 1, expected = 6, included_types = BRUTELOSS)) + TEST_FAIL("heal_overall_damage did not apply its healing correctly on the mouse!") + + // testing overhealing + + damage_returned = gusgus.heal_overall_damage(75, 99, updating_health = FALSE) + TEST_ASSERT_EQUAL(damage_returned, 6, \ + "heal_overall_damage() should have returned 6, but returned [damage_returned] instead!") + + if(!verify_damage(gusgus, 0, included_types = BRUTELOSS)) + TEST_FAIL("heal_overall_damage did not apply its healing correctly on the mouse!") diff --git a/code/modules/unit_tests/organs.dm b/code/modules/unit_tests/organs.dm index 4c99bfaa339fd2..4ba51e0870c00a 100644 --- a/code/modules/unit_tests/organs.dm +++ b/code/modules/unit_tests/organs.dm @@ -96,19 +96,22 @@ var/slot_to_use = test_organ.slot // Tests [mob/living/proc/adjustOrganLoss] - dummy.adjustOrganLoss(slot_to_use, test_organ.maxHealth * 10) + TEST_ASSERT_EQUAL(dummy.adjustOrganLoss(slot_to_use, test_organ.maxHealth * 10), -test_organ.maxHealth, \ + "Mob level \"apply organ damage\" returned the wrong value for [slot_to_use] organ with default arguments.") TEST_ASSERT_EQUAL(dummy.get_organ_loss(slot_to_use), test_organ.maxHealth, \ "Mob level \"apply organ damage\" can exceed the [slot_to_use] organ's damage cap with default arguments.") dummy.fully_heal(HEAL_ORGANS) // Tests [mob/living/proc/set_organ_damage] - dummy.setOrganLoss(slot_to_use, test_organ.maxHealth * 10) + TEST_ASSERT_EQUAL(dummy.setOrganLoss(slot_to_use, test_organ.maxHealth * 10), -test_organ.maxHealth, \ + "Mob level \"set organ damage\" returned the wrong value for [slot_to_use] organ with default arguments.") TEST_ASSERT_EQUAL(dummy.get_organ_loss(slot_to_use), test_organ.maxHealth, \ "Mob level \"set organ damage\" can exceed the [slot_to_use] organ's damage cap with default arguments.") dummy.fully_heal(HEAL_ORGANS) // Tests [mob/living/proc/adjustOrganLoss] with a large max supplied - dummy.adjustOrganLoss(slot_to_use, test_organ.maxHealth * 10, INFINITY) + TEST_ASSERT_EQUAL(dummy.adjustOrganLoss(slot_to_use, test_organ.maxHealth * 10, INFINITY), -test_organ.maxHealth, \ + "Mob level \"apply organ damage\" returned the wrong value for [slot_to_use] organ with a large maximum supplied.") TEST_ASSERT_EQUAL(dummy.get_organ_loss(slot_to_use), test_organ.maxHealth, \ "Mob level \"apply organ damage\" can exceed the [slot_to_use] organ's damage cap with a large maximum supplied.") dummy.fully_heal(HEAL_ORGANS) diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_changelingmidround.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_changelingmidround.png index ac412207c236df..d002f7466675bd 100644 Binary files a/code/modules/unit_tests/screenshots/screenshot_antag_icons_changelingmidround.png and b/code/modules/unit_tests/screenshots/screenshot_antag_icons_changelingmidround.png differ diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_cyberpolice.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_cyberpolice.png new file mode 100644 index 00000000000000..180be6064f8545 Binary files /dev/null and b/code/modules/unit_tests/screenshots/screenshot_antag_icons_cyberpolice.png differ diff --git a/code/modules/unit_tests/simple_animal_freeze.dm b/code/modules/unit_tests/simple_animal_freeze.dm index 97631c0b78a8c2..335e353b1e7beb 100644 --- a/code/modules/unit_tests/simple_animal_freeze.dm +++ b/code/modules/unit_tests/simple_animal_freeze.dm @@ -64,23 +64,15 @@ /mob/living/simple_animal/hostile/asteroid/gutlunch/grublunch, /mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck, /mob/living/simple_animal/hostile/asteroid/gutlunch/guthen, - /mob/living/simple_animal/hostile/asteroid/ice_demon, /mob/living/simple_animal/hostile/asteroid/polarbear, /mob/living/simple_animal/hostile/asteroid/polarbear/lesser, /mob/living/simple_animal/hostile/asteroid/wolf, - /mob/living/simple_animal/hostile/blob, - /mob/living/simple_animal/hostile/blob/blobbernaut, - /mob/living/simple_animal/hostile/blob/blobbernaut/independent, - /mob/living/simple_animal/hostile/blob/blobspore, - /mob/living/simple_animal/hostile/blob/blobspore/independent, - /mob/living/simple_animal/hostile/blob/blobspore/weak, /mob/living/simple_animal/hostile/construct, /mob/living/simple_animal/hostile/construct/artificer, /mob/living/simple_animal/hostile/construct/artificer/angelic, /mob/living/simple_animal/hostile/construct/artificer/hostile, /mob/living/simple_animal/hostile/construct/artificer/mystic, /mob/living/simple_animal/hostile/construct/artificer/noncult, - /mob/living/simple_animal/hostile/construct/harvester, /mob/living/simple_animal/hostile/construct/juggernaut, /mob/living/simple_animal/hostile/construct/juggernaut/angelic, /mob/living/simple_animal/hostile/construct/juggernaut/hostile, @@ -94,9 +86,6 @@ /mob/living/simple_animal/hostile/construct/wraith/mystic, /mob/living/simple_animal/hostile/construct/wraith/noncult, /mob/living/simple_animal/hostile/dark_wizard, - /mob/living/simple_animal/hostile/gorilla, - /mob/living/simple_animal/hostile/gorilla/lesser, - /mob/living/simple_animal/hostile/gorilla/cargo_domestic, /mob/living/simple_animal/hostile/guardian, /mob/living/simple_animal/hostile/guardian/assassin, /mob/living/simple_animal/hostile/guardian/charger, @@ -109,40 +98,38 @@ /mob/living/simple_animal/hostile/guardian/ranged, /mob/living/simple_animal/hostile/guardian/standard, /mob/living/simple_animal/hostile/guardian/support, - /mob/living/simple_animal/hostile/heretic_summon, - /mob/living/simple_animal/hostile/heretic_summon/armsy, - /mob/living/simple_animal/hostile/heretic_summon/armsy/prime, - /mob/living/simple_animal/hostile/heretic_summon/ash_spirit, - /mob/living/simple_animal/hostile/heretic_summon/maid_in_the_mirror, - /mob/living/simple_animal/hostile/heretic_summon/raw_prophet, - /mob/living/simple_animal/hostile/heretic_summon/rust_spirit, - /mob/living/simple_animal/hostile/heretic_summon/stalker, /mob/living/simple_animal/hostile/illusion, /mob/living/simple_animal/hostile/illusion/escape, /mob/living/simple_animal/hostile/illusion/mirage, /mob/living/simple_animal/hostile/jungle, /mob/living/simple_animal/hostile/jungle/leaper, - /mob/living/simple_animal/hostile/jungle/mook, /mob/living/simple_animal/hostile/megafauna, /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner, /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/doom, /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/guidance, /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/hunter, + /mob/living/simple_animal/hostile/megafauna/blood_drunk_miner/virtual_domain, /mob/living/simple_animal/hostile/megafauna/bubblegum, /mob/living/simple_animal/hostile/megafauna/bubblegum/hallucination, + /mob/living/simple_animal/hostile/megafauna/bubblegum/virtual_domain, /mob/living/simple_animal/hostile/megafauna/clockwork_defender, /mob/living/simple_animal/hostile/megafauna/colossus, + /mob/living/simple_animal/hostile/megafauna/colossus/virtual_domain, /mob/living/simple_animal/hostile/megafauna/demonic_frost_miner, /mob/living/simple_animal/hostile/megafauna/dragon, /mob/living/simple_animal/hostile/megafauna/dragon/lesser, + /mob/living/simple_animal/hostile/megafauna/dragon/virtual_domain, /mob/living/simple_animal/hostile/megafauna/hierophant, + /mob/living/simple_animal/hostile/megafauna/hierophant/virtual_domain, /mob/living/simple_animal/hostile/megafauna/legion, + /mob/living/simple_animal/hostile/megafauna/legion/virtual_domain, /mob/living/simple_animal/hostile/megafauna/legion/medium, /mob/living/simple_animal/hostile/megafauna/legion/medium/eye, /mob/living/simple_animal/hostile/megafauna/legion/medium/left, /mob/living/simple_animal/hostile/megafauna/legion/medium/right, /mob/living/simple_animal/hostile/megafauna/legion/small, /mob/living/simple_animal/hostile/megafauna/wendigo, + /mob/living/simple_animal/hostile/megafauna/wendigo/virtual_domain, /mob/living/simple_animal/hostile/mimic, /mob/living/simple_animal/hostile/mimic/copy, /mob/living/simple_animal/hostile/mimic/copy/machine, @@ -164,7 +151,6 @@ /mob/living/simple_animal/hostile/pirate/ranged, /mob/living/simple_animal/hostile/pirate/ranged/space, /mob/living/simple_animal/hostile/retaliate, - /mob/living/simple_animal/hostile/retaliate/goat, /mob/living/simple_animal/hostile/retaliate/goose, /mob/living/simple_animal/hostile/retaliate/goose/vomit, /mob/living/simple_animal/hostile/retaliate/nanotrasenpeace, @@ -177,12 +163,9 @@ /mob/living/simple_animal/hostile/skeleton/plasmaminer, /mob/living/simple_animal/hostile/skeleton/plasmaminer/jackhammer, /mob/living/simple_animal/hostile/skeleton/templar, - /mob/living/simple_animal/hostile/smspider, - /mob/living/simple_animal/hostile/smspider/overcharged, /mob/living/simple_animal/hostile/space_dragon, /mob/living/simple_animal/hostile/space_dragon/spawn_with_antag, /mob/living/simple_animal/hostile/vatbeast, - /mob/living/simple_animal/hostile/venus_human_trap, /mob/living/simple_animal/hostile/wizard, /mob/living/simple_animal/hostile/zombie, /mob/living/simple_animal/parrot, @@ -201,15 +184,12 @@ /mob/living/simple_animal/pet/cat/space, /mob/living/simple_animal/pet/gondola, /mob/living/simple_animal/pet/gondola/gondolapod, - /mob/living/simple_animal/revenant, + /mob/living/simple_animal/pet/gondola/virtual_domain, /mob/living/simple_animal/shade, /mob/living/simple_animal/slime, /mob/living/simple_animal/slime/pet, /mob/living/simple_animal/slime/random, /mob/living/simple_animal/slime/transformed_slime, - /mob/living/simple_animal/sloth, - /mob/living/simple_animal/sloth/citrus, - /mob/living/simple_animal/sloth/paperwork, /mob/living/simple_animal/soulscythe, //MODULAR SKYRAT ENTRIES diff --git a/code/modules/uplink/uplink_items/ammunition.dm b/code/modules/uplink/uplink_items/ammunition.dm index 292f87ffe13b32..e88727812528de 100644 --- a/code/modules/uplink/uplink_items/ammunition.dm +++ b/code/modules/uplink/uplink_items/ammunition.dm @@ -18,7 +18,6 @@ /datum/uplink_item/ammo/pistol name = "9mm Handgun Magazine" desc = "An additional 8-round 9mm magazine, compatible with the Makarov pistol." - progression_minimum = 10 MINUTES item = /obj/item/ammo_box/magazine/m9mm cost = 1 purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) @@ -28,7 +27,6 @@ name = "9mm Armour Piercing Magazine" desc = "An additional 8-round 9mm magazine, compatible with the Makarov pistol. \ These rounds are less effective at injuring the target but penetrate protective gear." - progression_minimum = 30 MINUTES item = /obj/item/ammo_box/magazine/m9mm/ap cost = 2 purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) @@ -37,7 +35,6 @@ name = "9mm Hollow Point Magazine" desc = "An additional 8-round 9mm magazine, compatible with the Makarov pistol. \ These rounds are more damaging but ineffective against armour." - progression_minimum = 30 MINUTES item = /obj/item/ammo_box/magazine/m9mm/hp cost = 3 purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) @@ -46,7 +43,6 @@ name = "9mm Incendiary Magazine" desc = "An additional 8-round 9mm magazine, compatible with the Makarov pistol. \ Loaded with incendiary rounds which inflict little damage, but ignite the target." - progression_minimum = 30 MINUTES item = /obj/item/ammo_box/magazine/m9mm/fire cost = 2 purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) @@ -55,7 +51,6 @@ name = ".357 Speed Loader" desc = "A speed loader that contains seven additional .357 Magnum rounds; usable with the Syndicate revolver. \ For when you really need a lot of things dead." - progression_minimum = 30 MINUTES item = /obj/item/ammo_box/a357 cost = 4 purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) //nukies get their own version diff --git a/code/modules/uplink/uplink_items/badass.dm b/code/modules/uplink/uplink_items/badass.dm index 93087be9dd00e9..67676edcd7da9f 100644 --- a/code/modules/uplink/uplink_items/badass.dm +++ b/code/modules/uplink/uplink_items/badass.dm @@ -48,7 +48,6 @@ manufactured to pack a little bit more of a punch if your client needs some convincing." item = /obj/item/storage/secure/briefcase/syndie cost = 3 - progression_minimum = 5 MINUTES restricted = TRUE illegal_tech = FALSE diff --git a/code/modules/uplink/uplink_items/bundle.dm b/code/modules/uplink/uplink_items/bundle.dm index 912c28e2bcb2b8..a930784fe1462c 100644 --- a/code/modules/uplink/uplink_items/bundle.dm +++ b/code/modules/uplink/uplink_items/bundle.dm @@ -58,7 +58,6 @@ These items are collectively worth more than 25 telecrystals, but you do not know which specialization \ you will receive. May contain discontinued and/or exotic items. \ The Syndicate will only provide one Syndi-Kit per agent." - progression_minimum = 30 MINUTES item = /obj/item/storage/box/syndicate/bundle_a cost = 20 stock_key = UPLINK_SHARED_STOCK_KITS @@ -70,7 +69,6 @@ In Syndi-kit Special, you will receive items used by famous syndicate agents of the past. \ Collectively worth more than 25 telecrystals, the syndicate loves a good throwback. \ The Syndicate will only provide one Syndi-Kit per agent." - progression_minimum = 30 MINUTES item = /obj/item/storage/box/syndicate/bundle_b cost = 20 stock_key = UPLINK_SHARED_STOCK_KITS @@ -149,7 +147,6 @@ The Syndicate will only provide one surplus item per agent." cost = 20 item = /obj/structure/closet/crate/syndicrate - progression_minimum = 30 MINUTES stock_key = UPLINK_SHARED_STOCK_SURPLUS crate_tc_value = 80 crate_type = /obj/structure/closet/crate/syndicrate @@ -173,6 +170,5 @@ The Syndicate will only provide one surplus item per agent." cost = 20 item = /obj/item/syndicrate_key - progression_minimum = 30 MINUTES purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) stock_key = UPLINK_SHARED_STOCK_SURPLUS diff --git a/code/modules/uplink/uplink_items/dangerous.dm b/code/modules/uplink/uplink_items/dangerous.dm index 0cdcf3a7bb7f6f..f1788c6e1dec32 100644 --- a/code/modules/uplink/uplink_items/dangerous.dm +++ b/code/modules/uplink/uplink_items/dangerous.dm @@ -19,7 +19,6 @@ name = "Makarov Pistol" desc = "A small, easily concealable handgun that uses 9mm auto rounds in 8-round magazines and is compatible \ with suppressors." - progression_minimum = 10 MINUTES item = /obj/item/gun/ballistic/automatic/pistol cost = 7 purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) @@ -28,7 +27,6 @@ name = "Box of Throwing Weapons" desc = "A box of shurikens and reinforced bolas from ancient Earth martial arts. They are highly effective \ throwing weapons. The bolas can knock a target down and the shurikens will embed into limbs." - progression_minimum = 10 MINUTES item = /obj/item/storage/box/syndie_kit/throwing_weapons cost = 3 illegal_tech = FALSE @@ -95,7 +93,6 @@ name = "Syndicate Revolver" desc = "Waffle Co.'s modernized Syndicate revolver. Fires 7 brutal rounds of .357 Magnum." item = /obj/item/gun/ballistic/revolver/syndicate - progression_minimum = 30 MINUTES cost = 13 surplus = 50 purchasable_from = ~(UPLINK_NUKE_OPS | UPLINK_CLOWN_OPS) //nukies get their own version diff --git a/code/modules/uplink/uplink_items/explosive.dm b/code/modules/uplink/uplink_items/explosive.dm index 32a5ad49d57abd..59a443256739a9 100644 --- a/code/modules/uplink/uplink_items/explosive.dm +++ b/code/modules/uplink/uplink_items/explosive.dm @@ -16,7 +16,6 @@ desc = "C-4 is plastic explosive of the common variety Composition C. You can use it to breach walls, sabotage equipment, or connect \ an assembly to it in order to alter the way it detonates. It can be attached to almost all objects and has a modifiable timer with a \ minimum setting of 10 seconds." - progression_minimum = 5 MINUTES item = /obj/item/grenade/c4 cost = 1 @@ -24,7 +23,6 @@ name = "Bag of C-4 explosives" desc = "Because sometimes quantity is quality. Contains 10 C-4 plastic explosives." item = /obj/item/storage/backpack/duffelbag/syndie/c4 - progression_minimum = 10 MINUTES cost = 8 //20% discount! cant_discount = TRUE @@ -43,7 +41,6 @@ desc = "When inserted into a tablet, this cartridge gives you four opportunities to \ detonate tablets 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." - progression_minimum = 20 MINUTES item = /obj/item/computer_disk/virus/detomatix cost = 6 restricted = TRUE @@ -64,7 +61,7 @@ name = "Pizza Bomb" desc = "A pizza box with a bomb cunningly attached to the lid. The timer needs to be set by opening the box; afterwards, \ opening the box again will trigger the detonation after the timer has elapsed. Comes with free pizza, for you or your target!" - progression_minimum = 30 MINUTES + progression_minimum = 15 MINUTES item = /obj/item/pizzabox/bomb cost = 6 surplus = 8 @@ -82,7 +79,6 @@ /datum/uplink_item/explosives/syndicate_bomb/emp name = "Syndicate EMP Bomb" desc = "A variation of the syndicate bomb designed to produce a large EMP effect." - progression_minimum = 30 MINUTES item = /obj/item/sbeacondrop/emp cost = 7 diff --git a/code/modules/uplink/uplink_items/implant.dm b/code/modules/uplink/uplink_items/implant.dm index 34fc9eedb0ff1d..87c9fd6c96c07f 100644 --- a/code/modules/uplink/uplink_items/implant.dm +++ b/code/modules/uplink/uplink_items/implant.dm @@ -9,11 +9,14 @@ /datum/uplink_item/implants/freedom name = "Freedom Implant" - desc = "An implant injected into the body and later activated at the user's will. It will attempt to free the \ - user from common restraints such as handcuffs." + desc = "Can be activated to release common restraints such as handcuffs, legcuffs, and even bolas tethered around the legs." item = /obj/item/storage/box/syndie_kit/imp_freedom cost = 5 +/datum/uplink_item/implants/freedom/New() + . = ..() + desc += " Implant has enough energy for [FREEDOM_IMPLANT_CHARGES] uses before it becomes inert and harmlessly self-destructs." + /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. \ diff --git a/code/modules/uplink/uplink_items/job.dm b/code/modules/uplink/uplink_items/job.dm index e585b07bb5fb6d..dca197774716f1 100644 --- a/code/modules/uplink/uplink_items/job.dm +++ b/code/modules/uplink/uplink_items/job.dm @@ -150,7 +150,6 @@ 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." - progression_minimum = 10 MINUTES item = /obj/item/reagent_containers/hypospray/medipen/magillitis cost = 15 restricted_roles = list(JOB_GENETICIST, JOB_RESEARCH_DIRECTOR) @@ -159,7 +158,6 @@ name = "Box of Gorilla Cubes" desc = "A box with three Waffle Co. brand gorilla cubes. Eat big to get big. \ Caution: Product may rehydrate when exposed to water." - progression_minimum = 15 MINUTES item = /obj/item/storage/box/gorillacubes cost = 6 restricted_roles = list(JOB_GENETICIST, JOB_RESEARCH_DIRECTOR) @@ -209,7 +207,8 @@ name = "Kinetic Accelerator Pressure Mod" desc = "A modification kit which allows Kinetic Accelerators to do greatly increased damage while indoors. \ Occupies 35% mod capacity." - progression_minimum = 30 MINUTES + // While less deadly than a revolver it does have infinite ammo + progression_minimum = 15 MINUTES 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! @@ -220,7 +219,6 @@ 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." - progression_minimum = 20 MINUTES cost = 12 item = /obj/item/storage/box/syndie_kit/mimery restricted_roles = list(JOB_MIME) @@ -238,7 +236,7 @@ /datum/uplink_item/role_restricted/chemical_gun name = "Reagent Dartgun" desc = "A heavily modified syringe gun which is capable of synthesizing its own chemical darts using input reagents. Can hold 90u of reagents." - progression_minimum = 20 MINUTES + progression_minimum = 15 MINUTES item = /obj/item/gun/chem cost = 12 restricted_roles = list(JOB_CHEMIST, JOB_CHIEF_MEDICAL_OFFICER, JOB_BOTANIST) @@ -246,7 +244,6 @@ /datum/uplink_item/role_restricted/pie_cannon name = "Banana Cream Pie Cannon" desc = "A special pie cannon for a special clown, this gadget can hold up to 20 pies and automatically fabricates one every two seconds!" - progression_minimum = 10 MINUTES cost = 10 item = /obj/item/pneumatic_cannon/pie/selfcharge restricted_roles = list(JOB_CLOWN) @@ -276,9 +273,6 @@ someone saves them or they manage to crawl out. Be sure not to ram into any walls or vending machines, as the springloaded seats \ are very sensitive. Now with our included lube defense mechanism which will protect you against any angry shitcurity! \ Premium features can be unlocked with a cryptographic sequencer!" - // It has a low progression cost because it's the sort of item that only works well early in the round - // Plus, it costs all your TC, and it's not an instant kill tool. - progression_minimum = 5 MINUTES item = /obj/vehicle/sealed/car/clowncar cost = 20 restricted_roles = list(JOB_CLOWN) @@ -290,9 +284,6 @@ His Grace grants gradual regeneration and complete stun immunity to His wielder, but be wary: if He gets too hungry, He will become impossible to drop and eventually kill you if not fed. \ However, if left alone for long enough, He will fall back to slumber. \ To activate His Grace, simply unlatch Him." - // It has a low progression cost because it's the sort of item that only works well early in the round - // Plus, it costs all your TC and will lock your uplink. - progression_minimum = 5 MINUTES lock_other_purchases = TRUE cant_discount = TRUE item = /obj/item/his_grace diff --git a/code/modules/uplink/uplink_items/nukeops.dm b/code/modules/uplink/uplink_items/nukeops.dm index 632d4cc2717f44..78dedc0c07261b 100644 --- a/code/modules/uplink/uplink_items/nukeops.dm +++ b/code/modules/uplink/uplink_items/nukeops.dm @@ -498,6 +498,16 @@ cost = 10 purchasable_from = UPLINK_NUKE_OPS +/datum/uplink_item/bundles_tc/cowboy + name = "Syndicate Outlaw Kit" + desc = "There've been high tales of an outlaw 'round these parts. A fella so ruthless and efficient no ranger could ever capture 'em. \ + Now you can be just like 'em! \ + This kit contains armor-lined cowboy equipment, a custom revolver and holster, and a horse with a complimentary apple to tame. \ + A lighter is also included, though you must supply your own smokes." + item = /obj/item/storage/box/syndie_kit/cowboy + cost = 18 + purchasable_from = UPLINK_NUKE_OPS + // Mech related gear /datum/uplink_category/mech diff --git a/code/modules/uplink/uplink_items/stealthy.dm b/code/modules/uplink/uplink_items/stealthy.dm index 491f8e8e99d6d7..2f205a9d0bd692 100644 --- a/code/modules/uplink/uplink_items/stealthy.dm +++ b/code/modules/uplink/uplink_items/stealthy.dm @@ -65,7 +65,6 @@ desc = "This box contains a guide on how to craft masterful works of origami, allowing you to transform normal pieces of paper into \ perfectly aerodynamic (and potentially lethal) paper airplanes." item = /obj/item/storage/box/syndie_kit/origami_bundle - progression_minimum = 10 MINUTES cost = 4 surplus = 0 purchasable_from = ~UPLINK_NUKE_OPS //clown ops intentionally left in, because that seems like some s-tier shenanigans. diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index fdb53c47572cb5..0652c554b8a4af 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -323,7 +323,7 @@ if(!ai.linked_core) // we probably shouldnt gib AIs with a core unlucky_ai = occupant ai.investigate_log("has been gibbed by having their mech destroyed.", INVESTIGATE_DEATHS) - ai.gib() //No wreck, no AI to recover + ai.gib(DROP_ALL_REMAINS) //No wreck, no AI to recover else mob_exit(ai,silent = TRUE, forced = TRUE) // so we dont ghost the AI continue diff --git a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm index dae449d8388b40..e3926aa7d3502e 100644 --- a/code/modules/vehicles/mecha/combat/savannah_ivanov.dm +++ b/code/modules/vehicles/mecha/combat/savannah_ivanov.dm @@ -212,7 +212,7 @@ to_chat(crushed_victim, span_userdanger("[chassis] crashes down on you from above!")) if(crushed_victim.stat != CONSCIOUS) crushed_victim.investigate_log("has been gibbed by a falling Savannah Ivanov mech.", INVESTIGATE_DEATHS) - crushed_victim.gib(FALSE, FALSE, FALSE) + crushed_victim.gib(DROP_ALL_REMAINS) continue crushed_victim.adjustBruteLoss(80) diff --git a/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm b/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm index 6aae4adaaeed79..de96f3ad5f6573 100644 --- a/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm +++ b/code/modules/vehicles/mecha/equipment/tools/mining_tools.dm @@ -122,7 +122,7 @@ SEND_SIGNAL(src, COMSIG_MECHA_DRILL_MOB, chassis, target) else target.investigate_log("has been gibbed by [src] (attached to [chassis]).", INVESTIGATE_DEATHS) - target.gib() + target.gib(DROP_ALL_REMAINS) else //drill makes a hole var/obj/item/bodypart/target_part = target.get_bodypart(target.get_random_valid_zone(BODY_ZONE_CHEST)) diff --git a/code/modules/vehicles/mecha/mecha_mob_interaction.dm b/code/modules/vehicles/mecha/mecha_mob_interaction.dm index c5f440ac97e25a..07b13a27ec0540 100644 --- a/code/modules/vehicles/mecha/mecha_mob_interaction.dm +++ b/code/modules/vehicles/mecha/mecha_mob_interaction.dm @@ -120,7 +120,7 @@ if(forced)//This should only happen if there are multiple AIs in a round, and at least one is Malf. if(!AI.linked_core) //if the victim AI has no core AI.investigate_log("has been gibbed by being forced out of their mech by another AI.", INVESTIGATE_DEATHS) - AI.gib() //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced. + AI.gib(DROP_ALL_REMAINS) //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced. AI = null mecha_flags &= ~SILICON_PILOT return diff --git a/code/modules/vehicles/vehicle_key.dm b/code/modules/vehicles/vehicle_key.dm index e1b45d55f0a80b..f6e5f7c4e2882e 100644 --- a/code/modules/vehicles/vehicle_key.dm +++ b/code/modules/vehicles/vehicle_key.dm @@ -41,7 +41,7 @@ switch(user.mind?.get_skill_level(/datum/skill/cleaning)) if(SKILL_LEVEL_NONE to SKILL_LEVEL_NOVICE) //Their mind is too weak to ascend as a janny user.visible_message(span_suicide("[user] is putting \the [src] in [user.p_their()] mouth and is trying to become one with the janicart, but has no idea where to start! It looks like [user.p_theyre()] trying to commit suicide!")) - user.gib() + user.gib(DROP_ALL_REMAINS) return MANUAL_SUICIDE if(SKILL_LEVEL_APPRENTICE to SKILL_LEVEL_JOURNEYMAN) //At least they tried user.visible_message(span_suicide("[user] is putting \the [src] in [user.p_their()] mouth and has inefficiently become one with the janicart! It looks like [user.p_theyre()] trying to commit suicide!")) diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm index 55e19152528220..02daa0ce7e7dd0 100644 --- a/code/modules/vending/autodrobe.dm +++ b/code/modules/vending/autodrobe.dm @@ -66,6 +66,8 @@ "products" = list( /obj/item/clothing/suit/costume/imperium_monk = 1, /obj/item/clothing/suit/chaplainsuit/holidaypriest = 1, + /obj/item/clothing/suit/chaplainsuit/habit = 1, + /obj/item/clothing/head/chaplain/habit_veil = 1, /obj/item/clothing/suit/chaplainsuit/whiterobe = 1, /obj/item/clothing/head/wizard/marisa/fake = 1, /obj/item/clothing/suit/wizrobe/marisa/fake = 1, diff --git a/code/modules/vending/drinnerware.dm b/code/modules/vending/drinnerware.dm index 2e00d9d2a01a41..c37750a2d3d8e4 100644 --- a/code/modules/vending/drinnerware.dm +++ b/code/modules/vending/drinnerware.dm @@ -14,6 +14,7 @@ /obj/item/kitchen/spoon/soup_ladle = 3, /obj/item/clothing/suit/apron/chef = 2, /obj/item/kitchen/rollingpin = 2, + /obj/item/kitchen/tongs = 2, /obj/item/knife/kitchen = 2, ), ), diff --git a/code/modules/vending/games.dm b/code/modules/vending/games.dm index 80fb1350841987..e51205c00e4a06 100644 --- a/code/modules/vending/games.dm +++ b/code/modules/vending/games.dm @@ -56,6 +56,7 @@ /obj/item/skillchip/sabrage = 2, /obj/item/skillchip/useless_adapter = 5, /obj/item/skillchip/wine_taster = 2, + /obj/item/skillchip/master_angler = 2, ), ), list( diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index 576cbb0b8b284c..ad1c63e7e796f3 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -19,6 +19,7 @@ /obj/item/stack/medical/bone_gel = 4, /obj/item/cane/white = 2, /obj/item/clothing/glasses/eyepatch/medical = 2, + /obj/item/storage/box/bandages = 2, ) contraband = list( /obj/item/storage/box/gum/happiness = 3, diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm index 4fd120bdc48759..66badd4adf2703 100644 --- a/code/modules/vending/medical_wall.dm +++ b/code/modules/vending/medical_wall.dm @@ -15,6 +15,7 @@ /obj/item/reagent_containers/medigel/sterilizine = 1, /obj/item/healthanalyzer/simple = 2, /obj/item/stack/medical/bone_gel = 2, + /obj/item/storage/box/bandages = 1, ) contraband = list( /obj/item/reagent_containers/pill/tox = 2, diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index 6a7edd8e854133..9b5af87ab44c6a 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -29,6 +29,7 @@ /obj/item/clothing/gloves/tackler = 5, /obj/item/grenade/stingbang = 1, /obj/item/watertank/pepperspray = 2, + /obj/item/storage/belt/holster/energy = 4, ) refill_canister = /obj/item/vending_refill/security default_price = PAYCHECK_CREW diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm index 2a5360c1ed2eb7..e43314aa3076b3 100644 --- a/code/modules/vending/wardrobes.dm +++ b/code/modules/vending/wardrobes.dm @@ -524,6 +524,8 @@ /obj/item/storage/backpack/cultpack = 1, /obj/item/storage/fancy/candle_box = 2, /obj/item/radio/headset/headset_srv = 2, + /obj/item/clothing/suit/chaplainsuit/habit = 1, + /obj/item/clothing/head/chaplain/habit_veil = 1, ) contraband = list( /obj/item/toy/plush/ratplush = 1, diff --git a/code/modules/wiremod/shell/drone.dm b/code/modules/wiremod/shell/drone.dm index dce5dca46adfe9..6f7afcfea04962 100644 --- a/code/modules/wiremod/shell/drone.dm +++ b/code/modules/wiremod/shell/drone.dm @@ -32,7 +32,7 @@ /mob/living/circuit_drone/updatehealth() . = ..() if(health < 0) - gib(no_brain = TRUE, no_organs = TRUE, no_bodyparts = TRUE) + gib() /mob/living/circuit_drone/welder_act(mob/living/user, obj/item/tool) . = ..() diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index 4258dc5a304d00..dca26d366d8762 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -74,12 +74,13 @@ if(target.stat == DEAD) var/hp_gained = target.maxHealth target.investigate_log("has been devoured by a zombie.", INVESTIGATE_DEATHS) - target.gib() - // zero as argument for no instant health update - user.adjustBruteLoss(-hp_gained, 0) - user.adjustToxLoss(-hp_gained, 0) - user.adjustFireLoss(-hp_gained, 0) - user.adjustCloneLoss(-hp_gained, 0) - user.updatehealth() - user.adjustOrganLoss(ORGAN_SLOT_BRAIN, -hp_gained) // Zom Bee gibbers "BRAAAAISNSs!1!" + target.gib(DROP_ALL_REMAINS) + var/need_mob_update + need_mob_update = user.adjustBruteLoss(-hp_gained, updating_health = FALSE) + need_mob_update += user.adjustToxLoss(-hp_gained, updating_health = FALSE) + need_mob_update += user.adjustFireLoss(-hp_gained, updating_health = FALSE) + need_mob_update += user.adjustCloneLoss(-hp_gained, updating_health = FALSE) + need_mob_update += user.adjustOrganLoss(ORGAN_SLOT_BRAIN, -hp_gained) // Zom Bee gibbers "BRAAAAISNSs!1!" user.set_nutrition(min(user.nutrition + hp_gained, NUTRITION_LEVEL_FULL)) + if(need_mob_update) + user.updatehealth() diff --git a/config/blanks.json b/config/blanks.json index 299fa67a594b38..f3b38d67bdb4bf 100644 --- a/config/blanks.json +++ b/config/blanks.json @@ -545,7 +545,7 @@ "
", "
By writing and signing this form, you consent to the processing of your personal data by Nanotrasen Corporation.

", "
", - "

Name of offical to take action:

", + "

Name of official to take action:

", "

[___________________________________]

", "

Official Decision:

", "

[___________________________________]

", diff --git a/config/config.txt b/config/config.txt index 8d28b656c30c1b..e8abb56fed5046 100644 --- a/config/config.txt +++ b/config/config.txt @@ -137,11 +137,14 @@ VOTE_PERIOD 600 ## players' votes default to "No vote" (otherwise, default to "No change") # DEFAULT_NO_VOTE -## disable abandon mob -NORESPAWN - -## Respawn delay (deciseconds), which doesn't allow to return to lobby (default 10 minutes) -#RESPAWN_DELAY 6000 +## Determines if players can respawn after death +## 0 = Cannot respawn (default) +## 1 = Can respawn +## 2 = Can respawn if choosing a different character +ALLOW_RESPAWN 0 + +## Respawn delay (deciseconds), which doesn't allow to return to lobby +RESPAWN_DELAY 0 ## set a hosted by name for unix platforms HOSTEDBY Yournamehere diff --git a/config/lavaruinblacklist.txt b/config/lavaruinblacklist.txt index 4332260d6becc9..b2574fd7fd62fd 100644 --- a/config/lavaruinblacklist.txt +++ b/config/lavaruinblacklist.txt @@ -11,8 +11,9 @@ ##RESPAWN #_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm -#_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm +_maps/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm #modular_skyrat/modules/mapping/_maps/RandomRuins/LavaRuins/lavaland_surface_syndicate_base1_skyrat.dmm +#_maps/RandomRuins/LavaRuins/skyrat/lavaland_surface_ash_walker1_skyrat.dmm #_maps/RandomRuins/AnywhereRuins/golem_ship.dmm ##SIN @@ -23,13 +24,24 @@ #_maps/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm ##MISC +#_maps/RandomRuins/AnywhereRuins/fountain_hall.dmm #_maps/RandomRuins/LavaRuins/lavaland_surface_automated_trade_outpost.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_gaia.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_library.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_mookvillage.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_tomb.dmm #_maps/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm +#_maps/RandomRuins/LavaRuins/lavaland_surface_watcher_grave.dmm #_maps/RandomRuins/LavaRuins/lavaland_surface_ww_vault.dmm -#_maps/RandomRuins/LavaRuins/lavaland_surface_automated_trade_outpost.dmm -#_maps/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm -#_maps/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm #_maps/RandomRuins/LavaRuins/lavaland_surface_wwiioutpost.dmm +<<<<<<< HEAD #_maps/RandomRuins/LavaRuins/lavaland_surface_tomb.dmm #_maps/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm #_maps/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm @@ -39,4 +51,7 @@ #_maps/RandomRuins/LavaRuins/lavaland_surface_elephant_graveyard.dmm #_maps/RandomRuins/LavaRuins/lavaland_surface_library.dmm #_maps/RandomRuins/AnywhereRuins/fountain_hall.dmm -#_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm \ No newline at end of file +#_maps/RandomRuins/LavaRuins/lavaland_surface_phonebooth.dmm +======= +#_maps/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm +>>>>>>> 0f5d14e68b1 (Mook village and basic mook refactor (#78789)) diff --git a/html/changelogs/AutoChangeLog-pr-23524.yml b/html/changelogs/AutoChangeLog-pr-23524.yml new file mode 100644 index 00000000000000..361042dc62ebe2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23524.yml @@ -0,0 +1,4 @@ +author: "nikothedude" +delete-after: True +changes: + - rscadd: "Sec/Medhuds can now see a small ! if a person has the DNR quick, as well as see a blurb in examine about it" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23580.yml b/html/changelogs/AutoChangeLog-pr-23580.yml new file mode 100644 index 00000000000000..291734c3a95454 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-23580.yml @@ -0,0 +1,4 @@ +author: "burgerenergy" +delete-after: True +changes: + - qol: "Both versions of Interdyne received some map touch ups. Standouts include; a fax machine, dorm locks, a make shift brig area, a revamped bathroom, botany, and kitchen, as well as backporting Icemoon improvements to the Lavaland version." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23964.yml b/html/changelogs/AutoChangeLog-pr-23964.yml deleted file mode 100644 index a5a9ca339e284f..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23964.yml +++ /dev/null @@ -1,11 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - refactor: "Hivelords and Legions now use the basic mob framework. Please report any unusual behaviour." - - rscadd: "Hivelords shed more spawn when they are attacked." - - rscadd: "Legions have learned how to fling their skulls across long distances." - - rscadd: "Legions can heal other lavaland mobs with their skulls." - - rscadd: "Legions are better at preserving corpses they consume, and sometimes make use of their radios." - - rscadd: "Legions may leave behind an unpleasant surprise after you are rescued from them." - - balance: "The crew monitoring console will now display you as dead if you are dead, an critically injured if in crit, rather than setting those icons purely based on your current health." - - qol: "You won't continue burning to a husk if consumed by a snow legion after being set on fire by an ice drake." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23969.yml b/html/changelogs/AutoChangeLog-pr-23969.yml deleted file mode 100644 index e68c1f16a513ab..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23969.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "A.C.M.O." -delete-after: True -changes: - - bugfix: "Fixes the death sandwich, making it safe to examine." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23970.yml b/html/changelogs/AutoChangeLog-pr-23970.yml deleted file mode 100644 index 90c3560af2270d..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23970.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "Fix water puddle runtime when washing items" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23971.yml b/html/changelogs/AutoChangeLog-pr-23971.yml deleted file mode 100644 index 77882c152d7f0a..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23971.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Rhials" -delete-after: True -changes: - - bugfix: "The Polymorph Belt should now update its sprite when active." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23972.yml b/html/changelogs/AutoChangeLog-pr-23972.yml deleted file mode 100644 index cd5835f48b8c35..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23972.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - refactor: "Snakes have been refactored into basic mobs. This means that they are a bit more intelligent than previous snakes, making them more docile and averse to harming people (unless otherwise provoked). They do chomp all sorts of mice though. You can feed them a dead mouse to make them your friend if you'd want that." - - sound: "If you listen closely to snakes, you might be able to hear a small hissing sound..." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23973.yml b/html/changelogs/AutoChangeLog-pr-23973.yml deleted file mode 100644 index c78f143cc15f51..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23973.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - rscadd: "Add drinking water causes drunk mobs to become sober" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23974.yml b/html/changelogs/AutoChangeLog-pr-23974.yml deleted file mode 100644 index 0cb3b6568f5cc0..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23974.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - code_imp: "adds a gas connector component that allows connection to the atmos piping system without the need of repathing" - - refactor: "changes the cryo machine to use this new system" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23976.yml b/html/changelogs/AutoChangeLog-pr-23976.yml deleted file mode 100644 index 5069c636850827..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23976.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - balance: "Head revolutionaries and heads of staff are no longer immediately considered disqualified when going AFK or disconnecting and are given a 2 minute grace period." - - admin: "Admins now get a log when a head revolutionary or head of staff disconnects or goes AFK during a revolution. They also get the same log 1 minute after to give them a chance to act on the information." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23978.yml b/html/changelogs/AutoChangeLog-pr-23978.yml deleted file mode 100644 index b42cf16ce625bc..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23978.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - code_imp: "Robot Customers have recently been touched codewise, please report any bugs or unexpected behavior as there really should not be any." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23979.yml b/html/changelogs/AutoChangeLog-pr-23979.yml deleted file mode 100644 index 3093dac19e2277..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23979.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - admin: "There is now a tool to apply a DNA Infuser entry to any human." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23980.yml b/html/changelogs/AutoChangeLog-pr-23980.yml deleted file mode 100644 index febc6a692b7b7b..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23980.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - rscadd: "Add candle design to biogenerator" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23981.yml b/html/changelogs/AutoChangeLog-pr-23981.yml deleted file mode 100644 index 29314e499ecc11..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23981.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - qol: "allowed names to start with a number if AI/Borg" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23982.yml b/html/changelogs/AutoChangeLog-pr-23982.yml deleted file mode 100644 index 41b052985ddcbf..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23982.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "fixed lobstrosities becoming unmovable when killed during their charge windup" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23983.yml b/html/changelogs/AutoChangeLog-pr-23983.yml deleted file mode 100644 index 7f6595037bfff6..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23983.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "dead bodies now cool down to room temperature over time" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23984.yml b/html/changelogs/AutoChangeLog-pr-23984.yml deleted file mode 100644 index 4cea4c40d9ceec..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23984.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - balance: "Diabetics rejoice! Nerfed sugar OD/hyperglycaemic shock to be an immediate KO followed by drowsiness afterwards until the OD is gone." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23985.yml b/html/changelogs/AutoChangeLog-pr-23985.yml deleted file mode 100644 index eb6c6b29171d01..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23985.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SkyratBot" -delete-after: True -changes: - - bugfix: "The Nuke Op MODsuit AI downloader only works once per purchase, as intended." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-23986.yml b/html/changelogs/AutoChangeLog-pr-23986.yml deleted file mode 100644 index 6febb0c667cf05..00000000000000 --- a/html/changelogs/AutoChangeLog-pr-23986.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "sergeirocks100" -delete-after: True -changes: - - bugfix: "Undershirts will now look as they should if you have a body type that differs from the gender default." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-24174.yml b/html/changelogs/AutoChangeLog-pr-24174.yml new file mode 100644 index 00000000000000..cd5b645f5c9e0f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-24174.yml @@ -0,0 +1,6 @@ +author: "Hatterhat" +delete-after: True +changes: + - bugfix: "The CIN replicator medipen pouch and pocket first-aid kit no longer have bag-like functionality (scooping/the action button), which they didn't need to fit in your pockets anyway." + - balance: "First-aid pouches (the ones through Cargo for 300 cr) now have five slots; one up from four." + - rscadd: "Ammo pouches can now be reskinned into casing pouches, which let them hold ten individual shell casings in your pocket. Yes, this includes shotgun shells. This is also primarily intended for shotgun users." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-24175.yml b/html/changelogs/AutoChangeLog-pr-24175.yml new file mode 100644 index 00000000000000..6f65e92a12f3f0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-24175.yml @@ -0,0 +1,5 @@ +author: "Hatterhat" +delete-after: True +changes: + - spellcheck: ".50 BMG surplus, incendiary, and marksman have now been given more SR-lore-accurate names." + - bugfix: "10mm Reaper can't be printed in ammo benches like it was intended. If you don't know what this means, don't worry about it." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-24283.yml b/html/changelogs/AutoChangeLog-pr-24283.yml new file mode 100644 index 00000000000000..b2c323707047e7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-24283.yml @@ -0,0 +1,10 @@ +author: "LT3" +delete-after: True +changes: + - rscadd: "Introducing Nanotrasen Wave! A Nanotrasen exclusive, Waveallows your PDA to be charged wirelessly through microwave frequencies. You can Wave-charge your device by placing it inside a compatible microwave and selecting the charge mode." + - rscadd: "Microwaves can be upgraded to add wireless charging" + - rscadd: "Cell-swappable microwave for the engineer on-the-go" + - rscadd: "Microwave now has a wire to swap charge/cook modes" + - rscadd: "Furnishings RCD upgrade now includes wireless microwave" + - rscadd: "Tramstation and Birdshot engineering break rooms now have microwave and donk pockets. Some microwaves come pre-equipped with wireless charging and an upgraded cell." + - bugfix: "The microwave in the snowdin ruin is now real, not a fluff prop" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-24284.yml b/html/changelogs/AutoChangeLog-pr-24284.yml new file mode 100644 index 00000000000000..78e4247ee9f58a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-24284.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - refactor: "Gorillas now use the basic mob framework. Please report any unusual side effects." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-24289.yml b/html/changelogs/AutoChangeLog-pr-24289.yml new file mode 100644 index 00000000000000..14a3193bacce17 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-24289.yml @@ -0,0 +1,6 @@ +author: "SkyratBot" +delete-after: True +changes: + - bugfix: "The Holy Hand Grenade's effect on revealing a revenant had its duration accidentally nerfed, it is now back to 10 seconds." + - bugfix: "Revenant midrounds should now properly run." + - bugfix: "Revenant harvesting should now let you actually pass the final do_after so you can harvest that sweet essence." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-24291.yml b/html/changelogs/AutoChangeLog-pr-24291.yml new file mode 100644 index 00000000000000..3f65148a845fc0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-24291.yml @@ -0,0 +1,4 @@ +author: "SkyratBot" +delete-after: True +changes: + - qol: "The rollerdome is now better - the dance floor works now, and the bar is groovier." \ No newline at end of file diff --git a/html/changelogs/archive/2023-09.yml b/html/changelogs/archive/2023-09.yml index 976efdac110c16..a45513671cec74 100644 --- a/html/changelogs/archive/2023-09.yml +++ b/html/changelogs/archive/2023-09.yml @@ -1154,3 +1154,109 @@ tattle: - qol: Basic animals now make sounds for audible emotes - sound: Added new sound effects for chicks, chickens, crabs, and insects +2023-09-29: + A.C.M.O.: + - bugfix: Fixes the death sandwich, making it safe to examine. + BurgerBB: + - bugfix: Scrubbers and Vents will no longer reset their settings on map load. + GoldenAlpharex: + - server: Added a way for calls to be made to interfere with player ranks on live + servers (updating the players if they're connected) from outside of the game. + Rhials: + - qol: The freedom implant has received minor feedback and other minor usage improvements. + - bugfix: The Polymorph Belt should now update its sprite when active. + SkyratBot: + - qol: allowed names to start with a number if AI/Borg + - rscadd: Add drinking water causes drunk mobs to become sober + - balance: Diabetics rejoice! Nerfed sugar OD/hyperglycaemic shock to be an immediate + KO followed by drowsiness afterwards until the OD is gone. + - code_imp: Robot Customers have recently been touched codewise, please report any + bugs or unexpected behavior as there really should not be any. + - admin: There is now a tool to apply a DNA Infuser entry to any human. + - bugfix: The Nuke Op MODsuit AI downloader only works once per purchase, as intended. + - code_imp: adds a gas connector component that allows connection to the atmos piping + system without the need of repathing + - refactor: changes the cryo machine to use this new system + - refactor: Hivelords and Legions now use the basic mob framework. Please report + any unusual behaviour. + - rscadd: Hivelords shed more spawn when they are attacked. + - rscadd: Legions have learned how to fling their skulls across long distances. + - rscadd: Legions can heal other lavaland mobs with their skulls. + - rscadd: Legions are better at preserving corpses they consume, and sometimes make + use of their radios. + - rscadd: Legions may leave behind an unpleasant surprise after you are rescued + from them. + - balance: The crew monitoring console will now display you as dead if you are dead, + an critically injured if in crit, rather than setting those icons purely based + on your current health. + - qol: You won't continue burning to a husk if consumed by a snow legion after being + set on fire by an ice drake. + - bugfix: removes incorrect stack traces when using some admin secrets + - balance: Head revolutionaries and heads of staff are no longer immediately considered + disqualified when going AFK or disconnecting and are given a 2 minute grace + period. + - admin: Admins now get a log when a head revolutionary or head of staff disconnects + or goes AFK during a revolution. They also get the same log 1 minute after to + give them a chance to act on the information. + - refactor: Snakes have been refactored into basic mobs. This means that they are + a bit more intelligent than previous snakes, making them more docile and averse + to harming people (unless otherwise provoked). They do chomp all sorts of mice + though. You can feed them a dead mouse to make them your friend if you'd want + that. + - sound: If you listen closely to snakes, you might be able to hear a small hissing + sound... + - bugfix: fixed lobstrosities becoming unmovable when killed during their charge + windup + - bugfix: Splattercasting resets your blood to normal values when you transsform + into a vampire. + - bugfix: Gaining a new species will set your blood volume down to the normal volume + levels if higher than normal. + - bugfix: Fix water puddle runtime when washing items + - bugfix: the parole status and discharged status are now green and blue respectively + in the security record interface + - bugfix: Dimensional Anomalies no longer destroy wall-mounted equipment. + - code_imp: Your bodytype now decides what gendered sounds you make. + - bugfix: Fixed crabs not correctly (kinda) walking sideway. + - bugfix: dead bodies now cool down to room temperature over time + - rscadd: Add candle design to biogenerator + sergeirocks100: + - bugfix: Undershirts will now look as they should if you have a body type that + differs from the gender default. + softcerv: + - rscadd: Adds in the ability for certain NIFSofts to be kept between rounds. +2023-09-30: + DrDiasyl aka DrTuxedo: + - balance: Holsters can now be clipped to any suit, and house Captain antique gun + and HoS gun. You now can buy holsters from the SecTech premium section. + Paxilmaniac: + - qol: The half mask respirator can have its TTS voice muffling properties toggled + with control click + - qol: Icecats are now listed in the round end report, so you can see who was up + icing they cat + - bugfix: Icecats should hopefully spawn with their special language correctly now + SkyratBot: + - code_imp: removed some redundant code for airlocks + - admin: Mob abilities can be granted to arbitrary mobs via the VV menu in a similar + way to spells. + - bugfix: Lavaland syndicate operatives can no longer trivially use the jetpack + on their modsuit to fly over the lava. + - bugfix: If two cosmic heretics ascend in the same round, their star gazer survival + will be linked to each individual heretic and not shared by just one of them. + - bugfix: You can't click the Knock heretic portal to join as a mob while already + signed up to become a mob. + - balance: Cosmic heretics can't order the Star Gazer around while jaunting. + - balance: The Knock Heretic portal cannot summon Flesh Worms, but can summon Fire + Sharks. + - balance: The Knock Heretic portal will disperse if its creator is killed. + - rscadd: SM crystal can now dust someone or something if it falls on it. + - bugfix: The reverse revolver now looks like a normal Syndicate revolver on inspection. + - bugfix: fixed the stamp in the metastation CMO office always spawning on the floor + - bugfix: You can now spray paint the SM without getting dusted + Smol42: + - rscadd: Added some new hairstyles + Zergspower: + - bugfix: Crew Monitor works again properly + nikothedude: + - rscadd: A waterbreathing quirk + - qol: Waterbreathing is now documented on species pages of the species that have + it diff --git a/html/changelogs/archive/2023-10.yml b/html/changelogs/archive/2023-10.yml new file mode 100644 index 00000000000000..265d5d5136b4e9 --- /dev/null +++ b/html/changelogs/archive/2023-10.yml @@ -0,0 +1,615 @@ +2023-10-01: + Hatterhat: + - balance: Bullets have had their base type's wound bonus reduced back to 0, down + from 20, because wounds are actually quite punishing. Funnily enough, most bullets + already have modified wound bonuses - except c9mm, c10mm, and most incendiaries, + so this probably doesn't change much. + - balance: .50 (used in the snipers and renamed to .416 or whatever) is now back + to TG balance standards. Knockdown on hit, 60 instead of 110 damage, etc. etc. + - bugfix: .50 Soporific was removed because disruptor ammo was right there and nobody + realized it existed. + - bugfix: After review of a missing equipment complaint, Nanotrasen remembered to + pay Lopland's quartermasters to put the customary flashbang and teargas grenade + boxes into the Void Raptor's armory. + Melbert: + - qol: Examine blocked out roundstart / latejoin job information. + - qol: Captain gets a little bit more information about how their radio works roundstart. + - bugfix: Fixed roundstart players not getting radio information. + Paxilmaniac: + - image: The buttondown shirts (underwear) have been updated with a better look + and more contrasted palette + SkyratBot: + - rscadd: A new export has arrived in the imports section, the Galactic Materials + Market! You can use this to buy and sell minerals for profit or cost, as well + as stock your station when you don't have any miners. + - rscadd: Insert sheets of minerals into the Galactic Materials Market to convert + them into a stock block, allowing you to lock in your price for 5 minutes. Wait + too long and it'll be subject to market value again! + - rscadd: Minerals can be bought on the market either using the station's cargo + budget by cargo crew, or privately by everyone else. + - rscdel: Any material stacks that can be bought and sold on the market before have + been removed from the cargo catalog. + - rscadd: Adds Bitrunning to supply department- a semi-offstation role that rewards + teamwork. + - rscadd: Adds new machines to complement the job- net pod, quantum server, quantum + consoles, and the nexacache vendor. + - rscadd: Adds several new maps which can be loaded and unloaded at will. + - rscadd: Some flair for the new bitrunning vendor. + - rscadd: Adds a new antagonist for the virtual domain only. Short lived ghost role + that fights bitrunners. + - rscdel: Removes the BEPIS machine, moves its tech into the Bitrunning vendor. + - bugfix: Fixes missing baseturfs and clowns in mining planet VDOM.. + - qol: Font settings in the chat panel applies to all text now. + - image: new chaplain outfit + - bugfix: Blob spores will respond to rallies more reliably (it won't runtime every + time they try and pathfind). + - bugfix: Blobbernaut pain animation overlays should align with the direction the + mob is facing instead of always facing South + - refactor: Blob spores, zombies, and blobbernauts now all use the basic mob framework. + They should work the same, but please report any issues. + - bugfix: Added warden to list of default required enemies for rulesets. + - bugfix: Blob Zombies and Blobbernauts have had their attack speed restored to + its original value + - refactor: Supermatter Spiders have been refactored into basic mobs, on the extremely + off chance you spot one and also notice any weird bugs regarding it, please + report it. + - balance: There are now 3 roundstart cyborg job slots open by default. + - rscadd: Quantum servers now talk over supply channel when they're done cooling + off. Go outside! + - bugfix: You can no longer use dragon swoop to bypass cordons. + - bugfix: Netpod brain damage is now properly reduced upon server upgrades. + - bugfix: Fixed an bug where swapping bodies in vdom prevented you from disconnecting. + - bugfix: Fixed a bug where a quantum server could get locked out of loading new + domains. + - bugfix: Changed quantum console UI to display "no bandwidth" rather than "none" + - bugfix: Actually fixed the hooked item exploit. + - rscadd: Heretic Rebalance + - balance: Researching the Main Knowledge paths that unlock Side Paths will grant + one Side Point that can be used only on those side paths. You can still spend + normal knowledge points on them if you wish. + - balance: Rune drawing time has been reduced from 30->20 seconds. Codex drawing + time has been reduced from 15->8. + - balance: 'Codex Cicatrix is now a roundstart knowledge, works as an amber focus + when held in-hand and opened, and has had its recipe changed to: 1 of any non-standard + pen (literally anything that isn''t the base pen), any book, and either animal + hide OR a corpse, any kind.' + - code_imp: Added support for using a list inside ritual requirements and a special + 'snowflake check' rituals can utilize. + - balance: The first non-path knowledge, the Mansus Hand Mark, has had its cost + reduced from 2->1 points. + - bugfix: Aloe and other baked foods that don't have reagents can be baked again + without turning to ash + Vekter: + - bugfix: Fixes the missing grinder in Birdshot's Virology department + jjpark-kb: + - bugfix: the ashwalker tendril will allow you to respawn again (the tendril blessing) + - bugfix: the round end report will accurately report ashwalker sacrifices + nikothedude: + - code_imp: Gauze removal is now handled by the gauze's destroy instead of seep_gauze + ninjanomnom: + - rscdel: An easter egg plushie that was spawning where it shouldn't has been brought + back home. + - rscadd: The secure closet can now spawn live gibtonite, enjoy your free bomb. +2023-10-02: + SkyratBot: + - balance: Sci now has access to the materials & canisters section in their departmental + order console + - rscadd: Expanded the fishing portal generator. It now comes with several portal + options that can be unlocked by performing fish scanning experiments, which + also award a modest amount of techweb points. + - balance: The fishing portal generator is now buildable and no longer orderable. + The board can be printed from cargo, service and science lathes. + - balance: Advanced fishing tech is no longer a BEPIS design. It now requires the + base fish scanning experiment and 2000 points to be unlocked. + - rscadd: The advanced fishing rod now comes with an incorporated experiscanner + specific for fish scanning. + - rscadd: Added a new skillchip that may change the icon of the "fish" shown in + the minigame UI to less generic ones. Reaching master level in fishing also + does that. + - qol: The experiment handler UI no longer shows unselectable experiments. + - bugfix: Security officers can now download the crew manifest PDA app that they + start with. + - rscadd: Wizards who complete the grand ritual can now gift everyone with eternal + life + distributivgesetz: + - bugfix: Font scaling in TGUI chat has been reverted to its original implementation. + softcerv: + - rscadd: Adds the mini-soulcatcher, a more lightweight soulcatcher that can be + attached to objects + - rscadd: Adds in the RSD brain interface, an item that allows for soulcatcher souls, + that died within a round and were scanned, to be transferred to a new brain. + - rscadd: Adds in the NIFSoft Scryer, a NIFSoft that gives the user a Scryer they + can use to communicate with other Scryer users. +2023-10-03: + SkyratBot: + - bugfix: fixed misplaced door on syndicate listening post + - rscadd: adds boxes of bandages, a quick healing item + - bugfix: Spiders, Morphs, Fire Sharks, and Regal Rats no longer have a reduced + click speed. + - image: Railings have had a visual update. + projectkepler-ru: + - balance: reverted the nerf on the X-01 + softcerv: + - rscadd: Adds in Purpura Eye, a NIFSoft that allows for the user to hypnotize others. + vinylspiders: + - bugfix: the pollution system will no longer try (and fail) to pollute a turf from + nullspace +2023-10-04: + Coded by Jacquerel, Sprited by Dalmationer: + - rscadd: Added tongs to the kitchen, which you can use to manipulate food from + further away + Fazzie: + - rscadd: Added a budget solar crate to the derelict teleporter room + - rscadd: Added a solar panel control to the north derelict solar + - qol: The derelict's AI coridoor is now shorter and prettier + - rscadd: A lot of new content has been added to the beach away mission + - qol: It also looks substantially better, too! + Motho: + - bugfix: An anonymous visitor to the NSV Void Raptor has turned in security's biosuit + to the lost and found. Security officers everywhere rejoice. + Paxilmaniac: + - rscadd: A significantly smaller selection of new SolFed weapons has taken the + place of the now missing Armadyne selection. + - rscdel: So basically, all of Armadyne is gone. + - qol: A large number of weapons now use singular interchangeable magazine types, + rather than having seven different 9mm magazines to do the same thing + - balance: Any weapon that was replaced is going to have different stats from what + they used to be, numbers subject to change + - sound: Several new firing sounds from TGMC for the new weapons + - image: Whole collection of new ammo, gun, case, and so on sprites by myself + - image: Gun case worn on the back sprites done by Zydras + - code_imp: Where applicable, containers spawning gun stuff use generate_items_inside, + which is much neater than spamming new x(src) + SkyratBot: + - bugfix: The Syndicate have fired their previous construction company after poor + results in recent outposts. + - qol: Departmental order consoles now alert their department via radio when their + cooldown expires + - bugfix: Fix butchered monkeys to transfer reagents and diseases to meat + - bugfix: Fix organs having no DNA and become bloody when violently removed. + - refactor: Raw Prophets now use the basic mob framework. Please report any unusual + behaviour. + - bugfix: Cutting open a hand-pressed paper bundle no longer deletes all of the + paper. + - balance: Kudzu will now be destroyed by adverse weather. + - balance: Kudzu will no longer spread over holes. + - refactor: fixed many instances of updatehealth() either being called needlessly + or not at all within on_mob_life() and in various other parts of the code + - refactor: damage procs now return useful information--the actual net change in + damage on the mob. added a unit test for this + - bugfix: Some icons for selecting character preferences are no longer scaled incorrectly. + ninjanomnom: + - admin: Appearance vars in VV now display instead of being left blank +2023-10-05: + FIoppie: + - sound: '*flap now makes a fluttering noise for moth wings' + - sound: Moths now have a death sound + - qol: '*tremble emote now is just "trembles!" instead of "trembles in fear!"' + LT3: + - image: Added colourable arm and leg wraps + Melbert: + - qol: Moved a lot of maintenance spawnpoints out of non-maintenance rooms. Some + antags (paradox clone, fugitives, nightmares, spiders) are now less likely to + spawn in obvious places like the morgue, tech storage, or dorms rooms. + Motho: + - image: Sector 13's station air alarms and fire alarms have been updated to be + more in line with other frontier station models. + SkyratBot: + - admin: Admins can turn off dynamic rulesets (or force them on despite not meeting + the qualification criteria) on a per-round basis. + - rscadd: The funds the syndicate have been saving by restricting galley access + has been suddenly funneled into a singular mosaic pattern in the experiments + wing. + - balance: CQC legsweeps now cause knockdown instead of paralysis. + - balance: CQC kicks now knockout a target on the floor for ten seconds if they + reach stam crit. Helmet protection shortens the knockout length. + - bugfix: Your heart will no longer be deleted if an admin heals you while you have + corazargh in your system. + - refactor: The cursed heart has been streamlined a bit, and now gives you a visual + cooldown for when you can beat your heart again. + Wallem: + - rscadd: Adds The Hand of Midas, an ancient Egyptian matchlock pistol. + honkpocket: + - bugfix: Extra magazines for all the Foam Force guns are now purchasable from cargo + imports + - rscadd: The Foam Force dart collector MOD modules are now purchasable from cargo + imports + - sound: added a unique racking sfx for the sol 'Renoster' shotgun + softcerv: + - qol: NIFSofts now use the same TGUI as their parent NIF. + tf-4: + - bugfix: Fixed some weirdness with mould mob attacks. + - qol: Mold mobs delete themselves on death. +2023-10-06: + LT3: + - image: Job icon for departmental guards, DS2 and other SR specific jobs are properly + aligned + Majkl-J: + - bugfix: Table to the cafe food processor + RatFromTheJungle: + - balance: Interdyne now spawns with Sidano SMG's, instead of .50 snipers + - bugfix: you can now actually wear the 'LIZARED' top, yippie! + SkyratBot: + - bugfix: The Galactic Materials Market now offers things for sale as it should. + - rscadd: Added blackout, happens when you drink...ALOT + - bugfix: plumbing reaction chamber now balances the ph of it's solution correctly + to the best of it's ability so no guarantees + - code_imp: converted plumbing reaction chamber & mixing chamber UI files to Typescript + - refactor: plumbing mixing chamber now also accepts an TGUI input list to input + it's chemicals + - image: We have received a new shipment of IDs, as the old ones were found out + to be haunted. + - image: Laser tag red team ID has received a massive nerf + - image: Station budget cards have gotten a facelift + - image: Emags and Doorjacks + - bugfix: Numbered prisoner IDs will now be legible + Wallem: + - rscadd: Buffs the Active Sonar module with a radial scan, and makes the power + costs more in-line with other modules. + softcerv: + - bugfix: the ghost role NIF boxes now contain the Purpura Eye NIFSoft + vinylspiders: + - bugfix: fixes gender shaping and height offsets on underwear + - bugfix: female gender shaping now works with digi jumpsuits + - bugfix: fixed rainbow jumpsuit digi sprite +2023-10-07: + GoldenAlpharex: + - bugfix: The round end report will no longer expose people's ckeys for the achievements + they obtained through the round, nor when they're contractor support agents. + LT3: + - bugfix: Adjusted Void Raptor shutters and firelocks in the pharmacy, hallway and + HoP line + - balance: Hypovial capacity now matches bottle capacity + - bugfix: Broken and placeholder hypovials can no longer be printed in the ChemMaster + Melbert: + - qol: AI, cyborg, and PAI camera (photo taking) behavior now uses balloon alerts + and has sound effects associated + - refactor: Refactored AI, cyborg, and PAI camera (photo taking) code + - bugfix: fixed being unable to print photos as a cyborg when below 50% toner, even + though photos only take 5% + SkyratBot: + - bugfix: Engineering borgs can no longer grab and drop their own iron/glass sheet + module. + - bugfix: It is no longer possible to chasm yourself on the geode. Again. + - rscadd: Fish analyzers can now be used to perform fish scanning experiments. + - balance: They can now be singularly bought as a goodie pack for 125 cr each, instead + of a crate of three for 500 cr. + - bugfix: Borgs will no longer become permanently upside-down if tipped over by + multiple people at the same time. + - balance: Despite earlier reports suggesting that the famous lethality of the Regal + Condor was largely a myth, there has been rumors that the gun has once again + started to display its true killing potential on any station that it 'manifests'. + - bugfix: The AI can no longer turn you off if you shapeshift into a robot. + - bugfix: Blood once again appears as small drops instead of splatters during minor + bleeding. + - bugfix: you are now made a ghost faster if you get gibbed + - bugfix: fixed bad food not having bad food reagents + - rscadd: The laser carbine, a weak but fully automatic sidegrade to the normal + laser gun, can now be ordered from cargo. + - bugfix: Adminheal will now properly clear negative mutations as intended. + - bugfix: Ice whelps can now use spells given to them by admins, and people who + have polymorphed into ice whelps can now polymorph back to normal. + - bugfix: Fixed silent catwalks. + - rscadd: Fake moustaches are now poorly slapped on top of what you're wearing + jjpark-kb: + - rscadd: ashwalker nest is now in the NE corner of lavaland + neocloudy: + - bugfix: MetaStation disposal pipes from Cargo to Disposals/the rest of the station + are working again. + nikothedude: + - rscadd: Synthetic wounds! Blunt, Pierce, Slash, Burn, Muscle. See PR 23733 for + more information + - rscadd: Robodrobe now has 2 chilled hercuri sprays for treating synthetic burn + wounds + - rscadd: Robodrobe now has 2 pairs of black gloves to let robotics painlessly meld + T3 synthetic blunt wounds + - balance: 'Synthetic damage multiplier: 1.3 -> 1.0' + - rscadd: '3 new cargo packs to science: 2 chilled hercuri, a synth trauma kit, + and synth medicine' + - balance: Quadruple amputee can now be picked with frail + - rscadd: Interdyne/DS2 now have advanced synthetic trauma kits in their medbays +2023-10-08: + LT3: + - image: Text alignment on ID cards slightly adjusted + Melbert: + - bugfix: Fixed an error from reading an ID card closely when you can't read + - config: Adds a config option for player respawning that enables respawns, but + forces you pick a new character. + - config: '"NORESPAWN" has been replaced with "ALLOW_RESPAWN 0". Unlimited respawns + is "ALLOW_RESPAWN 1" and character limited respawns is "ALLOW_RESPAWN 2".' + SkyratBot: + - bugfix: Fix bodies now lose fire stacks while husked. + - bugfix: Flesh Worms will move smoothly more consistently. + - balance: You can now remove and replace power cells from PDAs (with screwdriver). + - balance: PDAs now drain their power cells harder, and also take into account active + programs & their flashlight being on. + - balance: PDAs running out of charge now turn their flashlights off. + - qol: allows janitor keys to be stored in janitor wintercoats and janibets + - bugfix: PDA flashlights wont cause the cell to constantly drain faster and faster. + - bugfix: People who are irremediably bald can still grow a beard with barber aid. + - qol: Added slapcrafting to unloaded tech shells, click on them with ingredients + to quickly craft your shell. + - qol: gives empty fireaxe and mech removal crowbars cabinets directional helpers + - bugfix: fixed a PDA's messenger TGUI issue with handling of destroyed recipients. + - qol: '"prison" intercoms have been renamed to "receive-only" intercoms to make + it clearer they cannot transmit.' + - refactor: Rust Walkers, Ash Spirits, Flesh Stalkers, and The Maid in the Mirror + now use the basic mob framework. Please report any unusual behaviour. + - spellcheck: '"offical" has been officially corrected to "official" in several + official locations.' + - refactor: Sloths are now basic mobs, however their overall sluggish behavior shouldn't + have changed much- let us know if anything is broken. + - refactor: Refactored goats into basic mobs! Not much should have changed beyond + their endless desire to retaliate should you attack them, they're still just + as good as chomping away plant life as ever. + - qol: Miners can now tag monster spawners (necropolis tendrils, animal dens, demonic + portals, and netherworld links) by using their mining scanner on it, which updates + their GPS tag (and/or gives them one) to give it a numerical designation and + a short identifier for what it's spawning. + oranges: + - rscadd: Dogs now react to centrist grillers more realistically +2023-10-09: + Nerev4r: + - image: The crew's knowledge of origami and papercrafting has been extended to + making paper masks. Find them in the loadout, or just make them! + SkyratBot: + - qol: Supermatter shards can now be fastened with right click too. Now, just don't + forget to use a wrench. + - bugfix: Slaughter/Laughter demon melee cooldowns have been fixed and now attack + at the regular player character attack speed + - balance: The chemical gun and PKA pressure mod traitor items are now purchasable + within 15 minutes of the round starting rather than 20/30. + - balance: All preset bundle kits, the cash briefcase, the makarov, the revolver, + the throwing weapon kit, c4, the detomatix cartridge, the large EMP bomb, gorillas, + advanced mimery tome, pie cannon, clown car, His Grace, and the origami kit + are now all purchasable at the start of a round. + - refactor: ice demons have been refactored into basic mbos. please report any bugs + - rscadd: ice demons now have a unique trophy + - bugfix: Spider types get properly checked again. + nikothedude: + - bugfix: Borers work now +2023-10-10: + Fazzie: + - qol: NT's logo on Centcom's landing pad looks better + - qol: Centcom's Cargo and other rooms had their items rearanged to look marginally + better. Like you're every gonna see them! + - bugfix: The Thunderdome on Centcom now has up-to-date cooking machinery + GoldenAlpharex: + - qol: "You can now bind the Shift Layer Up/Down verbs to keybinds! Look for \"\ + shiftlayerup\" and \"shiftlayerdown\" respectively in your Game Preferences\ + \ >\_Keybindings to bind them, as they aren't bound by default (for now)!" + Hatterhat: + - qol: Internal health analyzer no longer displays both health and chem scans at + the same time; LMB for health, RMB for chems. + Melber: + - bugfix: Wearing bread (or roses, or other non-mask things) no longer prevents + you from TTS speaking. + Melbert: + - bugfix: Robotic bodyparts not attached to people are now properly affected by + EMPs. + - bugfix: Virtual Drink Glasses now look correct. + Motho: + - rscadd: Bitrunners can now have alternative job titles. FTU urges that these titles + are purely cosmetic and not representative of bitrunning ability. + - rscadd: Barbers, Botanists, Warehouse Techs, Coroners, Curators, Cyborgs, Geneticists, + Mimes, Nanotrasen Consultants, Roboticists, and Virologists enjoy new alternative + job titles. + - rscadd: Certain jobs now have Trainee/Newbie alternative job titles ordered at + the very bottom of the title selection dialog. If you or your character are + new to the job/department, set your title so your colleagues are aware! + - rscdel: Removed Engineering Trainee. + - qol: Alphabetized alt-titles excluding two key areas. The base title, and the + newbie title. + Nerev4r: + - image: One new long ring tail! + SkyratBot: + - bugfix: Warm donk-pockets should now have omnizine in them again. + - code_imp: COMSIG_GLOB_LIGHT_MECHANISM_COMPLETED is now COMSIG_GLOB_PUZZLE_COMPLETED + - qol: The autopsy tray (and surgery trays) can now hold the autopsy scanner + - bugfix: Metastation disposals will no longer infinitely loop garbage around the + station. + - bugfix: fixed gibbing from having too much blood not working in some cases + - refactor: Heavily refactored mirrors to be less ass cancer 1998 code. Player facing + changes are that mirrors now use a radial menu, women can get beards in magic + mirrors, made the magic mirror 'change sex' option Woke (it supports the 4 official + genders and physique as well) + - bugfix: Fixed Pride Mirror teleporting you into the space on the first use. Now + it waits until you officially cancel and say 'I am Done' so you can customize + yourself to your liking. + - bugfix: Cowardly mobs will consistently run away from you instead of getting tired + and just sort of standing there after an initial burst of movement. + - bugfix: Virtual domain gondola meat will no longer have a small chance to turn + you into a weaker gondola variant + - bugfix: Added extra checks to bitrunning domain cleanup so avatars are deleted + properly. + - rscadd: Quantum servers now look for a new machine called a byteforge to spawn + loot on- no longer on an invisible landmark. This should make the rooms rebuildable + after disasters. + - rscadd: '*Most* bitrunning machinery is now researchable and buildable via circuits + in the engineering protolathe.' + - refactor: Refactor gib code to be more robust. + - qol: Gibbing a mob will result in all items being dropped instead of getting deleted. + There are a few exceptions (like admin gib self) where this will not take place. + - code_imp: made an eensy teensie weensie change to some supermatter boilerplate + - code_imp: moved some global procs and vars related to reagents to its own dedicated + file. removed some unused procs and macros + - code_imp: heavy auto docs for a lot of procs + - refactor: adds reagent sanity and bound check code + - refactor: multiple reagents are more uniformly distributed when transferring them + between beakers or dropper & in every other reagent dependent operation + - code_imp: exploration drone adventures are now file-based and not database-based + - bugfix: Images are once more displayed as images in vv instead of as an appearance + TheSS13Melon: + - bugfix: Bitrunner now shows up with other cargo jobs on the suit sensors menu. + Wallem: + - rscadd: Nuclear Operatives now have ready access to ancient cowboy technology + in the form of the Outlaw Bundle. Now you too can roll into town on your horse. + honkpocket: + - bugfix: the OPFOR loadout 'Syndicate insurgent bundle' MODsuit is subtyped correctly + - bugfix: the OPFOR loadout 'Blood-Red MODsuit' is subtyped correctly + - balance: changes the mask in the 'Syndicate insurgent bundle' from SWAT to Syndicate + nikothedude: + - qol: SAD patients can now reject the treatment at the last step, preventing any + changes from being made + - balance: Synth tend wounds repeatable step now takes 2.5 seconds from 1 + - balance: 2 new synth tend wounds upgrades available to research + - bugfix: Synth tend wounds now gives proper feedback + - bugfix: Flipped tables now properly block movement + - balance: Defibrilators now EMP synths and apply a temporary brain trauma for 90 + seconds to them + - balance: Synth revival surgery time and steps vastly reduced/streamlined + ninjanomnom: + - rscadd: Pipes now have a colored visual display that shows their contents at a + glance. + softcerv: + - spellcheck: renames the purpura NIFSofts to libidine +2023-10-11: + GoldenAlpharex: + - bugfix: Frogs no longer make obnoxious sounds anymore (again). + Melbert: + - bugfix: Miner's Salve, Sterilizine, and Space Cleaner now all properly affect + burn wounds + Paxilmaniac: + - bugfix: The quartermaster's Rengo rifle will no longer have floating bayonets + SkyratBot: + - bugfix: moved a garbage spawner on Tramstation that was causing random runtimes + due to sometimes spawning in space depending on which module got loaded + - bugfix: fixes a runtime in organ on_death() + - bugfix: fixed some faulty research connections in between heretic's blade and + rust paths. + - bugfix: Heretic mobs will not be summoned with AI enabled, and won't turn into + small animals instead of summoning a flesh stalker. + - bugfix: Fixed some issues in the security camera UI - pressing next or back will + now loop through the cameras + - bugfix: Fixed some style issues in the camera console where selected cams weren't + showing as selected + - bugfix: Camera console search works again + - bugfix: you can no longer polymorph belt into a holoparasite + - refactor: Revenants, the mob that's split between planes of Life and Death, have + been refactored into a basic mob. While this alone shouldn't touch behavior, + a lot of the backend code has been gutted and refactored to try and furnish + a better antagonist experience. This might mean that some weird stuff can come + up and around, report something if it's utterly broken. + - code_imp: In order to better facilitate some code, you do not ghost outside of + a revenant on death, you simply get transferred into the ectoplasm. You should + still be able to speak with your ghost friends on how hard you got wrecked or + if you'll be able to resurrect though. + - code_imp: The timing on revenant stuff such as being revealed, stunned, and inhibited + (by holy weapons) should be tweaked a bit to allow better management. This should + mean that getting unstunned and such should be a bit more precise now. + - qol: Revenant instructions are now relayed in a neat little examine block. + - bugfix: Wound promotion and demotion no longer removes gauze from the limb + - balance: The Changeling Space Suit has been replaced by a new ability which makes + you passively spaceproof without replacing your clothing. + - admin: Editing the atmos sensitivity variables on a basic mob during the game + will now actually do something. + - qol: Adds a base physical description proc to gameplay species, displays it on + magic mirrors. It will give a description of not the lore of the species but + in what way they differ from base species. + - bugfix: Fixes a bad subtype on magical mirrors. + - bugfix: Magical mirrors now give the user ADVANCEDTOOLUSER and LITERACY if they + lack either of them, so monkey wizards aren't softlocked. + - bugfix: Borg modules can no longer be sold by pirates. + - balance: Unholy water acts as a coagulant for cultists. + - bugfix: bitrunners will no longer be lumped in with assistants on the crew monitor + console's display + - bugfix: count station food verb now counts food only onstation + - bugfix: Antiglow now probably has negative glow power. + - refactor: Harvester constructs have been updated to the basic mob framework. This + should have very little impact on their behavior, but please report any issues. + - bugfix: Fixes a few runtimes with TTS and skips some code if TTS isn't enabled. + - sound: Add burning sound loop to bonfires and fireplaces + - code_imp: Improved fireplaces to only process when lit + - bugfix: using a magic mirror to change gender or skintone will now update your + icon properly to match your selection + - rscadd: Adds practice carbines to all firing ranges. They don't deal damage. + - balance: Reviver Implant now able to revive dead people. + nikothedude: + - bugfix: Chest/Heads can now be augmented in the augment menu + - bugfix: Augments menu color wheels now properly recognize existing color + - rscadd: Science can now print advanced tools + - rscadd: Robotics can now print advanced medical tools and health analyzers + - rscadd: Roboticists can now randomly get advanced engi/medical tools in the mail + - rscadd: Table flipping now throws everything on the table +2023-10-12: + GoldenAlpharex: + - bugfix: Bitrunners and Coroners now have Akula outfits. + - bugfix: Shaft Miners now have the Cargo Akula outfit, rather than the default + one. + Hatterhat: + - balance: Blueshield's armor is now on par with a regular security vest's, with + comparatively improved fire/acid and barely improved bomb armor. (None of their + equipment covers their legs.) + - image: Blueshield's vest is now reskinnable, with three variants; the old slim + variant, a sec-vest variant, and a marine variant. + - image: Blueshield's earpiece is no longer a bright blue tumor on the side of their + head. + LT3: + - bugfix: After the untimely loss of too many novice HoPs, the Icebox "New IDs and + You" instructions have been moved from the icemoon wastes to the HoP's office, + ending this rite of passage + - bugfix: Added some missing firelocks in the pharmacy area. Icebox pharmacy now + has a shower + OrionTheFox: + - image: returns Lopland Security's blue ID trims, and updated a few modular ID + trims for DS2/NRI + SkyratBot: + - code_imp: removed round robin method of transferring reagents which would result + in some missing reagents after transferring. + - code_imp: added some more rounding for reagent operations. + - code_imp: cleaned up some plumbing & reaction chamber code + - code_imp: improves the performance of `update_total()` , `clear_reagents()` & + `del_reagent()` procs + - bugfix: plumbing setups will no longer output 0 or more than maximum available + volume of reagents. + - bugfix: removing, copying, transfering reagents is now done proportionally and + not equally again. + - refactor: examining individual reagents up close will display their volumes up + to 4 decimal places for accuracy. + - qol: droppers & beakers round the amount of reagents transferred before displaying + them to chat for easy readibility + - sound: the blood cult's rise to power is now accompanied by several new sound + effects + - rscadd: Adds a new lavaland ruin where you can find a unique egg. + - image: you can now change the style of lipstick to be higher or lower on the face + by alt-clicking the lipstick tube + - balance: Flesh Spiders heal automatically over time if they go a short time without + taking damage, instead of healing large chunks by clicking themselves and waiting + two seconds. + - qol: Spider egg clusters which only hatch into one kind of spider don't ask you + to select that one type from a radial menu with one option on it. + - qol: As a Flesh Spider, the game now tells you how you can heal yourself. + - bugfix: You cannot order with cargo budget if you don't have cargo access in the + Galactic Market + - bugfix: Private & Cargo orders no longer get mixed together in the same crate + if you order them interchangeably so no more embezzlement in the Galactic Market + - bugfix: Orders made with cargo budget come in a regular cargo crate thus allowing + you to open them without QM cargo budget card in the Galactic Market + - qol: Orders made in the Galactic Market will deduct money from your account/cargo + budget only after the order has been confirmed in the cargo request console + & after the shuttle arrives with your order. This way you drain the budget only + after your orders were successfully delivered and not before hand itself + - qol: You can now see what drones and gorillas are holding by examining them. + - admin: It's now easier to give handless mobs hands by applying the "dextrous" + element. + - balance: Spiders and Bears can now climb railings (you know if... they'd rather + do that than destroy them). + - refactor: venus human traps are basicmobs now + - balance: venus human traps have 100 health + - balance: venus human traps take damage out of range of kudzu, heal near kudzu, + are slightly slower, attack slower, and their damage output is slightly more + random + - balance: also venus human trap tangle ability now needs you to actually move backwards + to pull victims + - admin: Gondola supplypods are functional again. + - bugfix: Examining twice experiment handlers with an active fish-related experiment + now gives a comprehensible, correctly spaced list of scanned species rather + than something like "pufferfishguppyslimefishchasmchrab". + - bugfix: No more "line snapped" balloon messages everytime the fishing minigame + is over + - bugfix: Getting to the Master level of the fishing skill now correctly gives you + that slight helping hand to identify yet-to-be-caught fishes. + nikothedude: + - qol: Table flipping feedback is now in the form of balloon alerts + - rscadd: Robo can now print standard and alien surgical tools + - bugfix: Defibs now dont screw over organics if the user was robotic diff --git a/icons/area/areas_station.dmi b/icons/area/areas_station.dmi index b07ea38a1592b0..cbfe463efa5169 100644 Binary files a/icons/area/areas_station.dmi and b/icons/area/areas_station.dmi differ diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi index 38d1d44a000d13..31f26c3e6e11ea 100644 Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi index ae695c3227f3de..12e3ce9f7d5946 100644 Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ diff --git a/icons/effects/bitrunning.dmi b/icons/effects/bitrunning.dmi new file mode 100644 index 00000000000000..bfdc7c63436c2f Binary files /dev/null and b/icons/effects/bitrunning.dmi differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index 29e59dc6c7148d..b01986a9522d0e 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/hud/fishing_hud.dmi b/icons/hud/fishing_hud.dmi index b68acee09b76af..58c478d071064c 100644 Binary files a/icons/hud/fishing_hud.dmi and b/icons/hud/fishing_hud.dmi differ diff --git a/icons/hud/radial.dmi b/icons/hud/radial.dmi index 897cb3a872e292..42d5c451018aec 100644 Binary files a/icons/hud/radial.dmi and b/icons/hud/radial.dmi differ diff --git a/icons/hud/radial_fishing.dmi b/icons/hud/radial_fishing.dmi new file mode 100644 index 00000000000000..65fd55176b7c82 Binary files /dev/null and b/icons/hud/radial_fishing.dmi differ diff --git a/icons/hud/screen_alert.dmi b/icons/hud/screen_alert.dmi index a1fc01434e4564..0fa8ec218500ed 100755 Binary files a/icons/hud/screen_alert.dmi and b/icons/hud/screen_alert.dmi differ diff --git a/icons/mob/clothing/belt.dmi b/icons/mob/clothing/belt.dmi index 546e3da0f86aa6..d1a1777e4e4d8f 100644 Binary files a/icons/mob/clothing/belt.dmi and b/icons/mob/clothing/belt.dmi differ diff --git a/icons/mob/clothing/head/chaplain.dmi b/icons/mob/clothing/head/chaplain.dmi index efb6ec3c9e9082..100b7ee922fb91 100644 Binary files a/icons/mob/clothing/head/chaplain.dmi and b/icons/mob/clothing/head/chaplain.dmi differ diff --git a/icons/mob/clothing/head/plasmaman_head.dmi b/icons/mob/clothing/head/plasmaman_head.dmi index 9846cf02200117..1917ae7bcf538b 100644 Binary files a/icons/mob/clothing/head/plasmaman_head.dmi and b/icons/mob/clothing/head/plasmaman_head.dmi differ diff --git a/icons/mob/clothing/suits/chaplain.dmi b/icons/mob/clothing/suits/chaplain.dmi index 4b6368fb291d0e..8806bf5f679b44 100644 Binary files a/icons/mob/clothing/suits/chaplain.dmi and b/icons/mob/clothing/suits/chaplain.dmi differ diff --git a/icons/mob/clothing/suits/jacket.dmi b/icons/mob/clothing/suits/jacket.dmi index cd924e847eb3e4..a6f25d91c59bfe 100644 Binary files a/icons/mob/clothing/suits/jacket.dmi and b/icons/mob/clothing/suits/jacket.dmi differ diff --git a/icons/mob/clothing/under/cargo.dmi b/icons/mob/clothing/under/cargo.dmi index 4bf30a67a2d7bd..180f0e4ec876fb 100644 Binary files a/icons/mob/clothing/under/cargo.dmi and b/icons/mob/clothing/under/cargo.dmi differ diff --git a/icons/mob/clothing/under/plasmaman.dmi b/icons/mob/clothing/under/plasmaman.dmi index 41cbfb4482b48b..fcc8f008cd7aa8 100644 Binary files a/icons/mob/clothing/under/plasmaman.dmi and b/icons/mob/clothing/under/plasmaman.dmi differ diff --git a/icons/mob/effects/debuff_overlays.dmi b/icons/mob/effects/debuff_overlays.dmi new file mode 100644 index 00000000000000..383ce22aabec7f Binary files /dev/null and b/icons/mob/effects/debuff_overlays.dmi differ diff --git a/icons/mob/huds/hud.dmi b/icons/mob/huds/hud.dmi index 9a602eeb806abd..d71ba4b0940a67 100644 Binary files a/icons/mob/huds/hud.dmi and b/icons/mob/huds/hud.dmi differ diff --git a/icons/mob/human/human_face.dmi b/icons/mob/human/human_face.dmi index 6985cf07eee49a..6530b300aa676e 100644 Binary files a/icons/mob/human/human_face.dmi and b/icons/mob/human/human_face.dmi differ diff --git a/icons/mob/inhands/clothing/hats_lefthand.dmi b/icons/mob/inhands/clothing/hats_lefthand.dmi index 7111ee4d7480b0..191c85cf4825c8 100644 Binary files a/icons/mob/inhands/clothing/hats_lefthand.dmi and b/icons/mob/inhands/clothing/hats_lefthand.dmi differ diff --git a/icons/mob/inhands/clothing/hats_righthand.dmi b/icons/mob/inhands/clothing/hats_righthand.dmi index 96756fc44db9cd..8038e7474ee870 100644 Binary files a/icons/mob/inhands/clothing/hats_righthand.dmi and b/icons/mob/inhands/clothing/hats_righthand.dmi differ diff --git a/icons/mob/inhands/clothing/suits_lefthand.dmi b/icons/mob/inhands/clothing/suits_lefthand.dmi index 757fb8b8593c72..8b9fa5256a9327 100644 Binary files a/icons/mob/inhands/clothing/suits_lefthand.dmi and b/icons/mob/inhands/clothing/suits_lefthand.dmi differ diff --git a/icons/mob/inhands/clothing/suits_righthand.dmi b/icons/mob/inhands/clothing/suits_righthand.dmi index c749a2ed98a8e0..c88f4d224444fc 100644 Binary files a/icons/mob/inhands/clothing/suits_righthand.dmi and b/icons/mob/inhands/clothing/suits_righthand.dmi differ diff --git a/icons/mob/inhands/equipment/medical_lefthand.dmi b/icons/mob/inhands/equipment/medical_lefthand.dmi index 7ce3674c86aadf..feaed1690786ec 100644 Binary files a/icons/mob/inhands/equipment/medical_lefthand.dmi and b/icons/mob/inhands/equipment/medical_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/medical_righthand.dmi b/icons/mob/inhands/equipment/medical_righthand.dmi index 6ceb5efe4d83cd..15ccf5c090e599 100644 Binary files a/icons/mob/inhands/equipment/medical_righthand.dmi and b/icons/mob/inhands/equipment/medical_righthand.dmi differ diff --git a/icons/mob/simple/animal.dmi b/icons/mob/simple/animal.dmi index 6e8b31b7877c40..87fe3a21506b1d 100644 Binary files a/icons/mob/simple/animal.dmi and b/icons/mob/simple/animal.dmi differ diff --git a/icons/mob/simple/jungle/mook.dmi b/icons/mob/simple/jungle/mook.dmi index c9265b22a0ad20..fbc38d29d99deb 100644 Binary files a/icons/mob/simple/jungle/mook.dmi and b/icons/mob/simple/jungle/mook.dmi differ diff --git a/icons/mob/simple/lavaland/lavaland_monsters.dmi b/icons/mob/simple/lavaland/lavaland_monsters.dmi index 38b78cf468f1f1..f68e3db4a6cb91 100644 Binary files a/icons/mob/simple/lavaland/lavaland_monsters.dmi and b/icons/mob/simple/lavaland/lavaland_monsters.dmi differ diff --git a/icons/mob/simple/lavaland/lavaland_monsters_wide.dmi b/icons/mob/simple/lavaland/lavaland_monsters_wide.dmi index 2be68ef4c6696e..808fdc59d9bae9 100644 Binary files a/icons/mob/simple/lavaland/lavaland_monsters_wide.dmi and b/icons/mob/simple/lavaland/lavaland_monsters_wide.dmi differ diff --git a/icons/obj/aquarium.dmi b/icons/obj/aquarium.dmi index 3a27c83c906a83..19e2e68c4f8f33 100644 Binary files a/icons/obj/aquarium.dmi and b/icons/obj/aquarium.dmi differ diff --git a/icons/obj/card.dmi b/icons/obj/card.dmi index a5c4e8283010bd..a5e34e9cc27cbf 100644 Binary files a/icons/obj/card.dmi and b/icons/obj/card.dmi differ diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi index 20f24dd22402f8..fd898d3105fd88 100644 Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ diff --git a/icons/obj/clothing/head/chaplain.dmi b/icons/obj/clothing/head/chaplain.dmi index d95436fdd2d7ac..ed6f6248b317c6 100644 Binary files a/icons/obj/clothing/head/chaplain.dmi and b/icons/obj/clothing/head/chaplain.dmi differ diff --git a/icons/obj/clothing/head/plasmaman_hats.dmi b/icons/obj/clothing/head/plasmaman_hats.dmi index adcf9129c45830..f593a08b88c300 100644 Binary files a/icons/obj/clothing/head/plasmaman_hats.dmi and b/icons/obj/clothing/head/plasmaman_hats.dmi differ diff --git a/icons/obj/clothing/suits/chaplain.dmi b/icons/obj/clothing/suits/chaplain.dmi index 64474a04d31821..730e47cd6fa949 100644 Binary files a/icons/obj/clothing/suits/chaplain.dmi and b/icons/obj/clothing/suits/chaplain.dmi differ diff --git a/icons/obj/clothing/suits/jacket.dmi b/icons/obj/clothing/suits/jacket.dmi index c63f262f104944..dc507017cd25d9 100644 Binary files a/icons/obj/clothing/suits/jacket.dmi and b/icons/obj/clothing/suits/jacket.dmi differ diff --git a/icons/obj/clothing/under/cargo.dmi b/icons/obj/clothing/under/cargo.dmi index fc04a897d5ea86..63e40538899f7d 100644 Binary files a/icons/obj/clothing/under/cargo.dmi and b/icons/obj/clothing/under/cargo.dmi differ diff --git a/icons/obj/clothing/under/plasmaman.dmi b/icons/obj/clothing/under/plasmaman.dmi index 4277c43d54b405..4d416d5b05f1f2 100644 Binary files a/icons/obj/clothing/under/plasmaman.dmi and b/icons/obj/clothing/under/plasmaman.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index d89ee6e5d6408f..fe74b6c11c5c7d 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/obj/economy.dmi b/icons/obj/economy.dmi index dc90265b6e9019..04abc41cae1753 100644 Binary files a/icons/obj/economy.dmi and b/icons/obj/economy.dmi differ diff --git a/icons/obj/fishing.dmi b/icons/obj/fishing.dmi index 39bcc853442005..f7ab9fc1ad9c2a 100644 Binary files a/icons/obj/fishing.dmi and b/icons/obj/fishing.dmi differ diff --git a/icons/obj/food/egg.dmi b/icons/obj/food/egg.dmi index c7661fca918f0c..58908d8247913d 100644 Binary files a/icons/obj/food/egg.dmi and b/icons/obj/food/egg.dmi differ diff --git a/icons/obj/machines/bepis.dmi b/icons/obj/machines/bepis.dmi deleted file mode 100644 index f348c2e1b05596..00000000000000 Binary files a/icons/obj/machines/bepis.dmi and /dev/null differ diff --git a/icons/obj/machines/bitrunning.dmi b/icons/obj/machines/bitrunning.dmi new file mode 100644 index 00000000000000..b3f8ad63a6c993 Binary files /dev/null and b/icons/obj/machines/bitrunning.dmi differ diff --git a/icons/obj/machines/computer.dmi b/icons/obj/machines/computer.dmi index 10974f97bac685..5ffa3445db6922 100644 Binary files a/icons/obj/machines/computer.dmi and b/icons/obj/machines/computer.dmi differ diff --git a/icons/obj/machines/microwave.dmi b/icons/obj/machines/microwave.dmi index 427a5d9daaee6c..7a72ba5d3dca3a 100644 Binary files a/icons/obj/machines/microwave.dmi and b/icons/obj/machines/microwave.dmi differ diff --git a/icons/obj/medical/stack_medical.dmi b/icons/obj/medical/stack_medical.dmi index d12949da595f1a..c4ec905786c699 100644 Binary files a/icons/obj/medical/stack_medical.dmi and b/icons/obj/medical/stack_medical.dmi differ diff --git a/icons/obj/mining_zones/artefacts.dmi b/icons/obj/mining_zones/artefacts.dmi index f3f7d00e4eef8f..d4c603834d21be 100644 Binary files a/icons/obj/mining_zones/artefacts.dmi and b/icons/obj/mining_zones/artefacts.dmi differ diff --git a/icons/obj/pipes_n_cables/!pipe_gas_overlays.dmi b/icons/obj/pipes_n_cables/!pipe_gas_overlays.dmi new file mode 100644 index 00000000000000..0262adcaeb2419 Binary files /dev/null and b/icons/obj/pipes_n_cables/!pipe_gas_overlays.dmi differ diff --git a/icons/obj/pipes_n_cables/!pipes_bitmask.dmi b/icons/obj/pipes_n_cables/!pipes_bitmask.dmi new file mode 100644 index 00000000000000..97643036fbe3bb Binary files /dev/null and b/icons/obj/pipes_n_cables/!pipes_bitmask.dmi differ diff --git a/icons/obj/pipes_n_cables/pipe_template_pieces.dmi b/icons/obj/pipes_n_cables/pipe_template_pieces.dmi new file mode 100644 index 00000000000000..d0d2f7ff7bb809 Binary files /dev/null and b/icons/obj/pipes_n_cables/pipe_template_pieces.dmi differ diff --git a/icons/obj/pipes_n_cables/pipes_bitmask.dmi b/icons/obj/pipes_n_cables/pipes_bitmask.dmi deleted file mode 100644 index 7a382fb55c5e40..00000000000000 Binary files a/icons/obj/pipes_n_cables/pipes_bitmask.dmi and /dev/null differ diff --git a/icons/obj/railings.dmi b/icons/obj/railings.dmi index 28332e21324550..3dbbd7c8318e70 100644 Binary files a/icons/obj/railings.dmi and b/icons/obj/railings.dmi differ diff --git a/icons/obj/service/kitchen.dmi b/icons/obj/service/kitchen.dmi index cb47ddf35a2a6b..aeafe2591e9bdf 100644 Binary files a/icons/obj/service/kitchen.dmi and b/icons/obj/service/kitchen.dmi differ diff --git a/icons/obj/storage/box.dmi b/icons/obj/storage/box.dmi index 7ff4067c288600..d660e1b7bfe388 100644 Binary files a/icons/obj/storage/box.dmi and b/icons/obj/storage/box.dmi differ diff --git a/icons/obj/storage/storage.dmi b/icons/obj/storage/storage.dmi index cdaf8cae339f71..a55606fa3b33ba 100644 Binary files a/icons/obj/storage/storage.dmi and b/icons/obj/storage/storage.dmi differ diff --git a/icons/obj/weapons/guns/energy.dmi b/icons/obj/weapons/guns/energy.dmi index 97b75335b91a0e..e45c5ee4869ed7 100644 Binary files a/icons/obj/weapons/guns/energy.dmi and b/icons/obj/weapons/guns/energy.dmi differ diff --git a/icons/obj/weapons/guns/magic.dmi b/icons/obj/weapons/guns/magic.dmi index fe3eb6ae895f63..7cab0cdfc25926 100644 Binary files a/icons/obj/weapons/guns/magic.dmi and b/icons/obj/weapons/guns/magic.dmi differ diff --git a/icons/obj/weapons/guns/projectiles.dmi b/icons/obj/weapons/guns/projectiles.dmi index e1c70c4f5ade42..3c2d3ff452cd0c 100644 Binary files a/icons/obj/weapons/guns/projectiles.dmi and b/icons/obj/weapons/guns/projectiles.dmi differ diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi index 8a1575fcec6407..6ddc178b98cdb3 100644 Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ diff --git a/modular_skyrat/master_files/code/datums/components/grillable.dm b/modular_skyrat/master_files/code/datums/components/grillable.dm new file mode 100644 index 00000000000000..42146559af1ff5 --- /dev/null +++ b/modular_skyrat/master_files/code/datums/components/grillable.dm @@ -0,0 +1,9 @@ +/datum/component/grillable + /// What type of pollutant we spread around as we are grilleed, can be none + var/pollutant_type + +/datum/component/grillable/Initialize(cook_result, required_cook_time, positive_result, use_large_steam_sprite, list/added_reagents, pollutant_type) + . = ..() + if(. == COMPONENT_INCOMPATIBLE) + return + src.pollutant_type = pollutant_type diff --git a/modular_skyrat/master_files/code/datums/id_trim/jobs.dm b/modular_skyrat/master_files/code/datums/id_trim/jobs.dm index b26e823b0e0436..f0bcde700876ed 100644 --- a/modular_skyrat/master_files/code/datums/id_trim/jobs.dm +++ b/modular_skyrat/master_files/code/datums/id_trim/jobs.dm @@ -1,8 +1,8 @@ // MODULAR ID TRIM ACCESS OVERRIDES GO HERE!! +//(Most) of Security has inverted IDs, with custom blue-on-black icons. This is to distinguish them from their head, who has a white-on-blue icon /datum/id_trim/job/head_of_security - trim_icon = 'modular_skyrat/master_files/icons/obj/card.dmi' - subdepartment_color = COLOR_ASSEMBLY_BLACK // This actually is the shade of grey formerly used by the static icons! Didn't have to add anything extra! Just thought that was neat. + subdepartment_color = COLOR_ASSEMBLY_BLACK /datum/id_trim/job/warden trim_icon = 'modular_skyrat/master_files/icons/obj/card.dmi' @@ -53,10 +53,10 @@ department_color = COLOR_COMMAND_BLUE subdepartment_color = COLOR_CENTCOM_BLUE // Not the other way around. I think. sechud_icon_state = SECHUD_BLUESHIELD - extra_access = list(ACCESS_SECURITY, ACCESS_BRIG, ACCESS_COURT, ACCESS_CARGO, ACCESS_GATEWAY) // Someone needs to come back and order these alphabetically, this is a nightmare + extra_access = list(ACCESS_BRIG, ACCESS_CARGO, ACCESS_COURT, ACCESS_GATEWAY, ACCESS_SECURITY) minimal_access = list( - ACCESS_DETECTIVE, ACCESS_BRIG_ENTRANCE, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_ENGINEERING, ACCESS_MAINT_TUNNELS, ACCESS_RESEARCH, - ACCESS_RC_ANNOUNCE, ACCESS_COMMAND, ACCESS_WEAPONS, + ACCESS_BRIG_ENTRANCE, ACCESS_COMMAND, ACCESS_CONSTRUCTION, ACCESS_DETECTIVE, ACCESS_ENGINEERING, + ACCESS_MAINT_TUNNELS, ACCESS_MEDICAL, ACCESS_RC_ANNOUNCE, ACCESS_RESEARCH, ACCESS_WEAPONS, ) minimal_wildcard_access = list(ACCESS_CAPTAIN) template_access = list(ACCESS_CAPTAIN, ACCESS_CHANGE_IDS) @@ -68,13 +68,15 @@ subdepartment_color = COLOR_GREEN sechud_icon_state = SECHUD_NT_CONSULTANT extra_access = list() - minimal_access = list(ACCESS_SECURITY, ACCESS_BRIG_ENTRANCE, ACCESS_COURT, ACCESS_WEAPONS, - ACCESS_MEDICAL, ACCESS_PSYCHOLOGY, ACCESS_ENGINEERING, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_COMMAND, - ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE, - ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_LAWYER, - ACCESS_MECH_ENGINE, ACCESS_MECH_SCIENCE, ACCESS_MECH_SECURITY, ACCESS_MECH_MEDICAL, - ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_VAULT, ACCESS_MINING_STATION, - ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM, ACCESS_AUX_BASE, ACCESS_TELEPORTER, ACCESS_CENT_GENERAL) + minimal_access = list( + ACCESS_AI_UPLOAD, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_AUX_BASE, ACCESS_BAR, ACCESS_BRIG_ENTRANCE, + ACCESS_CENT_GENERAL, ACCESS_CHANGE_IDS, ACCESS_CHAPEL_OFFICE, ACCESS_COMMAND, ACCESS_CONSTRUCTION, + ACCESS_CREMATORIUM, ACCESS_COURT, ACCESS_ENGINEERING, ACCESS_EVA, ACCESS_GATEWAY, ACCESS_HOP, ACCESS_HYDROPONICS, + ACCESS_JANITOR, ACCESS_KEYCARD_AUTH, ACCESS_KITCHEN, ACCESS_LAWYER, ACCESS_LIBRARY, ACCESS_MAINT_TUNNELS, + ACCESS_MEDICAL, ACCESS_MECH_ENGINE, ACCESS_MECH_MEDICAL, ACCESS_MECH_SCIENCE, ACCESS_MECH_SECURITY, + ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_MORGUE, ACCESS_PSYCHOLOGY, ACCESS_RC_ANNOUNCE, + ACCESS_RESEARCH, ACCESS_SECURITY, ACCESS_TELEPORTER, ACCESS_THEATRE, ACCESS_VAULT, ACCESS_WEAPONS + ) minimal_wildcard_access = list(ACCESS_CAPTAIN, ACCESS_CENT_GENERAL) template_access = list(ACCESS_CAPTAIN, ACCESS_CHANGE_IDS) @@ -86,9 +88,11 @@ subdepartment_color = COLOR_ASSEMBLY_BLACK sechud_icon_state = SECHUD_CORRECTIONS_OFFICER extra_access = list() - minimal_access = list(ACCESS_SECURITY, ACCESS_BRIG_ENTRANCE, ACCESS_BRIG, ACCESS_COURT, - ACCESS_MAINT_TUNNELS, ACCESS_WEAPONS) - template_access = list(ACCESS_CAPTAIN, ACCESS_HOS, ACCESS_CHANGE_IDS) + minimal_access = list( + ACCESS_BRIG, ACCESS_BRIG_ENTRANCE, ACCESS_COURT, + ACCESS_MAINT_TUNNELS, ACCESS_SECURITY, ACCESS_WEAPONS + ) + template_access = list(ACCESS_CAPTAIN, ACCESS_CHANGE_IDS, ACCESS_HOS) job = /datum/job/corrections_officer /datum/id_trim/job/barber @@ -99,6 +103,6 @@ subdepartment_color = COLOR_SERVICE_LIME sechud_icon_state = SECHUD_BARBER extra_access = list() - minimal_access = list(ACCESS_THEATRE, ACCESS_MAINT_TUNNELS, ACCESS_BARBER, ACCESS_SERVICE) - template_access = list(ACCESS_CAPTAIN, ACCESS_HOP, ACCESS_CHANGE_IDS) + minimal_access = list(ACCESS_BARBER, ACCESS_MAINT_TUNNELS, ACCESS_SERVICE, ACCESS_THEATRE) + template_access = list(ACCESS_CAPTAIN, ACCESS_CHANGE_IDS, ACCESS_HOP) job = /datum/job/barber diff --git a/modular_skyrat/master_files/code/datums/storage/subtypes/pockets.dm b/modular_skyrat/master_files/code/datums/storage/subtypes/pockets.dm index 491eb74443a5f3..75a2f01aa9927f 100644 --- a/modular_skyrat/master_files/code/datums/storage/subtypes/pockets.dm +++ b/modular_skyrat/master_files/code/datums/storage/subtypes/pockets.dm @@ -4,18 +4,8 @@ . = ..() add_holdable(list( - // Adds pistol magazines from guncargo companies in their respective order - /obj/item/ammo_box/magazine/multi_sprite/pdh, - /obj/item/ammo_box/magazine/multi_sprite/ladon, - /obj/item/ammo_box/magazine/multi_sprite/firefly, - /obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper, - /obj/item/ammo_box/magazine/multi_sprite/mk58, - /obj/item/ammo_box/magazine/m45, - /obj/item/ammo_box/magazine/pepperball, // boot pepper - /obj/item/ammo_box/magazine/multi_sprite/g17, - /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby, - /obj/item/ammo_box/magazine/multi_sprite/cfa_snub, - /obj/item/ammo_box/magazine/multi_sprite/makarov, + /obj/item/ammo_box/magazine/c35sol_pistol, + /obj/item/ammo_box/magazine/c585trappiste_pistol, /obj/item/ammo_box/magazine/m9mm_aps, /obj/item/ammo_box/magazine/toy/pistol, )) diff --git a/modular_skyrat/master_files/code/datums/traits/good.dm b/modular_skyrat/master_files/code/datums/traits/good.dm index 22987f7705d197..08f265145a9ea5 100644 --- a/modular_skyrat/master_files/code/datums/traits/good.dm +++ b/modular_skyrat/master_files/code/datums/traits/good.dm @@ -68,6 +68,16 @@ right_arm.unarmed_miss_sound = initial(right_arm.unarmed_miss_sound) right_arm.unarmed_sharpness = initial(right_arm.unarmed_sharpness) +/datum/quirk/water_breathing + name = "Water breathing" + desc = "You are able to breathe underwater!" + value = 2 + mob_trait = TRAIT_WATER_BREATHING + gain_text = span_notice("You become acutely aware of the moisture in your lungs and in the air. It feels nice.") + lose_text = span_danger("You suddenly realize the moisture in your lungs feels really weird, and you almost choke on it!") + medical_record_text = "Patient possesses biology compatible with aquatic respiration." + icon = FA_ICON_FISH + // AdditionalEmotes *turf quirks /datum/quirk/water_aspect name = "Water aspect (Emotes)" diff --git a/modular_skyrat/master_files/code/datums/traits/neutral.dm b/modular_skyrat/master_files/code/datums/traits/neutral.dm index 6ca79ee52b8593..0ab2f6e90b7cb2 100644 --- a/modular_skyrat/master_files/code/datums/traits/neutral.dm +++ b/modular_skyrat/master_files/code/datums/traits/neutral.dm @@ -1,5 +1,16 @@ #define TRAIT_HYDRA_HEADS "hydrahead" // We still dont have a centralised trait file +GLOBAL_VAR_INIT(DNR_trait_overlay, generate_DNR_trait_overlay()) + +/// Instantiates GLOB.DNR_trait_overlay by creating a new mutable_appearance instance of the overlay. +/proc/generate_DNR_trait_overlay() + RETURN_TYPE(/mutable_appearance) + + var/mutable_appearance/DNR_trait_overlay = mutable_appearance('modular_skyrat/modules/indicators/icons/DNR_trait_overlay.dmi', "DNR", FLY_LAYER) + DNR_trait_overlay.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA | KEEP_APART + return DNR_trait_overlay + + // SKYRAT NEUTRAL TRAITS /datum/quirk/excitable name = "Excitable!" @@ -31,6 +42,47 @@ mob_trait = TRAIT_DNR icon = FA_ICON_SKULL_CROSSBONES +/datum/quirk/dnr/add(client/client_source) + . = ..() + + quirk_holder.update_dnr_hud() + +/datum/quirk/dnr/remove() + var/mob/living/old_holder = quirk_holder + + . = ..() + + old_holder.update_dnr_hud() + +/mob/living/prepare_data_huds() + . = ..() + + update_dnr_hud() + +/// Adds the DNR HUD element if src has TRAIT_DNR. Removes it otherwise. +/mob/living/proc/update_dnr_hud() + var/image/dnr_holder = hud_list?[DNR_HUD] + if(isnull(dnr_holder)) + return + + var/icon/temporary_icon = icon(icon, icon_state, dir) + dnr_holder.pixel_y = temporary_icon.Height() - world.icon_size + + if(HAS_TRAIT(src, TRAIT_DNR)) + set_hud_image_active(DNR_HUD) + dnr_holder.icon_state = "hud_dnr" + else + set_hud_image_inactive(DNR_HUD) + +/mob/living/carbon/human/examine(mob/user) + . = ..() + + if(stat != DEAD && HAS_TRAIT(src, TRAIT_DNR) && (HAS_TRAIT(user, TRAIT_SECURITY_HUD) || HAS_TRAIT(user, TRAIT_MEDICAL_HUD))) + . += "\n[span_boldwarning("This individual is unable to be revived, and may be permanently dead if allowed to die!")]" + +/datum/atom_hud/data/human/dnr + hud_icons = list(DNR_HUD) + // uncontrollable laughter /datum/quirk/item_quirk/joker name = "Pseudobulbar Affect" diff --git a/modular_skyrat/master_files/code/game/objects/items/cards_ids.dm b/modular_skyrat/master_files/code/game/objects/items/cards_ids.dm index 64f40cb5f86ba2..9b43fccfc3ab28 100644 --- a/modular_skyrat/master_files/code/game/objects/items/cards_ids.dm +++ b/modular_skyrat/master_files/code/game/objects/items/cards_ids.dm @@ -3,30 +3,13 @@ name = "generic silver identification card" icon = 'modular_skyrat/master_files/icons/obj/card.dmi' icon_state = "card_silvergen" - assigned_icon_state = "assigned_silver" + assigned_icon_state = null /obj/item/card/id/advanced/gold/generic name = "generic gold identification card" icon = 'modular_skyrat/master_files/icons/obj/card.dmi' icon_state = "card_goldgen" - assigned_icon_state = "assigned_gold" - -// COLOURABLE -/obj/item/card/id/advanced/colourable - name = "colourable identification card" - desc = "A failed prototype for customizable ID cards, it looks.. strange." // Read: I'm too lazy to implement this properly - icon_state = "id_card" - assigned_icon_state = null // Built into the sprite itself. - greyscale_config = /datum/greyscale_config/id_card - greyscale_colors = "#FF0000#00FF00#0000FF" - -/obj/item/card/id/advanced/colourable/Initialize(mapload) - . = ..() - AddElement(/datum/element/gags_recolorable) - -/obj/item/card/id/advanced/colourable/examine(mob/user) - . = ..() - . += span_info("You could change its colours with a spray can!") + assigned_icon_state = null // DS2 /obj/item/card/id/advanced/prisoner/ds2 diff --git a/modular_skyrat/master_files/code/game/objects/structures/mirror.dm b/modular_skyrat/master_files/code/game/objects/structures/mirror.dm new file mode 100644 index 00000000000000..ac17e8afd414b7 --- /dev/null +++ b/modular_skyrat/master_files/code/game/objects/structures/mirror.dm @@ -0,0 +1,9 @@ +// Magic Mirror Character Application +/obj/structure/mirror/magic/attack_hand(mob/living/carbon/human/user) + var/user_input = tgui_alert(user, "Would you like to apply your loaded character?","Confirm", list("Yes!", "No")) + + if(user_input == "Yes!") + user?.client?.prefs?.safe_transfer_prefs_to(user) + return TRUE + + return ..() diff --git a/modular_skyrat/master_files/code/modules/antagonists/traitor/objectives/kill_pet.dm b/modular_skyrat/master_files/code/modules/antagonists/traitor/objectives/kill_pet.dm index 68865d44b21956..b3486f40ba72e3 100644 --- a/modular_skyrat/master_files/code/modules/antagonists/traitor/objectives/kill_pet.dm +++ b/modular_skyrat/master_files/code/modules/antagonists/traitor/objectives/kill_pet.dm @@ -9,9 +9,9 @@ JOB_CHIEF_MEDICAL_OFFICER = /mob/living/simple_animal/pet/cat/runtime, JOB_CHIEF_ENGINEER = /mob/living/simple_animal/parrot/poly, JOB_QUARTERMASTER = list( - /mob/living/simple_animal/sloth/citrus, - /mob/living/simple_animal/sloth/paperwork, - /mob/living/simple_animal/hostile/gorilla/cargo_domestic, + /mob/living/basic/sloth/citrus, + /mob/living/basic/sloth/paperwork, + /mob/living/basic/gorilla/cargorilla, ), // Non-heads like the warden, these are automatically medium-risk at minimum // They are also the only two modular additions so far diff --git a/modular_skyrat/master_files/code/modules/bitrunning/orders/tech.dm b/modular_skyrat/master_files/code/modules/bitrunning/orders/tech.dm new file mode 100644 index 00000000000000..6c9a0626517b47 --- /dev/null +++ b/modular_skyrat/master_files/code/modules/bitrunning/orders/tech.dm @@ -0,0 +1,3 @@ +/datum/orderable_item/bepis/flashdark + item_path = /obj/item/flashlight/flashdark + cost_per_order = 750 diff --git a/modular_skyrat/master_files/code/modules/client/preferences/middleware/limbs_and_markings.dm b/modular_skyrat/master_files/code/modules/client/preferences/middleware/limbs_and_markings.dm index 09a174b1ff319c..1099d7a3e79cd9 100644 --- a/modular_skyrat/master_files/code/modules/client/preferences/middleware/limbs_and_markings.dm +++ b/modular_skyrat/master_files/code/modules/client/preferences/middleware/limbs_and_markings.dm @@ -41,8 +41,8 @@ "r_arm" = TRUE, "l_leg" = TRUE, "r_leg" = TRUE, - "chest" = FALSE, // TODO: figure out why head/chest augs dont render, needed for IPC head on non IPC body - "head" = FALSE, + "chest" = TRUE, + "head" = TRUE, "l_hand" = FALSE, "r_hand" = FALSE, ) @@ -73,9 +73,7 @@ if(!visuals_only) return - // If you ever add chest and head augments, please add the body zones to this list. - // Removing them for now for optimization purposes. - for(var/body_zone in list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)) + for(var/body_zone in list(BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_CHEST, BODY_ZONE_HEAD)) if(body_zone in visited_body_zones) continue @@ -164,7 +162,7 @@ usr, "Select new color", null, - preferences.body_markings[limb_slot][marking_entry_name], + preferences.body_markings[limb_slot][marking_entry_name][1], ) as color | null if(!new_color) return TRUE diff --git a/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm b/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm index f7ffc6fddd6280..be228d89f102d5 100644 --- a/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm +++ b/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm @@ -213,7 +213,6 @@ var/static/list/undershirt_to_bra = list( "Bra, Sports" = "Bra, Sports", "Sports Bra (Alt)" = "Sports Bra (Alt)", - "LIZARED Top" = "LIZARED Top", "Bra" = "Bra", "Bra - Alt" = "Bra - Alt", "Bra - Thin" = "Bra - Thin", diff --git a/modular_skyrat/master_files/code/modules/clothing/under/color.dm b/modular_skyrat/master_files/code/modules/clothing/under/color.dm index 07327d062b82cb..094dddaabd3585 100644 --- a/modular_skyrat/master_files/code/modules/clothing/under/color.dm +++ b/modular_skyrat/master_files/code/modules/clothing/under/color.dm @@ -1,6 +1,9 @@ /obj/item/clothing/under/color greyscale_config_worn_monkey = /datum/greyscale_config/jumpsuit/worn/monkey +/obj/item/clothing/under/color/rainbow + worn_icon_digi = 'modular_skyrat/master_files/icons/mob/clothing/under/color_digi.dmi' + /** * Random jumpsuit is the preferred style of the wearer if loaded as an outfit. * This is cleaner than creating a ../skirt variant as skirts are precached into SSwardrobe diff --git a/modular_skyrat/master_files/code/modules/clothing/under/jobs/centcom.dm b/modular_skyrat/master_files/code/modules/clothing/under/jobs/centcom.dm index 9c48b5a2736dc8..05aa24276d8a5c 100644 --- a/modular_skyrat/master_files/code/modules/clothing/under/jobs/centcom.dm +++ b/modular_skyrat/master_files/code/modules/clothing/under/jobs/centcom.dm @@ -13,12 +13,6 @@ */ //Check modular_skyrat\modules\nanotrasen_naval_command\code\clothing.dm for more of these! (Or, currently, ALL of these.) -/* -* ARMADYNE -*/ -//Check modular_skyrat\modules\sec_haul\code\peacekeeper\armadyne_clothing.dm for these (ORION TODO: debate moving them all into this one file - uniforms, at least) -//(TODO applies to NT as well) - /* * LOPLAND */ diff --git a/modular_skyrat/master_files/code/modules/jobs/job_types/_job_attire.dm b/modular_skyrat/master_files/code/modules/jobs/job_types/_job_attire.dm index a5de93b45dc3b5..05bc14211e3a42 100644 --- a/modular_skyrat/master_files/code/modules/jobs/job_types/_job_attire.dm +++ b/modular_skyrat/master_files/code/modules/jobs/job_types/_job_attire.dm @@ -8,6 +8,9 @@ /datum/job/bartender akula_outfit = /datum/outfit/akula +/datum/job/bitrunner + akula_outfit = /datum/outfit/akula/cargo_technician + /datum/job/botanist akula_outfit = /datum/outfit/akula @@ -84,7 +87,7 @@ akula_outfit = /datum/outfit/akula/security_officer /datum/job/shaft_miner - akula_outfit = /datum/outfit/akula + akula_outfit = /datum/outfit/akula/cargo_technician /datum/job/station_engineer akula_outfit = /datum/outfit/akula/station_engineer @@ -139,6 +142,9 @@ /datum/job/barber akula_outfit = /datum/outfit/akula +/datum/job/coroner + akula_outfit = /datum/outfit/akula/doctor + /datum/job/corrections_officer akula_outfit = /datum/outfit/akula/security_officer diff --git a/modular_skyrat/master_files/code/modules/jobs/job_types/roboticist.dm b/modular_skyrat/master_files/code/modules/jobs/job_types/roboticist.dm index d90c994c6ad40d..35e4f206de12cd 100644 --- a/modular_skyrat/master_files/code/modules/jobs/job_types/roboticist.dm +++ b/modular_skyrat/master_files/code/modules/jobs/job_types/roboticist.dm @@ -3,3 +3,24 @@ satchel = /obj/item/storage/backpack/satchel/science/robo duffelbag = /obj/item/storage/backpack/duffelbag/science/robo messenger = /obj/item/storage/backpack/messenger/science/robo + +/datum/job/roboticist + description = "Build cyborgs, mechs, AIs, and maintain them all. Create MODsuits for those that wish. Try to remind medical that you're \ + actually a lot better at treating synthetic crew members than them." + +/datum/job/roboticist/New() + . = ..() + + mail_goodies += list( + /obj/item/healthanalyzer/advanced = 15, + /obj/item/screwdriver/power/science = 6, + /obj/item/crowbar/power/science = 6, + /obj/item/weldingtool/experimental = 2, // a lot rarer since its relatively powerful + /obj/item/scalpel/advanced = 6, + /obj/item/retractor/advanced = 6, + /obj/item/cautery/advanced = 6, + /obj/item/storage/pill_bottle/liquid_solder = 6, + /obj/item/storage/pill_bottle/system_cleaner = 6, + /obj/item/storage/pill_bottle/nanite_slurry = 6, + /obj/item/reagent_containers/spray/hercuri/chilled = 8, + ) diff --git a/modular_skyrat/master_files/code/modules/mob/living/basic/icemoon/ice_demon.dm b/modular_skyrat/master_files/code/modules/mob/living/basic/icemoon/ice_demon.dm new file mode 100644 index 00000000000000..0c8f44b3118159 --- /dev/null +++ b/modular_skyrat/master_files/code/modules/mob/living/basic/icemoon/ice_demon.dm @@ -0,0 +1,3 @@ +// crusher loot /obj/item/crusher_trophy/ice_demon_cube -> /obj/item/crusher_trophy/demon_core +/mob/living/basic/mining/ice_demon + crusher_loot = /obj/item/crusher_trophy/demon_core diff --git a/modular_skyrat/master_files/code/modules/mob/living/carbon/death.dm b/modular_skyrat/master_files/code/modules/mob/living/carbon/death.dm index b2d6c97565213a..e7c3348e585964 100644 --- a/modular_skyrat/master_files/code/modules/mob/living/carbon/death.dm +++ b/modular_skyrat/master_files/code/modules/mob/living/carbon/death.dm @@ -1,18 +1,11 @@ // By temporarily removing the unspillable organs before calling the parent proc we can avoid Skyrat edits and make this less likely to break in the future -/mob/living/carbon/spill_organs(no_brain, no_organs, no_bodyparts, gibbed = FALSE) +/mob/living/carbon/spill_organs(drop_bitflags) var/list/held_organs = list() for(var/obj/item/organ/organ as anything in organs) if(!organ.drop_when_organ_spilling) held_organs.Add(organ) organs.Remove(organ) - // Organs always get spilled when the mob is gibbed - if(gibbed) - for(var/deleting_organ in held_organs) - qdel(deleting_organ) - - return ..() - . = ..() // put the unspillable organs back diff --git a/modular_skyrat/master_files/code/modules/mob/living/carbon/human/death.dm b/modular_skyrat/master_files/code/modules/mob/living/carbon/human/death.dm index b40e30ca8f86a5..7889b4f391ceca 100644 --- a/modular_skyrat/master_files/code/modules/mob/living/carbon/human/death.dm +++ b/modular_skyrat/master_files/code/modules/mob/living/carbon/human/death.dm @@ -1,8 +1,8 @@ // Pocket contents fly out when gibbed -/mob/living/carbon/human/gib(no_brain, no_organs, no_bodyparts, safe_gib = FALSE) - if(safe_gib) // we are just going to drop everything regardless +/mob/living/carbon/human/gib(drop_bitflags=NONE) + if(drop_bitflags & DROP_ITEMS) // we are just going to drop everything regardless return ..() - if(no_bodyparts) // don't drop any items when the mob is being reduced to a paste + if(!(drop_bitflags & DROP_BODYPARTS)) // don't drop any items when the mob is being reduced to a paste return ..() var/obj/item/left_pocket = l_store diff --git a/modular_skyrat/master_files/code/modules/mob/living/carbon/human/species_type/podpeople.dm b/modular_skyrat/master_files/code/modules/mob/living/carbon/human/species_type/podpeople.dm new file mode 100644 index 00000000000000..012665829fd23d --- /dev/null +++ b/modular_skyrat/master_files/code/modules/mob/living/carbon/human/species_type/podpeople.dm @@ -0,0 +1,6 @@ +// Character creation podpeople +/datum/species/pod/get_species_description() + return "Plant lore!" + +/datum/species/pod/get_species_lore() + return list("You're a plant!") diff --git a/modular_skyrat/master_files/code/modules/mob/living/human/species.dm b/modular_skyrat/master_files/code/modules/mob/living/human/species.dm index b2b9eaeecba58c..30df82a7f1158e 100644 --- a/modular_skyrat/master_files/code/modules/mob/living/human/species.dm +++ b/modular_skyrat/master_files/code/modules/mob/living/human/species.dm @@ -32,3 +32,14 @@ /datum/species/proc/apply_supplementary_body_changes(mob/living/carbon/human/target, datum/preferences/preferences, visuals_only = FALSE) return + +/datum/species/create_pref_traits_perks() + . = ..() + + if (TRAIT_WATER_BREATHING in inherent_traits) + . += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = FA_ICON_FISH, + SPECIES_PERK_NAME = "Waterbreathing", + SPECIES_PERK_DESC = "[plural_form] can breathe in water, making pools a lot safer to be in!", + )) diff --git a/modular_skyrat/master_files/code/modules/research/techweb/all_nodes.dm b/modular_skyrat/master_files/code/modules/research/techweb/all_nodes.dm index e263c4062c7815..b09de049865002 100644 --- a/modular_skyrat/master_files/code/modules/research/techweb/all_nodes.dm +++ b/modular_skyrat/master_files/code/modules/research/techweb/all_nodes.dm @@ -206,12 +206,14 @@ . = ..() design_ids += list( "borg_upgrade_snacks", + "mini_soulcatcher", ) /datum/techweb_node/neural_programming/New() . = ..() design_ids += list( "soulcatcher_device", + "rsd_interface", ) /datum/techweb_node/cyborg_upg_util/New() diff --git a/modular_skyrat/master_files/icons/donator/mob/clothing/hands.dmi b/modular_skyrat/master_files/icons/donator/mob/clothing/hands.dmi index 44e58131a33a19..93cadcbdbdbaf8 100644 Binary files a/modular_skyrat/master_files/icons/donator/mob/clothing/hands.dmi and b/modular_skyrat/master_files/icons/donator/mob/clothing/hands.dmi differ diff --git a/modular_skyrat/master_files/icons/donator/obj/clothing/gloves.dmi b/modular_skyrat/master_files/icons/donator/obj/clothing/gloves.dmi index 9c82af8e8b3fa1..62bfc6d5433351 100644 Binary files a/modular_skyrat/master_files/icons/donator/obj/clothing/gloves.dmi and b/modular_skyrat/master_files/icons/donator/obj/clothing/gloves.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/actions/actions_nif.dmi b/modular_skyrat/master_files/icons/mob/actions/actions_nif.dmi index 0e3d125038e8e7..eac81c9cca9f41 100644 Binary files a/modular_skyrat/master_files/icons/mob/actions/actions_nif.dmi and b/modular_skyrat/master_files/icons/mob/actions/actions_nif.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/ears.dmi b/modular_skyrat/master_files/icons/mob/clothing/ears.dmi index eb135d3fdc3b14..0626710027cb3b 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/ears.dmi and b/modular_skyrat/master_files/icons/mob/clothing/ears.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/mask.dmi b/modular_skyrat/master_files/icons/mob/clothing/mask.dmi index db9c50ab844015..07bef00e9c4a28 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/mask.dmi and b/modular_skyrat/master_files/icons/mob/clothing/mask.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi b/modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi index 199a17cdbb20a0..24004a9b2604bb 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi and b/modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/cargo.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/cargo.dmi index 9a8042cf0a0f6e..8d18e50d6233e3 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/cargo.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/cargo.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/cargo_digi.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/cargo_digi.dmi index c4ecb9e4f81203..faceea6def3269 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/cargo_digi.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/cargo_digi.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/under/color_digi.dmi b/modular_skyrat/master_files/icons/mob/clothing/under/color_digi.dmi index 1d7d6c0e9330c9..1366a6ba1ad53e 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/under/color_digi.dmi and b/modular_skyrat/master_files/icons/mob/clothing/under/color_digi.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/clothing/underwear.dmi b/modular_skyrat/master_files/icons/mob/clothing/underwear.dmi index 3d9209905cb3c3..ff6f4218c27e25 100644 Binary files a/modular_skyrat/master_files/icons/mob/clothing/underwear.dmi and b/modular_skyrat/master_files/icons/mob/clothing/underwear.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/huds/hud.dmi b/modular_skyrat/master_files/icons/mob/huds/hud.dmi index 276bdf638ffe15..235a45ecd4918e 100644 Binary files a/modular_skyrat/master_files/icons/mob/huds/hud.dmi and b/modular_skyrat/master_files/icons/mob/huds/hud.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/sprite_accessory/hair.dmi b/modular_skyrat/master_files/icons/mob/sprite_accessory/hair.dmi index fdfc3fee1c8bdd..681457fe596f1c 100644 Binary files a/modular_skyrat/master_files/icons/mob/sprite_accessory/hair.dmi and b/modular_skyrat/master_files/icons/mob/sprite_accessory/hair.dmi differ diff --git a/modular_skyrat/master_files/icons/mob/sprite_accessory/tails_big.dmi b/modular_skyrat/master_files/icons/mob/sprite_accessory/tails_big.dmi index f0c56e67183968..e77a1d1d77d126 100644 Binary files a/modular_skyrat/master_files/icons/mob/sprite_accessory/tails_big.dmi and b/modular_skyrat/master_files/icons/mob/sprite_accessory/tails_big.dmi differ diff --git a/modular_skyrat/master_files/icons/obj/card.dmi b/modular_skyrat/master_files/icons/obj/card.dmi index cc5b4eb3a0a571..9130183d19d8f4 100644 Binary files a/modular_skyrat/master_files/icons/obj/card.dmi and b/modular_skyrat/master_files/icons/obj/card.dmi differ diff --git a/modular_skyrat/master_files/icons/obj/clothing/masks.dmi b/modular_skyrat/master_files/icons/obj/clothing/masks.dmi index c9e746f0506286..7deb40b8d859a7 100644 Binary files a/modular_skyrat/master_files/icons/obj/clothing/masks.dmi and b/modular_skyrat/master_files/icons/obj/clothing/masks.dmi differ diff --git a/modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi b/modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi index a3274e254b1943..e0a71694d5b716 100644 Binary files a/modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi and b/modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi differ diff --git a/modular_skyrat/modules/GAGS/greyscale_configs.dm b/modular_skyrat/modules/GAGS/greyscale_configs.dm index 36870626d5dc36..9ee547d060eba9 100644 --- a/modular_skyrat/modules/GAGS/greyscale_configs.dm +++ b/modular_skyrat/modules/GAGS/greyscale_configs.dm @@ -1056,18 +1056,41 @@ digi // WRAPS -/datum/greyscale_config/wraps +/datum/greyscale_config/clothwraps name = "Cloth Wraps" icon_file = 'modular_skyrat/modules/GAGS/icons/shoes.dmi' json_config = 'modular_skyrat/modules/GAGS/json_configs/wraps/wraps.json' -/datum/greyscale_config/wraps/worn +/datum/greyscale_config/clothwraps/worn name = "Cloth Wraps (Worn)" json_config = 'modular_skyrat/modules/GAGS/json_configs/wraps/wraps_worn.json' -/datum/greyscale_config/wraps/worn/digi +/datum/greyscale_config/clothwraps/worn/digi name = "Cloth Wraps (Worn, Digi)" +/datum/greyscale_config/legwraps + name = "Leg Wraps" + icon_file = 'modular_skyrat/modules/GAGS/icons/shoes.dmi' + json_config = 'modular_skyrat/modules/GAGS/json_configs/wraps/legwraps.json' + +/datum/greyscale_config/legwraps/worn + name = "Leg Wraps (Worn)" + json_config = 'modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn.json' + +/datum/greyscale_config/legwraps/worn/digi + name = "Leg Wraps (Worn, Digi)" + json_config = 'modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn_digi.json' + +/datum/greyscale_config/armwraps + name = "Cloth Arm Wraps" + icon_file = 'modular_skyrat/master_files/icons/donator/obj/clothing/gloves.dmi' + json_config = 'modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps.json' + +/datum/greyscale_config/armwraps/worn + name = "Cloth Arm Wraps (Worn)" + icon_file = 'modular_skyrat/master_files/icons/donator/mob/clothing/hands.dmi' + json_config = 'modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps_worn.json' + // MISC SHOES /datum/greyscale_config/heels diff --git a/modular_skyrat/modules/GAGS/icons/shoes.dmi b/modular_skyrat/modules/GAGS/icons/shoes.dmi index 154b6f312ba683..243f4ff5ec444d 100644 Binary files a/modular_skyrat/modules/GAGS/icons/shoes.dmi and b/modular_skyrat/modules/GAGS/icons/shoes.dmi differ diff --git a/modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps.json b/modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps.json new file mode 100644 index 00000000000000..cfe620714a3787 --- /dev/null +++ b/modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps.json @@ -0,0 +1,10 @@ +{ + "arm_wraps": [ + { + "type": "icon_state", + "icon_state": "arm_wraps", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps_worn.json b/modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps_worn.json new file mode 100644 index 00000000000000..cfe620714a3787 --- /dev/null +++ b/modular_skyrat/modules/GAGS/json_configs/arm_wraps/arm_wraps_worn.json @@ -0,0 +1,10 @@ +{ + "arm_wraps": [ + { + "type": "icon_state", + "icon_state": "arm_wraps", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps.json b/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps.json new file mode 100644 index 00000000000000..0e605054f908dc --- /dev/null +++ b/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps.json @@ -0,0 +1,10 @@ +{ + "legwrap": [ + { + "type": "icon_state", + "icon_state": "legwrap_obj", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn.json b/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn.json new file mode 100644 index 00000000000000..8ddd9e1dc3b1d5 --- /dev/null +++ b/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn.json @@ -0,0 +1,10 @@ +{ + "legwrap": [ + { + "type": "icon_state", + "icon_state": "legwrap_mob", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn_digi.json b/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn_digi.json new file mode 100644 index 00000000000000..833a458c85397a --- /dev/null +++ b/modular_skyrat/modules/GAGS/json_configs/wraps/legwraps_worn_digi.json @@ -0,0 +1,10 @@ +{ + "legwrap": [ + { + "type": "icon_state", + "icon_state": "legwrap_mob_digi", + "blend_mode": "overlay", + "color_ids": [ 1 ] + } + ] +} diff --git a/modular_skyrat/modules/aesthetics/airalarm/code/airalarm.dm b/modular_skyrat/modules/aesthetics/airalarm/code/airalarm.dm index f3675f8e226900..6792118bbaab8c 100644 --- a/modular_skyrat/modules/aesthetics/airalarm/code/airalarm.dm +++ b/modular_skyrat/modules/aesthetics/airalarm/code/airalarm.dm @@ -1,6 +1,5 @@ /obj/machinery/airalarm - icon = 'modular_skyrat/modules/aesthetics/airalarm/icons/airalarm.dmi' - var/light_mask = "alarm-light-mask" + icon = 'icons/obj/machines/wallmounts.dmi' /obj/machinery/airalarm/update_appearance(updates) . = ..() diff --git a/modular_skyrat/modules/aesthetics/firealarm/icons/firealarm.dmi b/modular_skyrat/modules/aesthetics/firealarm/icons/firealarm.dmi index 20adc064d3254f..ce8c37b6004928 100644 Binary files a/modular_skyrat/modules/aesthetics/firealarm/icons/firealarm.dmi and b/modular_skyrat/modules/aesthetics/firealarm/icons/firealarm.dmi differ diff --git a/modular_skyrat/modules/aesthetics/guns/code/guns.dm b/modular_skyrat/modules/aesthetics/guns/code/guns.dm index ccc43793c335f1..ac20f9f5db997b 100644 --- a/modular_skyrat/modules/aesthetics/guns/code/guns.dm +++ b/modular_skyrat/modules/aesthetics/guns/code/guns.dm @@ -49,7 +49,7 @@ /datum/material/bluespace = SMALL_MATERIAL_AMOUNT * 0.2, \ ) -// for .35 Sol Ripper. one day, anon. one day +// for .35 Sol Ripper #define AMMO_MATS_RIPPER list( \ /datum/material/iron = SMALL_MATERIAL_AMOUNT * 1.6, \ /datum/material/glass = SMALL_MATERIAL_AMOUNT * 0.4, \ @@ -75,33 +75,6 @@ lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi' righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi' -/obj/item/gun/ballistic/shotgun/riot - name = "\improper Peacekeeper shotgun" - desc = "A Nanotrasen-made riot control shotgun fitted with an extended tube and a fixed tactical stock." - icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns.dmi' - worn_icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi' - lefthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi' - righthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi' - inhand_icon_state = "riot_shotgun" - inhand_x_dimension = 32 - inhand_y_dimension = 32 - can_suppress = TRUE - suppressed_sound = 'modular_skyrat/modules/aesthetics/guns/sound/suppressed_shotgun.ogg' - suppressed_volume = 100 - vary_fire_sound = TRUE - fire_sound = 'modular_skyrat/modules/aesthetics/guns/sound/shotgun_light.ogg' - -/obj/item/gun/ballistic/shotgun/riot/syndicate - name = "\improper Peacebreaker shotgun" - desc = "A Scarborough riot control shotgun fitted with a crimson furnishing and a wooden tactical stock. You swear you've seen this model elsewhere before..." - icon_state = "riotshotgun_syndie" - inhand_icon_state = "riot_shotgun_syndie" - can_be_sawn_off = FALSE - can_suppress = FALSE - -/obj/item/gun/ballistic/shotgun/riot/syndicate/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_SCARBOROUGH) - /obj/item/gun/ballistic/shotgun/automatic/combat name = "\improper Peacekeeper combat shotgun" desc = "A semi-automatic Nanotrasen Peacekeeper shotgun with tactical furnishing and heavier internals meant for sustained fire. Lacks a threaded barrel." @@ -327,31 +300,11 @@ desc = "One of countless obsolete ballistic rifles that still sees use as a cheap deterrent. Uses 10mm ammo and its bulky frame prevents one-hand firing." icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns.dmi' -/obj/item/gun/ballistic/automatic/ar/modular/model75 - name = "\improper NT ARG-75" - desc = "A contemporary rifle manufactured by NT chambered for .310 Strilka. It's equipped with a heavy duty integrally suppressed barrel, CQB scope and a topmounted laser sight." - icon_state = "arg75" - icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns.dmi' - fire_sound = 'sound/weapons/gun/pistol/shot_suppressed.ogg' - fire_delay = 5 - fire_sound_volume = 90 - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/ostwind/arg75 - -/obj/item/gun/ballistic/automatic/ar/modular/model75/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_NANOTRASEN) - -/obj/item/ammo_box/magazine/multi_sprite/ostwind/arg75 - name = "\improper ARG-75 magazine" - desc = "A twenty round double-stack magazine for the NT ARG-75 rifle. Chambered in .310 Strilka." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "pcr" - ammo_type = /obj/item/ammo_casing/strilka310 - caliber = CALIBER_STRILKA310 - max_ammo = 20 - // GUBMAN3 - FULL BULLET RENAME // i loathe the above +// overrides for 10mm ammo in modular_skyrat\modules\sec_haul\code\guns\bullets.dm + // overrides for .310 Strilka-derived ammo, e.g. lionhunter ammo, because you don't want to give security the ability to print infinite wallhack ammo, right? /obj/item/ammo_casing/strilka310/lionhunter name = "hunter's rifle round" @@ -378,23 +331,47 @@ // overrides for tgcode .50cal, used in their sniper/anti-materiel rifles /obj/item/ammo_casing/p50 - name = ".416 Stabilis polymer casing" + name = ".416 Stabilis casing" desc = "A .416 bullet casing." advanced_print_req = TRUE // you are NOT printing more ammo for this without effort. // then again the offstations with ammo printers and sniper rifles come with an ammo disk anyway, so -/obj/item/ammo_casing/p50/soporific - name = ".416 Stabilis tranquilizer casing" - desc = "A .416 bullet casing that specialises in sending the target to sleep rather than hell.\ +/obj/item/ammo_casing/p50/surplus + name = ".416 Stabilis surplus casing" + desc = "A .416 bullet casing. Intentionally underloaded, but still quite painful to be shot with.\ +

\ + SURPLUS/UNDERLOAD: Lacks armor penetration capabilities, contact-stun, or innate dismemberment ability. Still incredibly painful to be hit by." + projectile_type = /obj/projectile/bullet/p50/surplus + +/obj/item/ammo_casing/p50/disruptor + name = ".416 Stabilis disruptor casing" + desc = "A .416 bullet casing. Specializes in sending the target to sleep rather than hell, unless they're synthetic. Then they probably go to hell anyway.\ +

\ + DISRUPTOR: Forces humanoid targets to sleep, does heavy damage against cyborgs, EMPs struck targets." + +/obj/item/ammo_casing/p50/incendiary + name = ".416 Stabilis precision incendiary casing" + desc = "A .416 bullet casing. Made with an agitated-plasma tip, for making people regret being alive.\

\ - SOPORIFIC: Forces targets to sleep, deals no damage." - projectile_type = /obj/projectile/bullet/p50/soporific + PRECISION INCENDIARY: Lacks innate dismemberment ability and contact-stun, suffers against mechanized armor. Sets people on fire." + projectile_type = /obj/projectile/bullet/p50/incendiary /obj/item/ammo_casing/p50/penetrator - name = ".416 Stabilis APFSDS ++P bullet casing" - desc = "A .416 round casing designed to go through basically everything. A label warns not to use the round if the weapon cannot handle pressures greater than 85000 PSI.\ + name = ".416 Stabilis penetrator sabot casing" + desc = "A .416 bullet casing. Loaded with a hardened sabot and packed with extra propellant. \ + Designed to go through basically everything. A label warns of overpressure risk, and to not use the round if \ + a given weapon cannot handle pressures greater than 85000 PSI.\

\ - PENETRATOR: Goes through every surface, and every mob. Goes through everything. Yes, really." + PENETRATOR: Goes through basically everything. Lacks innate dismemberment ability and contact-stun capabilities." + +/obj/item/ammo_casing/p50/marksman + name = ".416 Stabilis marksman hyperkinetic casing" + desc = "A .416 bullet casing. Loaded with a hyperkinetic bullet that ignores mundane things like \"travel time\" \ + and a concerning amount of experimental propellant. A label warns of overpressure risk, and to not use the round if \ + a given weapon cannot handle pressures greater than 95000 PSI.\ +

\ + MARKSMAN: Bullets have no travel time, and can ricochet once. Does slightly less damage, lacks innate dismemberment and contact-stun capabilities." + projectile_type = /obj/projectile/bullet/p50/marksman // overrides for tgcode 4.6x30mm, used in the WT-550 /obj/item/ammo_casing/c46x30mm @@ -528,8 +505,11 @@ /obj/projectile/bullet/incendiary/c46x30mm name = "8mm incendiary bullet" -/obj/projectile/bullet/p50/soporific // COMMON BULLET IS ALREADY OVERRIDEN IN MODULAR > BULLETREBALANCE > CODE > sniper.dm - name = ".416 tranquilizer" +/obj/projectile/bullet/p50 + name = ".416 Stabilis bullet" + +/obj/projectile/bullet/p50/disruptor + name = ".416 disruptor bullet" /obj/projectile/bullet/p50/penetrator name = ".416 penetrator bullet" diff --git a/modular_skyrat/modules/aesthetics/guns/icons/guns.dmi b/modular_skyrat/modules/aesthetics/guns/icons/guns.dmi index 3933f899038732..deb9cd5931e232 100644 Binary files a/modular_skyrat/modules/aesthetics/guns/icons/guns.dmi and b/modular_skyrat/modules/aesthetics/guns/icons/guns.dmi differ diff --git a/modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi b/modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi index bc77592a879a2b..471407b916e9ff 100644 Binary files a/modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi and b/modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi differ diff --git a/modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi b/modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi index 0b1ab1864f49f7..131c63fca3bc39 100644 Binary files a/modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi and b/modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi differ diff --git a/modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi b/modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi index 76ae0487b9f6fa..7907e543b89427 100644 Binary files a/modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi and b/modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi differ diff --git a/modular_skyrat/modules/aesthetics/kitchen/microwave.dmi b/modular_skyrat/modules/aesthetics/kitchen/microwave.dmi index d5560e1bc077a1..e1c2860da6e1dd 100644 Binary files a/modular_skyrat/modules/aesthetics/kitchen/microwave.dmi and b/modular_skyrat/modules/aesthetics/kitchen/microwave.dmi differ diff --git a/modular_skyrat/modules/aesthetics/tools/tools.dmi b/modular_skyrat/modules/aesthetics/tools/tools.dmi index e40038a5dcf9f4..518fa54cba94fe 100644 Binary files a/modular_skyrat/modules/aesthetics/tools/tools.dmi and b/modular_skyrat/modules/aesthetics/tools/tools.dmi differ diff --git a/modular_skyrat/modules/aesthetics/tools/tools_lefthand.dmi b/modular_skyrat/modules/aesthetics/tools/tools_lefthand.dmi index bc1a97aa3e2d5e..256b736f8cca66 100644 Binary files a/modular_skyrat/modules/aesthetics/tools/tools_lefthand.dmi and b/modular_skyrat/modules/aesthetics/tools/tools_lefthand.dmi differ diff --git a/modular_skyrat/modules/aesthetics/tools/tools_righthand.dmi b/modular_skyrat/modules/aesthetics/tools/tools_righthand.dmi index d7355344627784..3ed4928ee11851 100644 Binary files a/modular_skyrat/modules/aesthetics/tools/tools_righthand.dmi and b/modular_skyrat/modules/aesthetics/tools/tools_righthand.dmi differ diff --git a/modular_skyrat/modules/alternative_job_titles/code/alt_job_titles.dm b/modular_skyrat/modules/alternative_job_titles/code/alt_job_titles.dm index d7abb4e00f0116..11de552190337a 100644 --- a/modular_skyrat/modules/alternative_job_titles/code/alt_job_titles.dm +++ b/modular_skyrat/modules/alternative_job_titles/code/alt_job_titles.dm @@ -12,48 +12,60 @@ /datum/job/ai alt_titles = list( "AI", + "Automated Overseer", "Station Intelligence", - "Automated Overseer" ) /datum/job/assistant alt_titles = list( "Assistant", - "Civilian", - "Tourist", + "Artist", "Businessman", "Businesswoman", - "Trader", + "Civilian", "Entertainer", "Freelancer", - "Artist", - "Off-Duty Staff", + "Tourist", + "Trader", "Off-Duty Crew", + "Off-Duty Staff", ) /datum/job/atmospheric_technician alt_titles = list( "Atmospheric Technician", - "Life Support Technician", "Emergency Fire Technician", "Firefighter", + "Life Support Technician", ) /datum/job/barber alt_titles = list( "Barber", + "Aethestician", + "Colorist", "Salon Manager", "Salon Technician", "Stylist", - "Colorist", ) /datum/job/bartender alt_titles = list( "Bartender", - "Mixologist", - "Barkeeper", "Barista", + "Barkeeper", + "Mixologist", + ) + +/datum/job/bitrunner + alt_titles = list( + "Bitrunner", + "Bitdomain Technician", + "Data Retrieval Specialist", + "Netdiver", + "Pod Jockey", + "Union Bitrunner", + "Junior Runner", ) /datum/job/blueshield @@ -66,11 +78,13 @@ /datum/job/botanist alt_titles = list( "Botanist", - "Hydroponicist", - "Gardener", "Botanical Researcher", - "Herbalist", "Florist", + "Gardener", + "Herbalist", + "Hydroponicist", + "Mycologist", + "Junior Botanist", ) /datum/job/bouncer @@ -89,33 +103,35 @@ /datum/job/captain alt_titles = list( "Captain", - "Station Commander", "Commanding Officer", "Site Manager", + "Station Commander", ) /datum/job/cargo_technician alt_titles = list( "Warehouse Technician", + "Commodities Trader", "Deck Worker", + "Inventory Associate", "Mailman", + "Receiving Clerk", "Union Associate", - "Inventory Associate", ) /datum/job/chaplain alt_titles = list( "Chaplain", - "Priest", - "Preacher", - "Reverend", - "Oracle", - "Pontifex", - "Magister", "High Priest", "Imam", - "Rabbi", + "Magister", "Monk", + "Oracle", + "Preacher", + "Priest", + "Pontifex", + "Rabbi", + "Reverend", ) /datum/job/chemist @@ -136,25 +152,25 @@ /datum/job/chief_medical_officer alt_titles = list( "Chief Medical Officer", - "Medical Director", - "Head of Medical", "Chief Physician", + "Head of Medical", "Head Physician", + "Medical Director", ) /datum/job/clown alt_titles = list( "Clown", + "Comedian", "Jester", "Joker", - "Comedian", ) /datum/job/cook alt_titles = list( "Cook", - "Chef", "Butcher", + "Chef", "Culinary Artist", "Sous-Chef", ) @@ -162,16 +178,19 @@ /datum/job/coroner alt_titles = list( "Coroner", - "Mortician", + "Forensic Pathologist", "Funeral Director", + "Medical Examiner", + "Mortician", ) /datum/job/curator alt_titles = list( "Curator", - "Librarian", - "Journalist", "Archivist", + "Conservator", + "Journalist", + "Librarian", ) /datum/job/customs_agent @@ -183,26 +202,27 @@ /datum/job/cyborg alt_titles = list( "Cyborg", - "Robot", "Android", + "Robot", ) /datum/job/detective alt_titles = list( "Detective", + "Forensic Scientist", "Forensic Technician", "Private Investigator", - "Forensic Scientist", ) /datum/job/doctor alt_titles = list( "Medical Doctor", - "Surgeon", - "Nurse", "General Practitioner", "Medical Resident", + "Nurse", "Physician", + "Surgeon", + "Medical Student", ) /datum/job/engineering_guard //see orderly @@ -210,58 +230,61 @@ /datum/job/geneticist alt_titles = list( "Geneticist", + "Gene Tailor", "Mutation Researcher", ) /datum/job/head_of_personnel alt_titles = list( "Head of Personnel", - "Executive Officer", - "Employment Officer", "Crew Supervisor", + "Employment Officer", + "Executive Officer", ) /datum/job/head_of_security alt_titles = list( "Head of Security", - "Security Commander", "Chief Constable", "Chief of Security", + "Security Commander", "Sheriff", ) /datum/job/janitor alt_titles = list( "Janitor", - "Custodian", - "Custodial Technician", - "Sanitation Technician", - "Maintenance Technician", "Concierge", + "Custodial Technician", + "Custodian", "Maid", + "Maintenance Technician", + "Sanitation Technician", ) /datum/job/lawyer alt_titles = list( "Lawyer", - "Internal Affairs Agent", - "Human Resources Agent", - "Defence Attorney", - "Public Defender", "Barrister", - "Prosecutor", + "Defense Attorney", + "Human Resources Agent", + "Internal Affairs Agent", "Legal Clerk", + "Prosecutor", + "Public Defender", ) /datum/job/mime alt_titles = list( "Mime", + "Mummer", "Pantomimist", ) /datum/job/nanotrasen_consultant alt_titles = list( "Nanotrasen Consultant", + "Nanotrasen Advisor", "Nanotrasen Diplomat", ) @@ -285,44 +308,42 @@ "Maximum Security Prisoner", "SuperMax Security Prisoner", "Protective Custody Prisoner", - "Convict", - "Felon", - "Inmate", ) /datum/job/psychologist alt_titles = list( "Psychologist", + "Counsellor", "Psychiatrist", "Therapist", - "Counsellor", ) /datum/job/quartermaster alt_titles = list( "Quartermaster", - "Union Requisitions Officer", "Deck Chief", - "Warehouse Supervisor", - "Supply Foreman", "Head of Supply", "Logistics Coordinator", + "Supply Foreman", + "Union Requisitions Officer", + "Warehouse Supervisor", ) /datum/job/research_director alt_titles = list( "Research Director", - "Silicon Administrator", - "Lead Researcher", "Biorobotics Director", - "Research Supervisor", "Chief Science Officer", + "Lead Researcher", + "Research Supervisor", + "Silicon Administrator", ) /datum/job/roboticist alt_titles = list( "Roboticist", "Biomechanical Engineer", + "Machinist", "Mechatronic Engineer", "Apprentice Roboticist", ) @@ -332,24 +353,24 @@ /datum/job/scientist alt_titles = list( "Scientist", + "Anomalist", "Circuitry Designer", - "Xenobiologist", "Cytologist", - "Plasma Researcher", - "Anomalist", + "Graduate Student", "Lab Technician", - "Theoretical Physicist", "Ordnance Technician", + "Plasma Researcher", + "Theoretical Physicist", "Xenoarchaeologist", + "Xenobiologist", "Research Assistant", - "Graduate Student", ) /datum/job/security_officer alt_titles = list( "Security Officer", - "Security Operative", "Peacekeeper", + "Security Operative", "Security Cadet", ) @@ -357,26 +378,27 @@ alt_titles = list( "Union Miner", "Excavator", - "Spelunker", "Drill Technician", "Prospector", + "Spelunker", + "Apprentice Miner", ) /datum/job/station_engineer alt_titles = list( "Station Engineer", - "Emergency Damage Control Technician", "Electrician", + "Emergency Damage Control Technician", "Engine Technician", "EVA Technician", "Mechanic", "Apprentice Engineer", - "Engineering Trainee", ) /datum/job/virologist alt_titles = list( "Virologist", + "Epidemiologist", "Pathologist", "Junior Pathologist", ) @@ -385,7 +407,7 @@ alt_titles = list( "Warden", "Brig Sergeant", - "Dispatch Officer", "Brig Governor", + "Dispatch Officer", "Jailer", ) diff --git a/modular_skyrat/modules/alternative_job_titles/code/job.dm b/modular_skyrat/modules/alternative_job_titles/code/job.dm index 2f47a4c1f0533c..13edfe45aa4c12 100644 --- a/modular_skyrat/modules/alternative_job_titles/code/job.dm +++ b/modular_skyrat/modules/alternative_job_titles/code/job.dm @@ -11,6 +11,9 @@ if(!player_client) return + if(!ishuman(equipping)) + return + var/chosen_title = player_client.prefs.alt_job_titles[job.title] || job.title var/obj/item/card/id/card = equipping.wear_id diff --git a/modular_skyrat/modules/ammo_workbench/code/design_disks.dm b/modular_skyrat/modules/ammo_workbench/code/design_disks.dm index f7955d053e009f..26e6302c6da792 100644 --- a/modular_skyrat/modules/ammo_workbench/code/design_disks.dm +++ b/modular_skyrat/modules/ammo_workbench/code/design_disks.dm @@ -1,5 +1,5 @@ /obj/item/disk/ammo_workbench - name = "Armadyne Munitions blueprint datadisk" + name = "munitions blueprint datadisk" desc = "You shouldn't be seeing this!" /// For doing things when installed/downloaded onto an ammo bench. @@ -9,8 +9,8 @@ /obj/item/disk/ammo_workbench/advanced name = "advanced munitions datadisk" - desc = "An Armadyne datadisk filled with advanced munition fabrication data for the ammunition workbench, including lethal ammotypes if not previously enabled. \ - Armadyne's munitions division does not take responsibility for any incidents that occur if safeties were circumvented beforehand." + desc = "An datadisk filled with advanced munition fabrication data for the ammunition workbench, including lethal ammotypes if not previously enabled. \ + No parties are liable for any incidents that occur if safeties were circumvented beforehand." /obj/item/disk/ammo_workbench/advanced/on_bench_install(obj/machinery/ammo_workbench/ammobench) ammobench.allowed_harmful = TRUE diff --git a/modular_skyrat/modules/ashwalkers/code/buildings/ash_tendril.dm b/modular_skyrat/modules/ashwalkers/code/buildings/ash_tendril.dm index eaa80cc59417d6..18d3baa3b51f0c 100644 --- a/modular_skyrat/modules/ashwalkers/code/buildings/ash_tendril.dm +++ b/modular_skyrat/modules/ashwalkers/code/buildings/ash_tendril.dm @@ -99,7 +99,7 @@ viewable_living.gib() continue - if(viewable_living.mind?.has_antag_datum(/datum/antagonist/ashwalker) && (viewable_living.key || viewable_living.get_ghost(FALSE, TRUE))) //special interactions for dead lava lizards with ghosts attached + if(viewable_living.mind?.has_antag_datum(/datum/antagonist/ashwalker) && (viewable_living.ckey || viewable_living.get_ghost(FALSE, TRUE))) //special interactions for dead lava lizards with ghosts attached revive_ashwalker(viewable_living) continue @@ -129,6 +129,8 @@ else living_observers.add_mood_event("oogabooga", /datum/mood_event/sacrifice_bad) + ashies.sacrifices_made++ + /** * Proc that will spawn the egg that will revive the ashwalker * This is also the Skyrat replacement for /proc/remake_walker diff --git a/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm b/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm index ba1dd931c3a225..7b38a565698b21 100644 --- a/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm +++ b/modular_skyrat/modules/ashwalkers/code/effects/ash_rituals.dm @@ -198,7 +198,7 @@ /datum/ash_ritual/summon_icemoon_creature/ritual_success(obj/effect/ash_rune/success_rune) . = ..() var/mob_type = pick( - /mob/living/simple_animal/hostile/asteroid/ice_demon, + /mob/living/basic/mining/ice_demon, /mob/living/basic/mining/ice_whelp, /mob/living/basic/mining/lobstrosity, /mob/living/simple_animal/hostile/asteroid/polarbear, diff --git a/modular_skyrat/modules/assault_operatives/code/armaments/_armament_primary.dm b/modular_skyrat/modules/assault_operatives/code/armaments/_armament_primary.dm index ff55e715b0e983..e2ef34a2972ef0 100644 --- a/modular_skyrat/modules/assault_operatives/code/armaments/_armament_primary.dm +++ b/modular_skyrat/modules/assault_operatives/code/armaments/_armament_primary.dm @@ -7,8 +7,8 @@ #define OPS_SUBCATEGORY_SHOTGUN "Shotguns" #define OPS_SUBCATEGORY_SHOTGUN_AMMO "Speciality Shotgun Ammo" -#define OPS_SUBCATEGORY_SNIPER "Marksman Rifles" -#define OPS_SUBCATEGORY_SNIPER_AMMO "Speciality Marksman Rifle Ammo" +#define OPS_SUBCATEGORY_SNIPER "Grenade Launchers" +#define OPS_SUBCATEGORY_SNIPER_AMMO "Speciality Grenade Launcher Ammo" /datum/armament_entry/assault_operatives/primary category = "Long Arms" @@ -20,50 +20,67 @@ subcategory = OPS_SUBCATEGORY_RIFLE /datum/armament_entry/assault_operatives/primary/rifle/assault_ops_rifle - item_type = /obj/item/gun/ballistic/automatic/assault_ops_rifle + item_type = /obj/item/gun/ballistic/automatic/sol_rifle/evil /datum/armament_entry/assault_operatives/primary/rifle_ammo subcategory = OPS_SUBCATEGORY_RIFLE_AMMO max_purchase = 10 cost = 1 -/datum/armament_entry/assault_operatives/primary/rifle_ammo/rubber - name = "\improper IGE-110 rubber magazine" - description = "Rifle ammo that is more likely to exhaust whoever its shot at, rather than killing them." - item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle/rubber +/datum/armament_entry/assault_operatives/primary/rifle_ammo/standard + item_type = /obj/item/ammo_box/magazine/c40sol_rifle/starts_empty + cost = 0 -/datum/armament_entry/assault_operatives/primary/rifle_ammo/ap - name = "\improper IGE-110 armor piercing magazine" - description = "Rifle ammo built specifically to penetrate through armor." - item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle/ap +/datum/armament_entry/assault_operatives/primary/rifle_ammo/drum + item_type = /obj/item/ammo_box/magazine/c40sol_rifle/drum/starts_empty + cost = 0 + +/datum/armament_entry/assault_operatives/primary/rifle_ammo/c40sol + item_type = /obj/item/ammo_box/c40sol + +/datum/armament_entry/assault_operatives/primary/rifle_ammo/c40sol_disabler + item_type = /obj/item/ammo_box/c40sol/fragmentation + +/datum/armament_entry/assault_operatives/primary/rifle_ammo/c40sol_pierce + item_type = /obj/item/ammo_box/c40sol/pierce + +/datum/armament_entry/assault_operatives/primary/rifle_ammo/c40sol_incendiary + item_type = /obj/item/ammo_box/c40sol/incendiary /datum/armament_entry/assault_operatives/primary/submachinegun subcategory = OPS_SUBCATEGORY_SMG /datum/armament_entry/assault_operatives/primary/submachinegun/assault_ops_smg - item_type = /obj/item/gun/ballistic/automatic/assault_ops_smg + item_type = /obj/item/gun/ballistic/automatic/sol_smg/evil /datum/armament_entry/assault_operatives/primary/submachinegun_ammo subcategory = OPS_SUBCATEGORY_SMG_AMMO max_purchase = 10 cost = 1 -/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/rubber - name = "\improper IGE-260 rubber magazine" - description = "Submachine gun ammo that is more likely to exhaust whoever its shot at, rather than killing them." - item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg/rubber +/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/standard + item_type = /obj/item/ammo_box/magazine/c35sol_pistol/starts_empty + cost = 0 + +/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/extended + item_type = /obj/item/ammo_box/magazine/c35sol_pistol/stendo/starts_empty + cost = 0 + +/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/c35sol + item_type = /obj/item/ammo_box/c35sol -/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/hp - name = "\improper IGE-260 hollowpoint magazine" - description = "Submachine gun ammo that hurts unarmored targets more, in exchange for worse performance against armor." - item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg/hp +/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/c35sol_disabler + item_type = /obj/item/ammo_box/c35sol/incapacitator + +/datum/armament_entry/assault_operatives/primary/submachinegun_ammo/c35sol_pierce + item_type = /obj/item/ammo_box/c35sol/ripper /datum/armament_entry/assault_operatives/primary/shotgun subcategory = OPS_SUBCATEGORY_SHOTGUN /datum/armament_entry/assault_operatives/primary/shotgun/assault_ops_shotgun - item_type = /obj/item/gun/ballistic/automatic/assault_ops_shotgun + item_type = /obj/item/gun/ballistic/shotgun/riot/sol/evil /datum/armament_entry/assault_operatives/primary/shotgun_ammo subcategory = OPS_SUBCATEGORY_SHOTGUN_AMMO @@ -71,50 +88,53 @@ cost = 1 /datum/armament_entry/assault_operatives/primary/shotgun_ammo/rubber - name = "\improper IGE-340 rubbershot magazine" - description = "Shotgun ammo that's much like buckshot, but more likely to exhaust whoever its shot at rather than killing them." - item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/rubbershot + item_type = /obj/item/ammo_box/advanced/s12gauge/rubber /datum/armament_entry/assault_operatives/primary/shotgun_ammo/flechette - name = "\improper IGE-340 flechette magazine" - description = "Shotgun ammo that fires armor piercing flechettes that can cause some nasty wounds." - item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/flechette + item_type = /obj/item/ammo_box/advanced/s12gauge/flechette /datum/armament_entry/assault_operatives/primary/shotgun_ammo/hollowpoint - name = "\improper IGE-340 hollowpoint slug magazine" - description = "Shotgun ammo that fires a large hollowpoint slug that hurts unarmored targets a lot more, in exchange for worse performance against armor." - item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/hollowpoint + item_type = /obj/item/ammo_box/advanced/s12gauge/hp /datum/armament_entry/assault_operatives/primary/shotgun_ammo/beehive - name = "\improper IGE-340 'beehive' magazine" - description = "Shotgun ammo that fires a spread of smart-bouncing pellets, that are more likely to exhaust whoever its shot at rather than killing them." - item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/beehive + item_type = /obj/item/ammo_box/advanced/s12gauge/beehive -/datum/armament_entry/assault_operatives/primary/shotgun_ammo/dragonsbreath - name = "\improper IGE-340 dragonsbreath magazine" - description = "Shotgun ammo that fires a spread of incendiary projectiles, creating a wall of fire whichever direction they are shot in." - item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/dragonsbreath +/datum/armament_entry/assault_operatives/primary/shotgun_ammo/incendiary + item_type = /obj/item/ammo_box/advanced/s12gauge/incendiary /datum/armament_entry/assault_operatives/primary/sniper subcategory = OPS_SUBCATEGORY_SNIPER -/datum/armament_entry/assault_operatives/primary/sniper/assault_ops_sniper - item_type = /obj/item/gun/ballistic/rifle/boltaction/assault_ops_sniper +/datum/armament_entry/assault_operatives/primary/sniper/assault_ops_gl + item_type = /obj/item/gun/ballistic/automatic/sol_grenade_launcher/evil /datum/armament_entry/assault_operatives/primary/sniper_ammo subcategory = OPS_SUBCATEGORY_SNIPER_AMMO max_purchase = 10 cost = 1 -/datum/armament_entry/assault_operatives/primary/sniper_ammo/eepy - name = "\improper IGE-410 soporific magazine" - description = "Sniper ammo that will put whoever it hits right to sleep, rather than killing them." - item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper/sleepytime +/datum/armament_entry/assault_operatives/primary/sniper_ammo/standard + item_type = /obj/item/ammo_box/magazine/c980_grenade/starts_empty + cost = 0 + +/datum/armament_entry/assault_operatives/primary/sniper_ammo/drum + item_type = /obj/item/ammo_box/magazine/c980_grenade/drum/starts_empty + cost = 0 + +/datum/armament_entry/assault_operatives/primary/sniper_ammo/practice + item_type = /obj/item/ammo_box/c980grenade + +/datum/armament_entry/assault_operatives/primary/sniper_ammo/smoke + item_type = /obj/item/ammo_box/c980grenade/smoke + +/datum/armament_entry/assault_operatives/primary/sniper_ammo/shrapnel + item_type = /obj/item/ammo_box/c980grenade/shrapnel + +/datum/armament_entry/assault_operatives/primary/sniper_ammo/phosphor + item_type = /obj/item/ammo_box/c980grenade/shrapnel/phosphor -/datum/armament_entry/assault_operatives/primary/sniper_ammo/penetrator - name = "\improper IGE-410 penetrator magazine" - description = "Sniper ammo that is capable of penetrating through multiple walls and people at once." - item_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper/penetrator +/datum/armament_entry/assault_operatives/primary/sniper_ammo/riot + item_type = /obj/item/ammo_box/c980grenade/riot #undef OPS_SUBCATEGORY_RIFLE #undef OPS_SUBCATEGORY_RIFLE_AMMO diff --git a/modular_skyrat/modules/assault_operatives/code/armaments/_armament_secondary.dm b/modular_skyrat/modules/assault_operatives/code/armaments/_armament_secondary.dm index 0022abd9868095..36460f04d630d9 100644 --- a/modular_skyrat/modules/assault_operatives/code/armaments/_armament_secondary.dm +++ b/modular_skyrat/modules/assault_operatives/code/armaments/_armament_secondary.dm @@ -11,8 +11,8 @@ /datum/armament_entry/assault_operatives/secondary/lethal subcategory = OPS_SUBCATEGORY_LETHAL_SIDE -/datum/armament_entry/assault_operatives/secondary/lethal/ansem - item_type = /obj/item/gun/ballistic/automatic/pistol/clandestine/assault_ops +/datum/armament_entry/assault_operatives/secondary/lethal/pistol + item_type = /obj/item/gun/ballistic/automatic/pistol/sol/evil /datum/armament_entry/assault_operatives/secondary/lethal/energy_sword item_type = /obj/item/melee/energy/sword/saber @@ -21,7 +21,7 @@ subcategory = OPS_SUBCATEGORY_NONLETHAL_SIDE /datum/armament_entry/assault_operatives/secondary/nonlethal/taze_me_bro - item_type = /obj/item/gun/energy/e_gun/advtaser/assault_ops + item_type = /obj/item/gun/energy/e_gun/advtaser /datum/armament_entry/assault_operatives/secondary/nonlethal/baton item_type = /obj/item/melee/baton/telescopic diff --git a/modular_skyrat/modules/assault_operatives/code/equipment_items/guns.dm b/modular_skyrat/modules/assault_operatives/code/equipment_items/guns.dm deleted file mode 100644 index 357c25e02f961a..00000000000000 --- a/modular_skyrat/modules/assault_operatives/code/equipment_items/guns.dm +++ /dev/null @@ -1,246 +0,0 @@ -// La Pistola - -/obj/item/gun/ballistic/automatic/pistol/clandestine/assault_ops - name = "\improper IGE-040 pistol" - desc = "A pistol chambered in 10mm magnum and painted in an ominous matte black. Strangely, the gun also seems to lack any form of manufacturer markings." - -/obj/item/gun/ballistic/automatic/pistol/clandestine/assault_ops/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_REMOVED) - -/obj/item/gun/energy/e_gun/advtaser/assault_ops - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/gun/energy/e_gun/advtaser/assault_ops/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_REMOVED) - -// Rifle - -/obj/item/gun/ballistic/automatic/assault_ops_rifle - name = "\improper IGE-110 rifle" - desc = "A bullpup rifle chambered in 5.6x40mm and painted in an ominous matte black. Strangely, the gun also seems to lack any form of manufacturer markings." - - icon_state = "ige_assault" - icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns.dmi' - inhand_icon_state = "ige_assault" - righthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_righthand.dmi' - lefthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_lefthand.dmi' - worn_icon_state = "ige_assault" - worn_icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_worn.dmi' - - base_pixel_x = -8 - pixel_x = -8 - - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle - fire_sound = 'modular_skyrat/modules/sec_haul/sound/sfrifle_fire.ogg' - can_suppress = TRUE - suppressor_x_offset = 4 - suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg' - burst_size = 2 - fire_delay = 3 - pin = /obj/item/firing_pin/implant/pindicate - -/obj/item/gun/ballistic/automatic/assault_ops_rifle/Initialize(mapload) - . = ..() - - AddComponent(/datum/component/scope, range_modifier = 1.5) - -/obj/item/gun/ballistic/automatic/assault_ops_rifle/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_REMOVED) - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle - name = "\improper IGE-110 magazine" - desc = "A twenty round magazine built for 5.6x40mm, intended for use in the IGE-110 rifle." - icon = 'modular_skyrat/modules/assault_operatives/icons/guns/magazines.dmi' - icon_state = "ige_assault_mag" - ammo_type = /obj/item/ammo_casing/realistic/a762x39 - caliber = "a762x39" - max_ammo = 20 - multiple_sprites = AMMO_BOX_FULL_EMPTY - possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_RUBBER, AMMO_TYPE_AP) - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle/rubber - ammo_type = /obj/item/ammo_casing/realistic/a762x39/civilian/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_rifle/ap - ammo_type = /obj/item/ammo_casing/realistic/a762x39/ap - round_type = AMMO_TYPE_AP - -// SMG - -/obj/item/gun/ballistic/automatic/assault_ops_smg - name = "\improper IGE-260 submachine gun" - desc = "A toploader submachine gun chambered in 9x25mm and painted in an ominous matte black. Strangely, the gun also seems to lack any form of manufacturer markings." - - icon_state = "ige_smg" - icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns.dmi' - inhand_icon_state = "ige_smg" - righthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_righthand.dmi' - lefthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_lefthand.dmi' - worn_icon_state = "ige_smg" - worn_icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_worn.dmi' - - base_pixel_x = -8 - pixel_x = -8 - - w_class = WEIGHT_CLASS_NORMAL - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg - fire_sound = 'modular_skyrat/modules/sec_haul/sound/smg_fire.ogg' - can_suppress = TRUE - burst_size = 1 - fire_delay = 0.8 - projectile_damage_multiplier = 0.6 - actions_types = list() - pin = /obj/item/firing_pin/implant/pindicate - -/obj/item/gun/ballistic/automatic/assault_ops_smg/Initialize(mapload) - . = ..() - - AddComponent(/datum/component/automatic_fire, fire_delay) - -/obj/item/gun/ballistic/automatic/assault_ops_smg/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_REMOVED) - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg - name = "\improper IGE-260 magazine" - desc = "A forty round magazine built for 9x25mm, intended for use in the IGE-260 submachine gun." - icon = 'modular_skyrat/modules/assault_operatives/icons/guns/magazines.dmi' - icon_state = "ige_smg_mag" - ammo_type = /obj/item/ammo_casing/c9mm - caliber = CALIBER_9MM - max_ammo = 40 - multiple_sprites = AMMO_BOX_FULL_EMPTY - possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_RUBBER, AMMO_TYPE_HOLLOWPOINT) - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg/rubber - ammo_type = /obj/item/ammo_casing/c9mm/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_smg/hp - ammo_type = /obj/item/ammo_casing/c9mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -// Shotgun - -/obj/item/gun/ballistic/automatic/assault_ops_shotgun - name = "\improper IGE-340 semi-automatic shotgun" - desc = "A magazine fed semi-automatic shotgun chambered in 12 GA and painted in an ominous matte black. Strangely, the gun also seems to lack any form of manufacturer markings." - - icon_state = "ige_shotgun" - icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns.dmi' - inhand_icon_state = "ige_shotgun" - righthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_righthand.dmi' - lefthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_lefthand.dmi' - worn_icon_state = "ige_shotgun" - worn_icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_worn.dmi' - - base_pixel_x = -8 - pixel_x = -8 - - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun - fire_sound = 'modular_skyrat/modules/sec_haul/sound/shotgun_bm.ogg' - can_suppress = TRUE - suppressor_x_offset = 4 - suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg' - burst_size = 1 - fire_delay = 1.5 - actions_types = list() - pin = /obj/item/firing_pin/implant/pindicate - -/obj/item/gun/ballistic/automatic/assault_ops_shotgun/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_REMOVED) - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun - name = "\improper IGE-340 magazine" - desc = "A seven round magazine built for 12 GA, intended for use in the IGE-340 shotgun." - icon = 'modular_skyrat/modules/assault_operatives/icons/guns/magazines.dmi' - icon_state = "ige_shotgun_mag" - ammo_type = /obj/item/ammo_casing/shotgun - caliber = CALIBER_SHOTGUN - max_ammo = 7 - multiple_sprites = AMMO_BOX_FULL_EMPTY - possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_RUBBER, AMMO_TYPE_AP, AMMO_TYPE_HOLLOWPOINT, AMMO_TYPE_IHDF, AMMO_TYPE_INCENDIARY) - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/rubbershot - ammo_type = /obj/item/ammo_casing/shotgun/rubbershot - round_type = AMMO_TYPE_RUBBER - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/flechette - ammo_type = /obj/item/ammo_casing/shotgun/flechette - round_type = AMMO_TYPE_AP - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/hollowpoint - ammo_type = /obj/item/ammo_casing/shotgun/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/beehive - ammo_type = /obj/item/ammo_casing/shotgun/beehive - round_type = AMMO_TYPE_IHDF - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_shotgun/dragonsbreath - ammo_type = /obj/item/ammo_casing/shotgun/dragonsbreath - round_type = AMMO_TYPE_INCENDIARY - -// Sniper - -/obj/item/gun/ballistic/rifle/boltaction/assault_ops_sniper - name = "\improper IGE-410-S marksman rifle" - desc = "A magazine fed bolt-action rifle with a short enough barrel that your shoulder hurts just looking at it. Chambered in .416 Stabilis, it is painted in an ominous matte black and seems to lack any form of manufacturer markings." - - icon_state = "ige_sniper" - icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns.dmi' - inhand_icon_state = "ige_sniper" - righthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_righthand.dmi' - lefthand_file = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_lefthand.dmi' - worn_icon_state = "ige_sniper" - worn_icon = 'modular_skyrat/modules/assault_operatives/icons/guns/guns_worn.dmi' - - base_pixel_x = -8 - pixel_x = -8 - - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING - internal_magazine = FALSE - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper - fire_sound = 'modular_skyrat/modules/sec_haul/sound/sniper_fire.ogg' - can_suppress = TRUE - suppressor_x_offset = 6 - suppressed_sound = 'sound/weapons/gun/general/heavy_shot_suppressed.ogg' - burst_size = 1 - fire_delay = 10 - recoil = 3 - can_be_sawn_off = FALSE - can_jam = FALSE - pin = /obj/item/firing_pin/implant/pindicate - -/obj/item/gun/ballistic/rifle/boltaction/assault_ops_sniper/Initialize(mapload) - . = ..() - - AddComponent(/datum/component/scope, range_modifier = 2.5) - -/obj/item/gun/ballistic/rifle/boltaction/assault_ops_sniper/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_REMOVED) - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper - name = "\improper IGE-410 magazine" - desc = "A five round magazine built for .416 Stabilis, intended for use in the IGE-410 sniper." - icon = 'modular_skyrat/modules/assault_operatives/icons/guns/magazines.dmi' - icon_state = "ige_sniper_mag" - ammo_type = /obj/item/ammo_casing/p50 - caliber = CALIBER_50BMG - max_ammo = 5 - multiple_sprites = AMMO_BOX_FULL_EMPTY - possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_RUBBER, AMMO_TYPE_AP) - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper/sleepytime - ammo_type = /obj/item/ammo_casing/p50/soporific - round_type = AMMO_TYPE_RUBBER - -/obj/item/ammo_box/magazine/multi_sprite/assault_ops_sniper/penetrator - ammo_type = /obj/item/ammo_casing/p50/penetrator - round_type = AMMO_TYPE_AP diff --git a/modular_skyrat/modules/black_mesa/code/armaments/_armament_primary.dm b/modular_skyrat/modules/black_mesa/code/armaments/_armament_primary.dm index 9c5344691d1448..80462185a0e0ea 100644 --- a/modular_skyrat/modules/black_mesa/code/armaments/_armament_primary.dm +++ b/modular_skyrat/modules/black_mesa/code/armaments/_armament_primary.dm @@ -41,7 +41,7 @@ magazine_cost = 4 /datum/armament_entry/hecu/primary/shotgun/shotgun_highcap - item_type = /obj/item/gun/ballistic/shotgun/m23 + item_type = /obj/item/gun/ballistic/shotgun/riot/sol max_purchase = 2 cost = 5 @@ -55,7 +55,7 @@ mags_to_spawn = 2 /datum/armament_entry/hecu/primary/special/sniper_rifle - item_type = /obj/item/gun/ballistic/automatic/cfa_rifle + item_type = /obj/item/gun/ballistic/automatic/sol_rifle/marksman max_purchase = 1 cost = 16 diff --git a/modular_skyrat/modules/black_mesa/code/armaments/_armaments_secondary.dm b/modular_skyrat/modules/black_mesa/code/armaments/_armaments_secondary.dm index da2f9575ed06e6..2098c72a7185dc 100644 --- a/modular_skyrat/modules/black_mesa/code/armaments/_armaments_secondary.dm +++ b/modular_skyrat/modules/black_mesa/code/armaments/_armaments_secondary.dm @@ -12,8 +12,8 @@ item_type = /obj/item/gun/ballistic/automatic/pistol/m1911 max_purchase = 4 -/datum/armament_entry/hecu/secondary/pistol/glock - item_type = /obj/item/gun/ballistic/automatic/pistol/g17/mesa +/datum/armament_entry/hecu/secondary/pistol/pistol + item_type = /obj/item/gun/ballistic/automatic/pistol/sol max_purchase = 4 mags_to_spawn = 3 diff --git a/modular_skyrat/modules/black_mesa/code/armaments/armament_miscellaneous.dm b/modular_skyrat/modules/black_mesa/code/armaments/armament_miscellaneous.dm index 8ec1c5e39a64aa..1916b4e90fc403 100644 --- a/modular_skyrat/modules/black_mesa/code/armaments/armament_miscellaneous.dm +++ b/modular_skyrat/modules/black_mesa/code/armaments/armament_miscellaneous.dm @@ -53,6 +53,6 @@ cost = 1 /datum/armament_entry/hecu/misc/hudglasses - item_type = /obj/item/clothing/glasses/hud/security/sunglasses/peacekeeper/armadyne + item_type = /obj/item/clothing/glasses/hud/security/sunglasses/peacekeeper max_purchase = 6 cost = 2 diff --git a/modular_skyrat/modules/black_mesa/code/drops.dm b/modular_skyrat/modules/black_mesa/code/drops.dm index a415f790b94c6a..30ab8bf0cf0a27 100644 --- a/modular_skyrat/modules/black_mesa/code/drops.dm +++ b/modular_skyrat/modules/black_mesa/code/drops.dm @@ -1,8 +1,8 @@ /obj/effect/spawner/random/hecu_smg name = "HECU SMG drops" spawn_all_loot = FALSE - loot = list(/obj/item/gun/ballistic/automatic/cfa_wildcat = 15, - /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat = 25, + loot = list(/obj/item/gun/ballistic/automatic/sol_smg = 15, + /obj/item/ammo_box/magazine/c35sol_pistol/stendo = 25, /obj/item/clothing/mask/gas/hecu2 = 15, /obj/item/clothing/head/helmet = 15, /obj/item/clothing/suit/armor/vest = 15, diff --git a/modular_skyrat/modules/black_mesa/code/ghost_spawners.dm b/modular_skyrat/modules/black_mesa/code/ghost_spawners.dm index 8efff44325d329..416def1973aa42 100644 --- a/modular_skyrat/modules/black_mesa/code/ghost_spawners.dm +++ b/modular_skyrat/modules/black_mesa/code/ghost_spawners.dm @@ -56,9 +56,9 @@ belt = /obj/item/storage/belt/security/full back = /obj/item/storage/backpack backpack_contents = list(/obj/item/radio, - /obj/item/gun/ballistic/automatic/pistol/g17/mesa, - /obj/item/ammo_box/magazine/multi_sprite/ladon, - /obj/item/ammo_box/magazine/multi_sprite/ladon, + /obj/item/gun/ballistic/automatic/pistol/sol, + /obj/item/ammo_box/magazine/c35sol_pistol, + /obj/item/ammo_box/magazine/c35sol_pistol, ) id = /obj/item/card/id id_trim = /datum/id_trim/security_guard diff --git a/modular_skyrat/modules/black_mesa/code/mobs/human_mobs.dm b/modular_skyrat/modules/black_mesa/code/mobs/human_mobs.dm index b83e961a701391..514c9aabe7cb92 100644 --- a/modular_skyrat/modules/black_mesa/code/mobs/human_mobs.dm +++ b/modular_skyrat/modules/black_mesa/code/mobs/human_mobs.dm @@ -162,7 +162,7 @@ icon_living = "security_guard_ranged" casingtype = /obj/item/ammo_casing/c9mm projectilesound = 'sound/weapons/gun/pistol/shot.ogg' - loot = list(/obj/effect/gibspawner/human, /obj/item/clothing/suit/armor/vest/blueshirt, /obj/item/gun/ballistic/automatic/pistol/g17/mesa) + loot = list(/obj/effect/gibspawner/human, /obj/item/clothing/suit/armor/vest/blueshirt, /obj/item/gun/ballistic/automatic/pistol/sol) rapid_melee = 1 /mob/living/simple_animal/hostile/blackmesa/blackops diff --git a/modular_skyrat/modules/blueshield/code/blueshield.dm b/modular_skyrat/modules/blueshield/code/blueshield.dm index 183bc4263c5d67..ed0cd1e27307eb 100644 --- a/modular_skyrat/modules/blueshield/code/blueshield.dm +++ b/modular_skyrat/modules/blueshield/code/blueshield.dm @@ -37,7 +37,6 @@ /obj/item/stack/spacecash/c500 = 3, /obj/item/disk/nuclear/fake/obvious = 2, /obj/item/clothing/head/collectable/captain = 4, - /obj/projectile/bullet/b460 = 1 ) veteran_only = TRUE @@ -53,9 +52,6 @@ shoes = /obj/item/clothing/shoes/jackboots ears = /obj/item/radio/headset/headset_bs/alt glasses = /obj/item/clothing/glasses/hud/security/sunglasses - backpack_contents = list( - /obj/item/storage/box/gunset/blueshield = 1, - ) implants = list(/obj/item/implant/mindshield) backpack = /obj/item/storage/backpack/blueshield satchel = /obj/item/storage/backpack/satchel/blueshield diff --git a/modular_skyrat/modules/blueshield/code/closet.dm b/modular_skyrat/modules/blueshield/code/closet.dm index 1ceaf37325b6f2..8c7a3c195c9c14 100644 --- a/modular_skyrat/modules/blueshield/code/closet.dm +++ b/modular_skyrat/modules/blueshield/code/closet.dm @@ -29,4 +29,5 @@ new /obj/item/restraints/handcuffs(src) new /obj/item/clothing/glasses/hud/security/sunglasses(src) new /obj/item/storage/medkit/tactical/blueshield(src) + new /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano(src) new /obj/item/storage/bag/garment/blueshield(src) diff --git a/modular_skyrat/modules/blueshield/code/clothing.dm b/modular_skyrat/modules/blueshield/code/clothing.dm index d25af6a26dd6b5..0875af9051048c 100644 --- a/modular_skyrat/modules/blueshield/code/clothing.dm +++ b/modular_skyrat/modules/blueshield/code/clothing.dm @@ -21,8 +21,8 @@ worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/ears.dmi' icon_state = "bshield_headset" worn_icon_state = "bshield_headset" - keyslot = new /obj/item/encryptionkey/heads/blueshield - keyslot2 = new /obj/item/encryptionkey/headset_cent + keyslot = /obj/item/encryptionkey/heads/blueshield + keyslot2 = /obj/item/encryptionkey/headset_cent /obj/item/radio/headset/headset_bs/alt icon_state = "bshield_headset_alt" @@ -39,16 +39,9 @@ icon = 'modular_skyrat/master_files/icons/obj/clothing/head/plasmaman_hats.dmi' worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/head/plasmaman_head.dmi' icon_state = "bs_envirohelm" - armor_type = /datum/armor/helmet_plasmaman_blueshield - -/datum/armor/helmet_plasmaman_blueshield - melee = 30 - bullet = 20 - laser = 20 - energy = 20 - bomb = 25 - bio = 100 - fire = 100 + armor_type = /datum/armor/head_helmet/plasmaman/blueshield + +/datum/armor/head_helmet/plasmaman/blueshield acid = 90 /obj/item/clothing/under/plasmaman/blueshield @@ -77,15 +70,10 @@ greyscale_colors = "#3A4E7D#DEB63D" //alternate_worn_icon_digi = 'modular_skyrat/icons/mob/head_muzzled.dmi' icon_state = "beret_badge_police" - armor_type = /datum/armor/beret_blueshield + armor_type = /datum/armor/head_helmet/blueshield supports_variations_flags = CLOTHING_SNOUTED_VARIATION_NO_NEW_ICON -/datum/armor/beret_blueshield - melee = 35 - bullet = 25 - laser = 25 - energy = 15 - bomb = 25 +/datum/armor/head_helmet/blueshield fire = 75 acid = 75 @@ -132,13 +120,30 @@ desc = "A tight-fitting kevlar-lined vest with a blue badge on the chest of it." icon_state = "blueshieldarmor" body_parts_covered = CHEST - armor_type = /datum/armor/vest_blueshield - -/datum/armor/vest_blueshield - melee = 35 - bullet = 25 - laser = 25 - energy = 25 + armor_type = /datum/armor/suit_armor/blueshield + uses_advanced_reskins = TRUE + unique_reskin = list( + "Slim" = list( + RESKIN_ICON = 'modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi', + RESKIN_ICON_STATE = "blueshieldarmor", + RESKIN_WORN_ICON = 'modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi', + RESKIN_WORN_ICON_STATE = "blueshieldarmor", + ), + "Marine" = list( + RESKIN_ICON = 'modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi', + RESKIN_ICON_STATE = "bs_marine", + RESKIN_WORN_ICON = 'modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi', + RESKIN_WORN_ICON_STATE = "bs_marine", + ), + "Bulky" = list( + RESKIN_ICON = 'modular_skyrat/master_files/icons/obj/clothing/suits/armor.dmi', + RESKIN_ICON_STATE = "vest_black", + RESKIN_WORN_ICON = 'modular_skyrat/master_files/icons/mob/clothing/suits/armor.dmi', + RESKIN_WORN_ICON_STATE = "vest_black", + ), + ) + +/datum/armor/suit_armor/blueshield bomb = 30 fire = 75 acid = 75 @@ -148,6 +153,7 @@ desc = "An expensive kevlar-lined jacket with a golden badge on the chest and \"NT\" emblazoned on the back. It weighs surprisingly little, despite how heavy it looks." icon_state = "blueshield" body_parts_covered = CHEST|ARMS + unique_reskin = null /obj/item/clothing/suit/armor/vest/blueshield/jacket/Initialize(mapload) . = ..() @@ -159,16 +165,7 @@ desc = "A comfy kevlar-lined coat with blue highlights, fit to keep the blueshield armored and warm." hoodtype = /obj/item/clothing/head/hooded/winterhood/skyrat/blueshield allowed = list(/obj/item/melee/baton/security/loaded) - armor_type = /datum/armor/wintercoat_blueshield - -/datum/armor/wintercoat_blueshield - melee = 35 - bullet = 25 - laser = 25 - energy = 25 - bomb = 30 - fire = 75 - acid = 75 + armor_type = /datum/armor/suit_armor/blueshield /obj/item/clothing/suit/hooded/wintercoat/skyrat/blueshield/Initialize(mapload) . = ..() @@ -177,13 +174,4 @@ /obj/item/clothing/head/hooded/winterhood/skyrat/blueshield icon_state = "hood_blueshield" desc = "A comfy kevlar-lined hood to go with the comfy kevlar-lined coat." - armor_type = /datum/armor/winterhood_blueshield - -/datum/armor/winterhood_blueshield - melee = 35 - bullet = 25 - laser = 25 - energy = 15 - bomb = 25 - fire = 75 - acid = 75 + armor_type = /datum/armor/suit_armor/blueshield diff --git a/modular_skyrat/modules/blueshield/code/encryptionkey.dm b/modular_skyrat/modules/blueshield/code/encryptionkey.dm index 952cb3e8c2ea72..deddf9bc4eb8ee 100644 --- a/modular_skyrat/modules/blueshield/code/encryptionkey.dm +++ b/modular_skyrat/modules/blueshield/code/encryptionkey.dm @@ -1,5 +1,6 @@ /obj/item/encryptionkey/heads/blueshield name = "\proper the blueshield's encryption key" - icon = 'modular_skyrat/modules/blueshield/icons/radio.dmi' - icon_state = "bshield_cypherkey" + icon_state = "cypherkey_centcom" channels = list(RADIO_CHANNEL_COMMAND = 1, RADIO_CHANNEL_SECURITY = 1) + greyscale_config = /datum/greyscale_config/encryptionkey_centcom + greyscale_colors = "#1d2657#dca01b" diff --git a/modular_skyrat/modules/blueshield/code/weapons.dm b/modular_skyrat/modules/blueshield/code/weapons.dm deleted file mode 100644 index 089dedefb15480..00000000000000 --- a/modular_skyrat/modules/blueshield/code/weapons.dm +++ /dev/null @@ -1,92 +0,0 @@ -// CMG gunset - IN USE -/obj/item/storage/box/gunset/blueshield - name = "Blueshield's CMG-2 gunset" - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/storage/box/gunset/blueshield/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/cmg/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/cmg(src) - new /obj/item/ammo_box/magazine/multi_sprite/cmg(src) - new /obj/item/ammo_box/magazine/multi_sprite/cmg/lethal(src) - new /obj/item/ammo_box/magazine/multi_sprite/cmg/lethal(src) - new /obj/item/suppressor/nanotrasen(src) - -//suppressor for the CMG -/obj/item/suppressor/nanotrasen - name = "NT-S suppressor" - desc = "A Nanotrasen brand small-arms suppressor, including a large NT logo stamped on the side." - - -// ----------- -// Unused guns: -// ----------- - -//Energy Revolver -/obj/item/gun/energy/e_gun/revolver //The virgin gun. - name = "energy revolver" - desc = "An advanced energy revolver with the capacity to shoot both electrodes and lasers." - force = 7 - ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser) - ammo_x_offset = 1 - charge_sections = 4 - fire_delay = 4 - icon = 'modular_skyrat/modules/blueshield/icons/energy.dmi' - icon_state = "bsgun" - inhand_icon_state = "minidisable" - lefthand_file = 'modular_skyrat/modules/blueshield/icons/guns_lefthand.dmi' - righthand_file = 'modular_skyrat/modules/blueshield/icons/guns_righthand.dmi' - obj_flags = UNIQUE_RENAME - cell_type = /obj/item/stock_parts/cell/blueshield - pin = /obj/item/firing_pin/implant/mindshield - selfcharge = TRUE - -/obj/item/stock_parts/cell/blueshield - name = "internal revolver power cell" - maxcharge = 1500 - chargerate = 300 - -//PDW-9 taser pistol -/obj/item/gun/energy/e_gun/revolver/pdw9 //The chad gun. - name = "PDW-9 taser pistol" - desc = "A military grade energy sidearm, used by many militia forces throughout the local sector. It comes with an internally recharging battery which is slow to recharge." - ammo_x_offset = 2 - icon_state = "pdw9pistol" - inhand_icon_state = null - cell_type = /obj/item/stock_parts/cell/pdw9 - -/obj/item/stock_parts/cell/pdw9 - name = "internal pistol power cell" - maxcharge = 1000 - chargerate = 300 - var/obj/item/gun/energy/e_gun/revolver/pdw9/parent - -/obj/item/stock_parts/cell/pdw9/Initialize(mapload) - . = ..() - parent = loc - -/obj/item/stock_parts/cell/pdw9/process() - . = ..() - parent.update_icon() - -//Allstar SC-3 PDW 'Hellfire' -/obj/item/gun/energy/laser/hellgun/blueshield - name = "\improper Allstar SC-3 PDW 'Hellfire'" - desc = "A prototype energy carbine, despite NT's ban on hellfire weaponry due to negative press. \ - Allstar continued to work on it, compacting it into a small form-factor for personal defense. \ - As part of the Asset Retention Program created by Nanotrasen, Allstar's prototype began to be put into use." - icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns.dmi' - worn_icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi' - lefthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi' - righthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi' - icon_state = "hellfirepdw" - worn_icon_state = "hellfirepdw" - ammo_type = list(/obj/item/ammo_casing/energy/laser/hellfire/bs) - -/obj/item/gun/energy/laser/hellgun/blueshield/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_ALLSTAR) - -/obj/item/ammo_casing/energy/laser/hellfire/bs - projectile_type = /obj/projectile/beam/laser/hellfire - e_cost = 83 //Lets it squeeze out a few more shots - select_name = "maim" diff --git a/modular_skyrat/modules/blueshield/icons/radio.dmi b/modular_skyrat/modules/blueshield/icons/radio.dmi index 94581e4346f385..9c5184305e1536 100644 Binary files a/modular_skyrat/modules/blueshield/icons/radio.dmi and b/modular_skyrat/modules/blueshield/icons/radio.dmi differ diff --git a/modular_skyrat/modules/bulletrebalance/code/sniper.dm b/modular_skyrat/modules/bulletrebalance/code/sniper.dm deleted file mode 100644 index 632f80251fd92e..00000000000000 --- a/modular_skyrat/modules/bulletrebalance/code/sniper.dm +++ /dev/null @@ -1,22 +0,0 @@ -/obj/projectile/bullet/p50 - name =".416 Stabilis bullet" - speed = 0.2 //This means it's insanely fast, not insanely slow - damage = 110 //You have 135 health, which does not make this an instant crit - paralyze = 0 //Knocks you on your ass hard enough as-is, we won't need the paralyze stat - dismemberment = 30 - armour_penetration = 61 //Bulletproof armor alone will not stop this - wound_bonus = 90 //Theoretically guaranteed wound - -/obj/projectile/bullet/p50/soporific - name = ".416 Stabilis tranquilizer casing" - damage_type = STAMINA - dismemberment = 0 - catastropic_dismemberment = FALSE - object_damage = 0 - -/obj/projectile/bullet/p50/soporific/on_hit(atom/target, blocked = FALSE) - . = ..() - if((blocked != 100) && isliving(target)) - var/mob/living/living_guy = target - living_guy.Sleeping(40 SECONDS) //Yes, its really 40 seconds of sleep, I hope you had your morning coffee. - diff --git a/modular_skyrat/modules/clock_cult/code/items/weaponry.dm b/modular_skyrat/modules/clock_cult/code/items/weaponry.dm index 9704cd0d4ef99b..92bd53531dd78f 100644 --- a/modular_skyrat/modules/clock_cult/code/items/weaponry.dm +++ b/modular_skyrat/modules/clock_cult/code/items/weaponry.dm @@ -291,6 +291,7 @@ icon = 'modular_skyrat/modules/clock_cult/icons/weapons/ammo.dmi' icon_state = "762_brass" ammo_type = /obj/item/ammo_casing/strilka310/lionhunter/clock + unique_reskin = NONE max_ammo = 3 multiple_sprites = AMMO_BOX_PER_BULLET diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/bolt_nanotrasen_firearms.dm b/modular_skyrat/modules/company_imports/code/armament_datums/bolt_nanotrasen_firearms.dm deleted file mode 100644 index 0d744d4b38ec80..00000000000000 --- a/modular_skyrat/modules/company_imports/code/armament_datums/bolt_nanotrasen_firearms.dm +++ /dev/null @@ -1,112 +0,0 @@ -/datum/armament_entry/company_import/nanotrasen_bolt_weapons - category = BOLT_NANOTRASEN_DEFENSE_NAME - company_bitflag = CARGO_COMPANY_BOLT_NANOTRASEN - -// Basic armor vests - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/armor - subcategory = "Light Body Armor" - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/armor/slim_vest - name = "type I vest - slim" - item_type = /obj/item/clothing/suit/armor/vest - cost = PAYCHECK_CREW * 3 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/armor/normal_vest - name = "type I vest - normal" - item_type = /obj/item/clothing/suit/armor/vest/alt - cost = PAYCHECK_CREW * 3 - -// Fully non-lethal weapons - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/nonlethal - subcategory = "Non-Lethal Weapons" - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/nonlethal/responder - item_type = /obj/item/gun/energy/disabler/bolt_disabler - cost = PAYCHECK_CREW * 5 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/nonlethal/pepperball - item_type = /obj/item/gun/ballistic/automatic/pistol/pepperball - cost = PAYCHECK_CREW * 5 - -// Lethal pistols, requires some company interest first - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm - subcategory = "Lethal Sidearms" - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/detective_revolver - item_type = /obj/item/gun/ballistic/revolver/c38/detective - cost = PAYCHECK_COMMAND * 4 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/g17 - item_type = /obj/item/gun/ballistic/automatic/pistol/g17 - cost = PAYCHECK_COMMAND * 4 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/mk58 - item_type = /obj/item/gun/ballistic/automatic/pistol/mk58 - cost = PAYCHECK_COMMAND * 4 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/m1911 - item_type = /obj/item/gun/ballistic/automatic/pistol/m1911 - cost = PAYCHECK_COMMAND * 4 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines - subcategory = "Sidearm Magazines" - cost = PAYCHECK_CREW - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/c38speedloader - item_type = /obj/item/ammo_box/c38 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/c38speedloader_rubber - item_type = /obj/item/ammo_box/c38/match/bouncy - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/g17 - item_type = /obj/item/ammo_box/magazine/multi_sprite/g17 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/g17_rubber - item_type = /obj/item/ammo_box/magazine/multi_sprite/g17/rubber - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/mk58 - item_type = /obj/item/ammo_box/magazine/multi_sprite/mk58 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/mk58_rubber - item_type = /obj/item/ammo_box/magazine/multi_sprite/mk58/rubber - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/sidearm_magazines/m1911 - item_type = /obj/item/ammo_box/magazine/m45 - -// Lethal anything that's not a pistol, requires high company interest - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm - subcategory = "Lethal Longarms" - restricted = TRUE - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm/riot_shotgun - item_type = /obj/item/gun/ballistic/shotgun/riot - cost = PAYCHECK_COMMAND * 6 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm/m23 - item_type = /obj/item/gun/ballistic/shotgun/m23 - cost = PAYCHECK_COMMAND * 8 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm/wt550 - item_type = /obj/item/gun/ballistic/automatic/wt550 - cost = PAYCHECK_COMMAND * 6 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm/cmg - item_type = /obj/item/gun/ballistic/automatic/cmg - cost = PAYCHECK_COMMAND * 6 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm_magazines - subcategory = "Longarm Magazines" - cost = PAYCHECK_CREW - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm_magazines/wt550 - item_type = /obj/item/ammo_box/magazine/wt550m9 - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm_magazines/cmg - item_type = /obj/item/ammo_box/magazine/multi_sprite/cmg/lethal - -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/longarm_magazines/cmg_rubber - item_type = /obj/item/ammo_box/magazine/multi_sprite/cmg diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm b/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm index 40f8ef775f7bf0..d6e5be0049e3e2 100644 --- a/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm +++ b/modular_skyrat/modules/company_imports/code/armament_datums/deforest_medical.dm @@ -226,21 +226,3 @@ /datum/armament_entry/company_import/deforest/cyber_organs/augments/breathing_tube name = "breathing tube implant" item_type = /obj/item/organ/internal/cyberimp/mouth/breathing_tube - -// Personal Defense Weapons (For when the pharmacist must become the harmacist) - -/datum/armament_entry/company_import/deforest/defense - subcategory = "Personal Defense Equipment" - contraband = TRUE - -/datum/armament_entry/company_import/deforest/defense/firefly - item_type = /obj/item/gun/ballistic/automatic/pistol/firefly - cost = PAYCHECK_COMMAND * 4 - -/datum/armament_entry/company_import/deforest/defense/firefly_mag - item_type = /obj/item/ammo_box/magazine/multi_sprite/firefly - cost = PAYCHECK_CREW - -/datum/armament_entry/company_import/deforest/defense/firefly_mag_rubber - item_type = /obj/item/ammo_box/magazine/multi_sprite/firefly/rubber - cost = PAYCHECK_CREW diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/microstar_energy.dm b/modular_skyrat/modules/company_imports/code/armament_datums/microstar_energy.dm index 35c89c03b1feb8..060a149e5dfa73 100644 --- a/modular_skyrat/modules/company_imports/code/armament_datums/microstar_energy.dm +++ b/modular_skyrat/modules/company_imports/code/armament_datums/microstar_energy.dm @@ -15,7 +15,7 @@ item_type = /obj/item/gun/energy/e_gun/mini cost = PAYCHECK_CREW * 5 -/datum/armament_entry/company_import/nanotrasen_bolt_weapons/lethal_sidearm/energy_holster +/datum/armament_entry/company_import/microstar/lethal_sidearm/energy_holster item_type = /obj/item/storage/belt/holster/energy/thermal cost = PAYCHECK_COMMAND * 6 diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/put_a_donk_on_it.dm b/modular_skyrat/modules/company_imports/code/armament_datums/put_a_donk_on_it.dm index 97d8307efd9a42..534801d0031a2f 100644 --- a/modular_skyrat/modules/company_imports/code/armament_datums/put_a_donk_on_it.dm +++ b/modular_skyrat/modules/company_imports/code/armament_datums/put_a_donk_on_it.dm @@ -99,6 +99,18 @@ item_type = /obj/item/gun/ballistic/automatic/l6_saw/toy/unrestricted cost = PAYCHECK_COMMAND * 5 +/datum/armament_entry/company_import/donk/mod_modules + subcategory = "Donk Co. MOD modules" + cost = PAYCHECK_COMMAND + +/datum/armament_entry/company_import/donk/mod_modules/dart_collector_safe + item_type = /obj/item/mod/module/recycler/donk/safe + cost = PAYCHECK_COMMAND + +/datum/armament_entry/company_import/donk/mod_modules/dart_collector + item_type = /obj/item/mod/module/recycler/donk + cost = PAYCHECK_COMMAND * 4 + /datum/armament_entry/company_import/donk/foamforce_ammo subcategory = "Foam Force (TM) Dart Accessories" cost = PAYCHECK_CREW @@ -111,14 +123,14 @@ item_type = /obj/item/ammo_box/foambox/riot cost = PAYCHECK_COMMAND * 1.5 -/datum/armament_entry/company_import/donk/foamforce_ammo +/datum/armament_entry/company_import/donk/foamforce_ammo/pistol_mag item_type = /obj/item/ammo_box/magazine/toy/pistol -/datum/armament_entry/company_import/donk/foamforce_ammo +/datum/armament_entry/company_import/donk/foamforce_ammo/smg_mag item_type = /obj/item/ammo_box/magazine/toy/smg -/datum/armament_entry/company_import/donk/foamforce_ammo +/datum/armament_entry/company_import/donk/foamforce_ammo/smgm45_mag item_type = /obj/item/ammo_box/magazine/toy/smgm45 -/datum/armament_entry/company_import/donk/foamforce_ammo +/datum/armament_entry/company_import/donk/foamforce_ammo/m762_mag item_type = /obj/item/ammo_box/magazine/toy/m762 diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/sol_defense.dm b/modular_skyrat/modules/company_imports/code/armament_datums/sol_defense.dm new file mode 100644 index 00000000000000..0df662cd959bfb --- /dev/null +++ b/modular_skyrat/modules/company_imports/code/armament_datums/sol_defense.dm @@ -0,0 +1,115 @@ +/datum/armament_entry/company_import/sol_defense + category = SOL_DEFENSE_DEFENSE_NAME + company_bitflag = CARGO_COMPANY_SOL_DEFENSE + +// Basic armor vests + +/datum/armament_entry/company_import/sol_defense/armor + subcategory = "Light Body Armor" + +/datum/armament_entry/company_import/sol_defense/armor/slim_vest + name = "type I vest - slim" + item_type = /obj/item/clothing/suit/armor/vest + cost = PAYCHECK_CREW * 3 + +/datum/armament_entry/company_import/sol_defense/armor/normal_vest + name = "type I vest - normal" + item_type = /obj/item/clothing/suit/armor/vest/alt + cost = PAYCHECK_CREW * 3 + +/datum/armament_entry/company_import/sol_defense/case + subcategory = "Weapon Cases" + +/datum/armament_entry/company_import/sol_defense/case/trappiste + item_type = /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/empty + cost = PAYCHECK_COMMAND + +/datum/armament_entry/company_import/sol_defense/case/carwo + item_type = /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/empty + cost = PAYCHECK_COMMAND * 2 + +/datum/armament_entry/company_import/sol_defense/sidearm + subcategory = "Sidearms" + +/datum/armament_entry/company_import/sol_defense/sidearm/eland + item_type = /obj/item/gun/ballistic/revolver/sol + cost = PAYCHECK_COMMAND * 4 + +/datum/armament_entry/company_import/sol_defense/sidearm/wespe + item_type = /obj/item/gun/ballistic/automatic/pistol/sol + cost = PAYCHECK_COMMAND * 4 + +/datum/armament_entry/company_import/sol_defense/sidearm/skild + item_type = /obj/item/gun/ballistic/automatic/pistol/trappiste + cost = PAYCHECK_COMMAND * 6 + +/datum/armament_entry/company_import/sol_defense/sidearm/takbok + item_type = /obj/item/gun/ballistic/revolver/takbok + cost = PAYCHECK_COMMAND * 6 + +// Lethal anything that's not a pistol, requires high company interest + +/datum/armament_entry/company_import/sol_defense/longarm + subcategory = "Longarms" + restricted = TRUE + +/datum/armament_entry/company_import/sol_defense/longarm/renoster + item_type = /obj/item/gun/ballistic/shotgun/riot/sol + cost = PAYCHECK_COMMAND * 6 + +/datum/armament_entry/company_import/sol_defense/longarm/sindano + item_type = /obj/item/gun/ballistic/automatic/sol_smg + cost = PAYCHECK_COMMAND * 6 + +/datum/armament_entry/company_import/sol_defense/longarm/elite + item_type = /obj/item/gun/ballistic/automatic/sol_rifle/marksman + cost = PAYCHECK_COMMAND * 12 + +/datum/armament_entry/company_import/sol_defense/longarm/infanterie + item_type = /obj/item/gun/ballistic/automatic/sol_rifle + cost = PAYCHECK_COMMAND * 14 + contraband = TRUE + +/datum/armament_entry/company_import/sol_defense/longarm/outomaties + item_type = /obj/item/gun/ballistic/automatic/sol_rifle/machinegun + cost = PAYCHECK_COMMAND * 23 + contraband = TRUE + +/datum/armament_entry/company_import/sol_defense/longarm/kiboko + item_type = /obj/item/gun/ballistic/automatic/sol_grenade_launcher + cost = PAYCHECK_COMMAND * 46 + contraband = TRUE + +/datum/armament_entry/company_import/sol_defense/magazines + subcategory = "Magazines" + cost = PAYCHECK_CREW + +/datum/armament_entry/company_import/sol_defense/magazines/c35_mag + item_type = /obj/item/ammo_box/magazine/c35sol_pistol/starts_empty + +/datum/armament_entry/company_import/sol_defense/magazines/c35_extended + item_type = /obj/item/ammo_box/magazine/c35sol_pistol/stendo/starts_empty + +/datum/armament_entry/company_import/sol_defense/magazines/c585_mag + item_type = /obj/item/ammo_box/magazine/c585trappiste_pistol/spawns_empty + +/datum/armament_entry/company_import/sol_defense/magazines/sol_rifle_short + item_type = /obj/item/ammo_box/magazine/c40sol_rifle/starts_empty + +/datum/armament_entry/company_import/sol_defense/magazines/sol_rifle_standard + item_type = /obj/item/ammo_box/magazine/c40sol_rifle/standard/starts_empty + cost = PAYCHECK_COMMAND + +/datum/armament_entry/company_import/sol_defense/magazines/sol_rifle_drum + item_type = /obj/item/ammo_box/magazine/c40sol_rifle/drum/starts_empty + cost = PAYCHECK_COMMAND * 3 + contraband = TRUE + +/datum/armament_entry/company_import/sol_defense/magazines/sol_grenade_standard + item_type = /obj/item/ammo_box/magazine/c980_grenade/starts_empty + cost = PAYCHECK_COMMAND * 2 + +/datum/armament_entry/company_import/sol_defense/magazines/sol_grenade_drum + item_type = /obj/item/ammo_box/magazine/c980_grenade/drum/starts_empty + cost = PAYCHECK_CREW * 3 + contraband = TRUE diff --git a/modular_skyrat/modules/company_imports/code/armament_datums/vitezstvi_ammo.dm b/modular_skyrat/modules/company_imports/code/armament_datums/vitezstvi_ammo.dm index 3e6df12d1246e8..d6083b39cbc956 100644 --- a/modular_skyrat/modules/company_imports/code/armament_datums/vitezstvi_ammo.dm +++ b/modular_skyrat/modules/company_imports/code/armament_datums/vitezstvi_ammo.dm @@ -11,7 +11,7 @@ item_type = /obj/item/circuitboard/machine/ammo_workbench cost = PAYCHECK_COMMAND * 5 -/datum/armament_entry/company_import/vitezstvi/ammo_bench +/datum/armament_entry/company_import/vitezstvi/ammo_bench/ammo_disk item_type = /obj/item/disk/ammo_workbench/advanced cost = PAYCHECK_COMMAND * 5 @@ -19,26 +19,28 @@ item_type = /obj/item/circuitboard/machine/dish_drive/bullet cost = PAYCHECK_COMMAND * 2 -// Boxes of non-shotgun ammo +// Weapon accessories -/datum/armament_entry/company_import/vitezstvi/ammo_boxes - subcategory = "Ammunition Boxes" - cost = PAYCHECK_CREW +/datum/armament_entry/company_import/vitezstvi/accessory + subcategory = "Weapon Accessories" -/datum/armament_entry/company_import/vitezstvi/ammo_boxes/pepperball - item_type = /obj/item/ammo_box/advanced/pepperballs +/datum/armament_entry/company_import/vitezstvi/accessory/suppressor + item_type = /obj/item/suppressor + cost = PAYCHECK_COMMAND -/datum/armament_entry/company_import/vitezstvi/ammo_boxes/m1911_lethals - item_type = /obj/item/ammo_box/c45 +/datum/armament_entry/company_import/vitezstvi/accessory/small_case + item_type = /obj/item/storage/toolbox/guncase/skyrat/pistol/empty + cost = PAYCHECK_COMMAND -/datum/armament_entry/company_import/vitezstvi/ammo_boxes/wt550_lethals - item_type = /obj/item/ammo_box/c46x30mm +/datum/armament_entry/company_import/vitezstvi/accessory/large_case + item_type = /obj/item/storage/toolbox/guncase/skyrat/empty + cost = PAYCHECK_COMMAND * 2 -/datum/armament_entry/company_import/vitezstvi/ammo_boxes/wt550_piercing - item_type = /obj/item/ammo_box/c46x30mm/ap +// Boxes of non-shotgun ammo -/datum/armament_entry/company_import/vitezstvi/ammo_boxes/wt550_rubber - item_type = /obj/item/ammo_box/c46x30mm/rubber +/datum/armament_entry/company_import/vitezstvi/ammo_boxes + subcategory = "Ammunition Boxes" + cost = PAYCHECK_CREW /datum/armament_entry/company_import/vitezstvi/ammo_boxes/peacekeeper_lethal item_type = /obj/item/ammo_box/c9mm @@ -73,6 +75,36 @@ /datum/armament_entry/company_import/vitezstvi/ammo_boxes/sabel_blank item_type = /obj/item/ammo_box/c56mm/blank +/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol35 + item_type = /obj/item/ammo_box/c35sol + +/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol35_disabler + item_type = /obj/item/ammo_box/c35sol/incapacitator + +/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol35_ripper + item_type = /obj/item/ammo_box/c35sol/ripper + +/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol40 + item_type = /obj/item/ammo_box/c40sol + +/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol40_disabler + item_type = /obj/item/ammo_box/c40sol/fragmentation + +/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol40_flame + item_type = /obj/item/ammo_box/c40sol/incendiary + +/datum/armament_entry/company_import/vitezstvi/ammo_boxes/sol40_pierce + item_type = /obj/item/ammo_box/c40sol/pierce + +/datum/armament_entry/company_import/vitezstvi/ammo_boxes/trappiste585 + item_type = /obj/item/ammo_box/c585trappiste + +/datum/armament_entry/company_import/vitezstvi/ammo_boxes/trappiste585_disabler + item_type = /obj/item/ammo_box/c585trappiste/incapacitator + +/datum/armament_entry/company_import/vitezstvi/ammo_boxes/trappiste585_hollowpoint + item_type = /obj/item/ammo_box/c585trappiste/hollowpoint + // Revolver speedloaders /datum/armament_entry/company_import/vitezstvi/speedloader @@ -121,3 +153,26 @@ /datum/armament_entry/company_import/vitezstvi/shot_shells/confetti item_type = /obj/item/ammo_box/advanced/s12gauge/honk description = "A box of 35 confetti shells, firing a spread of harmless confetti everywhere, yippie!" + +// Boxes of kiboko launcher ammo + +/datum/armament_entry/company_import/vitezstvi/grenade_shells + subcategory = "Grenade Shells" + cost = PAYCHECK_COMMAND + +/datum/armament_entry/company_import/vitezstvi/grenade_shells/practice + item_type = /obj/item/ammo_box/c980grenade + +/datum/armament_entry/company_import/vitezstvi/grenade_shells/smoke + item_type = /obj/item/ammo_box/c980grenade/smoke + +/datum/armament_entry/company_import/vitezstvi/grenade_shells/riot + item_type = /obj/item/ammo_box/c980grenade/riot + +/datum/armament_entry/company_import/vitezstvi/grenade_shells/shrapnel + item_type = /obj/item/ammo_box/c980grenade/shrapnel + contraband = TRUE + +/datum/armament_entry/company_import/vitezstvi/grenade_shells/phosphor + item_type = /obj/item/ammo_box/c980grenade/shrapnel/phosphor + contraband = TRUE diff --git a/modular_skyrat/modules/company_imports/code/company_datums.dm b/modular_skyrat/modules/company_imports/code/company_datums.dm index cdbfddaa03ddd0..263c8214ffc8df 100644 --- a/modular_skyrat/modules/company_imports/code/company_datums.dm +++ b/modular_skyrat/modules/company_imports/code/company_datums.dm @@ -82,8 +82,8 @@ // A coalition between nt and bolt to sell personal defense equipment and weapons /datum/cargo_company/nanotrasen_bolt_weapons - name = BOLT_NANOTRASEN_DEFENSE_NAME - company_flag = CARGO_COMPANY_BOLT_NANOTRASEN + name = SOL_DEFENSE_DEFENSE_NAME + company_flag = CARGO_COMPANY_SOL_DEFENSE cost = 6000 cost_change_lower = -1000 cost_change_upper = 4000 diff --git a/modular_skyrat/modules/company_imports/code/objects/vitezstvi/ammo_boxes.dm b/modular_skyrat/modules/company_imports/code/objects/vitezstvi/ammo_boxes.dm index 20ebab5002f3ca..fc7fb6015317f9 100644 --- a/modular_skyrat/modules/company_imports/code/objects/vitezstvi/ammo_boxes.dm +++ b/modular_skyrat/modules/company_imports/code/objects/vitezstvi/ammo_boxes.dm @@ -74,25 +74,6 @@ name = "ammo box (.34 incendiary)" ammo_type = /obj/item/ammo_casing/c34_incendiary -/obj/item/ammo_box/c12mm - name = "ammo box (12mm)" - icon = 'modular_skyrat/modules/company_imports/icons/ammo.dmi' - icon_state = "ammo_12mm" - ammo_type = /obj/item/ammo_casing/c12mm - max_ammo = 20 - -/obj/item/ammo_box/c12mm/ap - name = "ammo box (12mm AP)" - ammo_type = /obj/item/ammo_casing/c12mm/ap - -/obj/item/ammo_box/c12mm/hp - name = "ammo box (12mm HP)" - ammo_type = /obj/item/ammo_casing/c12mm/hp - -/obj/item/ammo_box/c12mm/fire - name = "ammo box (12mm incendiary)" - ammo_type = /obj/item/ammo_casing/c12mm/fire - /obj/item/ammo_box/c56mm name = "ammo box (5.6mm civilian)" desc = "5.6x40mm ammunition specifically made for civilian use like recreation, hunting, self-defense or LARP. While the package itself lacks any real identification \ diff --git a/modular_skyrat/modules/contractor/code/datums/contractor_datum.dm b/modular_skyrat/modules/contractor/code/datums/contractor_datum.dm index f7d4e09f41e5fd..5346d412702b1d 100644 --- a/modular_skyrat/modules/contractor/code/datums/contractor_datum.dm +++ b/modular_skyrat/modules/contractor/code/datums/contractor_datum.dm @@ -18,7 +18,8 @@ // Special case for reinforcements, we want to show their ckey and name on round end. if (istype(contractor_purchase, /datum/contractor_item/contractor_partner)) var/datum/contractor_item/contractor_partner/partner = contractor_purchase - contractor_support_unit += "
[partner.partner_mind.key] played [partner.partner_mind.current.name], their contractor support unit." + var/mob/living/carbon/human/partner_mob = partner.partner_mind.current + contractor_support_unit += "
[partner_mob.name] was [partner_mob.p_their()] contractor support unit." if (length(contractor_hub.purchased_items)) result += "
(used [total_spent_rep] Rep) " diff --git a/modular_skyrat/modules/cortical_borer/code/cortical_borer_abilities.dm b/modular_skyrat/modules/cortical_borer/code/cortical_borer_abilities.dm index 8a239f9c9a5328..fae00851ad41d9 100644 --- a/modular_skyrat/modules/cortical_borer/code/cortical_borer_abilities.dm +++ b/modular_skyrat/modules/cortical_borer/code/cortical_borer_abilities.dm @@ -50,7 +50,7 @@ name = "Open Chemical Injector" button_icon_state = "chemical" -/datum/action/cooldown/borer/inject_chemical/Trigger(trigger_flags) +/datum/action/cooldown/borer/inject_chemical/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -141,7 +141,7 @@ name = "Open Evolution Tree" button_icon_state = "newability" -/datum/action/cooldown/borer/evolution_tree/Trigger(trigger_flags) +/datum/action/cooldown/borer/evolution_tree/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -230,7 +230,7 @@ name = "Learn Focus" button_icon_state = "getfocus" -/datum/action/cooldown/borer/learn_focus/Trigger(trigger_flags) +/datum/action/cooldown/borer/learn_focus/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -268,7 +268,7 @@ button_icon_state = "bloodchem" chemical_evo_points = 5 -/datum/action/cooldown/borer/learn_bloodchemical/Trigger(trigger_flags) +/datum/action/cooldown/borer/learn_bloodchemical/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -314,7 +314,7 @@ button_icon_state = "bloodlevel" chemical_evo_points = 1 -/datum/action/cooldown/borer/upgrade_chemical/Trigger(trigger_flags) +/datum/action/cooldown/borer/upgrade_chemical/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -349,7 +349,7 @@ button_icon_state = "level" stat_evo_points = 1 -/datum/action/cooldown/borer/upgrade_stat/Trigger(trigger_flags) +/datum/action/cooldown/borer/upgrade_stat/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -379,7 +379,7 @@ name = "Toggle Hiding" button_icon_state = "hide" -/datum/action/cooldown/borer/toggle_hiding/Trigger(trigger_flags) +/datum/action/cooldown/borer/toggle_hiding/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -401,7 +401,7 @@ cooldown_time = 12 SECONDS button_icon_state = "fear" -/datum/action/cooldown/borer/fear_human/Trigger(trigger_flags) +/datum/action/cooldown/borer/fear_human/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -464,7 +464,7 @@ cooldown_time = 5 SECONDS button_icon_state = "blood" -/datum/action/cooldown/borer/check_blood/Trigger(trigger_flags) +/datum/action/cooldown/borer/check_blood/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -485,7 +485,7 @@ cooldown_time = 10 SECONDS button_icon_state = "host" -/datum/action/cooldown/borer/choosing_host/Trigger(trigger_flags) +/datum/action/cooldown/borer/choosing_host/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -593,7 +593,7 @@ cooldown_time = 30 SECONDS button_icon_state = "speak" -/datum/action/cooldown/borer/force_speak/Trigger(trigger_flags) +/datum/action/cooldown/borer/force_speak/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -628,7 +628,7 @@ button_icon_state = "reproduce" chemical_cost = 100 -/datum/action/cooldown/borer/produce_offspring/Trigger(trigger_flags) +/datum/action/cooldown/borer/produce_offspring/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -692,7 +692,7 @@ button_icon_state = "revive" chemical_cost = 200 -/datum/action/cooldown/borer/revive_host/Trigger(trigger_flags) +/datum/action/cooldown/borer/revive_host/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -732,7 +732,7 @@ button_icon_state = "willing" chemical_cost = 150 -/datum/action/cooldown/borer/willing_host/Trigger(trigger_flags) +/datum/action/cooldown/borer/willing_host/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE @@ -765,7 +765,7 @@ button_icon_state = "hiding" chemical_cost = 100 -/datum/action/cooldown/borer/stealth_mode/Trigger(trigger_flags) +/datum/action/cooldown/borer/stealth_mode/Trigger(trigger_flags, atom/target) var/mob/living/basic/cortical_borer/cortical_owner = owner var/in_stealth = (cortical_owner.upgrade_flags & BORER_STEALTH_MODE) if(in_stealth) @@ -794,7 +794,7 @@ button_icon_state = "reproduce" chemical_cost = 150 -/datum/action/cooldown/borer/empowered_offspring/Trigger(trigger_flags) +/datum/action/cooldown/borer/empowered_offspring/Trigger(trigger_flags, atom/target) . = ..() if(!.) return FALSE diff --git a/modular_skyrat/modules/customization/modules/client/augment/limbs.dm b/modular_skyrat/modules/customization/modules/client/augment/limbs.dm index e5f8f4f14e7beb..8ae5fed1f044d9 100644 --- a/modular_skyrat/modules/customization/modules/client/augment/limbs.dm +++ b/modular_skyrat/modules/customization/modules/client/augment/limbs.dm @@ -10,15 +10,16 @@ var/obj/item/bodypart/new_limb = path var/body_zone = initial(new_limb.body_zone) var/obj/item/bodypart/old_limb = augmented.get_bodypart(body_zone) + + old_limb.limb_id = initial(new_limb.limb_id) + old_limb.base_limb_id = initial(new_limb.limb_id) + old_limb.is_dimorphic = initial(new_limb.is_dimorphic) + if(uses_robotic_styles && prefs.augment_limb_styles[slot]) var/chosen_style = GLOB.robotic_styles_list[prefs.augment_limb_styles[slot]] - old_limb.limb_id = initial(new_limb.limb_id) - old_limb.base_limb_id = initial(new_limb.limb_id) old_limb.set_icon_static(chosen_style) old_limb.current_style = prefs.augment_limb_styles[slot] else - old_limb.limb_id = initial(new_limb.limb_id) - old_limb.base_limb_id = initial(new_limb.limb_id) old_limb.set_icon_static(initial(new_limb.icon)) old_limb.should_draw_greyscale = FALSE @@ -30,6 +31,8 @@ var/chosen_style = GLOB.robotic_styles_list[prefs.augment_limb_styles[slot]] new_limb.set_icon_static(chosen_style) new_limb.current_style = prefs.augment_limb_styles[slot] + for (var/obj/item/organ/external/external_organ as anything in old_limb.external_organs) + external_organ.transfer_to_limb(new_limb) new_limb.replace_limb(augmented) qdel(old_limb) diff --git a/modular_skyrat/modules/customization/modules/clothing/hands/hands.dm b/modular_skyrat/modules/customization/modules/clothing/hands/hands.dm index 1d395d906ae9bf..667796dbce4fe0 100644 --- a/modular_skyrat/modules/customization/modules/clothing/hands/hands.dm +++ b/modular_skyrat/modules/customization/modules/clothing/hands/hands.dm @@ -31,5 +31,16 @@ max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT resistance_flags = NONE +/obj/item/clothing/gloves/bracer/wraps + name = "cloth arm wraps" + desc = "Cloth bracers, the colour all left up to the choice of the wearer." + icon = 'modular_skyrat/master_files/icons/donator/obj/clothing/gloves.dmi' + icon_state = "arm_wraps" + inhand_icon_state = "greyscale_gloves" + greyscale_config = /datum/greyscale_config/armwraps + greyscale_config_worn = /datum/greyscale_config/armwraps/worn + greyscale_colors = "#FFFFFF" + flags_1 = IS_PLAYER_COLORABLE_1 + /obj/item/clothing/gloves worn_icon_teshari = TESHARI_HANDS_ICON diff --git a/modular_skyrat/modules/customization/modules/clothing/masks/gasmask.dm b/modular_skyrat/modules/customization/modules/clothing/masks/gasmask.dm index 9174700e738381..47ae6a48e89c2a 100644 --- a/modular_skyrat/modules/customization/modules/clothing/masks/gasmask.dm +++ b/modular_skyrat/modules/customization/modules/clothing/masks/gasmask.dm @@ -94,6 +94,19 @@ greyscale_config_worn_vox = /datum/greyscale_config/respirator/worn/vox greyscale_config_worn_teshari = /datum/greyscale_config/respirator/worn/teshari +/obj/item/clothing/mask/gas/respirator/examine(mob/user) + . = ..() + . += span_notice("You can toggle its ability to muffle your TTS voice with control click.") + +/obj/item/clothing/mask/gas/respirator/CtrlClick(mob/living/user) + if(!isliving(user)) + return + if(user.get_active_held_item() != src) + to_chat(user, span_warning("You must hold the [src] in your hand to do this!")) + return + voice_filter = voice_filter ? null : initial(voice_filter) + to_chat(user, span_notice("Mask voice muffling [voice_filter ? "enabled" : "disabled"].")) + /obj/item/clothing/mask/gas/clown_hat/vox desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask. This one's got an easily accessible feeding port to be more suitable for the Vox crewmembers." icon = 'modular_skyrat/master_files/icons/mob/clothing/species/vox/mask.dmi' diff --git a/modular_skyrat/modules/customization/modules/clothing/masks/paper.dm b/modular_skyrat/modules/customization/modules/clothing/masks/paper.dm new file mode 100644 index 00000000000000..97b52485b4b306 --- /dev/null +++ b/modular_skyrat/modules/customization/modules/clothing/masks/paper.dm @@ -0,0 +1,76 @@ +/obj/item/clothing/mask/paper + name = "paper mask" + desc = "It's true. Once you wear a mask for so long, you forget about who you are. Wonder if that happens with shitty paper ones." + icon = 'modular_skyrat/master_files/icons/obj/clothing/masks.dmi' + worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/mask.dmi' + icon_state = "mask_paper" + clothing_flags = MASKINTERNALS + flags_inv = HIDEFACIALHAIR|HIDESNOUT + w_class = WEIGHT_CLASS_SMALL + /// Whether or not the mask is currently being layered over (or under!) hair. + var/wear_over_hair = TRUE + unique_reskin = list( + "Blank" = "mask_paper", + "Neutral" = "mask_neutral", + "Eye" = "mask_eye", + "Sleep" = "mask_sleep", + "Heart" = "mask_heart", + "Core" = "mask_core", + "Plus" = "mask_plus", + "Square" = "mask_square", + "Bullseye" = "mask_bullseye", + "Vertical" = "mask_vertical", + "Horizontal" = "mask_horizontal", + "X" = "mask_x", + "Bug" = "mask_bug", + "Double" = "mask_double", + "Mark" = "mask_mark", + "Line" = "mask_line", + "Minus" = "mask_minus", + "Four" = "mask_four", + "Diamond" = "mask_diamond", + "Cat" = "mask_cat", + "Big Eye" = "mask_bigeye", + "Good" = "mask_good", + "Bad" = "mask_bad", + "Happy" = "mask_happy", + "Sad" = "mask_sad", + ) + +/obj/item/clothing/mask/paper/Initialize(mapload) + . = ..() + register_context() + if(wear_over_hair) + alternate_worn_layer = BACK_LAYER + +/obj/item/clothing/mask/paper/add_context(atom/source, list/context, obj/item/held_item, mob/user) + . = ..() + context[SCREENTIP_CONTEXT_ALT_LMB] = "Change Mask Face" + return CONTEXTUAL_SCREENTIP_SET + +/obj/item/clothing/mask/paper/reskin_obj(mob/user) + . = ..() + user.update_worn_mask() + current_skin = null //so we can infinitely reskin + +/obj/item/clothing/mask/paper/proc/adjust_mask(mob/living/carbon/human/user) + if(!istype(user)) + return + if(!user.incapacitated()) + wear_over_hair = !wear_over_hair + if(wear_over_hair) + alternate_worn_layer = BACK_LAYER + to_chat(user, "You sweep your hair over the mask.") + else + alternate_worn_layer = initial(alternate_worn_layer) + to_chat(user, "You sweep your hair under the mask.") + + user.update_body_parts() + user.update_inv_ears(0) + user.update_worn_mask() + +/obj/item/clothing/mask/paper/verb/toggle() + set category = "Object" + set name = "Adjust Mask" + set src in usr + adjust_mask(usr) diff --git a/modular_skyrat/modules/customization/modules/clothing/shoes/shoes.dm b/modular_skyrat/modules/customization/modules/clothing/shoes/shoes.dm index 682d2236a1e8f9..07d7cc81ea0414 100644 --- a/modular_skyrat/modules/customization/modules/clothing/shoes/shoes.dm +++ b/modular_skyrat/modules/customization/modules/clothing/shoes/shoes.dm @@ -95,13 +95,24 @@ worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/feet.dmi' icon_state = "blackjack" -/obj/item/clothing/shoes/wraps/colourable +/obj/item/clothing/shoes/wraps/cloth name = "cloth foot wraps" desc = "Boxer tape or bandages wrapped like a mummy, all left up to the choice of the wearer." icon_state = "clothwrap" - greyscale_config = /datum/greyscale_config/wraps - greyscale_config_worn = /datum/greyscale_config/wraps/worn - greyscale_config_worn_digi = /datum/greyscale_config/wraps/worn/digi + greyscale_config = /datum/greyscale_config/clothwraps + greyscale_config_worn = /datum/greyscale_config/clothwraps/worn + greyscale_config_worn_digi = /datum/greyscale_config/clothwraps/worn/digi + greyscale_colors = "#FFFFFF" + body_parts_covered = FALSE + flags_1 = IS_PLAYER_COLORABLE_1 + +/obj/item/clothing/shoes/wraps/colourable + name = "colourable foot wraps" + desc = "Ankle coverings. These ones have a customisable colour design." + icon_state = "legwrap" + greyscale_config = /datum/greyscale_config/legwraps + greyscale_config_worn = /datum/greyscale_config/legwraps/worn + greyscale_config_worn_digi = /datum/greyscale_config/legwraps/worn/digi greyscale_colors = "#FFFFFF" body_parts_covered = FALSE flags_1 = IS_PLAYER_COLORABLE_1 @@ -196,3 +207,14 @@ greyscale_config_worn_better_vox = /datum/greyscale_config/boots/worn/newvox greyscale_config_worn_vox = /datum/greyscale_config/boots/worn/oldvox flags_1 = IS_PLAYER_COLORABLE_1 + +/obj/item/clothing/shoes/wraps/cloth + name = "cloth foot wraps" + desc = "Boxer tape or bandages wrapped like a mummy, all left up to the choice of the wearer." + icon_state = "clothwrap" + greyscale_config = /datum/greyscale_config/clothwraps + greyscale_config_worn = /datum/greyscale_config/clothwraps/worn + greyscale_config_worn_digi = /datum/greyscale_config/clothwraps/worn/digi + greyscale_colors = "#FFFFFF" + body_parts_covered = FALSE + flags_1 = IS_PLAYER_COLORABLE_1 diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/hair.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/hair.dm index 172ea352ac2b5d..cbb1565392f3c9 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/hair.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/hair.dm @@ -479,6 +479,146 @@ name = "Hairfre" icon_state = "hair_hairfre" +/datum/sprite_accessory/hair/skyrat/bobcut_over_eye_1 + name = "Bobcut over eye 1" + icon_state = "hair_bobcut_over_eye_1" + +/datum/sprite_accessory/hair/skyrat/bobcut_over_eye_2 + name = "Bobcut over eye 2" + icon_state = "hair_bobcut_over_eye_2" + +/datum/sprite_accessory/hair/skyrat/bobcut_over_eye_3 + name = "Bobcut over eye 3" + icon_state = "hair_bobcut_over_eye_3" + +/datum/sprite_accessory/hair/skyrat/bonnie + name = "Bonnie" + icon_state = "hair_bonnie" + +/datum/sprite_accessory/hair/skyrat/bonnie_short + name = "Bonnie short" + icon_state = "hair_bonnie_short" + +/datum/sprite_accessory/hair/skyrat/bonnie_long + name = "Bonnie long" + icon_state = "hair_bonnie_long" + +/datum/sprite_accessory/hair/skyrat/bonnie_2 + name = "Bonnie 2" + icon_state = "hair_bonnie_2" + +/datum/sprite_accessory/hair/skyrat/bonnie_2_long + name = "Bonnie long 2" + icon_state = "hair_bonnie_2_long" + +/datum/sprite_accessory/hair/skyrat/bonie_2_short + name = "Bonnie short 2" + icon_state = "hair_bonnie_2_short" + +/datum/sprite_accessory/hair/skyrat/dawn + name = "Dawn" + icon_state = "hair_dawn" + +/datum/sprite_accessory/hair/skyrat/fluffy + name = "Fluffy" + icon_state = "hair_fluffy" + +/datum/sprite_accessory/hair/skyrat/fluffy_long + name = "Fluffy long" + icon_state = "hair_fluffy_long" + +/datum/sprite_accessory/hair/skyrat/khmuro + name = "Khmuro" + icon_state = "hair_khmuro" + +/datum/sprite_accessory/hair/skyrat/kobeni_1 + name = "Kobeni 1" + icon_state = "hair_kobeni_1" + +/datum/sprite_accessory/hair/skyrat/kobeni_2 + name = "Kobeni 2" + icon_state = "hair_kobeni_2" + +/datum/sprite_accessory/hair/skyrat/low_bun + name = "Low bun" + icon_state = "hair_low_bun" + +/datum/sprite_accessory/hair/skyrat/low_ponytail + name = "Low ponytail" + icon_state = "hair_low_ponytail" + +/datum/sprite_accessory/hair/skyrat/morning + name = "Morning" + icon_state = "hair_morning" + +/datum/sprite_accessory/hair/skyrat/over_ear_1 + name = "Over ear 1" + icon_state = "hair_over_ear_1" + +/datum/sprite_accessory/hair/skyrat/over_ear_2 + name = "Over ear 2" + icon_state = "hair_over_ear_2" + +/datum/sprite_accessory/hair/skyrat/over_eye + name = "Over eye" + icon_state = "hair_over_eye" + +/datum/sprite_accessory/hair/skyrat/ponytail + name = "Fluffy ponytail" + icon_state = "hair_ponytail" + +/datum/sprite_accessory/hair/skyrat/ponytail_short + name = "Short fluffy ponytail" + icon_state = "hair_ponytail_short" + +/datum/sprite_accessory/hair/skyrat/simple + name = "Simple" + icon_state = "hair_simple" + +/datum/sprite_accessory/hair/skyrat/simple_long + name = "Simple long" + icon_state = "hair_simple_long" + +/datum/sprite_accessory/hair/skyrat/simple_short + name = "Simple short" + icon_state = "hair_simple_short" + +/datum/sprite_accessory/hair/skyrat/strict + name = "Strict" + icon_state = "hair_strict" + +/datum/sprite_accessory/hair/skyrat/strict_long + name = "Strict long" + icon_state = "hair_strict_long" + +/datum/sprite_accessory/hair/skyrat/strict_short + name = "Strict short" + icon_state = "hair_strict_short" + +/datum/sprite_accessory/hair/skyrat/thin_ponytail + name = "Thin ponytail" + icon_state = "hair_thin_ponytail" + +/datum/sprite_accessory/hair/skyrat/thin_ponytail_long + name = "Long thin ponytail" + icon_state = "hair_thin_ponytail_long" + +/datum/sprite_accessory/hair/skyrat/twintails_2 + name = "Twintails 2" + icon_state = "hair_twintails_2" + +/datum/sprite_accessory/hair/skyrat/twintails_2_long + name = "Long twintails" + icon_state = "hair_twintails_2_long" + +/datum/sprite_accessory/hair/skyrat/twintails_2_short + name = "Short twintails" + icon_state = "hair_twintails_2_short" + +/datum/sprite_accessory/hair/skyrat/upwards + name = "Upwards" + icon_state = "hair_upwards" + // Facial hair /datum/sprite_accessory/facial_hair/skyrat diff --git a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/tails.dm b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/tails.dm index 0a23f98f2541f1..f3d9d346de5999 100644 --- a/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/tails.dm +++ b/modular_skyrat/modules/customization/modules/mob/dead/new_player/sprite_accessories/tails.dm @@ -309,6 +309,11 @@ name = "Shade (Striped)" icon_state = "shadekinlongstriped_large" +/datum/sprite_accessory/tails/mammal/wagging/big/ringtail + name = "Ring Tail (Long)" + icon_state = "bigring_large" + color_src = USE_MATRIXED_COLORS + /datum/sprite_accessory/tails/mammal/wagging/akula/akula name = "Akula" icon_state = "akula" diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm index 76ebf34b68250d..b87946aaf37c88 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm @@ -124,13 +124,19 @@ GLOBAL_LIST_EMPTY(customizable_races) if(species_human.underwear && !(species_human.underwear_visibility & UNDERWEAR_HIDE_UNDIES)) var/datum/sprite_accessory/underwear/underwear = GLOB.underwear_list[species_human.underwear] var/mutable_appearance/underwear_overlay + var/female_sprite_flags = FEMALE_UNIFORM_FULL // the default gender shaping if(underwear) var/icon_state = underwear.icon_state if(underwear.has_digitigrade && (species_human.bodytype & BODYTYPE_DIGITIGRADE)) icon_state += "_d" - underwear_overlay = mutable_appearance(underwear.icon, icon_state, -BODY_LAYER) + female_sprite_flags = FEMALE_UNIFORM_TOP_ONLY // for digi gender shaping + if(species_human.dna.species.sexes && species_human.physique == FEMALE && (underwear.gender == MALE)) + underwear_overlay = wear_female_version(icon_state, underwear.icon, BODY_LAYER, female_sprite_flags) + else + underwear_overlay = mutable_appearance(underwear.icon, icon_state, -BODY_LAYER) if(!underwear.use_static) underwear_overlay.color = species_human.underwear_color + underwear_overlay.pixel_y += height_offset standing += underwear_overlay if(species_human.bra && !(species_human.underwear_visibility & UNDERWEAR_HIDE_BRA)) @@ -142,7 +148,7 @@ GLOBAL_LIST_EMPTY(customizable_races) bra_overlay = mutable_appearance(bra.icon, icon_state, -BODY_LAYER) if(!bra.use_static) bra_overlay.color = species_human.bra_color - + bra_overlay.pixel_y += height_offset standing += bra_overlay if(species_human.undershirt && !(species_human.underwear_visibility & UNDERWEAR_HIDE_SHIRT)) @@ -155,6 +161,7 @@ GLOBAL_LIST_EMPTY(customizable_races) undershirt_overlay = mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER) if(!undershirt.use_static) undershirt_overlay.color = species_human.undershirt_color + undershirt_overlay.pixel_y += height_offset standing += undershirt_overlay if(species_human.socks && species_human.num_legs >= 2 && !(mutant_bodyparts["taur"]) && !(species_human.underwear_visibility & UNDERWEAR_HIDE_SOCKS)) diff --git a/modular_skyrat/modules/emotes/code/scream_emote.dm b/modular_skyrat/modules/emotes/code/scream_emote.dm index dd07e81cec84bd..50619d1bd851c3 100644 --- a/modular_skyrat/modules/emotes/code/scream_emote.dm +++ b/modular_skyrat/modules/emotes/code/scream_emote.dm @@ -24,7 +24,7 @@ return 'modular_skyrat/modules/emotes/sound/voice/scream_silicon.ogg' if(ismonkey(user)) return 'modular_skyrat/modules/emotes/sound/voice/scream_monkey.ogg' - if(istype(user, /mob/living/simple_animal/hostile/gorilla)) + if(istype(user, /mob/living/basic/gorilla)) return 'sound/creatures/gorilla.ogg' if(isalien(user)) return 'sound/voice/hiss6.ogg' diff --git a/modular_skyrat/modules/encounters/code/nri_raiders.dm b/modular_skyrat/modules/encounters/code/nri_raiders.dm index ce89ac660a29e1..aa3b406bc01b77 100644 --- a/modular_skyrat/modules/encounters/code/nri_raiders.dm +++ b/modular_skyrat/modules/encounters/code/nri_raiders.dm @@ -128,7 +128,7 @@ GLOBAL_VAR(first_officer) belt = /obj/item/storage/belt/security/nri back = /obj/item/storage/backpack/satchel/leather - backpack_contents = list(/obj/item/storage/box/nri_survival_pack/raider = 1, /obj/item/ammo_box/magazine/m9mm_aps = 3, /obj/item/gun/ballistic/automatic/pistol/ladon/nri = 1, /obj/item/crucifix = 1, /obj/item/clothing/mask/gas/hecu2 = 1, /obj/item/modular_computer/pda/security = 1) + backpack_contents = list(/obj/item/storage/box/nri_survival_pack/raider = 1, /obj/item/ammo_box/magazine/m9mm_aps = 3, /obj/item/gun/ballistic/automatic/pistol/nri = 1, /obj/item/crucifix = 1, /obj/item/clothing/mask/gas/hecu2 = 1, /obj/item/modular_computer/pda/security = 1) l_pocket = /obj/item/folder/blue/nri_cop r_pocket = /obj/item/storage/pouch/ammo @@ -343,40 +343,6 @@ GLOBAL_VAR(first_officer) command_name = "NRI Enforcer-Class Starship Telegram" report_sound = ANNOUNCER_NRI_RAIDERS -/obj/item/gun/ballistic/automatic/pistol/automag - name = "\improper Automag" - desc = "A .44 AMP handgun with a sleek metallic finish." - icon_state = "automag" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/automag.dmi' - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/automag - can_suppress = FALSE - fire_sound = 'modular_skyrat/modules/sec_haul/sound/automag.ogg' - rack_sound = 'sound/weapons/gun/pistol/rack.ogg' - lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' - bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - -/obj/item/ammo_box/magazine/automag - name = "handgun magazine (.44 AMP)" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "automag" - base_icon_state = "automag" - ammo_type = /obj/item/ammo_casing/c44 - caliber = CALIBER_44 - max_ammo = 7 - multiple_sprites = AMMO_BOX_PER_BULLET - -/obj/item/ammo_casing/c44 - name = ".44 AMP bullet casing" - desc = "A .44 AMP bullet casing." - caliber = CALIBER_44 - projectile_type = /obj/projectile/bullet/c44 - -/obj/projectile/bullet/c44 - name = ".44 AMP bullet" - damage = 40 - wound_bonus = 30 - /obj/item/storage/belt/military/nri/captain/pirate_officer/PopulateContents() generate_items_inside(list( /obj/item/knife/combat = 1, diff --git a/modular_skyrat/modules/exp_corps/code/expeditionary_trooper.dm b/modular_skyrat/modules/exp_corps/code/expeditionary_trooper.dm index 54fc933848ae6c..fdcbef42cabfef 100644 --- a/modular_skyrat/modules/exp_corps/code/expeditionary_trooper.dm +++ b/modular_skyrat/modules/exp_corps/code/expeditionary_trooper.dm @@ -29,4 +29,4 @@ new /obj/item/clothing/suit/armor/vest/expeditionary_corps(src) new /obj/item/storage/belt/military/expeditionary_corps/marksman(src) new /obj/item/storage/backpack/duffelbag/expeditionary_corps(src) - new /obj/item/storage/box/gunset/ladon(src) + new /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild(src) diff --git a/modular_skyrat/modules/exp_corps/code/gear.dm b/modular_skyrat/modules/exp_corps/code/gear.dm index 05c5a989ac8163..5d3668f3f6d6b7 100644 --- a/modular_skyrat/modules/exp_corps/code/gear.dm +++ b/modular_skyrat/modules/exp_corps/code/gear.dm @@ -96,6 +96,7 @@ /obj/item/storage/pouch/ammo/marksman name = "marksman's knife pouch" + unique_reskin = NONE /obj/item/storage/pouch/ammo/marksman/Initialize(mapload) . = ..() diff --git a/modular_skyrat/modules/faction/code/mapping/mapping_helpers.dm b/modular_skyrat/modules/faction/code/mapping/mapping_helpers.dm index 035e1597f4e541..67461a949b7e4d 100644 --- a/modular_skyrat/modules/faction/code/mapping/mapping_helpers.dm +++ b/modular_skyrat/modules/faction/code/mapping/mapping_helpers.dm @@ -181,11 +181,11 @@ new /obj/item/knife/combat(src) new /obj/item/switchblade(src) new /obj/item/switchblade(src) - new /obj/item/gun/ballistic/automatic/cfa_wildcat(src) - new /obj/item/gun/ballistic/automatic/cfa_wildcat(src) + new /obj/item/gun/ballistic/automatic/sol_smg(src) + new /obj/item/gun/ballistic/automatic/sol_smg(src) for(var/i in 1 to 2) - new /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat(src) - new /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat(src) + new /obj/item/ammo_box/magazine/c35sol_pistol/stendo(src) + new /obj/item/ammo_box/magazine/c35sol_pistol/stendo(src) new /obj/item/gun/ballistic/automatic/akm(src) for(var/i in 1 to 2) new /obj/item/ammo_box/magazine/akm(src) diff --git a/modular_skyrat/modules/food_replicator/code/replicator_designs/replicator_medical.dm b/modular_skyrat/modules/food_replicator/code/replicator_designs/replicator_medical.dm index 31b14284387efe..85fa2a2ee4f982 100644 --- a/modular_skyrat/modules/food_replicator/code/replicator_designs/replicator_medical.dm +++ b/modular_skyrat/modules/food_replicator/code/replicator_designs/replicator_medical.dm @@ -3,7 +3,7 @@ id = "slavic_cfap" build_type = BIOGENERATOR materials = list(/datum/material/biomass = 250) - build_path = /obj/item/storage/bag/pocket_medkit + build_path = /obj/item/storage/pouch/cin_medkit category = list( RND_CATEGORY_INITIAL, RND_CATEGORY_NRI_MEDICAL, @@ -14,7 +14,7 @@ id = "slavic_medipouch" build_type = BIOGENERATOR materials = list(/datum/material/biomass = 250) - build_path = /obj/item/storage/bag/medipen + build_path = /obj/item/storage/pouch/cin_medipens category = list( RND_CATEGORY_INITIAL, RND_CATEGORY_NRI_MEDICAL, diff --git a/modular_skyrat/modules/food_replicator/code/storage.dm b/modular_skyrat/modules/food_replicator/code/storage.dm index 09ae7bece12b30..fe7ffc41a28038 100644 --- a/modular_skyrat/modules/food_replicator/code/storage.dm +++ b/modular_skyrat/modules/food_replicator/code/storage.dm @@ -1,21 +1,19 @@ -/obj/item/storage/bag/medipen +/obj/item/storage/pouch/cin_medipens name = "colonial medipen pouch" desc = "A pouch for your (medi-)pens that goes in your pocket." icon = 'modular_skyrat/modules/food_replicator/icons/pouch.dmi' icon_state = "medipen_pouch" - slot_flags = ITEM_SLOT_POCKETS - w_class = WEIGHT_CLASS_BULKY - resistance_flags = FLAMMABLE + w_class = WEIGHT_CLASS_NORMAL -/obj/item/storage/bag/medipen/update_icon_state() +/obj/item/storage/pouch/cin_medipens/update_icon_state() icon_state = "[initial(icon_state)]_[contents.len]" return ..() -/obj/item/storage/bag/medipen/Initialize(mapload) +/obj/item/storage/pouch/cin_medipens/Initialize(mapload) . = ..() update_appearance() -/obj/item/storage/bag/medipen/Initialize(mapload) +/obj/item/storage/pouch/cin_medipens/Initialize(mapload) . = ..() atom_storage.max_specific_storage = WEIGHT_CLASS_TINY atom_storage.max_total_storage = 4 @@ -23,17 +21,16 @@ atom_storage.numerical_stacking = FALSE atom_storage.can_hold = typecacheof(list(/obj/item/reagent_containers/hypospray/medipen, /obj/item/pen, /obj/item/flashlight/pen)) -/obj/item/storage/bag/pocket_medkit +/obj/item/storage/pouch/cin_medkit name = "colonial first aid kit" - desc = "A medical pouch that goes in your pocket. Can be used to store things unrelated to medicine, except for guns, ammo and raw materials." + desc = "A medical case that goes in your pocket. Can be used to store things unrelated to medicine, except for guns, ammo and raw materials." icon = 'modular_skyrat/modules/food_replicator/icons/pouch.dmi' icon_state = "cfak" - slot_flags = ITEM_SLOT_POCKETS - w_class = WEIGHT_CLASS_BULKY - resistance_flags = FLAMMABLE + w_class = WEIGHT_CLASS_NORMAL -/obj/item/storage/bag/pocket_medkit/Initialize(mapload) +/obj/item/storage/pouch/cin_medkit/Initialize(mapload) . = ..() + atom_storage.numerical_stacking = TRUE atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL atom_storage.max_total_storage = 4 atom_storage.max_slots = 4 diff --git a/modular_skyrat/modules/goofsec/code/department_guards.dm b/modular_skyrat/modules/goofsec/code/department_guards.dm index 7a5828b5fa26de..c93b74ffa185c5 100644 --- a/modular_skyrat/modules/goofsec/code/department_guards.dm +++ b/modular_skyrat/modules/goofsec/code/department_guards.dm @@ -200,7 +200,7 @@ l_pocket = /obj/item/restraints/handcuffs/cable/pink backpack_contents = list( /obj/item/melee/baton/security/loaded/departmental/science = 1, - /obj/item/storage/box/gunset/pepperball = 1, + /obj/item/storage/toolbox/guncase/skyrat/pistol/pepperball = 1, ) backpack = /obj/item/storage/backpack/science @@ -304,7 +304,7 @@ l_pocket = /obj/item/restraints/handcuffs/cable/blue backpack_contents = list( /obj/item/melee/baton/security/loaded/departmental/medical = 1, - /obj/item/storage/box/gunset/pepperball = 1, + /obj/item/storage/toolbox/guncase/skyrat/pistol/pepperball = 1, ) backpack = /obj/item/storage/backpack/medic @@ -402,7 +402,7 @@ l_pocket = /obj/item/restraints/handcuffs/cable/yellow backpack_contents = list( /obj/item/melee/baton/security/loaded/departmental/engineering = 1, - /obj/item/storage/box/gunset/pepperball = 1, + /obj/item/storage/toolbox/guncase/skyrat/pistol/pepperball = 1, ) backpack = /obj/item/storage/backpack/industrial @@ -507,7 +507,7 @@ l_pocket = /obj/item/restraints/handcuffs/cable/orange backpack_contents = list( /obj/item/melee/baton/security/loaded/departmental/cargo = 1, - /obj/item/storage/box/gunset/pepperball = 1, + /obj/item/storage/toolbox/guncase/skyrat/pistol/pepperball = 1, ) backpack = /obj/item/storage/backpack @@ -604,7 +604,7 @@ r_pocket = /obj/item/assembly/flash/handheld backpack_contents = list( /obj/item/melee/baton/security/loaded/departmental/service = 1, - /obj/item/storage/box/gunset/pepperball = 1, + /obj/item/storage/toolbox/guncase/skyrat/pistol/pepperball = 1, ) glasses = /obj/item/clothing/glasses/sunglasses diff --git a/modular_skyrat/modules/goofsec/code/sec_clothing_overrides.dm b/modular_skyrat/modules/goofsec/code/sec_clothing_overrides.dm index ea06dc1163c22b..f1bece74ab47a7 100644 --- a/modular_skyrat/modules/goofsec/code/sec_clothing_overrides.dm +++ b/modular_skyrat/modules/goofsec/code/sec_clothing_overrides.dm @@ -762,6 +762,8 @@ /obj/item/gun/energy/dueling, /obj/item/gun/energy/laser/thermal, /obj/item/gun/ballistic/rifle/boltaction, //fits if you make it an obrez + /obj/item/gun/energy/laser/captain, + /obj/item/gun/energy/e_gun/hos, )) /obj/item/storage/belt/holster/detective @@ -785,6 +787,8 @@ /obj/item/gun/energy/dueling, /obj/item/gun/energy/laser/thermal, /obj/item/gun/ballistic/rifle/boltaction, //fits if you make it an obrez + /obj/item/gun/energy/laser/captain, + /obj/item/gun/energy/e_gun/hos, )) /* diff --git a/modular_skyrat/modules/gun_safety/code/safety_additions.dm b/modular_skyrat/modules/gun_safety/code/safety_additions.dm index 67b6fe8561ed11..af8f3665315775 100644 --- a/modular_skyrat/modules/gun_safety/code/safety_additions.dm +++ b/modular_skyrat/modules/gun_safety/code/safety_additions.dm @@ -25,9 +25,6 @@ /obj/item/gun/ballistic/automatic/pistol/deagle/ctf/give_gun_safeties() return -/obj/item/gun/ballistic/automatic/pistol/g17/mesa/give_gun_safeties() - return - /obj/item/gun/ballistic/revolver/grenadelauncher/give_gun_safeties() return diff --git a/modular_skyrat/modules/horrorform/code/horror_form.dm b/modular_skyrat/modules/horrorform/code/horror_form.dm index b99f4360c356eb..9e6ea71ad7335f 100644 --- a/modular_skyrat/modules/horrorform/code/horror_form.dm +++ b/modular_skyrat/modules/horrorform/code/horror_form.dm @@ -14,6 +14,7 @@ req_stat = UNCONSCIOUS /datum/action/changeling/horror_form/sting_action(mob/living/carbon/human/user) + ..() if(!user || HAS_TRAIT(user, TRAIT_NO_TRANSFORM)) return 0 user.visible_message(span_warning("[user] writhes and contorts, their body expanding to inhuman proportions!"), \ diff --git a/modular_skyrat/modules/hyposprays/code/hypovials.dm b/modular_skyrat/modules/hyposprays/code/hypovials.dm index edc7b41c85b5f3..a4781bfea8fe7f 100644 --- a/modular_skyrat/modules/hyposprays/code/hypovials.dm +++ b/modular_skyrat/modules/hyposprays/code/hypovials.dm @@ -45,32 +45,32 @@ //Fit in all hypos /obj/item/reagent_containers/cup/vial/small name = "hypovial" - desc = "A small, 60u capacity vial compatible with most hyposprays." - volume = 60 - possible_transfer_amounts = list(1,2,5,10,20,30,40,50,60) + desc = "A small, 50u capacity vial compatible with most hyposprays." + volume = 50 + possible_transfer_amounts = list(1,2,5,10,15,25,50) //Fit in CMO hypo only /obj/item/reagent_containers/cup/vial/large name = "large hypovial" icon_state = "hypoviallarge" - desc = "A large, 120u capacity vial that fits only in the most deluxe hyposprays." - volume = 120 + desc = "A large, 100u capacity vial that fits only in the most deluxe hyposprays." + volume = 100 type_suffix = "-l" - possible_transfer_amounts = list(1,2,5,10,20,30,40,50,100,120) + possible_transfer_amounts = list(1,2,5,10,20,30,40,50,100) //Hypos that are in the CMO's kit round start /obj/item/reagent_containers/cup/vial/large/deluxe name = "deluxe hypovial" - list_reagents = list(/datum/reagent/medicine/omnizine = 20, /datum/reagent/medicine/leporazine = 20, /datum/reagent/medicine/atropine = 20) + list_reagents = list(/datum/reagent/medicine/omnizine = 15, /datum/reagent/medicine/leporazine = 15, /datum/reagent/medicine/atropine = 15) /obj/item/reagent_containers/cup/vial/large/salglu name = "large green hypovial (salglu)" - list_reagents = list(/datum/reagent/medicine/salglu_solution = 60) + list_reagents = list(/datum/reagent/medicine/salglu_solution = 50) /obj/item/reagent_containers/cup/vial/large/synthflesh name = "large orange hypovial (synthflesh)" - list_reagents = list(/datum/reagent/medicine/c2/synthflesh = 60) + list_reagents = list(/datum/reagent/medicine/c2/synthflesh = 50) /obj/item/reagent_containers/cup/vial/large/multiver name = "large black hypovial (multiver)" - list_reagents = list(/datum/reagent/medicine/c2/multiver = 60) + list_reagents = list(/datum/reagent/medicine/c2/multiver = 50) diff --git a/modular_skyrat/modules/implants/code/augments_chest.dm b/modular_skyrat/modules/implants/code/augments_chest.dm index 230793228741a5..87e817da3795fe 100644 --- a/modular_skyrat/modules/implants/code/augments_chest.dm +++ b/modular_skyrat/modules/implants/code/augments_chest.dm @@ -1,3 +1,7 @@ +// for readability's sake, define here to match the healthscan() proc's use of it +// if someone updates that upstream, fix that here too, wouldja? +#define SCANNER_VERBOSE 1 + /obj/item/organ/internal/cyberimp/chest/scanner name = "internal health analyzer" desc = "An advanced health analyzer implant, designed to directly interface with a host's body and relay scan information to the brain on command." @@ -6,14 +10,21 @@ icon_state = "internal_HA" implant_overlay = null implant_color = null - actions_types = list(/datum/action/item_action/organ_action/use) + actions_types = list(/datum/action/item_action/organ_action/use/internal_analyzer) w_class = WEIGHT_CLASS_SMALL -/obj/item/organ/internal/cyberimp/chest/scanner/ui_action_click(owner, action) - if(istype(action, /datum/action/item_action/organ_action/use)) - if(organ_flags & ORGAN_FAILING) - to_chat(owner, span_warning("Your health analyzer relays an error! It can't interface with your body in its current condition!")) - return - else - healthscan(owner, owner, 1, TRUE) - chemscan(owner, owner) +/datum/action/item_action/organ_action/use/internal_analyzer + desc = "LMB: Health scan. RMB: Chemical scan. Requires implanted analyzer to not be failing due to EMPs or other causes. Does not provide treatment assistance." + +/datum/action/item_action/organ_action/use/internal_analyzer/Trigger(trigger_flags) + . = ..() + var/obj/item/organ/internal/cyberimp/chest/scanner/our_scanner = target + if(our_scanner.organ_flags & ORGAN_FAILING) + to_chat(owner, span_warning("Your health analyzer relays an error! It can't interface with your body in its current condition!")) + return + if(trigger_flags & TRIGGER_SECONDARY_ACTION) + chemscan(owner, owner) + else + healthscan(owner, owner, SCANNER_VERBOSE, TRUE) + +#undef SCANNER_VERBOSE diff --git a/modular_skyrat/modules/indicators/icons/DNR_trait_overlay.dmi b/modular_skyrat/modules/indicators/icons/DNR_trait_overlay.dmi new file mode 100644 index 00000000000000..950b5503c00eb0 Binary files /dev/null and b/modular_skyrat/modules/indicators/icons/DNR_trait_overlay.dmi differ diff --git a/modular_skyrat/modules/layer_shift/code/mob_movement.dm b/modular_skyrat/modules/layer_shift/code/mob_movement.dm index 2bc2ed4cdee594..740b3e2289ed82 100644 --- a/modular_skyrat/modules/layer_shift/code/mob_movement.dm +++ b/modular_skyrat/modules/layer_shift/code/mob_movement.dm @@ -6,34 +6,73 @@ //#define MOB_LAYER 4 // This is a byond standard define #define MOB_LAYER_SHIFT_MAX 4.05 -/mob/living/verb/layershift_up() +/mob/living/verb/shift_layer_up() set name = "Shift Layer Upwards" set category = "IC" if(incapacitated()) to_chat(src, span_warning("You can't do that right now!")) - return + return FALSE if(layer >= MOB_LAYER_SHIFT_MAX) to_chat(src, span_warning("You cannot increase your layer priority any further.")) - return + return FALSE layer = min(((layer * MOB_LAYER_MULTIPLIER) + MOB_LAYER_SHIFT_INCREMENT) / MOB_LAYER_MULTIPLIER, MOB_LAYER_SHIFT_MAX) var/layer_priority = round(layer * MOB_LAYER_MULTIPLIER - MOB_LAYER * MOB_LAYER_MULTIPLIER, MOB_LAYER_SHIFT_INCREMENT) // Just for text feedback to_chat(src, span_notice("Your layer priority is now [layer_priority].")) -/mob/living/verb/layershift_down() + return TRUE + + +/mob/living/verb/shift_layer_down() set name = "Shift Layer Downwards" set category = "IC" if(incapacitated()) to_chat(src, span_warning("You can't do that right now!")) - return + return FALSE if(layer <= MOB_LAYER_SHIFT_MIN) to_chat(src, span_warning("You cannot decrease your layer priority any further.")) - return + return FALSE layer = max(((layer * MOB_LAYER_MULTIPLIER) - MOB_LAYER_SHIFT_INCREMENT) / MOB_LAYER_MULTIPLIER, MOB_LAYER_SHIFT_MIN) var/layer_priority = round(layer * MOB_LAYER_MULTIPLIER - MOB_LAYER * MOB_LAYER_MULTIPLIER, MOB_LAYER_SHIFT_INCREMENT) // Just for text feedback to_chat(src, span_notice("Your layer priority is now [layer_priority].")) + + return TRUE + + +/datum/emote/living/shift_layer_up + key = "shiftlayerup" + key_third_person = "shiftlayerup" + message = null + mob_type_blacklist_typecache = list(/mob/living/brain) + cooldown = 0.25 SECONDS + +/datum/emote/living/shift_layer_up/run_emote(mob/user, params, type_override, intentional) + if(!can_run_emote(user)) + to_chat(user, span_warning("You can't change layer at this time.")) + return FALSE + + var/mob/living/layer_shifter = user + + return layer_shifter.shift_layer_up() + + +/datum/emote/living/shift_layer_down + key = "shiftlayerdown" + key_third_person = "shiftlayerdown" + message = null + mob_type_blacklist_typecache = list(/mob/living/brain) + cooldown = 0.25 SECONDS + +/datum/emote/living/shift_layer_down/run_emote(mob/user, params, type_override, intentional) + if(!can_run_emote(user)) + to_chat(user, span_warning("You can't change layer at this time.")) + return FALSE + + var/mob/living/layer_shifter = user + + return layer_shifter.shift_layer_down() diff --git a/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm b/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm index 7b6e248a278fc2..c41311e46945d4 100644 --- a/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm +++ b/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm @@ -667,7 +667,7 @@ /datum/loadout_item/pocket_items/masvedishcigar name = "Holocigar" item_path = /obj/item/clothing/mask/holocigarette/masvedishcigar - ckeywhitelist = list("masvedish") + ckeywhitelist = list("masvedish", "lutowski", "lawful", "anyacers", "apolloafk", "avianaviator", "notdhu") /datum/loadout_item/suit/lt3_armor name = "Silver Jacket Mk II" diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_gloves.dm b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_gloves.dm index 68d10776be68e0..8adc97dd42b574 100644 --- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_gloves.dm +++ b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_gloves.dm @@ -82,6 +82,10 @@ GLOBAL_LIST_INIT(loadout_gloves, generate_loadout_items(/datum/loadout_item/glov name = "Maid Arm Covers" item_path = /obj/item/clothing/gloves/maid +/datum/loadout_item/gloves/armwraps + name = "Colourable Arm Wraps" + item_path = /obj/item/clothing/gloves/bracer/wraps + /* * RINGS */ diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_masks.dm b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_masks.dm index a92764d30745f8..d0052806a13de3 100644 --- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_masks.dm +++ b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_masks.dm @@ -130,6 +130,10 @@ GLOBAL_LIST_INIT(loadout_masks, generate_loadout_items(/datum/loadout_item/mask) name = "Joy Mask" item_path = /obj/item/clothing/mask/joy +/datum/loadout_item/mask/paper + name = "Paper Mask" + item_path = /obj/item/clothing/mask/paper + /datum/loadout_item/mask/lollipop name = "Lollipop" item_path = /obj/item/food/lollipop diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_shoes.dm b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_shoes.dm index d24031b78e2cb7..1ac2cfcb6b45b8 100644 --- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_shoes.dm +++ b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_shoes.dm @@ -158,9 +158,13 @@ GLOBAL_LIST_INIT(loadout_shoes, generate_loadout_items(/datum/loadout_item/shoes name = "Blue Leg Wraps" item_path = /obj/item/clothing/shoes/wraps/blue +/datum/loadout_item/shoes/cuffs/colourable + name = "Colourable Leg Wraps" + item_path = /obj/item/clothing/shoes/wraps/colourable + /datum/loadout_item/shoes/clothwrap name = "Colourable Cloth Wraps" - item_path = /obj/item/clothing/shoes/wraps/colourable + item_path = /obj/item/clothing/shoes/wraps/cloth /* * MISC diff --git a/modular_skyrat/modules/mapping/code/lockers/cargodiselost/cargodiselockers.dm b/modular_skyrat/modules/mapping/code/lockers/cargodiselost/cargodiselockers.dm index 00c5d6e8b627b0..2d9be517a0b19e 100644 --- a/modular_skyrat/modules/mapping/code/lockers/cargodiselost/cargodiselockers.dm +++ b/modular_skyrat/modules/mapping/code/lockers/cargodiselost/cargodiselockers.dm @@ -15,8 +15,8 @@ new /obj/item/ammo_box/magazine/akm(src) new /obj/item/ammo_box/magazine/akm(src) new /obj/item/ammo_box/magazine/akm(src) - new /obj/item/ammo_box/magazine/multi_sprite/makarov(src) - new /obj/item/ammo_box/magazine/multi_sprite/makarov(src) + new /obj/item/ammo_box/magazine/c35sol_pistol(src) + new /obj/item/ammo_box/magazine/c35sol_pistol(src) new /obj/item/ammo_box/strilka310(src) new /obj/item/ammo_box/strilka310(src) new /obj/item/ammo_box/strilka310(src) @@ -25,7 +25,7 @@ /obj/structure/closet/secure_closet/personal/cabinet/freighterboss/PopulateContents() . = ..() - new /obj/item/gun/ballistic/automatic/cfa_rifle(src) + new /obj/item/gun/ballistic/automatic/sol_rifle/marksman(src) new /obj/item/storage/pouch/ammo(src) new /obj/item/clothing/suit/armor/bulletproof(src) new /obj/item/storage/belt/utility/syndicate(src) @@ -33,6 +33,6 @@ new /obj/item/clothing/gloves/combat(src) new /obj/item/storage/backpack/duffelbag/syndie(src) new /obj/item/radio(src) - new /obj/item/ammo_box/magazine/cm68(src) - new /obj/item/ammo_box/magazine/cm68(src) - new /obj/item/ammo_box/magazine/cm68(src) + new /obj/item/ammo_box/magazine/c40sol_rifle(src) + new /obj/item/ammo_box/magazine/c40sol_rifle(src) + new /obj/item/ammo_box/magazine/c40sol_rifle(src) diff --git a/modular_skyrat/modules/mapping/code/lockers/interdyne_fob/security.dm b/modular_skyrat/modules/mapping/code/lockers/interdyne_fob/security.dm index df1aa1cfe3f490..82eb8a853146d9 100644 --- a/modular_skyrat/modules/mapping/code/lockers/interdyne_fob/security.dm +++ b/modular_skyrat/modules/mapping/code/lockers/interdyne_fob/security.dm @@ -71,13 +71,12 @@ /obj/structure/closet/secure_closet/interdynefob/munitions_locker/PopulateContents() ..() - new /obj/item/ammo_box/c9mm(src) - new /obj/item/ammo_box/c9mm(src) - new /obj/item/ammo_box/magazine/m9mm(src) - new /obj/item/ammo_box/magazine/m9mm(src) - new /obj/item/ammo_box/magazine/m9mm(src) - new /obj/item/ammo_box/magazine/m9mm(src) - new /obj/item/ammo_box/advanced/s12gauge(src) - new /obj/item/ammo_box/advanced/s12gauge(src) - new /obj/item/ammo_box/advanced/s12gauge/rubber(src) - new /obj/item/ammo_box/advanced/s12gauge/rubber(src) + generate_items_inside(list( + /obj/item/ammo_box/magazine/c35sol_pistol = 6, + /obj/item/ammo_box/magazine/c35sol_pistol/stendo = 2, + /obj/item/ammo_box/c35sol = 2, + /obj/item/ammo_box/magazine/c40sol_rifle/standard = 2, + /obj/item/ammo_box/c40sol = 2, + /obj/item/ammo_box/advanced/s12gauge = 2, + /obj/item/ammo_box/advanced/s12gauge/rubber = 2, + ),src) diff --git a/modular_skyrat/modules/mapping/code/shuttles.dm b/modular_skyrat/modules/mapping/code/shuttles.dm index 9f5293d9a1dca5..1ad2e883eec562 100644 --- a/modular_skyrat/modules/mapping/code/shuttles.dm +++ b/modular_skyrat/modules/mapping/code/shuttles.dm @@ -121,19 +121,14 @@ implants = list(/obj/item/implant/weapons_auth) belt = /obj/item/storage/belt/military r_pocket = /obj/item/storage/pouch/ammo - l_pocket = /obj/item/gun/energy/disabler/bolt_disabler + l_pocket = /obj/item/gun/energy/e_gun/mini id = /obj/item/card/id/advanced/chameleon id_trim = /datum/id_trim/chameleon/operative skillchips = list(/obj/item/skillchip/job/engineer) backpack_contents = list( /obj/item/storage/box/survival/engineer/radio, /obj/item/melee/baton/telescopic, - /obj/item/gun/ballistic/automatic/pistol/cfa_snub/empty, - /obj/item/ammo_box/magazine/multi_sprite/cfa_snub, - /obj/item/ammo_box/magazine/multi_sprite/cfa_snub, - /obj/item/ammo_box/magazine/multi_sprite/cfa_snub/ap, - /obj/item/ammo_box/magazine/multi_sprite/cfa_snub/rubber, - /obj/item/ammo_box/magazine/multi_sprite/cfa_snub/rubber, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/wespe, /obj/item/grenade/c4, /obj/item/grenade/smokebomb ) @@ -151,18 +146,14 @@ implants = list(/obj/item/implant/weapons_auth) belt = /obj/item/storage/belt/military r_pocket = /obj/item/storage/pouch/ammo - l_pocket = /obj/item/gun/energy/disabler/bolt_disabler + l_pocket = /obj/item/gun/energy/e_gun/mini id = /obj/item/card/id/advanced/chameleon id_trim = /datum/id_trim/chameleon/operative skillchips = list(/obj/item/skillchip/job/engineer) backpack_contents = list( /obj/item/storage/box/survival/engineer/radio, /obj/item/melee/baton/telescopic, - /obj/item/gun/ballistic/automatic/pistol/cfa_ruby/empty, - /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/ap, - /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/ap, - /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/rubber, - /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/rubber, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild, /obj/item/megaphone/command ) diff --git a/modular_skyrat/modules/medical/attributions.txt b/modular_skyrat/modules/medical/attributions.txt new file mode 100644 index 00000000000000..f57c3fa0db566f --- /dev/null +++ b/modular_skyrat/modules/medical/attributions.txt @@ -0,0 +1,2 @@ +robotic_slash_T1.ogg, robotic_slash_T2.ogg, and robotic_slash_T3.ogg adapated from CGEffex's Bug Zapper2.wav (CC Attribution 4.0) +https://freesound.org/people/CGEffex/sounds/107004/ diff --git a/modular_skyrat/modules/medical/code/cargo/packs.dm b/modular_skyrat/modules/medical/code/cargo/packs.dm new file mode 100644 index 00000000000000..0de1f24eb16700 --- /dev/null +++ b/modular_skyrat/modules/medical/code/cargo/packs.dm @@ -0,0 +1,36 @@ +/datum/supply_pack/science/chilled_hercuri + name = "Chilled Hercuri Pack" + desc = "Contains 2 pre-chilled bottles of hercuri, 100u each. Useful for dealing with severely burnt synthetics!" + cost = CARGO_CRATE_VALUE * 2.5 + contains = list(/obj/item/reagent_containers/spray/hercuri/chilled = 2) + crate_name = "chilled hercuri crate" + + access_view = FALSE + access = FALSE + access_any = FALSE + +/datum/supply_pack/science/synth_treatment_kits + name = "Synthetic Treatment Kits" + desc = "Contains 2 treatment kits for synthetic lifeforms, filled with everything you need to treat an inorganic wound!" + cost = CARGO_CRATE_VALUE * 4.5 + contains = list(/obj/item/storage/backpack/duffelbag/synth_treatment_kit = 2) + crate_name = "synthetic treatment kits crate" + + access_view = FALSE + access = FALSE + access_any = FALSE + +/datum/supply_pack/science/synth_healing_chems + name = "Synthetic Medicine Pack" + desc = "Contains a variety of synthetic-exclusive medicine. 2 pill bottles of liquid solder, 2 of nanite slurry, 2 of system cleaner." + cost = CARGO_CRATE_VALUE * 7 // rarely made, so it should be expensive(?) + contains = list( + /obj/item/storage/pill_bottle/liquid_solder = 2, + /obj/item/storage/pill_bottle/nanite_slurry = 2, + /obj/item/storage/pill_bottle/system_cleaner = 2 + ) + crate_name = "synthetic medicine crate" + + access_view = FALSE + access = FALSE + access_any = FALSE diff --git a/modular_skyrat/modules/medical/code/medkit.dm b/modular_skyrat/modules/medical/code/medkit.dm new file mode 100644 index 00000000000000..8ea40ae54bd4ef --- /dev/null +++ b/modular_skyrat/modules/medical/code/medkit.dm @@ -0,0 +1,177 @@ +/obj/item/storage/backpack/duffelbag/synth_treatment_kit + name = "synthetic treatment kit" + desc = "A \"surgical\" duffel bag containing everything you need to treat the worst and best of inorganic wounds." + icon = 'modular_skyrat/master_files/icons/obj/clothing/backpacks.dmi' + worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/back.dmi' + lefthand_file = 'modular_skyrat/master_files/icons/mob/inhands/clothing/backpack_lefthand.dmi' + righthand_file = 'modular_skyrat/master_files/icons/mob/inhands/clothing/backpack_righthand.dmi' + icon_state = "duffel_robo" + inhand_icon_state = "duffel_robo" + +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/PopulateContents() // yes, this is all within the storage capacity + // Slash/Pierce wound tools - can reduce intensity of electrical damage (wires can fix generic burn damage) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/wirecutters(src) + // Blunt/Brute tools + new /obj/item/weldingtool/largetank(src) // Used for repairing blunt damage or heating metal at T3 blunt + new /obj/item/screwdriver(src) // Used for fixing T1 blunt or securing internals of T2/3 blunt + new /obj/item/bonesetter(src) + // Clothing items + new /obj/item/clothing/head/utility/welding(src) + new /obj/item/clothing/gloves/color/black(src) // Protects from T3 mold metal step + new /obj/item/clothing/glasses/hud/diagnostic(src) // When worn, generally improves wound treatment quality + // Reagent containers + new /obj/item/reagent_containers/spray/hercuri/chilled(src) // Highly effective (specifically coded to be) against burn wounds + // Generic medical items + new /obj/item/stack/medical/gauze/twelve(src) + new /obj/item/healthanalyzer(src) + new /obj/item/healthanalyzer/simple(src) // Buffs wound treatment and gives details of wounds it scans + // "Ghetto" tools, things you shouldnt ideally use but you might have to + new /obj/item/stack/medical/bone_gel(src) // Ghetto T2/3 option for securing internals + new /obj/item/plunger(src) // Can be used to mold heated metal at T3 + +// a treatment kit with extra space and more tools/upgraded tools, like a crowbar, insuls, a reinforced plunger, a crowbar and wrench +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma + name = "synthetic trauma kit" + desc = "A \"surgical\" duffel bag containing everything you need to treat the worst and best of inorganic wounds. This one has extra tools and space \ + for treatment of the WORST of the worst! However, it's highly specialized interior means it can ONLY hold synthetic repair tools." + storage_type = /datum/storage/duffel/synth_trauma_kit + +/datum/storage/duffel/synth_trauma_kit + exception_max = 6 + max_slots = 27 + max_total_storage = 35 + +/datum/storage/duffel/synth_trauma_kit/New(atom/parent, max_slots, max_specific_storage, max_total_storage, numerical_stacking, allow_quick_gather, allow_quick_empty, collection_mode, attack_hand_interact) + . = ..() + + var/static/list/exception_cache = typecacheof(list( + // Mainly just stacks, with the exception of pill bottles and sprays + /obj/item/stack/cable_coil, + /obj/item/stack/medical/gauze, + /obj/item/reagent_containers/spray, + /obj/item/stack/medical/bone_gel, + /obj/item/rcd_ammo, + /obj/item/storage/pill_bottle, + )) + + var/static/list/can_hold_list = list( + // Stacks + /obj/item/stack/cable_coil, + /obj/item/stack/medical/gauze, + /obj/item/stack/medical/bone_gel, + // Reagent containers, for synth medicine + /obj/item/reagent_containers/spray, + /obj/item/storage/pill_bottle, + /obj/item/reagent_containers/pill, + /obj/item/reagent_containers/cup, + /obj/item/reagent_containers/syringe, + // Tools, including tools you might not want to use but might have to (hemostat/retractor/etc) + /obj/item/screwdriver, + /obj/item/wrench, + /obj/item/crowbar, + /obj/item/weldingtool, + /obj/item/bonesetter, + /obj/item/wirecutters, + /obj/item/hemostat, + /obj/item/retractor, + /obj/item/cautery, + /obj/item/plunger, + // RCD stuff - RCDs can easily treat the 1st step of T3 blunt + /obj/item/construction/rcd, + /obj/item/rcd_ammo, + // Clothing items + /obj/item/clothing/gloves, + /obj/item/clothing/glasses/hud/health, + /obj/item/clothing/glasses/hud/diagnostic, + /obj/item/clothing/glasses/welding, + /obj/item/clothing/glasses/sunglasses, // still provides some welding protection + /obj/item/clothing/head/utility/welding, + /obj/item/clothing/mask/gas/welding, + // Generic health items + /obj/item/healthanalyzer, + ) + exception_hold = exception_cache + + // We keep the type list and the typecache list separate... + var/static/list/can_hold_cache = typecacheof(can_hold_list) + can_hold = can_hold_cache + + //...So we can run this without it generating a line for every subtype. + can_hold_description = generate_hold_desc(can_hold_list) + +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma/PopulateContents() // yes, this is all within the storage capacity + // Slash/Pierce wound tools - can reduce intensity of electrical damage (wires can fix generic burn damage) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/wirecutters(src) + // Blunt/Brute tools + new /obj/item/weldingtool/hugetank(src) // Used for repairing blunt damage or heating metal at T3 blunt + new /obj/item/screwdriver(src) // Used for fixing T1 blunt or securing internals of T2/3 blunt + new /obj/item/wrench(src) // Same as screwdriver for T2/3 + new /obj/item/crowbar(src) // Ghetto fixing option for T2/3 blunt + new /obj/item/bonesetter(src) + // Clothing items + new /obj/item/clothing/head/utility/welding(src) + new /obj/item/clothing/gloves/color/black(src) // Protects from T3 mold metal step + new /obj/item/clothing/gloves/color/yellow(src) // Protects from electrical damage and crowbarring a blunt wound + new /obj/item/clothing/glasses/hud/diagnostic(src) // When worn, generally improves wound treatment quality + // Reagent containers + new /obj/item/reagent_containers/spray/hercuri/chilled(src) // Highly effective (specifically coded to be) against burn wounds + // Generic medical items + new /obj/item/stack/medical/gauze/twelve(src) + new /obj/item/healthanalyzer(src) + new /obj/item/healthanalyzer/simple(src) // Buffs wound treatment and gives details of wounds it scans + // "Ghetto" tools, things you shouldnt ideally use but you might have to + new /obj/item/stack/medical/bone_gel(src) // Ghetto T2/3 option for securing internals + new /obj/item/plunger/reinforced(src) // Can be used to mold heated metal at T3 + +// advanced tools, an RCD, chems, etc etc. dont give this one to the crew early in the round +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma/advanced + name = "advanced synth trauma kit" + desc = "An \"advanced\" \"surgical\" duffel bag containing absolutely everything you need to treat the worst and best of inorganic wounds. \ + This one has extra tools and space for treatment of the ones even worse than the WORST of the worst! However, its highly specialized interior \ + means it can ONLY hold synthetic repair tools." + + storage_type = /datum/storage/duffel/synth_trauma_kit/advanced + +/datum/storage/duffel/synth_trauma_kit/advanced + exception_max = 10 + max_slots = 31 + max_total_storage = 48 + +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma/advanced/PopulateContents() // yes, this is all within the storage capacity + // Slash/Pierce wound tools - can reduce intensity of electrical damage (wires can fix generic burn damage) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/stack/cable_coil(src) + new /obj/item/crowbar/power(src) // jaws of life - wirecutters and crowbar + // Blunt/Brute tools + new /obj/item/weldingtool/experimental(src) // Used for repairing blunt damage or heating metal at T3 blunt + new /obj/item/screwdriver/power(src) // drill - screwdriver and wrench + new /obj/item/construction/rcd/loaded(src) // lets you instantly heal T3 blunt step 1 + new /obj/item/bonesetter(src) + // Clothing items + new /obj/item/clothing/head/utility/welding(src) + new /obj/item/clothing/gloves/combat(src) // insulated AND heat-resistant + new /obj/item/clothing/glasses/hud/diagnostic(src) // When worn, generally improves wound treatment quality + // Reagent containers + new /obj/item/reagent_containers/spray/hercuri/chilled(src) // Highly effective (specifically coded to be) against burn wounds + new /obj/item/reagent_containers/spray/hercuri/chilled(src) // 2 of them + new /obj/item/storage/pill_bottle/nanite_slurry(src) // Heals blunt/burn + new /obj/item/storage/pill_bottle/liquid_solder(src) // Heals brain damage + new /obj/item/storage/pill_bottle/system_cleaner(src) // Heals toxin damage and purges chems + // Generic medical items + new /obj/item/stack/medical/gauze/twelve(src) + new /obj/item/healthanalyzer/advanced(src) // advanced, not a normal analyzer + new /obj/item/healthanalyzer/simple(src) // Buffs wound treatment and gives details of wounds it scans + // "Ghetto" tools, things you shouldn't ideally use but you might have to + new /obj/item/stack/medical/bone_gel(src) // Ghetto T2/3 option for securing internals + new /obj/item/plunger/reinforced(src) // Can be used to mold heated metal at T3 blunt + +/obj/item/storage/backpack/duffelbag/synth_treatment_kit/trauma/advanced/unzipped + zipped_up = FALSE diff --git a/modular_skyrat/modules/medical/code/sprays.dm b/modular_skyrat/modules/medical/code/sprays.dm new file mode 100644 index 00000000000000..8e2371e3f28549 --- /dev/null +++ b/modular_skyrat/modules/medical/code/sprays.dm @@ -0,0 +1,12 @@ +/obj/item/reagent_containers/spray/hercuri/chilled + name = "chilled hercuri spray" // effective at cooling low-temperature burns but also is more efficienct at cooling high-temperature + desc = "A medical spray bottle. This one contains hercuri, a medicine used to negate the effects of dangerous high-temperature environments. \ + This one comes pre-chilled, making it especially good at cooling synthetic burns! \n\ + It has a bold warning label near the nozzle: ONLY USE IN EMERGENCIES! WILL CAUSE FREEZING! SECONDARY EFFECT ONLY USEFUL ON LIVING SYNTHS! INEFFECTIVE ON DECEASED! \n\ + There's a smaller warning label on the body of the spray: IN EVENT OF RUNAWAY ENDOTHERMY, APPLY SYSTEM CLEANER!" + var/starting_temperature = 100 + +/obj/item/reagent_containers/spray/hercuri/chilled/add_initial_reagents() + . = ..() + + reagents.chem_temp = starting_temperature diff --git a/modular_skyrat/modules/medical/code/wounds/medical.dm b/modular_skyrat/modules/medical/code/wounds/medical.dm index 80662956e5f350..5a3723fff4bfb2 100644 --- a/modular_skyrat/modules/medical/code/wounds/medical.dm +++ b/modular_skyrat/modules/medical/code/wounds/medical.dm @@ -4,8 +4,6 @@ /obj/item/stack/medical/gauze /// The amount of direct hits our limb can take before we fall off. var/integrity = 2 - /// The bodypart we are attached to. Nullable if we aren't applied to anything. - var/obj/item/bodypart/bodypart /// If we are splinting a limb, this is the overlay prefix we will use. var/splint_prefix = "splint" /// If we are bandaging a limb, this is the overlay prefix we will use. @@ -14,25 +12,16 @@ var/can_splint = TRUE /obj/item/bodypart/apply_gauze(obj/item/stack/gauze) - RegisterSignal(src, COMSIG_BODYPART_GAUZED, PROC_REF(got_gauzed)) - . = ..() - UnregisterSignal(src, COMSIG_BODYPART_GAUZED) + owner?.update_bandage_overlays() -/// Signal handler that allows us to modularly detect if we were applied to a limb or not. -/obj/item/bodypart/proc/got_gauzed(datum/signal_source, obj/item/stack/medical/gauze/new_gauze) - SIGNAL_HANDLER +/obj/item/stack/medical/gauze/Destroy() + var/mob/living/carbon/previously_gauzed = gauzed_bodypart?.owner - if (istype(current_gauze, /obj/item/stack/medical/gauze)) - var/obj/item/stack/medical/gauze/applied_gauze = current_gauze - applied_gauze.set_limb(src) // new_gauze isnt actually the gauze that was applied weirdly + . = ..() -/obj/item/stack/medical/gauze/Destroy() - bodypart?.current_gauze = null - bodypart?.owner?.update_bandage_overlays() - set_limb(null) - return ..() + previously_gauzed?.update_bandage_overlays() /** * rip_off() called when someone rips it off @@ -43,7 +32,7 @@ /obj/item/stack/medical/gauze/proc/rip_off() if (is_pristine()) . = new src.type(null, 1) - bodypart?.owner?.update_bandage_overlays() + qdel(src) /// Returns either [splint_prefix] or [gauze_prefix] depending on if we are splinting or not. Suffixes it with a digitigrade flag if applicable for the limb. @@ -56,8 +45,8 @@ else prefix = gauze_prefix - var/suffix = bodypart.body_zone - if(bodypart.bodytype & BODYTYPE_DIGITIGRADE) + var/suffix = gauzed_bodypart.body_zone + if(gauzed_bodypart.bodytype & BODYTYPE_DIGITIGRADE) suffix += "_digitigrade" return "[prefix]_[suffix]" @@ -69,7 +58,7 @@ if (!can_splint) return FALSE - for (var/datum/wound/iterated_wound as anything in bodypart.wounds) + for (var/datum/wound/iterated_wound as anything in gauzed_bodypart.wounds) if (iterated_wound.wound_flags & SPLINT_OVERLAY) return TRUE @@ -95,35 +84,30 @@ /obj/item/stack/medical/gauze/proc/get_hit() integrity-- if(integrity <= 0) - if(bodypart.owner) - to_chat(bodypart.owner, span_warning("The [name] on your [bodypart.name] tears and falls off!")) + if(gauzed_bodypart.owner) + to_chat(gauzed_bodypart.owner, span_warning("The [name] on your [gauzed_bodypart.name] tears and falls off!")) qdel(src) /obj/item/stack/medical/gauze/Topic(href, href_list) . = ..() if(href_list["remove"]) - if(!bodypart.owner) + if(!gauzed_bodypart.owner) return if(!iscarbon(usr)) return - if(!in_range(usr, bodypart.owner)) + if(!in_range(usr, gauzed_bodypart.owner)) return - var/mob/living/carbon/C = usr - var/self = (C == bodypart.owner) - C.visible_message(span_notice("[C] begins removing [name] from [self ? "[bodypart.owner.p_Their()]" : "[bodypart.owner]'s" ] [bodypart.name]..."), span_notice("You begin to remove [name] from [self ? "your" : "[bodypart.owner]'s"] [bodypart.name]...")) - if(!do_after(C, (self ? SELF_AID_REMOVE_DELAY : OTHER_AID_REMOVE_DELAY), target=bodypart.owner)) + var/mob/living/carbon/carbon_user = usr + var/self = (carbon_user == gauzed_bodypart.owner) + carbon_user.visible_message(span_notice("[carbon_user] begins removing [name] from [self ? "[gauzed_bodypart.owner.p_Their()]" : "[gauzed_bodypart.owner]'s" ] [gauzed_bodypart.name]..."), span_notice("You begin to remove [name] from [self ? "your" : "[gauzed_bodypart.owner]'s"] [gauzed_bodypart.name]...")) + if(!do_after(carbon_user, (self ? SELF_AID_REMOVE_DELAY : OTHER_AID_REMOVE_DELAY), target = gauzed_bodypart.owner)) return if(QDELETED(src)) return - C.visible_message(span_notice("[C] removes [name] from [self ? "[bodypart.owner.p_Their()]" : "[bodypart.owner]'s" ] [bodypart.name]."), span_notice("You remove [name] from [self ? "your" : "[bodypart.owner]'s" ] [bodypart.name].")) + carbon_user.visible_message(span_notice("[carbon_user] removes [name] from [self ? "[gauzed_bodypart.owner.p_Their()]" : "[gauzed_bodypart.owner]'s" ] [gauzed_bodypart.name]."), span_notice("You remove [name] from [self ? "your" : "[gauzed_bodypart.owner]'s" ] [gauzed_bodypart.name].")) var/obj/item/gotten = rip_off() - if(gotten && !C.put_in_hands(gotten)) - gotten.forceMove(get_turf(C)) - -/// Sets bodypart to limb, and then updates owner's bandage overlays. Limb is nullable. -/obj/item/stack/medical/gauze/proc/set_limb(limb) - bodypart = limb - bodypart?.owner?.update_bandage_overlays() + if(gotten && !carbon_user.put_in_hands(gotten)) + gotten.forceMove(get_turf(carbon_user)) /// Returns the name of ourself when used in a "owner is [usage_prefix] by [name]" examine_more situation/ /obj/item/stack/proc/get_gauze_description() diff --git a/modular_skyrat/modules/medical/code/wounds/muscle.dm b/modular_skyrat/modules/medical/code/wounds/muscle.dm index c1f9c3fc4c3515..35cc54c7099b07 100644 --- a/modular_skyrat/modules/medical/code/wounds/muscle.dm +++ b/modular_skyrat/modules/medical/code/wounds/muscle.dm @@ -33,13 +33,14 @@ Overwriting of base procs */ /datum/wound/muscle/wound_injury(datum/wound/old_wound = null, attack_direction) - if(limb.held_index && victim.get_item_for_held_index(limb.held_index) && (disabling || prob(30 * severity))) - var/obj/item/I = victim.get_item_for_held_index(limb.held_index) - if(istype(I, /obj/item/offhand)) - I = victim.get_inactive_held_item() + var/obj/item/held_item = victim.get_item_for_held_index(limb.held_index || 0) + if(held_item && (disabling || prob(30 * severity))) + if(istype(held_item, /obj/item/offhand)) + held_item = victim.get_inactive_held_item() - if(I && victim.dropItemToGround(I)) - victim.visible_message(span_danger("[victim] drops [I] in shock!"), span_warning("The force on your [parse_zone(limb.body_zone)] causes you to drop [I]!"), vision_distance=COMBAT_MESSAGE_RANGE) + if(held_item && victim.dropItemToGround(held_item)) + victim.visible_message(span_danger("[victim] drops [held_item] in shock!"), \ + span_warning("The force on your [parse_zone(limb.body_zone)] causes you to drop [held_item]!"), vision_distance=COMBAT_MESSAGE_RANGE) return ..() @@ -173,3 +174,9 @@ id = "torn muscle" /datum/status_effect/wound/muscle/severe id = "ruptured tendon" + +/datum/status_effect/wound/muscle/robotic/moderate + id = "worn servo" + +/datum/status_effect/wound/muscle/robotic/severe + id = "severed hydraulic" diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm new file mode 100644 index 00000000000000..52995365b01fb6 --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt.dm @@ -0,0 +1,398 @@ +/// The multiplier put against our movement effects if our victim has the determined reagent +#define ROBOTIC_WOUND_DETERMINATION_MOVEMENT_EFFECT_MOD 0.7 +/// The multiplier of stagger intensity on hit if our victim has the determined reagent +#define ROBOTIC_WOUND_DETERMINATION_STAGGER_MOVEMENT_MULT 0.7 + +/// The multiplier put against our movement effects if our limb is grasped +#define ROBOTIC_BLUNT_GRASPED_MOVEMENT_MULT 0.7 + +/datum/wound/blunt/robotic + name = "Robotic Blunt (Screws and bolts) Wound" + wound_flags = (ACCEPTS_GAUZE|SPLINT_OVERLAY|CAN_BE_GRASPED) + + default_scar_file = METAL_SCAR_FILE + + /// If we suffer severe head booboos, we can get brain traumas tied to them + var/datum/brain_trauma/active_trauma + /// What brain trauma group, if any, we can draw from for head wounds + var/brain_trauma_group + /// If we deal brain traumas, when is the next one due? + var/next_trauma_cycle + /// How long do we wait +/- 20% for the next trauma? + var/trauma_cycle_cooldown + + /// The ratio stagger score will be multiplied against for determining the final chance of moving away from the attacker. + var/stagger_movement_chance_ratio = 1 + /// The ratio stagger score will be multiplied against for determining the amount of pixelshifting we will do when we are hit. + var/stagger_shake_shift_ratio = 0.05 + + /// The ratio of stagger score to shake duration during a stagger() call + var/stagger_score_to_shake_duration_ratio = 0.1 + + /// In the stagger aftershock, the stagger score will be multiplied against for determining the chance of dropping held items. + var/stagger_drop_chance_ratio = 1.25 + /// In the stagger aftershock, the stagger score will be multiplied against for determining the chance of falling over. + var/stagger_fall_chance_ratio = 1 + + /// In the stagger aftershock, the stagger score will be multiplied against for determining how long we are knocked down for. + var/stagger_aftershock_knockdown_ratio = 0.5 + /// In the stagger after shock, the stagger score will be multiplied against this (if caused by movement) for determining how long we are knocked down for. + var/stagger_aftershock_knockdown_movement_ratio = 0.1 + + /// If the victim stops moving before the aftershock, aftershock effects will be multiplied against this. + var/aftershock_stopped_moving_score_mult = 0.1 + + /// The ratio damage applied will be multiplied against for determining our stagger score. + var/chest_attacked_stagger_mult = 2.5 + /// The minimum score an attack must do to trigger a stagger. + var/chest_attacked_stagger_minimum_score = 5 + /// The ratio of damage to stagger chance on hit. + var/chest_attacked_stagger_chance_ratio = 2 + + /// The base score given to stagger() when we successfully stagger on a move. + var/base_movement_stagger_score = 30 + /// The base chance of moving to trigger stagger(). + var/chest_movement_stagger_chance = 1 + + /// The base duration of a stagger()'s sprite shaking. + var/base_stagger_shake_duration = 1.5 SECONDS + /// The base duration of a stagger()'s sprite shaking if caused by movement. + var/base_stagger_movement_shake_duration = 1.5 SECONDS + + /// The ratio of stagger score to camera shake chance. + var/stagger_camera_shake_chance_ratio = 0.75 + /// The base duration of a stagger's aftershock's camerashake. + var/base_aftershock_camera_shake_duration = 1.5 SECONDS + /// The base strength of a stagger's aftershock's camerashake. + var/base_aftershock_camera_shake_strength = 0.5 + + /// The amount of x and y pixels we will be shaken around by during a movement stagger. + var/movement_stagger_shift = 1 + + /// If we are currently oscillating. If true, we cannot stagger(). + var/oscillating = FALSE + + /// % chance for hitting our limb to fix something. + var/percussive_maintenance_repair_chance = 10 + /// Damage must be under this to proc percussive maintenance. + var/percussive_maintenance_damage_max = 7 + /// Damage must be over this to proc percussive maintenance. + var/percussive_maintenance_damage_min = 0 + + /// The time, in world time, that we will be allowed to do another movement shake. Useful because it lets us prioritize attacked shakes over movement shakes. + var/time_til_next_movement_shake_allowed = 0 + + /// The percent our limb must get to max possible damage by burn damage alone to count as malleable if it has no T2 burn wound. + var/limb_burn_percent_to_max_threshold_for_malleable = 0.8 // must be 75% to max damage by burn damage alone + + /// The last time our victim has moved. Used for determining if we should increase or decrease the chance of having stagger aftershock. + var/last_time_victim_moved = 0 + + processes = TRUE + +/datum/wound_pregen_data/blunt_metal + abstract = TRUE + required_limb_biostate = BIO_METAL + wound_series = WOUND_SERIES_METAL_BLUNT_BASIC + required_wounding_types = list(WOUND_BLUNT) + +/datum/wound_pregen_data/blunt_metal/generate_scar_priorities() + return list("[BIO_METAL]") + +/datum/wound/blunt/robotic/set_victim(new_victim) + if(victim) + UnregisterSignal(victim, COMSIG_MOVABLE_MOVED) + UnregisterSignal(victim, COMSIG_MOB_AFTER_APPLY_DAMAGE) + if(new_victim) + RegisterSignal(new_victim, COMSIG_MOVABLE_MOVED, PROC_REF(victim_moved)) + RegisterSignal(new_victim, COMSIG_MOB_AFTER_APPLY_DAMAGE, PROC_REF(victim_attacked)) + + return ..() + +/datum/wound/blunt/robotic/get_limb_examine_description() + return span_warning("This limb looks loosely held together.") + +// this wound is unaffected by cryoxadone and pyroxadone +/datum/wound/blunt/robotic/on_xadone(power) + return + +/datum/wound/blunt/robotic/wound_injury(datum/wound/old_wound, attack_direction) + . = ..() + + // hook into gaining/losing gauze so crit bone wounds can re-enable/disable depending if they're slung or not + if(limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group) + processes = TRUE + active_trauma = victim.gain_trauma_type(brain_trauma_group, TRAUMA_RESILIENCE_WOUND) + next_trauma_cycle = world.time + (rand(100-WOUND_BONE_HEAD_TIME_VARIANCE, 100+WOUND_BONE_HEAD_TIME_VARIANCE) * 0.01 * trauma_cycle_cooldown) + + var/obj/item/held_item = victim.get_item_for_held_index(limb.held_index || 0) + if(held_item && (disabling || prob(30 * severity))) + if(istype(held_item, /obj/item/offhand)) + held_item = victim.get_inactive_held_item() + if(held_item && victim.dropItemToGround(held_item)) + victim.visible_message(span_danger("[victim] drops [held_item] in shock!"), span_warning("The force on your [limb.plaintext_zone] causes you to drop [held_item]!"), vision_distance=COMBAT_MESSAGE_RANGE) + +/datum/wound/blunt/robotic/remove_wound(ignore_limb, replaced) + . = ..() + + QDEL_NULL(active_trauma) + +/datum/wound/blunt/robotic/handle_process(seconds_per_tick, times_fired) + . = ..() + + if (!victim || IS_IN_STASIS(victim)) + return + + if (limb.body_zone == BODY_ZONE_HEAD && brain_trauma_group && world.time > next_trauma_cycle) + if (active_trauma) + QDEL_NULL(active_trauma) + else + active_trauma = victim.gain_trauma_type(brain_trauma_group, TRAUMA_RESILIENCE_WOUND) + next_trauma_cycle = world.time + (rand(100-WOUND_BONE_HEAD_TIME_VARIANCE, 100+WOUND_BONE_HEAD_TIME_VARIANCE) * 0.01 * trauma_cycle_cooldown) + +/// If true, allows our superstructure to be modified if we are T3. RCDs can always fix our superstructure. +/datum/wound/blunt/robotic/proc/limb_malleable() + if (!isnull(get_overheat_wound())) + return TRUE + var/burn_damage_to_max = (limb.burn_dam / limb.max_damage) // only exists for the weird case where it cant get a overheat wound + if (burn_damage_to_max >= limb_burn_percent_to_max_threshold_for_malleable) + return TRUE + return FALSE + +/// If we have one, returns a robotic overheat wound of severe severity or higher. Null otherwise. +/datum/wound/blunt/robotic/proc/get_overheat_wound() + RETURN_TYPE(/datum/wound/burn/robotic/overheat) + for (var/datum/wound/found_wound as anything in limb.wounds) + var/datum/wound_pregen_data/pregen_data = found_wound.get_pregen_data() + if (pregen_data.wound_series == WOUND_SERIES_METAL_BURN_OVERHEAT && found_wound.severity >= WOUND_SEVERITY_SEVERE) // meh solution but whateva + return found_wound + return null + +/// If our victim is lying down and is attacked in the chest, effective oscillation damage is multiplied against this. +#define OSCILLATION_ATTACKED_LYING_DOWN_EFFECT_MULT 0.5 + +/// If the attacker is wearing a diag hud, chance of percussive maintenance succeeding is multiplied against this. +#define PERCUSSIVE_MAINTENANCE_DIAG_HUD_CHANCE_MULT 1.5 +/// If our wound has been scanned by a wound analyzer, chance of percussive maintenance succeeding is multiplied against this. +#define PERCUSSIVE_MAINTENANCE_WOUND_SCANNED_CHANCE_MULT 1.5 +/// If the attacker is NOT our victim, chance of percussive maintenance succeeding is multiplied against this. +#define PERCUSSIVE_MAINTENANCE_ATTACKER_NOT_VICTIM_CHANCE_MULT 2.5 + +/// Signal handler proc to when our victim has damage applied via apply_damage(), which is a external attack. +/datum/wound/blunt/robotic/proc/victim_attacked(datum/source, damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item) + SIGNAL_HANDLER + + if (def_zone != limb.body_zone) // use this proc since receive damage can also be called for like, chems and shit + return + if(!victim) + return + + var/effective_damage = (damage - blocked) + + var/obj/item/stack/gauze = limb.current_gauze + if(gauze) + effective_damage *= gauze.splint_factor + + switch (limb.body_zone) + + if(BODY_ZONE_CHEST) + var/oscillation_mult = 1 + if (victim.body_position == LYING_DOWN) + oscillation_mult *= OSCILLATION_ATTACKED_LYING_DOWN_EFFECT_MULT + var/oscillation_damage = effective_damage + var/stagger_damage = oscillation_damage * chest_attacked_stagger_mult + if (victim.has_status_effect(/datum/status_effect/determined)) + oscillation_damage *= ROBOTIC_WOUND_DETERMINATION_STAGGER_MOVEMENT_MULT + if ((stagger_damage >= chest_attacked_stagger_minimum_score) && prob(oscillation_damage * chest_attacked_stagger_chance_ratio)) + stagger(stagger_damage * oscillation_mult, attack_direction, attacking_item, shift = stagger_damage * stagger_shake_shift_ratio) + + if(!uses_percussive_maintenance() || damage < percussive_maintenance_damage_min || damage > percussive_maintenance_damage_max || damagetype != BRUTE || sharpness) + return + var/success_chance_mult = 1 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + success_chance_mult *= PERCUSSIVE_MAINTENANCE_WOUND_SCANNED_CHANCE_MULT + var/mob/living/user + if (isatom(attacking_item)) + var/atom/attacking_atom = attacking_item + user = attacking_atom.loc // nullable + + if (istype(user)) + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + success_chance_mult *= PERCUSSIVE_MAINTENANCE_DIAG_HUD_CHANCE_MULT + + if (user != victim) + success_chance_mult *= PERCUSSIVE_MAINTENANCE_ATTACKER_NOT_VICTIM_CHANCE_MULT // encourages people to get other people to beat the shit out of their limbs + if (prob(percussive_maintenance_repair_chance * success_chance_mult)) + handle_percussive_maintenance_success(attacking_item, user) + else + handle_percussive_maintenance_failure(attacking_item, user) + +#undef OSCILLATION_ATTACKED_LYING_DOWN_EFFECT_MULT +#undef PERCUSSIVE_MAINTENANCE_DIAG_HUD_CHANCE_MULT +#undef PERCUSSIVE_MAINTENANCE_WOUND_SCANNED_CHANCE_MULT +#undef PERCUSSIVE_MAINTENANCE_ATTACKER_NOT_VICTIM_CHANCE_MULT + +/// The percent, in decimal, of a stagger's shake() duration, that will be used in a addtimer() to queue aftershock(). +#define STAGGER_PERCENT_OF_SHAKE_DURATION_TO_AFTERSHOCK_DELAY 0.65 // 1 = happens at the end, .5 = happens halfway through + +/// Causes an oscillation, which 1. has a chance to move our victim away from the attacker, and 2. after a delay, calls aftershock(). +/datum/wound/blunt/robotic/proc/stagger(stagger_score, attack_direction, obj/item/attacking_item, from_movement, shake_duration = base_stagger_shake_duration, shift, knockdown_ratio = stagger_aftershock_knockdown_ratio) + if (oscillating) + return + + var/self_message = "Your [limb.plaintext_zone] oscillates" + var/message = "[victim]'s [limb.plaintext_zone] oscillates" + if (attacking_item) + message += " from the impact" + else if (from_movement) + message += " from the movement" + message += "!" + self_message += "! You might be able to avoid an aftershock by stopping and waiting..." + + if (isnull(attack_direction)) + attack_direction = get_dir(victim, attacking_item) + + if (!isnull(attack_direction) && prob(stagger_score * stagger_movement_chance_ratio)) + to_chat(victim, span_warning("The force of the blow sends you reeling!")) + var/turf/target_loc = get_step(victim, attack_direction) + victim.Move(target_loc) + + victim.visible_message(span_warning(message), ignored_mobs = victim) + to_chat(victim, span_warning(self_message)) + victim.balloon_alert(victim, "oscillation! stop moving") + + victim.Shake(pixelshiftx = shift, pixelshifty = shift, duration = shake_duration) + var/aftershock_delay = (shake_duration * STAGGER_PERCENT_OF_SHAKE_DURATION_TO_AFTERSHOCK_DELAY) + var/knockdown_time = stagger_score * knockdown_ratio + addtimer(CALLBACK(src, PROC_REF(aftershock), stagger_score, attack_direction, attacking_item, world.time, knockdown_time), aftershock_delay) + oscillating = TRUE + +#undef STAGGER_PERCENT_OF_SHAKE_DURATION_TO_AFTERSHOCK_DELAY + +#define AFTERSHOCK_GRACE_THRESHOLD_PERCENT 0.33 // lower mult = later grace period = more forgiving + +/** + * Timer proc from stagger(). + * + * Based on chance, causes items to be dropped, knockdown to be applied, and/or screenshake to occur. + * Chance is massively reduced if the victim isn't moving. + */ +/datum/wound/blunt/robotic/proc/aftershock(stagger_score, attack_direction, obj/item/attacking_item, stagger_starting_time, knockdown_time) + if (!still_exists()) + return FALSE + + var/message = "The oscillations from your [limb.plaintext_zone] spread, " + var/limb_message = "causing " + var/limb_affected + + var/stopped_moving_grace_threshold = (world.time - ((world.time - stagger_starting_time) * AFTERSHOCK_GRACE_THRESHOLD_PERCENT)) + var/victim_stopped_moving = (last_time_victim_moved <= stopped_moving_grace_threshold) + if (victim_stopped_moving) + stagger_score *= aftershock_stopped_moving_score_mult + + if (prob(stagger_score * stagger_drop_chance_ratio)) + limb_message += "your hands" + victim.drop_all_held_items() + limb_affected = TRUE + + if (prob(stagger_score * stagger_fall_chance_ratio)) + if (limb_affected) + limb_message += " and " + limb_message += "your legs" + victim.Knockdown(knockdown_time) + limb_affected = TRUE + + if (prob(stagger_score * stagger_camera_shake_chance_ratio)) + if (limb_affected) + limb_message += " and " + limb_message += "your head" + shake_camera(victim, base_aftershock_camera_shake_duration, base_aftershock_camera_shake_strength) + limb_affected = TRUE + + if (limb_affected) + message += "[limb_message] to shake uncontrollably!" + else + message += "but pass harmlessly" + if (victim_stopped_moving) + message += " thanks to your stillness" + message += "." + + to_chat(victim, span_danger(message)) + victim.balloon_alert(victim, "oscillation over") + + oscillating = FALSE + +#undef AFTERSHOCK_GRACE_THRESHOLD_PERCENT + +/// Called when percussive maintenance succeeds at its random roll. +/datum/wound/blunt/robotic/proc/handle_percussive_maintenance_success(attacking_item, mob/living/user) + victim.visible_message(span_green("[victim]'s [limb.plaintext_zone] rattles from the impact, but looks a lot more secure!"), \ + span_green("Your [limb.plaintext_zone] rattles into place!")) + remove_wound() + +/// Called when percussive maintenance fails at its random roll. +/datum/wound/blunt/robotic/proc/handle_percussive_maintenance_failure(attacking_item, mob/living/user) + to_chat(victim, span_warning("Your [limb.plaintext_zone] rattles around, but you don't sense any sign of improvement.")) + +/// If our victim has no gravity, the effects of movement are multiplied by this. +#define VICTIM_MOVED_NO_GRAVITY_EFFECT_MULT 0.5 +/// If our victim is resting, or is walking and isnt forced to move, the effects of movement are multiplied by this. +#define VICTIM_MOVED_CAREFULLY_EFFECT_MULT 0.25 + +/// Signal handler proc that applies movements affect to our victim if they were moved. +/datum/wound/blunt/robotic/proc/victim_moved(datum/source, atom/old_loc, dir, forced, list/old_locs) + SIGNAL_HANDLER + + var/overall_mult = 1 + + var/obj/item/stack/gauze = limb.current_gauze + if (gauze) + overall_mult *= gauze.splint_factor + if (!victim.has_gravity(get_turf(victim))) + overall_mult *= VICTIM_MOVED_NO_GRAVITY_EFFECT_MULT + else if (victim.body_position == LYING_DOWN || (!forced && victim.move_intent == MOVE_INTENT_WALK)) + overall_mult *= VICTIM_MOVED_CAREFULLY_EFFECT_MULT + if (victim.has_status_effect(/datum/status_effect/determined)) + overall_mult *= ROBOTIC_WOUND_DETERMINATION_MOVEMENT_EFFECT_MOD + if (limb.grasped_by) + overall_mult *= ROBOTIC_BLUNT_GRASPED_MOVEMENT_MULT + + overall_mult *= get_buckled_movement_consequence_mult(victim.buckled) + + if (limb.body_zone == BODY_ZONE_CHEST) + var/stagger_chance = chest_movement_stagger_chance * overall_mult + if (prob(stagger_chance)) + stagger(base_movement_stagger_score, shake_duration = base_stagger_movement_shake_duration, from_movement = TRUE, shift = movement_stagger_shift, knockdown_ratio = stagger_aftershock_knockdown_movement_ratio) + + last_time_victim_moved = world.time + +#undef VICTIM_MOVED_NO_GRAVITY_EFFECT_MULT +#undef VICTIM_MOVED_CAREFULLY_EFFECT_MULT + +/// If our victim is buckled to a generic object, movement effects will be multiplied against this. +#define VICTIM_BUCKLED_BASE_MOVEMENT_EFFECT_MULT 0.5 +/// If our victim is buckled to a medical bed (e.g. rollerbed), movement effects will be multiplied against this. +#define VICTIM_BUCKLED_ROLLER_BED_MOVEMENT_EFFECT_MULT 0.05 + +/// Returns a multiplier to our movement effects based on what our victim is buckled to. +/datum/wound/blunt/robotic/proc/get_buckled_movement_consequence_mult(atom/movable/buckled_to) + if (!buckled_to) + return 1 + + if (istype(buckled_to, /obj/structure/bed/medical)) + return VICTIM_BUCKLED_ROLLER_BED_MOVEMENT_EFFECT_MULT + else + return VICTIM_BUCKLED_BASE_MOVEMENT_EFFECT_MULT + +#undef VICTIM_BUCKLED_BASE_MOVEMENT_EFFECT_MULT +#undef VICTIM_BUCKLED_ROLLER_BED_MOVEMENT_EFFECT_MULT + +/// If this wound can be treated in its current state by just hitting it with a low force object. Exists for conditional logic, e.g. "Should we respond +/// to percussive maintenance right now?". Critical blunt uses this to only react when the limb is malleable and superstructure is broken. +/datum/wound/blunt/robotic/proc/uses_percussive_maintenance() + return FALSE + +#undef ROBOTIC_WOUND_DETERMINATION_MOVEMENT_EFFECT_MOD +#undef ROBOTIC_WOUND_DETERMINATION_STAGGER_MOVEMENT_MULT + +#undef ROBOTIC_BLUNT_GRASPED_MOVEMENT_MULT diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T1.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T1.dm new file mode 100644 index 00000000000000..9cd2ae0adbbc0f --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T1.dm @@ -0,0 +1,65 @@ +/datum/wound/blunt/robotic/moderate + name = "Loosened Screws" + desc = "Various semi-external fastening instruments have loosened, causing components to jostle, inhibiting limb control." + treat_text = "Recommend topical re-fastening of instruments with a screwdriver, though percussive maintenance via low-force bludgeoning may suffice - \ + albeit at risk of worsening the injury." + examine_desc = "appears to be loosely secured" + occur_text = "jostles awkwardly and seems to slightly unfasten" + severity = WOUND_SEVERITY_MODERATE + simple_treat_text = "Bandaging the wound will reduce the impact until it's screws are secured - which is faster if done by \ + someone else, a roboticist, an engineer, or with a diagnostic HUD." + homemade_treat_text = "In a pinch, percussive maintenance can reset the screws - the chance of which is increased if done by someone else or \ + with a diagnostic HUD!" + status_effect_type = /datum/status_effect/wound/blunt/robotic/moderate + treatable_tools = list(TOOL_SCREWDRIVER) + interaction_efficiency_penalty = 1.2 + limp_slowdown = 2.5 + limp_chance = 30 + threshold_penalty = 20 + can_scar = FALSE + a_or_from = "from" + +/datum/wound_pregen_data/blunt_metal/loose_screws + abstract = FALSE + wound_path_to_generate = /datum/wound/blunt/robotic/moderate + viable_zones = list(BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) + threshold_minimum = 30 + +/datum/wound/blunt/robotic/moderate/uses_percussive_maintenance() + return TRUE + +/datum/wound/blunt/robotic/moderate/treat(obj/item/potential_treater, mob/user) + if (potential_treater.tool_behaviour == TOOL_SCREWDRIVER) + fasten_screws(potential_treater, user) + return TRUE + + return ..() + +/// The main treatment for T1 blunt. Uses a screwdriver, guaranteed to always work, better with a diag hud. Removes the wound. +/datum/wound/blunt/robotic/moderate/proc/fasten_screws(obj/item/screwdriver_tool, mob/user) + if (!screwdriver_tool.tool_start_check()) + return + + var/delay_mult = 1 + + if (user == victim) + delay_mult *= 3 + + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + delay_mult *= 0.5 + + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.5 + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + victim.visible_message(span_notice("[user] begins fastening the screws of [their_or_other] [limb.plaintext_zone]..."), \ + span_notice("You begin fastening the screws of [your_or_other] [limb.plaintext_zone]...")) + + if (!screwdriver_tool.use_tool(target = victim, user = user, delay = (10 SECONDS * delay_mult), volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return + + victim.visible_message(span_green("[user] finishes fastening [their_or_other] [limb.plaintext_zone]!"), \ + span_green("You finish fastening [your_or_other] [limb.plaintext_zone]!")) + + remove_wound() diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T2.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T2.dm new file mode 100644 index 00000000000000..68bac1fe12bf05 --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T2.dm @@ -0,0 +1,52 @@ +/datum/wound/blunt/robotic/secures_internals/severe + name = "Detached Fastenings" + desc = "Various fastening devices are extremely loose and solder has disconnected at multiple points, causing significant jostling of internal components and \ + noticable limb dysfunction." + treat_text = "Fastening of bolts and screws by a qualified technician (though bone gel may suffice in the absence of one) followed by re-soldering." + examine_desc = "jostles with every move, solder visibly broken" + occur_text = "visibly cracks open, solder flying everywhere" + severity = WOUND_SEVERITY_SEVERE + + simple_treat_text = "If on the chest, walk, grasp it, splint, rest or buckle yourself to something to reduce movement effects. \ + Afterwards, get someone else, ideally a robo/engi to screwdriver/wrench it, and then re-solder it!" + homemade_treat_text = "If unable to screw/wrench, bone gel can, over time, secure inner components at risk of corrossion. \ + Alternatively, crowbar the limb open to expose the internals - this will make it easier to re-secure them, but has a high risk of shocking you, \ + so use insulated gloves. This will cripple the limb, so use it only as a last resort!" + + wound_flags = (ACCEPTS_GAUZE|MANGLES_EXTERIOR|SPLINT_OVERLAY|CAN_BE_GRASPED) + treatable_by = list(/obj/item/stack/medical/bone_gel) + status_effect_type = /datum/status_effect/wound/blunt/robotic/severe + treatable_tools = list(TOOL_WELDER, TOOL_CROWBAR) + + interaction_efficiency_penalty = 2 + limp_slowdown = 6 + limp_chance = 60 + + brain_trauma_group = BRAIN_TRAUMA_MILD + trauma_cycle_cooldown = 1.5 MINUTES + + threshold_penalty = 40 + + base_movement_stagger_score = 40 + + chest_attacked_stagger_chance_ratio = 5 + chest_attacked_stagger_mult = 3 + + chest_movement_stagger_chance = 3 + + stagger_aftershock_knockdown_ratio = 0.3 + stagger_aftershock_knockdown_movement_ratio = 0.2 + + a_or_from = "from" + + ready_to_secure_internals = TRUE + ready_to_resolder = FALSE + + scar_keyword = "bluntsevere" + +/datum/wound_pregen_data/blunt_metal/fastenings + abstract = FALSE + + wound_path_to_generate = /datum/wound/blunt/robotic/secures_internals/severe + + threshold_minimum = 65 diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T3.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T3.dm new file mode 100644 index 00000000000000..aa85498108aa5c --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/robotic_blunt_T3.dm @@ -0,0 +1,385 @@ +/datum/wound/blunt/robotic/secures_internals/critical + name = "Collapsed Superstructure" + desc = "The superstructure has totally collapsed in one or more locations, causing extreme internal oscillation with every move and massive limb dysfunction" + treat_text = "Reforming of superstructure via either RCD or manual molding, followed by typical treatment of loosened internals. \ + To manually mold, the limb must be aggressively grabbed and welded held to it to make it malleable (though attacking it til thermal overload may be adequate) \ + followed by firmly grasping and molding the limb with heat-resistant gloves." + occur_text = "caves in on itself, damaged solder and shrapnel flying out in a miniature explosion" + examine_desc = "has caved in, with internal components visible through gaps in the metal" + severity = WOUND_SEVERITY_CRITICAL + + disabling = TRUE + + simple_treat_text = "If on the chest, walk, grasp it, splint, rest or buckle yourself to something to reduce movement effects. \ + Afterwards, get someone, ideally a robo/engi to firmly grasp the limb and hold a welder to it. Then, have them use their hands to mold the metal - \ + careful though, it's hot! An RCD can skip all this, but is hard to come by. Afterwards, have them screw/wrench and then re-solder the limb!" + + homemade_treat_text = "The metal can be made malleable by repeated application of a welder, to a severe burn. Afterwards, a plunger can reset the metal, \ + as can percussive maintenance. After the metal is reset, if unable to screw/wrench, bone gel can, over time, secure inner components at risk of corrossion. \ + Alternatively, crowbar the limb open to expose the internals - this will make it easier to re-secure them, but has a high risk of shocking you, \ + so use insulated gloves. This will cripple the limb, so use it only as a last resort!" + + interaction_efficiency_penalty = 2.8 + limp_slowdown = 8 + limp_chance = 80 + threshold_penalty = 60 + + brain_trauma_group = BRAIN_TRAUMA_SEVERE + trauma_cycle_cooldown = 2.5 MINUTES + + scar_keyword = "bluntcritical" + + status_effect_type = /datum/status_effect/wound/blunt/robotic/critical + + sound_effect = 'sound/effects/wounds/crack2.ogg' + + wound_flags = (ACCEPTS_GAUZE|MANGLES_EXTERIOR|SPLINT_OVERLAY|CAN_BE_GRASPED) + treatable_by = list(/obj/item/stack/medical/bone_gel) + status_effect_type = /datum/status_effect/wound/blunt/robotic/critical + treatable_tools = list(TOOL_WELDER, TOOL_CROWBAR) + + base_movement_stagger_score = 55 + + base_aftershock_camera_shake_duration = 1.75 SECONDS + base_aftershock_camera_shake_strength = 1 + + chest_attacked_stagger_chance_ratio = 6.5 + chest_attacked_stagger_mult = 4 + + chest_movement_stagger_chance = 14 + + aftershock_stopped_moving_score_mult = 0.3 + + stagger_aftershock_knockdown_ratio = 0.5 + stagger_aftershock_knockdown_movement_ratio = 0.3 + + percussive_maintenance_repair_chance = 3 + percussive_maintenance_damage_max = 6 + + regen_time_needed = 60 SECONDS + gel_damage = 20 + + ready_to_secure_internals = FALSE + ready_to_resolder = FALSE + + a_or_from = "a" + + /// Has the first stage of our treatment been completed? E.g. RCDed, manually molded... + var/superstructure_remedied = FALSE + +/datum/wound_pregen_data/blunt_metal/superstructure + abstract = FALSE + wound_path_to_generate = /datum/wound/blunt/robotic/secures_internals/critical + threshold_minimum = 125 + +/datum/wound/blunt/robotic/secures_internals/critical/item_can_treat(obj/item/potential_treater) + if(!superstructure_remedied) + if(istype(potential_treater, /obj/item/construction/rcd)) + return TRUE + if(limb_malleable() && istype(potential_treater, /obj/item/plunger)) + return TRUE + return ..() + +/datum/wound/blunt/robotic/secures_internals/critical/check_grab_treatments(obj/item/potential_treater, mob/user) + if(potential_treater.tool_behaviour == TOOL_WELDER && (!superstructure_remedied && !limb_malleable())) + return TRUE + return ..() + +/datum/wound/blunt/robotic/secures_internals/critical/treat(obj/item/item, mob/user) + if(!superstructure_remedied) + if(istype(item, /obj/item/construction/rcd)) + return rcd_superstructure(item, user) + if(uses_percussive_maintenance() && istype(item, /obj/item/plunger)) + return plunge(item, user) + if(item.tool_behaviour == TOOL_WELDER && !limb_malleable() && isliving(victim.pulledby)) + var/mob/living/living_puller = victim.pulledby + if (living_puller.grab_state >= GRAB_AGGRESSIVE) // only let other people do this + return heat_metal(item, user) + return ..() + +/datum/wound/blunt/robotic/secures_internals/critical/try_handling(mob/living/carbon/human/user) + if(user.pulling != victim || user.zone_selected != limb.body_zone) + return FALSE + + if(superstructure_remedied || !limb_malleable()) + return FALSE + + if(user.grab_state < GRAB_AGGRESSIVE) + to_chat(user, span_warning("You must have [victim] in an aggressive grab to manipulate [victim.p_their()] [lowertext(name)]!")) + return TRUE + + user.visible_message(span_danger("[user] begins softly pressing against [victim]'s collapsed [limb.plaintext_zone]..."), \ + span_notice("You begin softly pressing against [victim]'s collapsed [limb.plaintext_zone]..."), \ + ignored_mobs = victim) + to_chat(victim, span_userdanger("[user] begins pressing against your collapsed [limb.plaintext_zone]!")) + + var/delay_mult = 1 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.75 + + if(!do_after(user, 8 SECONDS, target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return + mold_metal(user) + return TRUE + +/// If the user turns combat mode on after they start to mold metal, our limb takes this much brute damage. +#define MOLD_METAL_SABOTAGE_BRUTE_DAMAGE 30 // really punishing +/// Our limb takes this much brute damage on a failed mold metal attempt. +#define MOLD_METAL_FAILURE_BRUTE_DAMAGE 5 +/// If the user's hand is unprotected from heat when they mold metal, we do this much burn damage to it. +#define MOLD_METAL_HAND_BURNT_BURN_DAMAGE 5 +/// Gloves must be above or at this threshold to cause the user to not be burnt apon trying to mold metal. +#define MOLD_METAL_HEAT_RESISTANCE_THRESHOLD 1000 // less than the black gloves max resist +/** + * Standard treatment for 1st step of T3, after the limb has been made malleable. Done via aggrograb. + * High chance to work, very high with robo/engi wires and diag hud. + * Can be sabotaged by switching to combat mode. + * Deals brute to the limb on failure. + * Burns the hand of the user if its not insulated. + */ +/datum/wound/blunt/robotic/secures_internals/critical/proc/mold_metal(mob/living/carbon/human/user) + var/chance = 60 + + var/knows_wires = FALSE + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + chance *= 2 + knows_wires = TRUE + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + chance *= 1.25 + knows_wires = TRUE + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + chance *= 2 + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + if (knows_wires) + chance *= 1.25 + else + chance *= 2 + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + + if ((user != victim && user.combat_mode)) + user.visible_message(span_bolddanger("[user] molds [their_or_other] [limb.plaintext_zone] into a really silly shape! What a goofball!"), \ + span_danger("You maliciously mold [victim]'s [limb.plaintext_zone] into a weird shape, damaging it in the process!"), ignored_mobs = victim) + to_chat(victim, span_userdanger("[user] molds your [limb.plaintext_zone] into a weird shape, damaging it in the process!")) + + limb.receive_damage(brute = MOLD_METAL_SABOTAGE_BRUTE_DAMAGE, wound_bonus = CANT_WOUND, damage_source = user) + else if (prob(chance)) + user.visible_message(span_green("[user] carefully molds [their_or_other] [limb.plaintext_zone] into the proper shape!"), \ + span_green("You carefully mold [victim]'s [limb.plaintext_zone] into the proper shape!"), ignored_mobs = victim) + to_chat(victim, span_green("[user] carefully molds your [limb.plaintext_zone] into the proper shape!")) + to_chat(user, span_green("[capitalize(your_or_other)] [limb.plaintext_zone] has been molded into the proper shape! Your next step is to use a screwdriver/wrench to secure your internals.")) + set_superstructure_status(TRUE) + else + user.visible_message(span_danger("[user] accidentally molds [their_or_other] [limb.plaintext_zone] into the wrong shape!"), \ + span_danger("You accidentally mold [your_or_other] [limb.plaintext_zone] into the wrong shape!"), ignored_mobs = victim) + to_chat(victim, span_userdanger("[user] accidentally molds your [limb.plaintext_zone] into the wrong shape!")) + + limb.receive_damage(brute = MOLD_METAL_FAILURE_BRUTE_DAMAGE, damage_source = user, wound_bonus = CANT_WOUND) + + var/sufficiently_insulated_gloves = FALSE + var/obj/item/clothing/gloves/worn_gloves = user.gloves + if ((worn_gloves?.heat_protection & HANDS) && worn_gloves?.max_heat_protection_temperature && worn_gloves.max_heat_protection_temperature >= MOLD_METAL_HEAT_RESISTANCE_THRESHOLD) + sufficiently_insulated_gloves = TRUE + + if (sufficiently_insulated_gloves || HAS_TRAIT(user, TRAIT_RESISTHEAT) || HAS_TRAIT(user, TRAIT_RESISTHEATHANDS)) + return + + to_chat(user, span_danger("You burn your hand on [victim]'s [limb.plaintext_zone]!")) + var/obj/item/bodypart/affecting = user.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm") + affecting?.receive_damage(burn = MOLD_METAL_HAND_BURNT_BURN_DAMAGE, damage_source = limb) + +#undef MOLD_METAL_SABOTAGE_BRUTE_DAMAGE +#undef MOLD_METAL_FAILURE_BRUTE_DAMAGE +#undef MOLD_METAL_HAND_BURNT_BURN_DAMAGE +#undef MOLD_METAL_HEAT_RESISTANCE_THRESHOLD + +/** + * A "safe" way to give our victim a T2 burn wound. Requires an aggrograb, and a welder. This is required to mold metal, the 1st step of treatment. + * Guaranteed to work. After a delay, causes a T2 burn wound with no damage. + * Can be sabotaged by enabling combat mode to cause a T3. + */ +/datum/wound/blunt/robotic/secures_internals/critical/proc/heat_metal(obj/item/welder, mob/living/user) + if (!welder.tool_use_check()) + return TRUE + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + + user?.visible_message(span_danger("[user] carefully holds [welder] to [their_or_other] [limb.plaintext_zone], slowly heating it..."), \ + span_warning("You carefully hold [welder] to [your_or_other] [limb.plaintext_zone], slowly heating it..."), ignored_mobs = victim) + + var/delay_mult = 1 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.75 + + if (!welder.use_tool(target = victim, user = user, delay = 10 SECONDS * delay_mult, volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + var/wound_path = /datum/wound/burn/robotic/overheat/severe + if (user != victim && user.combat_mode) + wound_path = /datum/wound/burn/robotic/overheat/critical // it really isnt that bad, overheat wounds are a bit funky + user.visible_message(span_danger("[user] heats [victim]'s [limb.plaintext_zone] aggressively, overheating it far beyond the necessary point!"), \ + span_danger("You heat [victim]'s [limb.plaintext_zone] aggressively, overheating it far beyond the necessary point!"), ignored_mobs = victim) + to_chat(victim, span_userdanger("[user] heats your [limb.plaintext_zone] aggressively, overheating it far beyond the necessary point!")) + + var/datum/wound/burn/robotic/overheat/overheat_wound = new wound_path + overheat_wound.apply_wound(limb, wound_source = welder) + + to_chat(user, span_green("[capitalize(your_or_other)] [limb.plaintext_zone] is now heated, allowing it to be molded! Your next step is to have someone physically reset the superstructure with their hands.")) + return TRUE + +/// Cost of an RCD to quickly fix our broken in raw matter +#define ROBOTIC_T3_BLUNT_WOUND_RCD_COST 25 +/// Cost of an RCD to quickly fix our broken in silo material +#define ROBOTIC_T3_BLUNT_WOUND_RCD_SILO_COST ROBOTIC_T3_BLUNT_WOUND_RCD_COST / 4 + +/// The "premium" treatment for 1st step of T3. Requires an RCD. Guaranteed to work, but can cause damage if delay is high. +/datum/wound/blunt/robotic/secures_internals/critical/proc/rcd_superstructure(obj/item/construction/rcd/treating_rcd, mob/user) + if (!treating_rcd.tool_use_check()) + return TRUE + + var/has_enough_matter = (treating_rcd.get_matter(user) > ROBOTIC_T3_BLUNT_WOUND_RCD_COST) + var/silo_has_enough_materials = (treating_rcd.get_silo_iron() > ROBOTIC_T3_BLUNT_WOUND_RCD_SILO_COST) + + if (!silo_has_enough_materials && has_enough_matter) + return TRUE + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + + var/base_time = 10 SECONDS + var/delay_mult = 1 + var/knows_wires = FALSE + if (victim == user) + delay_mult *= 3 // real slow + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.75 + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + delay_mult *= 0.5 + knows_wires = TRUE + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + delay_mult *= 0.5 // engis are accustomed to using RCDs + knows_wires = TRUE + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + if (knows_wires) + delay_mult *= 0.85 + else + delay_mult *= 0.5 + + var/final_time = (base_time * delay_mult) + var/misused = (final_time > base_time) // if we damage the limb when we're done + + if (user) + var/misused_text = (misused ? "unsteadily " : "") + + var/message = "[user]'s RCD whirs to life as it begins [misused_text]replacing the damaged superstructure of [their_or_other] [limb.plaintext_zone]..." + var/self_message = "Your RCD whirs to life as it begins [misused_text]replacing the damaged superstructure of [your_or_other] [limb.plaintext_zone]..." + + if (misused) // warning span if misused, notice span otherwise + message = span_danger(message) + self_message = span_danger(self_message) + else + message = span_notice(message) + self_message = span_notice(self_message) + + user.visible_message(message, self_message) + + if (!treating_rcd.use_tool(target = victim, user = user, delay = final_time, volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + playsound(get_turf(treating_rcd), 'sound/machines/ping.ogg', 75) // celebration! we did it + set_superstructure_status(TRUE) + + var/use_amount = (silo_has_enough_materials ? ROBOTIC_T3_BLUNT_WOUND_RCD_SILO_COST : ROBOTIC_T3_BLUNT_WOUND_RCD_COST) + treating_rcd.useResource(use_amount, user) + + if (user) + var/misused_text = (misused ? ", though it replaced a bit more than it should've..." : "!") + var/message = "[user]'s RCD lets out a small ping as it finishes replacing the superstructure of [their_or_other] [limb.plaintext_zone][misused_text]" + var/self_message = "Your RCD lets out a small ping as it finishes replacing the superstructure of [your_or_other] [limb.plaintext_zone][misused_text]" + if (misused) + message = span_danger(message) + self_message = span_danger(self_message) + else + message = span_green(message) + self_message = span_green(self_message) + + user.visible_message(message, self_message) + if (misused) + limb.receive_damage(brute = 10, damage_source = treating_rcd, wound_bonus = CANT_WOUND) + // the double message is fine here, since the first message also tells you if you fucked up and did some damage + to_chat(user, span_green("The superstructure has been reformed! Your next step is to secure the internals via a screwdriver/wrench.")) + return TRUE + +#undef ROBOTIC_T3_BLUNT_WOUND_RCD_COST +#undef ROBOTIC_T3_BLUNT_WOUND_RCD_SILO_COST + +/** + * Goofy but practical, this is the superior ghetto self-tend of T3's first step compared to percussive maintenance. + * Still requires the limb to be malleable, but has a high chance of success and doesn't burn your hand, but gives worse bonuses for wires/HUD. + */ +/datum/wound/blunt/robotic/secures_internals/critical/proc/plunge(obj/item/plunger/treating_plunger, mob/user) + if (!treating_plunger.tool_use_check()) + return TRUE + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + user?.visible_message(span_notice("[user] begins plunging at the dents on [their_or_other] [limb.plaintext_zone] with [treating_plunger]..."), \ + span_green("You begin plunging at the dents on [your_or_other] [limb.plaintext_zone] with [treating_plunger]...")) + + var/delay_mult = 1 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.75 + + delay_mult /= treating_plunger.plunge_mod + + if (!treating_plunger.use_tool(target = victim, user = user, delay = 8 SECONDS * delay_mult, volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + var/success_chance = 80 + if (victim == user) + success_chance *= 0.6 + + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + success_chance *= 1.25 + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + success_chance *= 1.1 + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + success_chance *= 1.25 // its kinda alien to do this, so even people with the wires get the full bonus of diag huds + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + success_chance *= 1.5 + + if (prob(success_chance)) + user?.visible_message(span_green("[victim]'s [limb.plaintext_zone] lets out a sharp POP as [treating_plunger] forces it into its normal position!"), \ + span_green("[victim]'s [limb.plaintext_zone] lets out a sharp POP as your [treating_plunger] forces it into its normal position!")) + to_chat(user, span_green("[capitalize(your_or_other)] [limb.plaintext_zone]'s structure has been reset to it's proper position! Your next step is to secure it with a screwdriver/wrench, though bone gel would also work.")) + set_superstructure_status(TRUE) + else + user?.visible_message(span_danger("[victim]'s [limb.plaintext_zone] splinters from [treating_plunger]'s plunging!"), \ + span_danger("[capitalize(your_or_other)] [limb.plaintext_zone] splinters from your [treating_plunger]'s plunging!")) + limb.receive_damage(brute = 5, damage_source = treating_plunger) + + return TRUE + +/datum/wound/blunt/robotic/secures_internals/critical/handle_percussive_maintenance_success(attacking_item, mob/living/user) + var/your_or_other = (user == victim ? "your" : "[victim]'s") + victim.visible_message(span_green("[victim]'s [limb.plaintext_zone] gets smashed into a proper shape!"), \ + span_green("Your [limb.plaintext_zone] gets smashed into a proper shape!")) + + var/user_message = "[capitalize(your_or_other)] [limb.plaintext_zone]'s superstructure has been reset! Your next step is to screwdriver/wrench the internals, \ + though if you're desperate enough to use percussive maintenance, you might want to either use a crowbar or bone gel..." + to_chat(user, span_green(user_message)) + + set_superstructure_status(TRUE) + +/datum/wound/blunt/robotic/secures_internals/critical/handle_percussive_maintenance_failure(attacking_item, mob/living/user) + to_chat(victim, span_danger("Your [limb.plaintext_zone] only deforms more from the impact...")) + limb.receive_damage(brute = 1, damage_source = attacking_item, wound_bonus = CANT_WOUND) + +/datum/wound/blunt/robotic/secures_internals/critical/uses_percussive_maintenance() + return (!superstructure_remedied && limb_malleable()) + +/// Transitions our steps by setting both superstructure and secure internals readiness. +/datum/wound/blunt/robotic/secures_internals/critical/proc/set_superstructure_status(remedied) + superstructure_remedied = remedied + ready_to_secure_internals = remedied diff --git a/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm b/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm new file mode 100644 index 00000000000000..9dd515813efe60 --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/blunt/secures_internals.dm @@ -0,0 +1,388 @@ +/// A subtype of blunt wounds that has a "secure internals" step +/datum/wound/blunt/robotic/secures_internals + /// Our current counter for gel + gauze regeneration + var/regen_time_elapsed = 0 SECONDS + /// Time needed for gel to secure internals. + var/regen_time_needed = 30 SECONDS + + /// If we have used bone gel to secure internals. + var/gelled = FALSE + /// Total brute damage taken over the span of [regen_time_needed] deciseconds when we gel our limb. + var/gel_damage = 10 // brute in total + + /// If we are ready to begin screwdrivering or gelling our limb. + var/ready_to_secure_internals = FALSE + /// If our external plating has been torn open and we can access our internals without a tool + var/crowbarred_open = FALSE + /// If internals are secured, and we are ready to weld our limb closed and end the wound + var/ready_to_resolder = TRUE + +/datum/wound/blunt/robotic/secures_internals/handle_process(seconds_per_tick, times_fired) + . = ..() + + if (!victim || IS_IN_STASIS(victim)) + return + + if (gelled) + regen_time_elapsed += ((seconds_per_tick SECONDS) / 2) + if(victim.body_position == LYING_DOWN) + if(SPT_PROB(30, seconds_per_tick)) + regen_time_elapsed += 1 SECONDS + if(victim.IsSleeping() && SPT_PROB(30, seconds_per_tick)) + regen_time_elapsed += 1 SECONDS + + var/effective_damage = ((gel_damage / (regen_time_needed / 10)) * seconds_per_tick) + var/obj/item/stack/gauze = limb.current_gauze + if (gauze) + effective_damage *= gauze.splint_factor + limb.receive_damage(effective_damage, wound_bonus = CANT_WOUND, damage_source = src) + if(effective_damage && prob(33)) + var/gauze_text = (gauze?.splint_factor ? ", although the [gauze] helps to prevent some of the leakage" : "") + to_chat(victim, span_danger("Your [limb.plaintext_zone] sizzles as some gel leaks and warps the exterior metal[gauze_text]...")) + + if(regen_time_elapsed > regen_time_needed) + if(!victim || !limb) + qdel(src) + return + to_chat(victim, span_green("The gel within your [limb.plaintext_zone] has fully hardened, allowing you to re-solder it!")) + gelled = FALSE + ready_to_resolder = TRUE + ready_to_secure_internals = FALSE + set_disabling(FALSE) + +/datum/wound/blunt/robotic/secures_internals/modify_desc_before_span(desc) + . = ..() + + var/use_exclamation = FALSE + + if (!limb.current_gauze) // gauze covers it up + if (crowbarred_open) + . += ", [span_notice("and is violently torn open, internals visible to the outside")]" + use_exclamation = TRUE + if (gelled) + . += ", [span_notice("with fizzling blue surgical gel leaking out of the cracks")]" + use_exclamation = TRUE + if (use_exclamation) + . += "!" + +/datum/wound/blunt/robotic/secures_internals/get_scanner_description(mob/user) + . = ..() + + var/to_add = get_wound_status() + if (!isnull(to_add)) + . += "\nWound status: [to_add]" + +/datum/wound/blunt/robotic/secures_internals/get_simple_scanner_description(mob/user) + . = ..() + + var/to_add = get_wound_status() + if (!isnull(to_add)) + . += "\nWound status: [to_add]" + +/// Returns info specific to the dynamic state of the wound. +/datum/wound/blunt/robotic/secures_internals/proc/get_wound_status(mob/user) + if (crowbarred_open) + . += "The limb has been torn open, allowing ease of access to internal components, but also disabling it. " + if (gelled) + . += "Bone gel has been applied, causing progressive corrosion of the metal, but eventually securing the internals. " + +/datum/wound/blunt/robotic/secures_internals/item_can_treat(obj/item/potential_treater, mob/user) + if (potential_treater.tool_behaviour == TOOL_WELDER || potential_treater.tool_behaviour == TOOL_CAUTERY) + if (ready_to_resolder) + return TRUE + + if (ready_to_secure_internals) + if (item_can_secure_internals(potential_treater)) + return TRUE + + return ..() + +/datum/wound/blunt/robotic/secures_internals/treat(obj/item/potential_treater, mob/user) + if (ready_to_secure_internals) + if (istype(potential_treater, /obj/item/stack/medical/bone_gel)) + return apply_gel(potential_treater, user) + else if (!crowbarred_open && potential_treater.tool_behaviour == TOOL_CROWBAR) + return crowbar_open(potential_treater, user) + else if (item_can_secure_internals(potential_treater)) + return secure_internals_normally(potential_treater, user) + else if (ready_to_resolder && (potential_treater.tool_behaviour == TOOL_WELDER) || (potential_treater.tool_behaviour == TOOL_CAUTERY)) + return resolder(potential_treater, user) + + return ..() + +/// Returns TRUE if the item can be used in our 1st step (2nd if T3) of repairs. +/datum/wound/blunt/robotic/secures_internals/proc/item_can_secure_internals(obj/item/potential_treater) + return (potential_treater.tool_behaviour == TOOL_SCREWDRIVER || potential_treater.tool_behaviour == TOOL_WRENCH || istype(potential_treater, /obj/item/stack/medical/bone_gel)) + +#define CROWBAR_OPEN_SELF_TEND_DELAY_MULT 2 +#define CROWBAR_OPEN_KNOWS_ROBO_WIRES_DELAY_MULT 0.5 +#define CROWBAR_OPEN_KNOWS_ENGI_WIRES_DELAY_MULT 0.5 +#define CROWBAR_OPEN_HAS_DIAG_HUD_DELAY_MULT 0.5 +#define CROWBAR_OPEN_WOUND_SCANNED_DELAY_MULT 0.5 +/// If our limb is essential, damage dealt to it by tearing it open will be multiplied against this. +#define CROWBAR_OPEN_ESSENTIAL_LIMB_DAMAGE_MULT 1.5 + +/// The "power" put into electrocute_act whenever someone gets shocked when they crowbar open our limb +#define CROWBAR_OPEN_SHOCK_POWER 20 +/// The brute damage done to this limb (doubled on essential limbs) when it is crowbarred open +#define CROWBAR_OPEN_BRUTE_DAMAGE 20 + +/** + * Available during the "secure internals" step of T2 and T3. Requires a crowbar. Low-quality ghetto option. + * + * Tears open the limb, exposing internals. This massively increases the chance of secure internals succeeding, and removes the self-tend malice. + * + * Deals significant damage to the limb, and shocks the user (causing failure) if victim is alive, this limb is wired, and user is not insulated. + */ +/datum/wound/blunt/robotic/secures_internals/proc/crowbar_open(obj/item/crowbarring_item, mob/living/user) + if (!crowbarring_item.tool_start_check()) + return TRUE + + var/delay_mult = 1 + if (user == victim) + delay_mult *= CROWBAR_OPEN_SELF_TEND_DELAY_MULT + + var/knows_wires = FALSE + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + delay_mult *= CROWBAR_OPEN_KNOWS_ROBO_WIRES_DELAY_MULT + knows_wires = TRUE + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + delay_mult *= CROWBAR_OPEN_KNOWS_ENGI_WIRES_DELAY_MULT + knows_wires = TRUE + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + if (knows_wires) + delay_mult *= (CROWBAR_OPEN_HAS_DIAG_HUD_DELAY_MULT * 1.5) + else + delay_mult *= CROWBAR_OPEN_HAS_DIAG_HUD_DELAY_MULT + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= CROWBAR_OPEN_WOUND_SCANNED_DELAY_MULT + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + + var/self_message = span_warning("You start prying open [your_or_other] [limb.plaintext_zone] with [crowbarring_item]...") + + user?.visible_message(span_bolddanger("[user] starts prying open [their_or_other] [limb.plaintext_zone] with [crowbarring_item]!"), self_message, ignored_mobs = list(victim)) + + var/victim_message + if (user != victim) // this exists so we can do a userdanger + victim_message = span_userdanger("[user] starts prying open your [limb.plaintext_zone] with [crowbarring_item]!") + else + victim_message = self_message + to_chat(victim, victim_message) + + playsound(get_turf(crowbarring_item), 'sound/machines/airlock_alien_prying.ogg', 30, TRUE) + if (!crowbarring_item.use_tool(target = victim, user = user, delay = (7 SECONDS * delay_mult), volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + var/limb_can_shock = (victim.stat != DEAD && limb.biological_state & BIO_WIRED) + var/stunned = FALSE + + var/message + + if (user && limb_can_shock) + var/electrocute_flags = (SHOCK_KNOCKDOWN|SHOCK_NO_HUMAN_ANIM|SHOCK_SUPPRESS_MESSAGE) + var/stun_chance = 100 + + if (HAS_TRAIT(user, TRAIT_SHOCKIMMUNE)) + stun_chance = 0 + + else if (iscarbon(user)) // doesn't matter if we're shock immune, it's set to 0 anyway + var/mob/living/carbon/carbon_user = user + if (carbon_user.gloves) + stun_chance *= carbon_user.gloves.siemens_coefficient + + if (ishuman(user)) + var/mob/living/carbon/human/human_user = user + stun_chance *= human_user.physiology.siemens_coeff + stun_chance *= carbon_user.dna.species.siemens_coeff + + if (stun_chance && prob(stun_chance)) + electrocute_flags &= ~SHOCK_KNOCKDOWN + electrocute_flags &= ~SHOCK_NO_HUMAN_ANIM + stunned = TRUE + + message = span_boldwarning("[user] is shocked by [their_or_other] [limb.plaintext_zone], [user.p_their()] crowbar slipping as [user.p_they()] briefly convulse!") + self_message = span_userdanger("You are shocked by [your_or_other] [limb.plaintext_zone], causing your crowbar to slip out!") + if (user != victim) + victim_message = span_userdanger("[user] is shocked by your [limb.plaintext_zone] in [user.p_their()] efforts to tear it open!") + + var/shock_damage = CROWBAR_OPEN_SHOCK_POWER + if (limb.current_gauze) + shock_damage *= limb.current_gauze.splint_factor // always good to let gauze do something + user.electrocute_act(shock_damage, limb, flags = electrocute_flags) + + if (!stunned) + var/other_shock_text = "" + var/self_shock_text = "" + if (!limb_can_shock) + other_shock_text = ", and is striken by golden bolts of electricity" + self_shock_text = ", but are immediately shocked by the electricity contained within" + message = span_boldwarning("[user] tears open [their_or_other] [limb.plaintext_zone] with [user.p_their()] crowbar[other_shock_text]!") + self_message = span_warning("You tear open [your_or_other] [limb.plaintext_zone] with your crowbar[self_shock_text]!") + if (user != victim) + victim_message = span_userdanger("Your [limb.plaintext_zone] fragments and splinters as [user] tears it open with [user.p_their()] crowbar!") + + playsound(get_turf(crowbarring_item), 'sound/effects/bang.ogg', 35, TRUE) // we did it! + to_chat(user, span_green("You've torn [your_or_other] [limb.plaintext_zone] open, heavily damaging it but making it a lot easier to screwdriver the internals!")) + var/damage = CROWBAR_OPEN_BRUTE_DAMAGE + if (limb_essential()) // can't be disabled + damage *= CROWBAR_OPEN_ESSENTIAL_LIMB_DAMAGE_MULT + limb.receive_damage(brute = CROWBAR_OPEN_BRUTE_DAMAGE, wound_bonus = CANT_WOUND, damage_source = crowbarring_item) + set_torn_open(TRUE) + + if (user == victim) + victim_message = self_message + + user.visible_message(message, self_message, ignored_mobs = list(victim)) + to_chat(victim, victim_message) + return TRUE + +#undef CROWBAR_OPEN_SELF_TEND_DELAY_MULT +#undef CROWBAR_OPEN_KNOWS_ROBO_WIRES_DELAY_MULT +#undef CROWBAR_OPEN_KNOWS_ENGI_WIRES_DELAY_MULT +#undef CROWBAR_OPEN_HAS_DIAG_HUD_DELAY_MULT +#undef CROWBAR_OPEN_WOUND_SCANNED_DELAY_MULT +#undef CROWBAR_OPEN_ESSENTIAL_LIMB_DAMAGE_MULT + +#undef CROWBAR_OPEN_BRUTE_DAMAGE +#undef CROWBAR_OPEN_SHOCK_POWER + +/// Sets [crowbarred_open] to the new value. If we werent originally disabling, or if we arent currently and we're torn open, we set disabling to true. +/datum/wound/blunt/robotic/secures_internals/proc/set_torn_open(torn_open_state) + // if we aren't disabling but we were torn open, OR if we aren't disabling by default + var/should_update_disabling = ((!disabling && torn_open_state) || !initial(disabling)) + + crowbarred_open = torn_open_state + if(should_update_disabling) + set_disabling(torn_open_state) + +/// If, on a secure internals attempt, we have less than this chance to succeed, we warn the user. +#define SECURE_INTERNALS_CONFUSED_CHANCE_THRESHOLD 25 +#define SECURE_INTERNALS_FAILURE_BRUTE_DAMAGE 5 + +/** + * The primary way of performing the secure internals step for T2/T3. Uses a screwdriver/wrench. Very hard to do by yourself, or without a diag hud/wire knowledge. + * Roboticists/engineers have a very high chance of succeeding. + * Deals some brute damage on failure, but moves to the final step of treatment (re-soldering) on success. + * + * If [crowbarred_open], made far more likely and remove the self-tend malice. + */ +/datum/wound/blunt/robotic/secures_internals/proc/secure_internals_normally(obj/item/securing_item, mob/user) + if (!securing_item.tool_start_check()) + return TRUE + + var/chance = 10 + var/delay_mult = 1 + + if (user == victim) + if (!crowbarred_open) + chance *= 0.2 + delay_mult *= 2 + + var/knows_wires = FALSE + if (crowbarred_open) + chance *= 4 // even self-tends get a high chance of success if torn open! + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + chance *= 8 // almost guaranteed if its not self surgery - guaranteed with diag hud + delay_mult *= 0.75 + knows_wires = TRUE + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + chance *= 5.5 + delay_mult *= 0.85 + knows_wires = TRUE + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + if (knows_wires) + chance *= 1.25 // ((10 * 8) * 1.25) = 100% + else + chance *= 4 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + chance *= 1.5 // youre not intended to fix this by yourself this way + delay_mult *= 0.8 + + var/confused = (chance < SECURE_INTERNALS_CONFUSED_CHANCE_THRESHOLD) // generate chance beforehand, so we can use this var + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + user?.visible_message(span_notice("[user] begins the delicate operation of securing the internals of [their_or_other] [limb.plaintext_zone]..."), \ + span_notice("You begin the delicate operation of securing the internals of [your_or_other] [limb.plaintext_zone]...")) + if (confused) + to_chat(user, span_warning("You are confused by the layout of [your_or_other] [limb.plaintext_zone]! A diagnostic hud would help, as would knowing robo/engi wires! You could also tear the limb open with a crowbar, or get someone else to help.")) + + if (!securing_item.use_tool(target = victim, user = user, delay = (10 SECONDS * delay_mult), volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + if (prob(chance)) + user?.visible_message(span_green("[user] finishes securing the internals of [their_or_other] [limb.plaintext_zone]!"), \ + span_green("You finish securing the internals of [your_or_other] [limb.plaintext_zone]!")) + to_chat(user, span_green("[capitalize(your_or_other)] [limb.plaintext_zone]'s internals are now secure! Your next step is to weld/cauterize it.")) + ready_to_secure_internals = FALSE + ready_to_resolder = TRUE + else + user?.visible_message(span_danger("[user] screws up and accidentally damages [their_or_other] [limb.plaintext_zone]!")) + limb.receive_damage(brute = SECURE_INTERNALS_FAILURE_BRUTE_DAMAGE, damage_source = securing_item, wound_bonus = CANT_WOUND) + + return TRUE + +#undef SECURE_INTERNALS_CONFUSED_CHANCE_THRESHOLD +#undef SECURE_INTERNALS_FAILURE_BRUTE_DAMAGE + +/** + * "Premium" ghetto option of the secure internals step for T2/T3. Requires bone gel. Guaranteed to work. + * Deals damage over time and disables the limb, but finishes the step afterwards. + */ +/datum/wound/blunt/robotic/secures_internals/proc/apply_gel(obj/item/stack/medical/bone_gel/gel, mob/user) + if (gelled) + to_chat(user, span_warning("[user == victim ? "Your" : "[victim]'s"] [limb.plaintext_zone] is already filled with bone gel!")) + return TRUE + + var/delay_mult = 1 + if (victim == user) + delay_mult *= 0.5 + + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.75 + + user.visible_message(span_danger("[user] begins hastily applying [gel] to [victim]'s [limb.plaintext_zone]..."), span_warning("You begin hastily applying [gel] to [user == victim ? "your" : "[victim]'s"] [limb.plaintext_zone], disregarding the acidic effect it seems to have on the metal...")) + + if (!do_after(user, (8 SECONDS * delay_mult), target = victim, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + gel.use(1) + if(user != victim) + user.visible_message(span_notice("[user] finishes applying [gel] to [victim]'s [limb.plaintext_zone], emitting a fizzing noise!"), span_notice("You finish applying [gel] to [victim]'s [limb.plaintext_zone]!"), ignored_mobs=victim) + to_chat(victim, span_userdanger("[user] finishes applying [gel] to your [limb.plaintext_zone], and you can hear the sizzling of the metal...")) + else + victim.visible_message(span_notice("[victim] finishes applying [gel] to [victim.p_their()] [limb.plaintext_zone], emitting a funny fizzing sound!"), span_notice("You finish applying [gel] to your [limb.plaintext_zone], and you can hear the sizzling of the metal...")) + + gelled = TRUE + set_disabling(TRUE) + processes = TRUE + return TRUE + +/** + * The final step of T2/T3, requires a welder/cautery. Guaranteed to work. Cautery is slower. + * Once complete, removes the wound entirely. + */ +/datum/wound/blunt/robotic/secures_internals/proc/resolder(obj/item/welding_item, mob/user) + if (!welding_item.tool_start_check()) + return TRUE + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + victim.visible_message(span_notice("[user] begins re-soldering [their_or_other] [limb.plaintext_zone]..."), \ + span_notice("You begin re-soldering [your_or_other] [limb.plaintext_zone]...")) + + var/delay_mult = 1 + if (welding_item.tool_behaviour == TOOL_CAUTERY) + delay_mult *= 3 // less efficient + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.75 + + if (!welding_item.use_tool(target = victim, user = user, delay = 7 SECONDS * delay_mult, volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + victim.visible_message(span_green("[user] finishes re-soldering [their_or_other] [limb.plaintext_zone]!"), \ + span_notice("You finish re-soldering [your_or_other] [limb.plaintext_zone]!")) + remove_wound() + return TRUE diff --git a/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm b/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm new file mode 100644 index 00000000000000..24ac18eeab6ba5 --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/robotic_burns.dm @@ -0,0 +1,441 @@ +#define OVERHEAT_ON_STASIS_HEAT_MULT 0.25 +/// At 100% hercuri composition, a spray of reagents will have its effective chem temp reduced by this. 50%, reduced by half this, etc. +#define ROBOTIC_BURN_REAGENT_EXPOSURE_HERCURI_MAX_HEAT_DECREMENT 60 +/// At 100% hercuri composition, a spray of reagents will have its heat shock damage reduced by this. 50%, reduced by half this, etc. +#define ROBOTIC_BURN_REAGENT_EXPOSURE_HERCURI_HEAT_SHOCK_MULT_DECREMENT 0.3 + +/datum/wound_pregen_data/burnt_metal + abstract = TRUE + required_limb_biostate = BIO_METAL + required_wounding_types = list(WOUND_BURN) + wound_series = WOUND_SERIES_METAL_BURN_OVERHEAT + +/datum/wound_pregen_data/burnt_metal/generate_scar_priorities() + return list("[BIO_METAL]") + +/datum/wound/burn/robotic/overheat + treat_text = "Introduction of a cold environment or lowering of body temperature." + + simple_desc = "Metals are overheated, increasing damage taken significantly and raising body temperature!" + simple_treat_text = "Ideally cryogenics, but any source of low body temperature can work. Spraying with spray bottles/extinguishers/showers \ + will quickly cool the limb, but cause damage. Hercuri is especially effective in quick cooling. \ + Clothing reduces the water/hercuri that makes it to the metal, and gauze binds it and reduces the damage taken." + homemade_treat_text = "You can also splash any liquid on it for a rather inefficient and damaging coolant!" + + default_scar_file = METAL_SCAR_FILE + + wound_flags = (ACCEPTS_GAUZE|SPLINT_OVERLAY|CAN_BE_GRASPED) // gauze binds the metal and makes it resistant to thermal shock + + processes = TRUE + + /// The virtual temperature of the chassis. Crucial for many things, like our severity, the temp we transfer, our cooling damage, etc. + var/chassis_temperature + + /// The lower bound of the chassis_temperature we can start with. + var/starting_temperature_min = (BODYTEMP_NORMAL + 200) + /// The upper bound of the chassis_temperature we can start with. + var/starting_temperature_max = (BODYTEMP_NORMAL + 250) + + /// If [chassis_temperature] goes below this, we reduce in severity. + var/cooling_threshold = (BODYTEMP_NORMAL + 3) + /// If [chassis_temperature] goes above this, we increase in severity. + var/heating_threshold = (BODYTEMP_NORMAL + 300) + + /// The buffer in kelvin we will subtract from the chassis_temperature of a wound we demote to. + var/cooling_demote_buffer = 60 + /// The buffer in kelvin we will add to the chassis_temperature of a wound we promote to. + var/heating_promote_buffer = 60 + + /// The coefficient of heat transfer we will use when shifting our temp to the victim's. + var/bodytemp_coeff = 0.04 + /// For every degree below normal bodytemp, we will multiply our incoming temperature by 1 + degrees * this. Allows incentivization of freezing yourself instead of just waiting. + var/bodytemp_difference_expose_bonus_ratio = 0.035 + /// The coefficient of heat transfer we will use when shifting our victim's temp to ours. + var/outgoing_bodytemp_coeff = 0 + /// The mult applied to heat output when we are on a important limb, e.g. head/torso. + var/important_outgoing_mult = 1.2 + /// The coefficient of heat transfer we will use when shifting our temp to a turf. + var/turf_coeff = 0.02 + + /// The maximum temperature we can cause by heating our victim. + var/max_outgoing_temperature = BODYTEMP_HEAT_WOUND_LIMIT - 1 + + /// If we are hit with burn damage, the damage will be multiplied against this to determine the effective heat we get. + var/incoming_damage_heat_coeff = 3 + + /// The coefficient of heat transfer we will use when receiving heat from reagent contact. + var/base_reagent_temp_coefficient = 0.02 + + /// The ratio of temp shift -> brute damage. Careful with this value, it can make stuff really really nasty. + var/heat_shock_delta_to_damage_ratio = 0.12 + /// The minimum heat difference we must have on reagent contact to cause heat shock damage. + var/heat_shock_minimum_delta = 5 + + /// If we are sprayed with a extinguisher/shower with obscuring clothing on (think clothing that prevents surgery), the effect is multiplied against this. + var/sprayed_with_reagent_clothed_mult = 0.15 + + /// The wound we demote to when we go below cooling threshold. If null, removes us. + var/datum/wound/burn/robotic/demotes_to + /// The wound we promote to when we go above heating threshold. + var/datum/wound/burn/robotic/promotes_to + + /// The color of the light we will generate. + var/light_color + /// The power of the light we will generate. + var/light_power + /// The range of the light we will generate. + var/light_range + + /// The glow we have attached to our victim, to simulate our limb glowing. + var/obj/effect/dummy/lighting_obj/moblight/mob_glow + +/datum/wound/burn/robotic/overheat/New(temperature) + chassis_temperature = (isnull(temperature) ? get_random_starting_temperature() : temperature) + + return ..() + +/datum/wound/burn/robotic/overheat/Destroy() + QDEL_NULL(mob_glow) + return ..() + +/datum/wound/burn/robotic/overheat/set_victim(mob/living/new_victim) + if (victim) + QDEL_NULL(mob_glow) + UnregisterSignal(victim, COMSIG_MOB_AFTER_APPLY_DAMAGE) + UnregisterSignal(victim, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS) + if (new_victim) + mob_glow = new_victim.mob_light(light_range, light_power, light_color) + mob_glow.set_light_on(TRUE) + RegisterSignal(new_victim, COMSIG_MOB_AFTER_APPLY_DAMAGE, PROC_REF(victim_attacked)) + RegisterSignal(new_victim, COMSIG_ATOM_AFTER_EXPOSE_REAGENTS, PROC_REF(victim_exposed_to_reagents)) + + return ..() + +/datum/wound/burn/robotic/overheat/proc/get_random_starting_temperature() + return LERP(starting_temperature_min, starting_temperature_max, rand()) // LERP since we deal with decimals + +/datum/wound/burn/robotic/get_limb_examine_description() + return span_warning("The metal on this limb is glowing radiantly.") + +/datum/wound/burn/robotic/overheat/handle_process(seconds_per_tick, times_fired) + if (isnull(victim)) + var/turf/our_turf = get_turf(limb) + if (!isnull(our_turf)) + expose_temperature(our_turf.GetTemperature(), (turf_coeff * seconds_per_tick)) + return + if (outgoing_bodytemp_coeff <= 0) + return + var/statis_mult = 1 + if (IS_IN_STASIS(victim)) // stasis heavily reduces the ingoing and outgoing transfer of heat + statis_mult *= OVERHEAT_ON_STASIS_HEAT_MULT + + var/difference_from_average = max((BODYTEMP_NORMAL - victim.bodytemperature), 0) + var/difference_mult = 1 + (difference_from_average * bodytemp_difference_expose_bonus_ratio) + if (expose_temperature(victim.bodytemperature, (bodytemp_coeff * seconds_per_tick * statis_mult * difference_mult))) + return + var/mult = outgoing_bodytemp_coeff + if (limb_essential()) + mult *= important_outgoing_mult + var/adjustment_allowed = max((max_outgoing_temperature - victim.bodytemperature), 0) + var/amount_to_adjust = min((((chassis_temperature - victim.bodytemperature) * mult) * TEMPERATURE_DAMAGE_COEFFICIENT * seconds_per_tick * statis_mult), adjustment_allowed) + victim.adjust_bodytemperature(amount_to_adjust) + +/// Signal proc for when our victim is externally attacked. Increases chassis temp based on burn damage received. +/datum/wound/burn/robotic/overheat/proc/victim_attacked(datum/source, damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction, attacking_item) + SIGNAL_HANDLER + + if (def_zone != limb.body_zone) // use this proc since receive damage can also be called for like, chems and shit + return + + if (!victim) + return + + if (damagetype != BURN) + return + + if (wound_bonus == CANT_WOUND) + return + + var/effective_damage = (damage - blocked) + if (effective_damage <= 0) + return + + expose_temperature((chassis_temperature + effective_damage), incoming_damage_heat_coeff) + +/** + * Signal proc for when our victim is exposed to reagents, obviously. + * + * Equalizes temp to the reagent temp, but also causes thermal shock. Basically, does damage based on the temp differential. + * Clothes reduce the effects massively. Hercuri reduces the thermal shock and gets a special temp buff. + */ +/datum/wound/burn/robotic/overheat/proc/victim_exposed_to_reagents(datum/signal_source, list/reagents, datum/reagents/source, methods, volume_modifier, show_message) + SIGNAL_HANDLER + + var/reagent_coeff = base_reagent_temp_coefficient + if (!get_location_accessible(victim, limb.body_zone)) + if (ishuman(victim)) + // hi! its niko! small rant + // this proc has no goddamn reason to be on human, it could so easily just have used a proc on carbon that would get the required bodyparts to check + // but no. it had to hardcode the list in the proc itself so its impossible to modularly fix this + // so instead we just say fuck it and hope to god only human subtypes get this wound + // tldr; ryll why + var/mob/living/carbon/human/human_victim = victim + for (var/obj/item/clothing/iter_clothing as anything in human_victim.get_clothing_on_part(limb)) + if (iter_clothing.clothing_flags & THICKMATERIAL) + return + + reagent_coeff *= sprayed_with_reagent_clothed_mult + + if (istype(source.my_atom, /obj/effect/particle_effect/water/extinguisher)) // this used to be a lot, lot more modular, but sadly reagent temps/volumes and shit are horribly inconsistant + expose_temperature(source.chem_temp, (2.55 * reagent_coeff), TRUE) + return + + if (istype(source.my_atom, /obj/machinery/shower)) + expose_temperature(source.chem_temp, (15 * volume_modifier * reagent_coeff), TRUE) + return + + var/total_reagent_amount = 0 + var/hercuri_amount = 0 + for (var/datum/reagent/iterated_reagent as anything in reagents) + total_reagent_amount += reagents[iterated_reagent] + if (iterated_reagent.type == /datum/reagent/medicine/c2/hercuri) + hercuri_amount = reagents[iterated_reagent] + + var/hercuri_percent = (hercuri_amount / total_reagent_amount) + + var/hercuri_chem_temp_increment = (ROBOTIC_BURN_REAGENT_EXPOSURE_HERCURI_MAX_HEAT_DECREMENT * hercuri_percent) + var/local_chem_temp = max(source.chem_temp - hercuri_chem_temp_increment, 0) + + var/heat_shock_damage_mult = 1 - (ROBOTIC_BURN_REAGENT_EXPOSURE_HERCURI_HEAT_SHOCK_MULT_DECREMENT * hercuri_percent) + + expose_temperature(local_chem_temp, (reagent_coeff * volume_modifier * total_reagent_amount), TRUE, heat_shock_damage_mult = heat_shock_damage_mult) + +/// Adjusts chassis_temperature by the delta between temperature and itself, multiplied by coeff. +/// If heat_shock is TRUE, limb will receive brute damage based on the delta. +/datum/wound/burn/robotic/overheat/proc/expose_temperature(temperature, coeff = 0.02, heat_shock = FALSE, heat_shock_damage_mult = 1) + var/temp_delta = (temperature - chassis_temperature) * coeff + + var/unclamped_new_temperature = (chassis_temperature + temp_delta) + var/clamped_new_temperature + var/heat_adjustment_used + + if(temp_delta > 0) + clamped_new_temperature = min(min(chassis_temperature + max(temp_delta, 1), temperature), heating_threshold) + heat_adjustment_used = (clamped_new_temperature / unclamped_new_temperature) + else + clamped_new_temperature = max(max(chassis_temperature + min(temp_delta, -1), temperature), cooling_threshold) + heat_adjustment_used = (unclamped_new_temperature / clamped_new_temperature) + + if (heat_shock && abs(temp_delta) > heat_shock_minimum_delta) + var/gauze_mult = 1 + var/obj/item/stack/gauze = limb.current_gauze + if (gauze) + gauze_mult *= (gauze.splint_factor) * 0.4 // very very effective + + if (limb.grasped_by) + gauze_mult *= 0.7 // hold it down yourself + + if (victim) + var/gauze_or_not = (!isnull(gauze) ? ", but [gauze] helps to keep it together" : "") + var/clothing_text = (!get_location_accessible(victim, limb.body_zone) ? ", [victim.p_their()] clothing absorbing some of the liquid" : "") + victim.visible_message(span_warning("[victim]'s [limb.plaintext_zone] strains from the thermal shock[clothing_text][gauze_or_not]!")) + playsound(victim, 'sound/items/welder.ogg', 25) + + var/damage = (((abs(temp_delta) * heat_shock_delta_to_damage_ratio) * gauze_mult) * heat_shock_damage_mult) * heat_adjustment_used + limb.receive_damage(brute = damage, wound_bonus = CANT_WOUND) + + chassis_temperature = clamped_new_temperature // can only be decimal or 1, so it can only reduce the intensity of the adjustment + + return check_temperature() + +/// Removes, demotes, or promotes ourselves to a new wound type if our temperature is past a heating/cooling threshold. +/datum/wound/burn/robotic/overheat/proc/check_temperature() + if (chassis_temperature <= cooling_threshold) + if (demotes_to) + victim.visible_message(span_green("[victim]'s [limb.plaintext_zone] turns a more pleasant thermal color as it cools down a little..."), span_green("Your [limb.plaintext_zone] seems to cool down a little!")) + replace_wound(new demotes_to(cooling_threshold - cooling_demote_buffer)) + return TRUE + else + victim.visible_message(span_green("[victim]'s [limb.plaintext_zone] simmers gently as it returns to its usual colors!"), span_green("Your [limb.plaintext_zone] simmers gently as it returns to its usual colors!")) + remove_wound() + return TRUE + else if (promotes_to && chassis_temperature >= heating_threshold) + victim.visible_message(span_danger("[victim]'s [limb.plaintext_zone] brightens as it overheats further!"), span_userdanger("Your [limb.plaintext_zone] sizzles and brightens as it overheats further!")) + replace_wound(new promotes_to(heating_threshold + heating_promote_buffer)) + return TRUE + +/// Returns a string with our temperature and heating/cooling thresholds, for use in health analyzers. +/datum/wound/burn/robotic/overheat/proc/get_wound_status_info() + var/current_temp_celcius = round(chassis_temperature - T0C, 0.1) + var/current_temp_fahrenheit = round(chassis_temperature * 1.8-459.67, 0.1) + + var/cool_celcius = round(cooling_threshold - T0C, 0.1) + var/cool_fahrenheit = round(cooling_threshold * 1.8-459.67, 0.1) + + var/heat_celcius = round(heating_threshold - T0C, 0.1) + var/heat_fahrenheit = round(heating_threshold * 1.8-459.67, 0.1) + + return "Its current temperature is [span_blue("[current_temp_celcius ] °C ([current_temp_fahrenheit] °F)")], \ + and needs to cool to [span_nicegreen("[cool_celcius] °C ([cool_fahrenheit] °F)")], but \ + will worsen if heated to [span_purple("[heat_celcius] °C ([heat_fahrenheit] °F)")]." + +/datum/wound/burn/robotic/overheat/get_scanner_description(mob/user) + . = ..() + + . += "\nWound status: [get_wound_status_info()]" + +/datum/wound/burn/robotic/overheat/get_simple_scanner_description(mob/user) + . = ..() + + . += "\nWound status: [get_wound_status_info()]" + +// this wound is unaffected by cryoxadone and pyroxadone +/datum/wound/burn/robotic/overheat/on_xadone(power) + return + +/datum/wound/burn/robotic/overheat/moderate + name = "Transient Overheating" + desc = "External metals have exceeded lower-bound thermal limits and have lost some structural integrity, increasing damage taken as well as the chance to \ + sustain additional wounds." + occur_text = "lets out a slight groan as it turns a dull shade of thermal red" + examine_desc = "is glowing a dull thermal red and giving off heat" + treat_text = "Reduction of body temperature to expedite the passive heat dissipation - or, if thermal shock is to be risked, application of a fire extinguisher/shower." + severity = WOUND_SEVERITY_MODERATE + + damage_multiplier_penalty = 1.15 //1.15x damage taken + + starting_temperature_min = (BODYTEMP_NORMAL + 350) + starting_temperature_max = (BODYTEMP_NORMAL + 400) + + cooling_threshold = (BODYTEMP_NORMAL + 100) + heating_threshold = (BODYTEMP_NORMAL + 500) + + cooling_demote_buffer = 60 + heating_promote_buffer = 100 + + a_or_from = "from" + + // easy to get + threshold_penalty = 30 + + status_effect_type = /datum/status_effect/wound/burn/robotic/moderate + + sound_volume = 20 + + outgoing_bodytemp_coeff = 0.0056 + bodytemp_coeff = 0.006 + + base_reagent_temp_coefficient = 0.03 + heat_shock_delta_to_damage_ratio = 0.2 + + promotes_to = /datum/wound/burn/robotic/overheat/severe + + light_color = COLOR_RED + light_power = 0.1 + light_range = 0.5 + + can_scar = FALSE + +/datum/wound_pregen_data/burnt_metal/transient_overheat + abstract = FALSE + + wound_path_to_generate = /datum/wound/burn/robotic/overheat/moderate + + threshold_minimum = 30 + +/datum/wound/burn/robotic/overheat/severe + name = "Thermal Overload" + desc = "Exterior plating has surpassed critical thermal levels, causing significant failure in structural integrity and overheating of internal systems." + occur_text = "sizzles, the externals turning a dull shade of orange" + examine_desc = "appears discolored and polychromatic, parts of it glowing a dull orange" + treat_text = "Isolation from physical hazards, and accommodation of passive heat dissipation - active cooling may be used, but temperature differentials significantly \ + raise the risk of thermal shock." + severity = WOUND_SEVERITY_SEVERE + + a_or_from = "from" + + threshold_penalty = 65 + + status_effect_type = /datum/status_effect/wound/burn/robotic/severe + damage_multiplier_penalty = 1.25 // 1.25x damage taken + + starting_temperature_min = (BODYTEMP_NORMAL + 550) + starting_temperature_max = (BODYTEMP_NORMAL + 600) + + heating_promote_buffer = 150 + + cooling_threshold = (BODYTEMP_NORMAL + 375) + heating_threshold = (BODYTEMP_NORMAL + 800) + + outgoing_bodytemp_coeff = 0.0053 + bodytemp_coeff = 0.004 + + base_reagent_temp_coefficient = 0.03 + heat_shock_delta_to_damage_ratio = 0.2 + + demotes_to = /datum/wound/burn/robotic/overheat/moderate + promotes_to = /datum/wound/burn/robotic/overheat/critical + + light_color = COLOR_BRIGHT_ORANGE + light_power = 0.8 + light_range = 0.5 + + scar_keyword = "burnsevere" + +/datum/wound_pregen_data/burnt_metal/severe + abstract = FALSE + wound_path_to_generate = /datum/wound/burn/robotic/overheat/severe + threshold_minimum = 80 + +/datum/wound/burn/robotic/overheat/critical + name = "Runaway Exothermy" + desc = "Carapace is beyond melting point, causing catastrophic structural integrity failure as well as massively heating up the subject." + occur_text = "turns a bright shade of radiant white as it sizzles and melts" + examine_desc = "is a blinding shade of white, almost melting from the heat" + treat_text = "Immediate confinement to cryogenics, as rapid overheating and physical vulnerability may occur. Active cooling is not advised, \ + since the thermal shock may be lethal with such a temperature differential." + severity = WOUND_SEVERITY_CRITICAL + + a_or_from = "from" + + sound_effect = 'sound/effects/wounds/sizzle2.ogg' + + threshold_penalty = 100 + + status_effect_type = /datum/status_effect/wound/burn/robotic/critical + + damage_multiplier_penalty = 1.5 //1.5x damage taken + + starting_temperature_min = (BODYTEMP_NORMAL + 1050) + starting_temperature_max = (BODYTEMP_NORMAL + 1100) + + cooling_demote_buffer = 100 + + cooling_threshold = (BODYTEMP_NORMAL + 775) + heating_threshold = INFINITY + + outgoing_bodytemp_coeff = 0.0055 // burn... BURN... + bodytemp_coeff = 0.0025 + + base_reagent_temp_coefficient = 0.03 + heat_shock_delta_to_damage_ratio = 0.2 + + max_outgoing_temperature = BODYTEMP_HEAT_WOUND_LIMIT // critical CAN cause wounds, but only barely + + demotes_to = /datum/wound/burn/robotic/overheat/severe + + wound_flags = (MANGLES_EXTERIOR|ACCEPTS_GAUZE|SPLINT_OVERLAY|CAN_BE_GRASPED) + + light_color = COLOR_VERY_SOFT_YELLOW + light_power = 1.3 + light_range = 1.5 + + scar_keyword = "burncritical" + +/datum/wound_pregen_data/burnt_metal/critical + abstract = FALSE + wound_path_to_generate = /datum/wound/burn/robotic/overheat/critical + threshold_minimum = 140 + +#undef OVERHEAT_ON_STASIS_HEAT_MULT +#undef ROBOTIC_BURN_REAGENT_EXPOSURE_HERCURI_MAX_HEAT_DECREMENT diff --git a/modular_skyrat/modules/medical/code/wounds/synth/robotic_muscle.dm b/modular_skyrat/modules/medical/code/wounds/synth/robotic_muscle.dm new file mode 100644 index 00000000000000..4e91c58f7f675b --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/robotic_muscle.dm @@ -0,0 +1,47 @@ +/datum/wound/muscle/robotic + sound_effect = 'sound/effects/wounds/blood1.ogg' + +/datum/wound_pregen_data/muscle/robotic + required_limb_biostate = (BIO_METAL) + +/datum/wound/muscle/robotic/moderate + name = "Overworked Servo" + desc = "A servo has been overworked, and will operate with reduced efficiency until rested." + treat_text = "A tight splint on the affected limb, as well as plenty of rest and sleep." + examine_desc = "appears to be moving sluggishly" + occur_text = "jitters for a moment before moving sluggishly" + severity = WOUND_SEVERITY_MODERATE + interaction_efficiency_penalty = 1.5 + limp_slowdown = 2 + limp_chance = 30 + threshold_penalty = 15 + status_effect_type = /datum/status_effect/wound/muscle/robotic/moderate + regen_ticks_needed = 90 + +/datum/wound_pregen_data/muscle/robotic/servo + abstract = FALSE + wound_path_to_generate = /datum/wound/muscle/robotic/moderate + threshold_minimum = 35 + +/datum/wound/muscle/robotic/severe + name = "Exhausted Piston" + sound_effect = 'sound/effects/wounds/blood2.ogg' + desc = "An important hydraulic piston has been critically overused, resulting in total dysfunction until it recovers." + treat_text = "A tight splint on the affected limb, as well as plenty of rest and sleep." + examine_desc = "is stiffly limp, the extremities splayed out widely" + occur_text = "goes completely stiff, seeming to lock into position" + severity = WOUND_SEVERITY_SEVERE + interaction_efficiency_penalty = 2 + limp_slowdown = 5 + limp_chance = 40 + threshold_penalty = 35 + disabling = TRUE + status_effect_type = /datum/status_effect/wound/muscle/robotic/severe + regen_ticks_needed = 150 + +/datum/wound_pregen_data/muscle/robotic/hydraulic + abstract = FALSE + + wound_path_to_generate = /datum/wound/muscle/robotic/severe + threshold_minimum = 80 + diff --git a/modular_skyrat/modules/medical/code/wounds/synth/robotic_pierce.dm b/modular_skyrat/modules/medical/code/wounds/synth/robotic_pierce.dm new file mode 100644 index 00000000000000..b7e4f259e5d2af --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/robotic_pierce.dm @@ -0,0 +1,146 @@ +// Pierce +// Slow to rise but high damage overall +// Hard-ish to fix +/datum/wound/electrical_damage/pierce + heat_differential_healing_mult = 0.01 + simple_desc = "Electrical conduits have been pierced open, resulting in a fault that slowly intensifies, but with extreme maximum voltage!" + +/datum/wound_pregen_data/electrical_damage/pierce + abstract = TRUE + wound_series = WOUND_SERIES_WIRE_PIERCE_ELECTRICAL_DAMAGE + required_wounding_types = list(WOUND_PIERCE) + +/datum/wound/burn/electrical_damage/pierce/get_limb_examine_description() + return span_warning("The metal on this limb is pierced open.") + +/datum/wound/electrical_damage/pierce/moderate + name = "Punctured Capacitor" + desc = "A major capacitor has been broken open, causing slow but noticable electrical damage." + occur_text = "shoots out a short stream of sparks" + examine_desc = "is shuddering gently, movements a little weak" + treat_text = "Replacing of damaged wiring, though repairs via wirecutting instruments or sutures may suffice, albeit at limited efficiency. In case of emergency, \ + subject may be subjected to high temperatures to allow solder to reset." + + sound_effect = 'modular_skyrat/modules/medical/sound/robotic_slash_T1.ogg' + + severity = WOUND_SEVERITY_MODERATE + + sound_volume = 30 + + threshold_penalty = 30 + + intensity = 10 SECONDS + processing_full_shock_threshold = 7 MINUTES + + processing_shock_power_per_second_max = 1.2 + processing_shock_power_per_second_min = 1.1 + + processing_shock_stun_chance = 0.5 + processing_shock_spark_chance = 35 + + process_shock_spark_count_max = 1 + process_shock_spark_count_min = 1 + + wirecut_repair_percent = 0.065 // not even faster at this point + wire_repair_percent = 0.026 + + initial_sparks_amount = 1 + + status_effect_type = /datum/status_effect/wound/electrical_damage/pierce/moderate + + a_or_from = "a" + + scar_keyword = "piercemoderate" + +/datum/wound_pregen_data/electrical_damage/pierce/moderate + abstract = FALSE + wound_path_to_generate = /datum/wound/electrical_damage/pierce/moderate + threshold_minimum = 40 + +/datum/wound/electrical_damage/pierce/severe + name = "Penetrated Transformer" + desc = "A major transformer has been pierced, causing slow-to-progess but eventually intense electrical damage." + occur_text = "sputters and goes limp for a moment as it ejects a stream of sparks" + examine_desc = "is shuddering significantly, its servos briefly giving way in a rythmic pattern" + treat_text = "Containment of damaged wiring via gauze, then application of fresh wiring/sutures, or resetting of displaced wiring via wirecutter/retractor." + + sound_effect = 'modular_skyrat/modules/medical/sound/robotic_slash_T2.ogg' + + severity = WOUND_SEVERITY_SEVERE + + sound_volume = 15 + + threshold_penalty = 40 + + intensity = 20 SECONDS + processing_full_shock_threshold = 6.5 MINUTES + + processing_shock_power_per_second_max = 1.6 + processing_shock_power_per_second_min = 1.5 + + processing_shock_stun_chance = 2.5 + processing_shock_spark_chance = 60 + + process_shock_spark_count_max = 2 + process_shock_spark_count_min = 1 + + wirecut_repair_percent = 0.068 + wire_repair_percent = 0.02 + + initial_sparks_amount = 3 + + status_effect_type = /datum/status_effect/wound/electrical_damage/pierce/moderate + + a_or_from = "a" + + scar_keyword = "piercemoderate" + +/datum/wound_pregen_data/electrical_damage/pierce/severe + abstract = FALSE + wound_path_to_generate = /datum/wound/electrical_damage/pierce/severe + threshold_minimum = 60 + +/datum/wound/electrical_damage/pierce/critical + name = "Ruptured PSU" + desc = "The local PSU of this limb has suffered a core rupture, causing a progressive power failure that will slowly intensify into massive electrical damage." + occur_text = "flashes with radiant blue, emitting a noise not unlike a Jacob's Ladder" + examine_desc = "'s PSU is visible, with a sizable hole in the center" + treat_text = "Immediate securing via gauze, followed by emergency cable replacement and securing via wirecutters or hemostat. \ + If the fault has become uncontrollable, extreme heat therapy is recommended." + + severity = WOUND_SEVERITY_CRITICAL + wound_flags = (ACCEPTS_GAUZE|MANGLES_EXTERIOR|CAN_BE_GRASPED|SPLINT_OVERLAY) + + sound_effect = 'modular_skyrat/modules/medical/sound/robotic_slash_T3.ogg' + + sound_volume = 30 + + threshold_penalty = 60 + + intensity = 30 SECONDS + processing_full_shock_threshold = 5.5 MINUTES + + processing_shock_power_per_second_max = 2.2 + processing_shock_power_per_second_min = 2.1 + + processing_shock_stun_chance = 1 + processing_shock_spark_chance = 90 + + process_shock_spark_count_max = 3 + process_shock_spark_count_min = 2 + + wirecut_repair_percent = 0.067 + wire_repair_percent = 0.018 + + initial_sparks_amount = 8 + + status_effect_type = /datum/status_effect/wound/electrical_damage/pierce/moderate + + a_or_from = "a" + + scar_keyword = "piercecritical" + +/datum/wound_pregen_data/electrical_damage/pierce/critical + abstract = FALSE + wound_path_to_generate = /datum/wound/electrical_damage/pierce/critical + threshold_minimum = 110 diff --git a/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm b/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm new file mode 100644 index 00000000000000..a28737520b5fdc --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/synth/robotic_slash.dm @@ -0,0 +1,628 @@ +/// How much damage and progress is reduced when on stasis. +#define ELECTRICAL_DAMAGE_ON_STASIS_MULT 0.15 +/// How much damage and progress is reduced when limb is grasped. +#define ELECTRICAL_DAMAGE_GRASPED_MULT 0.7 +/// How much damage and progress is reduced when our victim lies down. +#define ELECTRICAL_DAMAGE_LYING_DOWN_MULT 0.7 +/// How much progress is reduced when our victim is dead. +#define ELECTRICAL_DAMAGE_DEAD_PROGRESS_MULT 0.2 // they'll be resting to, so this is more like 0.1 + +/// Base time for a wirecutter being used. +#define ELECTRICAL_DAMAGE_WIRECUTTER_BASE_DELAY 8 SECONDS +/// Base time for a cable coil being used. +#define ELECTRICAL_DAMAGE_SUTURE_WIRE_BASE_DELAY 0.8 SECONDS +/// Global damage multiplier for the power a given electrical damage wound will add per tick. +#define ELECTRICAL_DAMAGE_POWER_PER_TICK_MULT 1 +/// Global damage multiplier for how much repairing wiring will reduce intensity. Higher is more. +#define ELECTRICAL_DAMAGE_SUTURE_WIRE_HEALING_AMOUNT_MULT 1 + +/// The minimum shock power we must have available to zap our victim. Must be at least one, since electrocute_act fails if its lower. +#define ELECTRICAL_DAMAGE_MINIMUM_SHOCK_POWER_PER_ZAP 1 +/// The maximum burn damage our limb can have before we refuse to let people who havent aggrograbbed the limb repair it with wires. This is so people can opt to just fix the burn damage. +#define ELECTRICAL_DAMAGE_MAX_BURN_DAMAGE_TO_LET_WIRES_REPAIR 5 + +/datum/wound/electrical_damage + name = "Electrical (Wires) Wound" + + simple_treat_text = "Replacing of broken wiring, or repairing via a wirecutter. Bandaging binds the wiring and reduces intensity buildup, \ + as does firmly grasping the limb - both the victim and someone else can do this. Roboticists/Engineers get a bonus to treatment, as do diagnostic HUDs." + homemade_treat_text = "Sutures can repair the wiring at reduced efficiency, as can retractors. In a pinch, high temperatures can repair the wiring!" + + wound_flags = (ACCEPTS_GAUZE|CAN_BE_GRASPED|SPLINT_OVERLAY) + + treatable_tools = list(TOOL_WIRECUTTER, TOOL_RETRACTOR) + treatable_by = list(/obj/item/stack/medical/suture) + treatable_by_grabbed = list(/obj/item/stack/cable_coil) + + default_scar_file = METAL_SCAR_FILE + + processes = TRUE + + /// How many sparks do we spawn when we're gained? + var/initial_sparks_amount = 1 + + /// How much of our damage is reduced if the target is shock immune. Percent. + var/shock_immunity_self_damage_reduction = 75 + + /// Mult for our damage if we are unimportant. + var/limb_unimportant_damage_mult = 0.8 + /// Mult for our progress if we are unimportant. + var/limb_unimportant_progress_mult = 0.8 + + /// The overall "intensity" of this wound. Goes up to [processing_full_shock_threshold], and is used for determining our effect scaling. Measured in deciseconds. + var/intensity + /// The time, in deciseconds, it takes to reach 100% power. + var/processing_full_shock_threshold = 3 MINUTES + /// If [intensity] is at or below this, we remove ourselves. + var/minimum_intensity = 0 + + /// How much shock power we add to [processing_shock_power_this_tick] per tick. Lower bound + var/processing_shock_power_per_second_min = 0.1 + /// How much shock power we add to [processing_shock_power_this_tick] per tick. Upper bound + var/processing_shock_power_per_second_max = 0.2 + + /// In the case we get below 1 power, we add the power to this buffer and use it next tick. + var/processing_shock_power_this_tick = 0 + /// The chance for each processed shock to stun the user. + var/processing_shock_stun_chance = 0 + /// The chance for each processed shock to spark. + var/processing_shock_spark_chance = 30 + /// The chance for each processed shock to message the user. + var/process_shock_message_chance = 80 + + /// Simple mult for how much of real time is added to [intensity]. + var/seconds_per_intensity_mult = 1 + + /// How many sparks we spawn if a shock sparks. Lower bound + var/process_shock_spark_count_min = 1 + /// How many sparks we spawn if a shock sparks. Upper bound + var/process_shock_spark_count_max = 1 + + // Generally should be less fast than wire, but its effectiveness should increase with severity + /// The percent, in decimal, a successful wirecut use will reduce intensity by. + var/wirecut_repair_percent + // Generally should be lower than wirecut + /// The percent, in decimal, a successful wire use will reduce intensity by. + var/wire_repair_percent + + /// The basic multiplier to all our effects. Damage, progress, etc. + var/overall_effect_mult = 1 + + /// The bodyheat our victim must be at or above to start getting passive healing. + var/heat_thresh_to_heal = (BODYTEMP_HEAT_DAMAGE_LIMIT + 30) + /// The mult that heat differences between normal and bodytemp threshold is multiplied against. Controls passive heat healing. + var/heat_differential_healing_mult = 0.08 + + /// Percent chance for a heat repair to give the victim a message. + var/heat_heal_message_chance = 20 + + /// If [get_intensity_mult()] is at or above this, the limb gets disabled. If null, it will never occur. + var/disable_at_intensity_mult + +/datum/wound_pregen_data/electrical_damage + abstract = TRUE + required_limb_biostate = (BIO_WIRED) + required_wounding_types = list(WOUND_SLASH) + wound_series = WOUND_SERIES_WIRE_SLASH_ELECTRICAL_DAMAGE + +/datum/wound_pregen_data/electrical_damage/generate_scar_priorities() + return list("[BIO_METAL]") // wire scars dont exist so we can just use metal + +/datum/wound/burn/electrical_damage/slash/get_limb_examine_description() + return span_warning("The wiring on this limb is slashed open.") + +/datum/wound/electrical_damage/handle_process(seconds_per_tick, times_fired) + . = ..() + + var/base_mult = get_base_mult() + + var/seconds_per_tick_for_intensity = seconds_per_tick * get_progress_mult() + seconds_per_tick_for_intensity = modify_progress_after_progress_mult(seconds_per_tick_for_intensity, seconds_per_tick) + + adjust_intensity(seconds_per_tick_for_intensity SECONDS) + + if (!victim || victim.stat == DEAD) + return + + var/damage_mult = get_damage_mult(victim) + var/intensity_mult = get_intensity_mult() + + damage_mult *= seconds_per_tick + damage_mult *= intensity_mult + + var/picked_damage = LERP(processing_shock_power_per_second_min, processing_shock_power_per_second_max, rand()) + processing_shock_power_this_tick += (picked_damage * damage_mult) + if (processing_shock_power_this_tick <= ELECTRICAL_DAMAGE_MINIMUM_SHOCK_POWER_PER_ZAP) + return + + var/stun_chance = (processing_shock_stun_chance * intensity_mult) * base_mult + var/spark_chance = (processing_shock_spark_chance * intensity_mult) * base_mult + + var/should_stun = SPT_PROB(stun_chance, seconds_per_tick) + var/should_message = SPT_PROB(process_shock_message_chance, seconds_per_tick) + + zap(victim, + processing_shock_power_this_tick, + stun = should_stun, + spark = SPT_PROB(spark_chance, seconds_per_tick), + animation = should_stun, message = FALSE, + message = should_stun, + tell_victim_if_no_message = should_message, + ignore_immunity = TRUE, + jitter_time = seconds_per_tick, + stutter_time = 0, + delay_stun = TRUE, + knockdown = TRUE, + ignore_gloves = TRUE + ) + processing_shock_power_this_tick = 0 + +/// If someone is aggrograbbing us and targetting our limb, intensity progress is multiplied against this. +#define LIMB_AGGROGRABBED_PROGRESS_MULT 0.5 + +/// Returns the multiplier used by our intensity progress. Intensity increment is multiplied against this. +/datum/wound/electrical_damage/proc/get_progress_mult() + var/progress_mult = get_base_mult() * seconds_per_intensity_mult + + if (!limb_essential()) + progress_mult *= limb_unimportant_progress_mult + + if (isliving(victim.pulledby)) + var/mob/living/living_puller = victim.pulledby + if (living_puller.grab_state >= GRAB_AGGRESSIVE && living_puller.zone_selected == limb.body_zone) + progress_mult *= LIMB_AGGROGRABBED_PROGRESS_MULT // they're holding it down + + if (victim.stat == DEAD) + progress_mult *= ELECTRICAL_DAMAGE_DEAD_PROGRESS_MULT // doesnt totally stop it but slows it down a lot + + return progress_mult +#undef LIMB_AGGROGRABBED_PROGRESS_MULT + +/// Returns the multiplier used by the damage we deal. +/datum/wound/electrical_damage/proc/get_damage_mult(mob/living/target) + SHOULD_BE_PURE(TRUE) + + var/damage_mult = get_base_mult() + + if (!limb_essential()) + damage_mult *= limb_unimportant_damage_mult + + return damage_mult * ELECTRICAL_DAMAGE_POWER_PER_TICK_MULT + +/// Returns the global multiplier used by both progress and damage. +/datum/wound/electrical_damage/proc/get_base_mult() + var/base_mult = 1 + + if (victim) + if (IS_IN_STASIS(victim)) + base_mult *= ELECTRICAL_DAMAGE_ON_STASIS_MULT + if (victim.body_position == LYING_DOWN) + base_mult *= ELECTRICAL_DAMAGE_LYING_DOWN_MULT + if (limb.grasped_by) + base_mult *= ELECTRICAL_DAMAGE_GRASPED_MULT + + if (victim.has_status_effect(/datum/status_effect/determined)) + base_mult *= WOUND_DETERMINATION_BLEED_MOD + + if (HAS_TRAIT(victim, TRAIT_SHOCKIMMUNE)) // it'd be a bit cheesy to just become immune to this, so it only makes it a lot lot better + base_mult *= shock_immunity_self_damage_reduction + + var/splint_mult = (limb.current_gauze ? limb.current_gauze.splint_factor : 1) + base_mult *= splint_mult + + return overall_effect_mult * base_mult + +/// Is called after seconds_for_intensity is modified by get_progress_mult(). +/datum/wound/electrical_damage/proc/modify_progress_after_progress_mult(seconds_for_intensity, seconds_per_tick) + if (!victim) + return seconds_for_intensity + + return seconds_for_intensity - (get_heat_healing() * seconds_per_tick) + +/// Returns how many deciseconds progress should be reduced by, based on the current heat of our victim's body. +/datum/wound/electrical_damage/proc/get_heat_healing(do_message = prob(heat_heal_message_chance)) + var/healing_amount = max((victim.bodytemperature - heat_thresh_to_heal), 0) * heat_differential_healing_mult + if (do_message && healing_amount) + to_chat(victim, span_notice("You feel the solder within your [limb.plaintext_zone] reform and repair your [name]...")) + + return healing_amount + +/// Changes intensity by the given amount, and then updates our status, removing ourselves if fixed. +/datum/wound/electrical_damage/proc/adjust_intensity(to_adjust) + intensity = clamp((intensity + to_adjust), 0, processing_full_shock_threshold) + + if (disable_at_intensity_mult) + set_disabling(get_intensity_mult() >= disable_at_intensity_mult) + + remove_if_fixed() + +/datum/wound/electrical_damage/wound_injury(datum/wound/electrical_damage/old_wound, attack_direction) + . = ..() + + if (old_wound) + intensity = max(intensity, old_wound.intensity) + processing_shock_power_this_tick = old_wound.processing_shock_power_this_tick + + do_sparks(initial_sparks_amount, FALSE, victim) + +/datum/wound/electrical_damage/modify_desc_before_span(desc, mob/user) + . = ..() + + if (limb.current_gauze) + return + + var/intensity_mult = get_intensity_mult() + if (intensity_mult < 0.2 || (victim.stat == DEAD)) + return + + . += ", and " + + var/extra + switch (intensity_mult) + if (0.2 to 0.4) + extra += "[span_deadsay("is letting out some sparks")]" + if (0.4 to 0.6) + extra += "[span_deadsay("is sparking quite a bit")]" + if (0.6 to 0.8) + extra += "[span_deadsay("is practically hemorrhaging sparks")]" + if (0.8 to 1) + extra += "[span_deadsay("has golden bolts of electricity constantly striking the surface")]" + + . += extra + +/datum/wound/electrical_damage/get_scanner_description(mob/user) + . = ..() + + . += "\nWound status: [get_wound_status_info()]" + +/datum/wound/electrical_damage/get_simple_scanner_description(mob/user) + . = ..() + + . += "\nWound status: [get_wound_status_info()]" + +/// Returns a string with our fault intensity and threshold to removal for use in health analyzers. +/datum/wound/electrical_damage/proc/get_wound_status_info() + return "Fault intensity is currently at [span_bold("[get_intensity_mult() * 100]")]%. It must be reduced to [span_blue("[minimum_intensity]")]% to remove the wound." + +// this wound is unaffected by cryoxadone and pyroxadone +/datum/wound/electrical_damage/on_xadone(power) + return + +/datum/wound/electrical_damage/item_can_treat(obj/item/potential_treater, mob/user) + if (istype(potential_treater, /obj/item/stack/cable_coil) && ((user.pulling == victim && user.grab_state >= GRAB_AGGRESSIVE) || (limb.burn_dam <= ELECTRICAL_DAMAGE_MAX_BURN_DAMAGE_TO_LET_WIRES_REPAIR))) + return TRUE // if we're aggrograbbed, or relatively undamaged, go ahead. else, we dont want to impede normal treatment + + return ..() + +/datum/wound/electrical_damage/treat(obj/item/treating_item, mob/user) + if (treating_item.tool_behaviour == TOOL_WIRECUTTER || treating_item.tool_behaviour == TOOL_RETRACTOR) + return wirecut(treating_item, user) + + if (istype(treating_item, /obj/item/stack/medical/suture) || istype(treating_item, /obj/item/stack/cable_coil)) + return suture_wires(treating_item, user) + + return ..() + +/** + * The "trauma" treatment, done with cables/sutures. Sutures get a debuff. + * Low self-tend penalty. + * Very fast, but low value. Eats up wires for breakfast. + * Has limited wire/HUD bonuses. If you're a robo, use a wirecutter instead. + */ +/datum/wound/electrical_damage/proc/suture_wires(obj/item/stack/suturing_item, mob/living/carbon/human/user) + if (!suturing_item.tool_start_check()) + return TRUE + + var/is_suture = (istype(suturing_item, /obj/item/stack/medical/suture)) + + var/change = (processing_full_shock_threshold * wire_repair_percent) * ELECTRICAL_DAMAGE_SUTURE_WIRE_HEALING_AMOUNT_MULT + var/delay_mult = 1 + if (user == victim) + delay_mult *= 1.5 + if (is_suture) + delay_mult *= 2 + var/obj/item/stack/medical/suture/suture_item = suturing_item + var/obj/item/stack/medical/suture/base_suture = /obj/item/stack/medical/suture + change += (suture_item.heal_brute - initial(base_suture.heal_brute)) + + // as this is the trauma treatment, there are less bonuses + // if youre doing this, youre probably doing this on-the-spot + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + delay_mult *= 0.8 + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + delay_mult *= 0.9 + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + delay_mult *= 0.8 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + change *= 1.2 + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + var/replacing_or_suturing = (is_suture ? "repairing some" : "replacing") + while (suturing_item.tool_start_check()) + user?.visible_message(span_danger("[user] begins [replacing_or_suturing] wiring within [their_or_other] [limb.plaintext_zone] with [suturing_item]..."), \ + span_notice("You begin [replacing_or_suturing] wiring within [your_or_other] [limb.plaintext_zone] with [suturing_item]...")) + if (!suturing_item.use_tool(target = victim, user = user, delay = ELECTRICAL_DAMAGE_SUTURE_WIRE_BASE_DELAY * delay_mult, amount = 1, volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + if (user != victim && user.combat_mode) + user?.visible_message(span_danger("[user] mangles some of [their_or_other] [limb.plaintext_zone]'s wiring!"), \ + span_danger("You mangle some of [your_or_other] [limb.plaintext_zone]'s wiring!"), ignored_mobs = victim) + to_chat(victim, span_userdanger("[capitalize(your_or_other)] mangles some of your [limb.plaintext_zone]'s wiring!")) + adjust_intensity(change * 2) + else + var/repairs_or_replaces = (is_suture ? "repairs" : "replaces") + var/repair_or_replace = (is_suture ? "repair" : "replace") + user?.visible_message(span_notice("[user] [repairs_or_replaces] some of [their_or_other] [limb.plaintext_zone]'s wiring!"), \ + span_notice("You [repair_or_replace] some of [your_or_other] [limb.plaintext_zone]'s wiring!")) + adjust_intensity(-change) + victim.balloon_alert(user, "intensity reduced to [get_intensity_mult() * 100]%") + + if (fixed()) + return TRUE + return TRUE + +/** + * The "proper" treatment, done with wirecutters/retractors. Retractors get a debuff. + * High self-tend penalty. + * Slow, but high value. + * Has high wire/HUD bonuses. The ideal treatment for a robo. + */ +/datum/wound/electrical_damage/proc/wirecut(obj/item/wirecutting_tool, mob/living/carbon/human/user) + if (!wirecutting_tool.tool_start_check()) + return TRUE + + var/is_retractor = (wirecutting_tool.tool_behaviour == TOOL_RETRACTOR) + + var/change = (processing_full_shock_threshold * wirecut_repair_percent) + var/delay_mult = 1 + if (user == victim) + delay_mult *= 2.5 + if (is_retractor) + delay_mult *= 2 + change *= 0.8 + var/knows_wires = FALSE + if (HAS_TRAIT(user, TRAIT_KNOW_ROBO_WIRES)) + delay_mult *= 0.9 + change *= 1.7 + knows_wires = TRUE + else if (HAS_TRAIT(user, TRAIT_KNOW_ENGI_WIRES)) + change *= 1.35 + knows_wires = TRUE + if (HAS_TRAIT(user, TRAIT_DIAGNOSTIC_HUD)) + if (knows_wires) + delay_mult *= 0.9 + else + delay_mult *= 0.75 + if (HAS_TRAIT(src, TRAIT_WOUND_SCANNED)) + delay_mult *= 0.8 + + var/their_or_other = (user == victim ? "[user.p_their()]" : "[victim]'s") + var/your_or_other = (user == victim ? "your" : "[victim]'s") + while (wirecutting_tool.tool_start_check()) + user?.visible_message(span_danger("[user] begins resetting misplaced wiring within [their_or_other] [limb.plaintext_zone]..."), \ + span_notice("You begin resetting misplaced wiring within [your_or_other] [limb.plaintext_zone]...")) + if (!wirecutting_tool.use_tool(target = victim, user = user, delay = ELECTRICAL_DAMAGE_WIRECUTTER_BASE_DELAY * delay_mult, volume = 50, extra_checks = CALLBACK(src, PROC_REF(still_exists)))) + return TRUE + + if (user != victim && user.combat_mode) + user?.visible_message(span_danger("[user] mangles some of [their_or_other] [limb.plaintext_zone]'s wiring!"), \ + span_danger("You mangle some of [your_or_other] [limb.plaintext_zone]'s wiring!"), ignored_mobs = victim) + to_chat(victim, span_userdanger("[capitalize(your_or_other)] mangles some of your [limb.plaintext_zone]'s wiring!")) + adjust_intensity(change * 2) + else + user?.visible_message(span_notice("[user] resets some of [their_or_other] [limb.plaintext_zone]'s wiring!"), \ + span_notice("You reset some of [your_or_other] [limb.plaintext_zone]'s wiring!")) + adjust_intensity(-change) + victim.balloon_alert(user, "intensity reduced to [get_intensity_mult() * 100]%") + + if (fixed()) + return TRUE + return TRUE + +/// If fixed() is true, we remove ourselves and return TRUE. FALSE otherwise. +/datum/wound/electrical_damage/proc/remove_if_fixed() + if (fixed()) + to_chat(victim, span_green("Your [limb.plaintext_zone] has recovered from its [name]!")) + remove_wound() + return TRUE + return FALSE + +/// Should we remove ourselves? +/datum/wound/electrical_damage/proc/fixed() + return (intensity <= minimum_intensity || isnull(limb)) + +/// Returns the multiplier we apply to our outgoing damage based off our current intensity. Is always between 0-1. +/datum/wound/electrical_damage/proc/get_intensity_mult() + return (min((intensity / processing_full_shock_threshold), 1)) + +/// Wrapper for electrocute_act +/datum/wound/electrical_damage/proc/zap( + mob/living/target, + damage, + coeff = 1, + stun, + spark = TRUE, + animation = TRUE, + message = TRUE, + ignore_immunity = FALSE, + delay_stun = FALSE, + knockdown = FALSE, + ignore_gloves = FALSE, + tell_victim_if_no_message = TRUE, + jitter_time = 20 SECONDS, + stutter_time = 4 SECONDS, +) + + var/flags = NONE + if (!stun) + flags |= SHOCK_NOSTUN + if (!animation) + flags |= SHOCK_NO_HUMAN_ANIM + if (!message) + flags |= SHOCK_SUPPRESS_MESSAGE + if (tell_victim_if_no_message && target == victim) + to_chat(target, span_warning("Your [limb.plaintext_zone] short-circuits and zaps you!")) + if (ignore_immunity) + flags |= SHOCK_IGNORE_IMMUNITY + if (delay_stun) + flags |= SHOCK_DELAY_STUN + if (knockdown) + flags |= SHOCK_KNOCKDOWN + if (ignore_gloves) + flags |= SHOCK_NOGLOVES + + target.electrocute_act(damage, limb, coeff, flags, jitter_time, stutter_time) + if (spark) + do_sparks(rand(process_shock_spark_count_min, process_shock_spark_count_max), FALSE, victim) + +// Slash +// Fast to rise, but lower damage overall +// Also a bit easy to treat +/datum/wound/electrical_damage/slash + simple_desc = "Wiring has been slashed open, resulting in a fault that quickly intensifies!" + +/datum/wound/electrical_damage/slash/moderate + name = "Frayed Wiring" + desc = "Internal wiring has suffered a slight abrasion, causing a slow electrical fault that will intensify over time." + occur_text = "lets out a few sparks, as a few frayed wires stick out" + examine_desc = "has a few frayed wires sticking out" + treat_text = "Replacing of damaged wiring, though repairs via wirecutting instruments or sutures may suffice, albeit at limited efficiency. In case of emergency, \ + subject may be subjected to high temperatures to allow solder to reset." + + sound_effect = 'modular_skyrat/modules/medical/sound/robotic_slash_T1.ogg' + + severity = WOUND_SEVERITY_MODERATE + + sound_volume = 30 + + threshold_penalty = 20 + + intensity = 10 SECONDS + processing_full_shock_threshold = 3 MINUTES + + processing_shock_power_per_second_max = 0.5 + processing_shock_power_per_second_min = 0.4 + + processing_shock_stun_chance = 0 + processing_shock_spark_chance = 30 + + process_shock_spark_count_max = 1 + process_shock_spark_count_min = 1 + + wirecut_repair_percent = 0.085 // not even faster at this point + wire_repair_percent = 0.035 + + initial_sparks_amount = 1 + + status_effect_type = /datum/status_effect/wound/electrical_damage/slash/moderate + + a_or_from = "from" + + scar_keyword = "slashmoderate" + +/datum/wound_pregen_data/electrical_damage/slash/moderate + abstract = FALSE + wound_path_to_generate = /datum/wound/electrical_damage/slash/moderate + threshold_minimum = 35 + +/datum/wound/electrical_damage/slash/severe + name = "Severed Conduits" + desc = "A number of wires have been completely cut, resulting in electrical faults that will intensify at a worrying rate." + occur_text = "sends some electrical fiber in the direction of the blow, beginning to profusely spark" + examine_desc = "has multiple severed wires visible to the outside" + treat_text = "Containment of damaged wiring via gauze, then application of fresh wiring/sutures, or resetting of displaced wiring via wirecutter/retractor." + + sound_effect = 'modular_skyrat/modules/medical/sound/robotic_slash_T2.ogg' + + severity = WOUND_SEVERITY_SEVERE + + sound_volume = 15 + + threshold_penalty = 30 + + intensity = 10 SECONDS + processing_full_shock_threshold = 2 MINUTES + + processing_shock_power_per_second_max = 0.7 + processing_shock_power_per_second_min = 0.6 + + processing_shock_stun_chance = 0 + processing_shock_spark_chance = 60 + + process_shock_spark_count_max = 2 + process_shock_spark_count_min = 1 + + wirecut_repair_percent = 0.1 + wire_repair_percent = 0.032 + + initial_sparks_amount = 3 + + status_effect_type = /datum/status_effect/wound/electrical_damage/slash/severe + + a_or_from = "from" + + scar_keyword = "slashsevere" + +/datum/wound_pregen_data/electrical_damage/slash/severe + abstract = FALSE + wound_path_to_generate = /datum/wound/electrical_damage/slash/severe + threshold_minimum = 60 + +/datum/wound/electrical_damage/slash/critical + name = "Systemic Fault" + desc = "A significant portion of the power distribution network has been cut open, resulting in massive power loss and runaway electrocution." + occur_text = "lets out a violent \"zhwarp\" sound as angry electric arcs attack the surrounding air" + examine_desc = "has lots of wires mauled wires sticking out" + treat_text = "Immediate securing via gauze, followed by emergency cable replacement and securing via wirecutters or retractor. \ + If the fault has become uncontrollable, extreme heat therapy is recommended." + + severity = WOUND_SEVERITY_CRITICAL + wound_flags = (ACCEPTS_GAUZE|MANGLES_INTERIOR|CAN_BE_GRASPED|SPLINT_OVERLAY) + + sound_effect = 'modular_skyrat/modules/medical/sound/robotic_slash_T3.ogg' + + sound_volume = 30 + + threshold_penalty = 50 + + intensity = 10 SECONDS + processing_full_shock_threshold = 1.25 MINUTES + + processing_shock_power_per_second_max = 1.3 + processing_shock_power_per_second_min = 1.1 + + processing_shock_stun_chance = 5 + processing_shock_spark_chance = 90 + + process_shock_spark_count_max = 3 + process_shock_spark_count_min = 2 + + wirecut_repair_percent = 0.12 + wire_repair_percent = 0.03 + + initial_sparks_amount = 8 + + status_effect_type = /datum/status_effect/wound/electrical_damage/slash/critical + + a_or_from = "a" + + scar_keyword = "slashcritical" + +/datum/wound_pregen_data/electrical_damage/slash/critical + abstract = FALSE + wound_path_to_generate = /datum/wound/electrical_damage/slash/critical + threshold_minimum = 100 + +#undef ELECTRICAL_DAMAGE_ON_STASIS_MULT +#undef ELECTRICAL_DAMAGE_GRASPED_MULT +#undef ELECTRICAL_DAMAGE_LYING_DOWN_MULT +#undef ELECTRICAL_DAMAGE_DEAD_PROGRESS_MULT + +#undef ELECTRICAL_DAMAGE_WIRECUTTER_BASE_DELAY +#undef ELECTRICAL_DAMAGE_SUTURE_WIRE_BASE_DELAY + +#undef ELECTRICAL_DAMAGE_MINIMUM_SHOCK_POWER_PER_ZAP +#undef ELECTRICAL_DAMAGE_MAX_BURN_DAMAGE_TO_LET_WIRES_REPAIR +#undef ELECTRICAL_DAMAGE_POWER_PER_TICK_MULT +#undef ELECTRICAL_DAMAGE_SUTURE_WIRE_HEALING_AMOUNT_MULT diff --git a/modular_skyrat/modules/medical/code/wounds/wound_effects.dm b/modular_skyrat/modules/medical/code/wounds/wound_effects.dm new file mode 100644 index 00000000000000..8f9aef16210d3e --- /dev/null +++ b/modular_skyrat/modules/medical/code/wounds/wound_effects.dm @@ -0,0 +1,33 @@ +/datum/status_effect/wound/blunt/robotic/moderate + id = "unsecure_moderate" + +/datum/status_effect/wound/blunt/robotic/severe + id = "unsecure_severe" + +/datum/status_effect/wound/blunt/robotic/critical + id = "unsecure_critical" + +/datum/status_effect/wound/electrical_damage/slash/moderate + id = "electric_slash_moderate" + +/datum/status_effect/wound/electrical_damage/slash/severe + id = "electric_slash_severe" + +/datum/status_effect/wound/electrical_damage/slash/critical + id = "electric_slash_critical" + +/datum/status_effect/wound/electrical_damage/pierce/moderate + id = "electric_pierce_moderate" + +/datum/status_effect/wound/electrical_damage/pierce/severe + id = "electric_pierce_severe" + +/datum/status_effect/wound/electrical_damage/pierce/critical + id = "electric_pierce_critical" + +/datum/status_effect/wound/burn/robotic/moderate + id = "overheated" +/datum/status_effect/wound/burn/robotic/severe + id = "warpedmetal" +/datum/status_effect/wound/burn/robotic/critical + id = "demagnetizedmetal" diff --git a/modular_skyrat/modules/medical/readme.md b/modular_skyrat/modules/medical/readme.md new file mode 100644 index 00000000000000..6ab0af32ddf7e9 --- /dev/null +++ b/modular_skyrat/modules/medical/readme.md @@ -0,0 +1,51 @@ + + +https://github.com/Skyrat-SS13/Skyrat-tg/pull/2336 +https://github.com/Skyrat-SS13/Skyrat-tg/pull/23733 + +## Skyrat Medical Update + +Module ID: SKYRAT_MEDICAL_UPDATE + +### Description: + +Various changes to the medical system, from adding bandage overlays, to new wounds, to modularized procs. + + + +### TG Proc/File Changes: + +- code/_DEFINES/wounds.dm: Added muscle/synth wound series, added them to the global list of wound series +- cat2_medicine_reagents.dm: /datum/reagent/medicine/c2/hercuri/on_mob_life, Allowed hercuri to affect synthetics, also changed hercuri process flags for this purpose +- quirks.dm: Commented out the quadruple_amputee/frail blacklist as frail can now apply to prosthetics + + +### Modular Overrides: + +- N/A + + +### Defines: + +- Many local synthetic wound defines + + +### Included files that are not contained in this module: + +- strings/wounds/metal_scar_desc.json -- Required to be here for _string_lists.dm usage + + +### Credits: + +Azarak - Original medical update, muscle wounds, bandage overlays +Niko - Synthetic wounds +TG coding/Skyrat coding channels and community - Support, ideas, reviews + + diff --git a/modular_skyrat/modules/medical/sound/robotic_slash_T1.ogg b/modular_skyrat/modules/medical/sound/robotic_slash_T1.ogg new file mode 100644 index 00000000000000..cb7b3d0a79f499 Binary files /dev/null and b/modular_skyrat/modules/medical/sound/robotic_slash_T1.ogg differ diff --git a/modular_skyrat/modules/medical/sound/robotic_slash_T2.ogg b/modular_skyrat/modules/medical/sound/robotic_slash_T2.ogg new file mode 100644 index 00000000000000..4fad2583575380 Binary files /dev/null and b/modular_skyrat/modules/medical/sound/robotic_slash_T2.ogg differ diff --git a/modular_skyrat/modules/medical/sound/robotic_slash_T3.ogg b/modular_skyrat/modules/medical/sound/robotic_slash_T3.ogg new file mode 100644 index 00000000000000..f0ea8e2217027a Binary files /dev/null and b/modular_skyrat/modules/medical/sound/robotic_slash_T3.ogg differ diff --git a/modular_skyrat/modules/medical_designs/medical_designs.dm b/modular_skyrat/modules/medical_designs/medical_designs.dm index 288adf0643b314..d0360fbfc2bc4a 100644 --- a/modular_skyrat/modules/medical_designs/medical_designs.dm +++ b/modular_skyrat/modules/medical_designs/medical_designs.dm @@ -8,3 +8,13 @@ RND_CATEGORY_EQUIPMENT + RND_SUBCATEGORY_EQUIPMENT_MEDICAL ) departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE + +/datum/design/surgery/healing/robotic_healing_upgrade + name = "Repair robotic limbs upgrade: Advanced" + surgery = /datum/surgery/robot_healing/upgraded + id = "robotic_heal_surgery_upgrade" + +/datum/design/surgery/healing/robotic_healing_upgrade_2 + name = "Repair robotic limbs upgrade: Experimental" + surgery = /datum/surgery/robot_healing/experimental + id = "robotic_heal_surgery_upgrade_2" diff --git a/modular_skyrat/modules/microfusion/code/gun_types.dm b/modular_skyrat/modules/microfusion/code/gun_types.dm index 24a1eeed05384d..052e3b32db1045 100644 --- a/modular_skyrat/modules/microfusion/code/gun_types.dm +++ b/modular_skyrat/modules/microfusion/code/gun_types.dm @@ -49,7 +49,6 @@ */ /obj/effect/spawner/armory_spawn/microfusion - icon_state = "random_rifle" guns = list( /obj/item/gun/microfusion/mcr01, /obj/item/gun/microfusion/mcr01, diff --git a/modular_skyrat/modules/modular_ert/code/odst/odst_outfit.dm b/modular_skyrat/modules/modular_ert/code/odst/odst_outfit.dm index cb618c41d31623..41f356151946de 100644 --- a/modular_skyrat/modules/modular_ert/code/odst/odst_outfit.dm +++ b/modular_skyrat/modules/modular_ert/code/odst/odst_outfit.dm @@ -5,7 +5,7 @@ glasses = /obj/item/clothing/glasses/hud/security/night ears = /obj/item/radio/headset/headset_cent/alt gloves = /obj/item/clothing/gloves/combat - l_hand = /obj/item/gun/ballistic/automatic/pitbull + l_hand = /obj/item/gun/ballistic/automatic/sol_rifle/machinegun belt = /obj/item/storage/belt/military/odst back = /obj/item/mod/control/pre_equipped/responsory/security backpack_contents = list( diff --git a/modular_skyrat/modules/modular_implants/code/nif_persistence.dm b/modular_skyrat/modules/modular_implants/code/nif_persistence.dm index 1dc272c434e8f9..fd24fd3b5792e7 100644 --- a/modular_skyrat/modules/modular_implants/code/nif_persistence.dm +++ b/modular_skyrat/modules/modular_implants/code/nif_persistence.dm @@ -15,6 +15,8 @@ var/nif_is_calibrated /// How many rewards points does the NIF have stored on it? var/stored_rewards_points + /// A string containing programs that are transfered from one round to the next. + var/persistent_nifsofts /// Saves the NIF data for a individual user. /mob/living/carbon/human/proc/save_nif_data(datum/modular_persistence/persistence, remove_nif = FALSE) @@ -51,14 +53,19 @@ persistence.stored_rewards_points = installed_nif.rewards_points var/datum/component/nif_examine/examine_component = GetComponent(/datum/component/nif_examine) - persistence.nif_examine_text = examine_component?.nif_examine_text + + var/persistent_nifsoft_paths = "" // We need to convert all of the paths in the list into a single string for(var/datum/nifsoft/nifsoft as anything in installed_nif.loaded_nifsofts) - if(!nifsoft.persistence) + if(nifsoft.persistence) + nifsoft.save_persistence_data(persistence) + + if(!nifsoft.able_to_keep || !nifsoft.keep_installed) continue - nifsoft.save_persistence_data(persistence) + persistent_nifsoft_paths += "&[(nifsoft.type)]" + persistence.persistent_nifsofts = persistent_nifsoft_paths /// Loads the NIF data for an individual user. /mob/living/carbon/human/proc/load_nif_data(datum/modular_persistence/persistence) @@ -74,6 +81,16 @@ new_nif.current_theme = persistence.nif_theme new_nif.is_calibrated = persistence.nif_is_calibrated new_nif.rewards_points = persistence.stored_rewards_points + + var/list/persistent_nifsoft_paths = list() + for(var/text as anything in splittext(persistence.persistent_nifsofts, "&")) + var/datum/nifsoft/nifsoft_to_add = text2path(text) + if(!ispath(nifsoft_to_add, /datum/nifsoft) || !initial(nifsoft_to_add.able_to_keep)) + continue + + persistent_nifsoft_paths.Add(nifsoft_to_add) + + new_nif.persistent_nifsofts = persistent_nifsoft_paths.Copy() new_nif.Insert(src) var/datum/component/nif_examine/examine_component = GetComponent(/datum/component/nif_examine) diff --git a/modular_skyrat/modules/modular_implants/code/nif_research.dm b/modular_skyrat/modules/modular_implants/code/nif_research.dm index 7e8e1ca94f8cec..4e88040cddff23 100644 --- a/modular_skyrat/modules/modular_implants/code/nif_research.dm +++ b/modular_skyrat/modules/modular_implants/code/nif_research.dm @@ -28,6 +28,16 @@ category = list(RND_CATEGORY_TOOLS + RND_SUBCATEGORY_EQUIPMENT_MEDICAL) // look, the anesthetic machine's there too departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE +/datum/design/mini_soulcatcher + name = "Poltergeist-Type RSD" + desc = "A miniature version of a Soulcatcher that can be attached to various objects." + id = "mini_soulcatcher" + build_type = PROTOLATHE | AWAY_LATHE + build_path = /obj/item/attachable_soulcatcher + materials = list(/datum/material/glass = SMALL_MATERIAL_AMOUNT * 5, /datum/material/iron = SMALL_MATERIAL_AMOUNT * 5) + category = list(RND_CATEGORY_AI + RND_SUBCATEGORY_AI_MISC) // look, the anesthetic machine's there too + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE | DEPARTMENT_BITFLAG_SERVICE | DEPARTMENT_BITFLAG_MEDICAL + /datum/design/nifsoft_hud build_type = PROTOLATHE | AWAY_LATHE materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT, /datum/material/silver = HALF_SHEET_MATERIAL_AMOUNT, /datum/material/plastic = SHEET_MATERIAL_AMOUNT) diff --git a/modular_skyrat/modules/modular_implants/code/nifs.dm b/modular_skyrat/modules/modular_implants/code/nifs.dm index 69c0a581c3594c..6ce9f780f83966 100644 --- a/modular_skyrat/modules/modular_implants/code/nifs.dm +++ b/modular_skyrat/modules/modular_implants/code/nifs.dm @@ -92,6 +92,8 @@ var/list/loaded_nifsofts = list() ///What programs come already installed on the NIF? var/list/preinstalled_nifsofts = list(/datum/nifsoft/soul_poem) + ///What programs do we want to carry between rounds? + var/list/persistent_nifsofts = list() ///This shows up in the NIF settings screen as a way to ICly display lore. var/manufacturer_notes = "There is no data currently avalible for this product." @@ -147,8 +149,8 @@ linked_mob.AddComponent(/datum/component/nif_examine) RegisterSignal(linked_mob, COMSIG_LIVING_DEATH, PROC_REF(damage_on_death)) - if(preinstalled_nifsofts) - send_message("Loading preinstalled NIFSofts, please wait...") + if(preinstalled_nifsofts || persistent_nifsofts) + send_message("Loading preinstalled and stored NIFSofts, please wait...") addtimer(CALLBACK(src, PROC_REF(install_preinstalled_nifsofts)), 3 SECONDS) /obj/item/organ/internal/cyberimp/brain/nif/Remove(mob/living/carbon/organ_owner, special = FALSE) @@ -174,6 +176,10 @@ for(var/datum/nifsoft/preinstalled_nifsoft as anything in preinstalled_nifsofts) new preinstalled_nifsoft(src) + for(var/stored_nifsoft in persistent_nifsofts) + var/datum/nifsoft/new_stored_nifsoft = new stored_nifsoft(src) + new_stored_nifsoft.keep_installed = TRUE + return TRUE /obj/item/organ/internal/cyberimp/brain/nif/process(seconds_per_tick) @@ -501,6 +507,7 @@ new /obj/item/disk/nifsoft_uploader/summoner(src) new /obj/item/disk/nifsoft_uploader/money_sense(src) new /obj/item/disk/nifsoft_uploader/dorms(src) + new /obj/item/disk/nifsoft_uploader/dorms/hypnosis(src) new /obj/item/disk/nifsoft_uploader/soulcatcher(src) /obj/item/storage/box/nif_ghost_box/ghost_role/PopulateContents() diff --git a/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm b/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm index 0423e28c830ae0..dfc9916ab83bca 100644 --- a/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm +++ b/modular_skyrat/modules/modular_implants/code/nifs_tgui.dm @@ -45,6 +45,8 @@ "active_cost" = nifsoft.active_cost, "reference" = REF(nifsoft), "ui_icon" = nifsoft.ui_icon, + "able_to_keep" = nifsoft.able_to_keep, + "keep_installed" = nifsoft.keep_installed, ) data["loaded_nifsofts"] += list(nifsoft_data) @@ -119,6 +121,8 @@ return FALSE current_theme = target_theme + for(var/datum/nifsoft/installed_nifsoft as anything in loaded_nifsofts) + installed_nifsoft.update_theme() if("activate_nifsoft") var/datum/nifsoft/activated_nifsoft = locate(params["activated_nifsoft"]) in loaded_nifsofts @@ -126,3 +130,11 @@ return FALSE activated_nifsoft.activate() + + if("toggle_keeping_nifsoft") + var/datum/nifsoft/nifsoft_to_keep = locate(params["nifsoft_to_keep"]) in loaded_nifsofts + if(!nifsoft_to_keep || !nifsoft_to_keep.able_to_keep) + return FALSE + + nifsoft_to_keep.keep_installed = !nifsoft_to_keep.keep_installed + update_static_data_for_all_viewers() diff --git a/modular_skyrat/modules/modular_implants/code/nifsoft_catalog.dm b/modular_skyrat/modules/modular_implants/code/nifsoft_catalog.dm index 6319fa60d9fbdf..4cd6beea37955f 100644 --- a/modular_skyrat/modules/modular_implants/code/nifsoft_catalog.dm +++ b/modular_skyrat/modules/modular_implants/code/nifsoft_catalog.dm @@ -1,11 +1,13 @@ GLOBAL_LIST_INIT(purchasable_nifsofts, list( /datum/nifsoft/hivemind, /datum/nifsoft/summoner, - /datum/nifsoft/shapeshifter, + /datum/nifsoft/action_granter/shapeshifter, /datum/nifsoft/summoner/dorms, /datum/nifsoft/soul_poem, /datum/nifsoft/soulcatcher, + /datum/nifsoft/scryer, /datum/nifsoft/summoner/book, + /datum/nifsoft/action_granter/hypnosis, )) /datum/computer_file/program/nifsoft_downloader @@ -80,6 +82,7 @@ GLOBAL_LIST_INIT(purchasable_nifsofts, list( "category" = initial(buyable_nifsoft.buying_category), "ui_icon" = initial(buyable_nifsoft.ui_icon), "reference" = buyable_nifsoft, + "keepable" = initial(buyable_nifsoft.able_to_keep), ) var/category = nifsoft_details["category"] if(!(category in product_list)) diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts.dm b/modular_skyrat/modules/modular_implants/code/nifsofts.dm index d7c382cfddbae1..ddbff9cf86e6d6 100644 --- a/modular_skyrat/modules/modular_implants/code/nifsofts.dm +++ b/modular_skyrat/modules/modular_implants/code/nifsofts.dm @@ -18,6 +18,8 @@ var/buying_category = NIFSOFT_CATEGORY_GENERAL ///What font awesome icon is shown next to the name of the nifsoft? var/ui_icon = "floppy-disk" + ///What UI theme do we want to display to users if this NIFSoft has TGUI? + var/ui_theme = "default" ///Can the program be installed with other instances of itself? var/single_install = TRUE @@ -47,6 +49,10 @@ var/rewards_points_eligible = TRUE ///Does the NIFSoft have anything that is saved cross-round? var/persistence = FALSE + /// Is the NIFSoft something that we want to allow the user to keep? + var/able_to_keep = FALSE + /// Are we keeping the NIFSoft installed between rounds? This is decided by the user + var/keep_installed = FALSE ///Is it a lewd item? var/lewd_nifsoft = FALSE @@ -63,6 +69,7 @@ qdel(src) load_persistence_data() + update_theme() /datum/nifsoft/Destroy() if(active) @@ -144,6 +151,15 @@ /datum/nifsoft/ui_state(mob/user) return GLOB.conscious_state +/// Updates the theme of the NIFSoft to match the parent NIF +/datum/nifsoft/proc/update_theme() + var/obj/item/organ/internal/cyberimp/brain/nif/target_nif = parent_nif.resolve() + if(!target_nif) + return FALSE + + ui_theme = target_nif.current_theme + return TRUE + /// A disk that can upload NIFSofts to a recpient with a NIFSoft installed. /obj/item/disk/nifsoft_uploader name = "Generic NIFSoft datadisk" diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/base_types/action_granter.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/base_types/action_granter.dm new file mode 100644 index 00000000000000..05d1012d629e74 --- /dev/null +++ b/modular_skyrat/modules/modular_implants/code/nifsofts/base_types/action_granter.dm @@ -0,0 +1,26 @@ +/// This type of NIFSoft grans the user an action when active. +/datum/nifsoft/action_granter + active_mode = TRUE + activation_cost = 10 + active_cost = 1 + /// What is the path of the action that we want to grant? + var/action_to_grant = /datum/action/innate + /// What action are we giving the user of the NIFSoft? + var/datum/action/innate/granted_action + +/datum/nifsoft/action_granter/activate() + . = ..() + if(active) + granted_action = new action_to_grant + granted_action.Grant(linked_mob) + return + + if(granted_action) + granted_action.Remove(linked_mob) + +/datum/nifsoft/action_granter/Destroy() + if(granted_action) + QDEL_NULL(granted_action) + return ..() + + diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/dorms.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/dorms.dm index d6f02e394e4810..97506d8d69d6bc 100644 --- a/modular_skyrat/modules/modular_implants/code/nifsofts/dorms.dm +++ b/modular_skyrat/modules/modular_implants/code/nifsofts/dorms.dm @@ -1,12 +1,12 @@ /obj/item/disk/nifsoft_uploader/dorms - name = "Grimoire Purpura" + name = "Grimoire Libidine" loaded_nifsoft = /datum/nifsoft/summoner/dorms /datum/nifsoft/summoner/dorms - name = "Grimoire Purpura" - program_desc = "Grimoire Purpura, a fork of the Grimoire Caeruleam code, allows users to conveniently access an extensive database of various adult toys. " + name = "Grimoire Libidine" + program_desc = "Grimoire Libidine, a fork of the Grimoire Caeruleam code, allows users to conveniently access an extensive database of various adult toys. " holographic_filter = FALSE //No RGB toys - name_tag = "purpura " + name_tag = "libidine " lewd_nifsoft = TRUE ui_icon = "heart" @@ -62,7 +62,7 @@ purchase_price = 150 /obj/item/disk/nifsoft_uploader/dorms/contract - name = "\improper Purpura Contract" + name = "\improper Libidine Contract" loaded_nifsoft = /datum/nifsoft/hypno reusable = TRUE //This is set to true because of how this handles updating laws ///What laws will be assigned when using the NIFSoft on someone? @@ -93,8 +93,8 @@ return TRUE /datum/nifsoft/hypno - name = "Purpura Contract" - program_desc = "Once installed, the Purpura Contract compells the user to follow the rules stored in the data of the NIFSoft. \n OOC NOTE: This is strictly here for adult roleplay. None of the laws here actually need to be obeyed and you can uninstall this NIFSoft at any time." + name = "Libidine Contract" + program_desc = "Once installed, the Libidine Contract compells the user to follow the rules stored in the data of the NIFSoft. \n OOC NOTE: This is strictly here for adult roleplay. None of the laws here actually need to be obeyed and you can uninstall this NIFSoft at any time." purchase_price = 0 lewd_nifsoft = TRUE ui_icon = "file-contract" diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/hypnosis.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/hypnosis.dm new file mode 100644 index 00000000000000..be88ad77cd8345 --- /dev/null +++ b/modular_skyrat/modules/modular_implants/code/nifsofts/hypnosis.dm @@ -0,0 +1,66 @@ +/obj/item/disk/nifsoft_uploader/dorms/hypnosis + name = "Purpura Eye" + loaded_nifsoft = /datum/nifsoft/action_granter/hypnosis + +/datum/nifsoft/action_granter/hypnosis + name = "Libidine Eye" + program_desc = "Based on the hypnotic equipment provided by the LustWish vendor, the Libidine Eye NIFSoft allows the user to ensnare others in a hypnotic trance. ((This is intended as a tool for ERP, don't use this for gameplay reasons.))" + buying_category = NIFSOFT_CATEGORY_FUN + lewd_nifsoft = TRUE + purchase_price = 150 + able_to_keep = TRUE + active_cost = 0.1 + ui_icon = "eye" + action_to_grant = /datum/action/innate/nif_hypnotize + +/datum/action/innate/nif_hypnotize + name = "Hypnotize" + background_icon = 'modular_skyrat/master_files/icons/mob/actions/action_backgrounds.dmi' + background_icon_state = "android" + button_icon = 'modular_skyrat/master_files/icons/mob/actions/actions_nif.dmi' + button_icon_state = "hypnotize" + +/datum/action/innate/nif_hypnotize/Activate() + var/mob/living/carbon/human/user = owner + if(!istype(user)) + return FALSE + + var/mob/living/carbon/human/target_human = user.pulling + if(!istype(target_human) || user.grab_state < GRAB_AGGRESSIVE) + to_chat(user, span_warning("You need to aggressively grab someone to hypnotize them.")) + return FALSE + + if(!target_human.client?.prefs?.read_preference(/datum/preference/toggle/erp/sex_toy)) + to_chat(user, span_warning("[target_human] doesn't want to be hypnotized.")) + return FALSE + + to_chat(user, span_notice("You begin to place [target_human] into a hypnotic trance.")) + + if(!do_after(user, 12 SECONDS, target_human)) + return FALSE + + var/choice = tgui_alert(target_human, "Do you believe in hypnosis? (This will allow [user] to issue hypnotic suggestions.)", "Hypnosis", list("Yes", "No")) + if(choice != "Yes") + to_chat(user, span_warning("[target_human]'s attention breaks despite your efforts. They clearly don't seem interested!")) + to_chat(target_human, span_warning("Your attention breaks as you realize that you don't want to listen to [user]'s suggestions.")) + return FALSE + + user.visible_message(span_purple("[target_human] falls into a deep, hypnotic slumber right at the snap of your fingers."), span_purple("You suddenly fall limp at the snap of [user]'s fingers.")) + user.emote("snap") + target_human.SetSleeping(60 SECONDS) + target_human.log_message("[target_human] was placed into a hypnotic sleep by [user].", LOG_GAME) + + var/secondary_choice = tgui_alert(user, "Would you like to give [target_human] a hypnotic suggestion or release them?", "Hypnosis", list("Suggestion", "Release")) + while(secondary_choice == "Suggestion" && target_human.IsSleeping()) + if(!in_range(user, target_human)) + to_chat(user, span_warning("You must be in whisper range to [target_human] in order to give hypnotic suggestions.")) + target_human.SetSleeping(0) + return FALSE + + var/input_text = tgui_input_text(user, "What would you like to suggest?", "Hypnotic Suggestion") + to_chat(user, span_purple("You whisper into [target_human]'s ears in a soothing voice.")) + to_chat(target_human, span_hypnophrase("[input_text]")) + secondary_choice = tgui_alert(user, "Would you like to give [target_human] an additional hypnotic suggestion or release them?", "Hypnosis", list("Suggestion", "Release")) + + user.visible_message(span_purple("You wake up from your deep, hypnotic slumber. The suggestions from [user] now settled into your mind."), span_purple("[target_human] wakes up from their slumber.")) + target_human.SetSleeping(0) diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/prop_summoner.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/prop_summoner.dm index c7e93412ac2bd4..aab1cc52b7a910 100644 --- a/modular_skyrat/modules/modular_implants/code/nifsofts/prop_summoner.dm +++ b/modular_skyrat/modules/modular_implants/code/nifsofts/prop_summoner.dm @@ -16,6 +16,7 @@ activation_cost = 100 // Around 1/10th the energy of a standard NIF buying_category = NIFSOFT_CATEGORY_FUN ui_icon = "book-open" + able_to_keep = TRUE // These NIFSofts are mostly for comsetic/fun reasons anyways. /// Does the resulting object have a holographic like filter appiled to it? var/holographic_filter = TRUE diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/scryer.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/scryer.dm new file mode 100644 index 00000000000000..3cf689624e0951 --- /dev/null +++ b/modular_skyrat/modules/modular_implants/code/nifsofts/scryer.dm @@ -0,0 +1,117 @@ +/obj/item/disk/nifsoft_uploader/scryer + name = "NIFSoft Scryer Uploader Disk" + loaded_nifsoft = /datum/nifsoft/scryer + +/datum/nifsoft/scryer + name = "NIFLink Holocaller" + program_desc = "This ubiquitous NIFSoft adds Scryer functionality similar to MODSuits to the user's NIF; allowing for real-time communication through AR hologlass screens from a hardlight projector sat around the wearer's neck" + active_mode = TRUE + active_cost = 1 + activation_cost = 20 + purchase_price = 200 + buying_category = NIFSOFT_CATEGORY_UTILITY + ui_icon = "video" + /// What is the scryer currently associated with the NIFSoft? + var/obj/item/clothing/neck/link_scryer/loaded/nifsoft/linked_scryer + +/datum/nifsoft/scryer/New() + . = ..() + var/obj/item/organ/internal/cyberimp/brain/nif/parent_resolved = parent_nif.resolve() + if(!istype(parent_resolved)) + stack_trace("[src] ([REF(src)]) tried to create a linked scryer but it had no parent_nif!") + if(!linked_scryer) + stack_trace("[src] ([REF(src)]) created with no linked scryer!") + linked_scryer = new (parent_resolved) + linked_scryer.parent_nifsoft = WEAKREF(src) + +/datum/nifsoft/scryer/Destroy() + if(!QDELETED(linked_scryer)) + QDEL_NULL(linked_scryer) + + return ..() + +/datum/nifsoft/scryer/activate() + . = ..() + if(. == FALSE) + return FALSE + + if(!active) + if(linked_scryer) + var/parent_resolved = parent_nif.resolve() + if(parent_resolved) + return linked_mob.transferItemToLoc(linked_scryer, parent_resolved, TRUE) + return FALSE + + if(linked_mob.handcuffed) + linked_mob.balloon_alert(linked_mob, "handcuffed") + activate() + return FALSE + + if(!linked_mob.equip_to_slot_if_possible(linked_scryer, ITEM_SLOT_NECK)) //This sends out a message to the mob if it can't be put on. + activate() + return FALSE + + return TRUE + +/obj/item/clothing/neck/link_scryer + /// Do we have custom controls? This is only affects the text shown when examining + var/custom_examine_controls = FALSE + +/obj/item/clothing/neck/link_scryer/loaded/nifsoft + name = "\improper NIFLink Holocaller" + desc = "A nanomachine construct working as a modified version of the MODlink scryer, conjured using a NIF; functionally the same, but able to carry out holocalls in a more portable format." + custom_examine_controls = TRUE + /// A weakref of the parent NIFSoft that the scryer belongs to. + var/datum/weakref/parent_nifsoft + +/obj/item/clothing/neck/link_scryer/loaded/nifsoft/Initialize(mapload) + . = ..() + if(cell) + QDEL_NULL(cell) + + cell = new /obj/item/stock_parts/cell/infinite/nif_cell(src) + +/obj/item/clothing/neck/link_scryer/loaded/nifsoft/Destroy() + if(parent_nifsoft) + var/datum/nifsoft/scryer/resolved_nifsoft = parent_nifsoft.resolve() + if(!QDELETED(resolved_nifsoft)) + resolved_nifsoft.linked_scryer = null + + return ..() + +/obj/item/clothing/neck/link_scryer/loaded/nifsoft/examine(mob/user) + . = ..() + . += span_notice("The MODlink ID is [mod_link.id], frequency is [mod_link.frequency || "unset"]. Right-click with a multitool to copy/imprint the frequency.") + . += span_notice("Right-click with an empty hand to change the name.") + +/obj/item/clothing/neck/link_scryer/loaded/nifsoft/equipped(mob/living/user, slot) + . = ..() + if(slot & ITEM_SLOT_NECK) + return TRUE + + var/datum/nifsoft/scryer/scryer_nifsoft = parent_nifsoft.resolve() + if(!istype(scryer_nifsoft)) + return FALSE + + scryer_nifsoft.activate() //If it's not on the neck, it shouldn't be active. + return TRUE + +/obj/item/clothing/neck/link_scryer/loaded/nifsoft/screwdriver_act(mob/living/user, obj/item/tool) + balloon_alert(user, "cell non-removable!") + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/item/clothing/neck/link_scryer/loaded/nifsoft/attack_hand_secondary(mob/user, list/modifiers) + var/new_label = reject_bad_text(tgui_input_text(user, "Change the visible name", "Set Name", label, MAX_NAME_LEN)) + if(!new_label) + balloon_alert(user, "invalid name!") + return + label = new_label + balloon_alert(user, "name set!") + update_name() + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/// This cell is only meant for use in items temporarily created by a NIF. Do not let players extract this from devices. +/obj/item/stock_parts/cell/infinite/nif_cell + name = "Nanite Cell" + desc = "If you see this, please make an issue on GitHub." + diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/shapeshifter.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/shapeshifter.dm index bbbf7dc2c07b65..dfa70dc78eb7cb 100644 --- a/modular_skyrat/modules/modular_implants/code/nifsofts/shapeshifter.dm +++ b/modular_skyrat/modules/modular_implants/code/nifsofts/shapeshifter.dm @@ -1,35 +1,15 @@ /obj/item/disk/nifsoft_uploader/shapeshifter name = "Polymorph" - loaded_nifsoft = /datum/nifsoft/shapeshifter + loaded_nifsoft = /datum/nifsoft/action_granter -/datum/nifsoft/shapeshifter +/datum/nifsoft/action_granter/shapeshifter name = "Polymorph" program_desc = "This program is a large-scale refitting of the nanomachine channels running over the skin of a NIF user. This allows the nanites to reach under the skin and even into the very bone structure of the host; including incorporation of mimetic materials and femto-level manipulation devices all for the purpose of allowing the user to, essentially, shapeshift on a low level. However, despite the incredible complexity behind these processes, there are still limits on the range of 'forms' a user can take. Mass can neither be created nor destroyed, after all, and you can only distribute and rearrange it in so many ways across a functioning humanoid body; meaning, the user cannot adopt forms too far out of their 'true' one." - activation_cost = 10 - active_mode = TRUE - active_cost = 1 compatible_nifs = list(/obj/item/organ/internal/cyberimp/brain/nif/standard) purchase_price = 350 buying_category = NIFSOFT_CATEGORY_COSMETIC ui_icon = "paintbrush" - - ///The NIF version of the Shapeshifter Ability - var/datum/action/innate/alter_form/nif/shapeshifter - -/datum/nifsoft/shapeshifter/activate() - . = ..() - if(active) - shapeshifter = new - shapeshifter.Grant(linked_mob) - return - - if(shapeshifter) - shapeshifter.Remove(linked_mob) - -/datum/nifsoft/shapeshifter/Destroy() - . = ..() - if(shapeshifter) - QDEL_NULL(shapeshifter) + action_to_grant = /datum/action/innate/alter_form/nif /// The NIF version of alter form. This lacks the ability to change body color. diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/soul_poem.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/soul_poem.dm index 4dc4434d59ddd5..093e9e566b73e6 100644 --- a/modular_skyrat/modules/modular_implants/code/nifsofts/soul_poem.dm +++ b/modular_skyrat/modules/modular_implants/code/nifsofts/soul_poem.dm @@ -166,6 +166,7 @@ var/list/data = list() data["messages"] = message_list + data["theme"] = ui_theme data["receiving_data"] = receiving_data data["transmitting_data"] = transmitting_data diff --git a/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm b/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm index 9236a49f963ba5..2ec95a411ef36a 100644 --- a/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm +++ b/modular_skyrat/modules/modular_implants/code/nifsofts/soulcatcher.dm @@ -7,6 +7,7 @@ program_desc = "The 'Soulcatcher' coreware is a near-complete upgrade of the nanomachine systems in a NIF, meant for one purpose; supposedly, channeling the dead. This upgrade, in truth, functions as a Resonance Simulation Device; an RSD for short, an instrument capable of hosting someone's consciousness, context or otherwise. 'Resonance', a term for the specific pattern of neural activity that gives way to someone's consciousness, was discovered in the early 2500s by researchers Yun-Seo Jin and Kamakshi Padmanabhan, coining what is now called 'Jin-Padmanabhan Resonance,' or 'JP/Soul Resonance.' This 'Resonance' gives off a sophont's consciousness, their sense of continuation, and their 'I am me.' This Resonance can vary in structure and 'strength' from person to person, and even change over someone's life. When the brain of a sophont undergoes death and stops neural activity, then Resonance dissipates entirely and lingering consciousness becomes essentially an echo, rapidly fading over time.\n\nThe earliest RSDs were massive machines, drawing incredible power and utilizing bleeding-edge, clunky software to 'play' someone's Resonance at 1:1 accuracy with their original brain. However, complications arose that are still being studied. Resonance is replicable and can be re-created artificially; however, like trying to duplicate genetic code, the capture needs to be extremely accurate, and rapidly put into place. Instruments such as RSDs are capable of picking up on lingering consciousness after the end of Resonance, and resuming it through artificial neural activity can give it strength to continue once more. RSDs such as Soulcatchers can only work at such a distance, otherwise running the risk of the Resonance essentially corrupting due to poor signal.\n\nIt is currently impossible to run Resonance in two places at once, because the same Resonance over two places experiences interference; like noise canceling headphones. Slimes and other gestalt consciousnesses can modulate their harmonics to a degree, bearing a partial disconnect and bringing themselves into constructive interference with similar harmonic signatures. A deepscan of the person's brain is necessary to give their consciousness 'context;' running their Resonance and capturing their consciousness alone results in a person with their same original intelligence, but zero memories or identity. These scans rapidly become outdated due to the growth of the brain, and it is prohibitively complex to store them in their entirety.\n\nThe first portable RSD, or Soulcatcher, was developed by the Spider Clan. These were initially designed for the captive interrogation of a person's consciousness without having to worry about the struggling of their body, and for dead or aging members of the mysterious group of orbital shinobi to be able to guide field operatives. These Soulcatchers are the main instrument to play Resonance, but recent advances in medical science have been leading to more. Occasionally, it is known for unusual sources of 'wild' Resonance, called Phantoms, to end up inside of the nearest Soulcatcher, a key finding its own lock; with a wide array of theories as to how these come into existence. Much as how some people intentionally become stable Engrams to achieve digital immortality, such as the witches of the Altspace Coven, it is possible for others to forcibly enter a Soulcatcher and act as a sort of Phantom by hacking their way in." purchase_price = 150 //RP tool persistence = TRUE + able_to_keep = TRUE ui_icon = "ghost" /// What is the linked soulcatcher datum used by this NIFSoft? @@ -93,6 +94,17 @@ persistence.nif_soulcatcher_rooms = list2params(room_list) return TRUE +/datum/nifsoft/soulcatcher/update_theme() + . = ..() + if(!.) + return FALSE // uhoh + + var/datum/component/soulcatcher/current_soulcatcher = linked_soulcatcher.resolve() + if(!istype(current_soulcatcher)) + stack_trace("[src] ([REF(src)]) tried to update its theme when it was missing a linked_soulcatcher component!") + return FALSE + current_soulcatcher.ui_theme = ui_theme + /datum/modular_persistence ///A param string containing soulcatcher rooms var/nif_soulcatcher_rooms = "" diff --git a/modular_skyrat/modules/modular_implants/code/soulcatcher/attachable_soulcatcher.dm b/modular_skyrat/modules/modular_implants/code/soulcatcher/attachable_soulcatcher.dm new file mode 100644 index 00000000000000..cd84179e083898 --- /dev/null +++ b/modular_skyrat/modules/modular_implants/code/soulcatcher/attachable_soulcatcher.dm @@ -0,0 +1,111 @@ +/datum/component/soulcatcher/small_device + max_souls = 1 + +/datum/component/soulcatcher/attachable_soulcatcher + max_souls = 1 + communicate_as_parent = TRUE + removable = TRUE + +/datum/component/soulcatcher/attachable_soulcatcher/New() + . = ..() + var/obj/item/parent_item = parent + if(!istype(parent_item)) + return COMPONENT_INCOMPATIBLE + + name = parent_item.name + var/datum/soulcatcher_room/first_room = soulcatcher_rooms[1] + first_room.name = parent_item.name + first_room.room_description = parent_item.desc + + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(parent, COMSIG_CLICK_CTRL_SHIFT, PROC_REF(bring_up_ui)) + RegisterSignal(parent, COMSIG_PREQDELETED, PROC_REF(remove_self)) + +/// Adds text to the examine text of the parent item, explaining that the item can be used to enable the use of NIFSoft HUDs +/datum/component/soulcatcher/attachable_soulcatcher/proc/on_examine(datum/source, mob/user, list/examine_text) + SIGNAL_HANDLER + examine_text += span_cyan("[source] has a soulcatcher attached to it, Ctrl+Shift+Click to use it.") + +/datum/component/soulcatcher/attachable_soulcatcher/proc/bring_up_ui(datum/source, mob/user) + SIGNAL_HANDLER + INVOKE_ASYNC(src, PROC_REF(ui_interact), user) + +/datum/component/soulcatcher/attachable_soulcatcher/Destroy(force) + UnregisterSignal(parent, COMSIG_ATOM_EXAMINE) + UnregisterSignal(parent, COMSIG_CLICK_CTRL_SHIFT) + UnregisterSignal(parent, COMSIG_PREQDELETED) + return ..() + +/datum/component/soulcatcher/attachable_soulcatcher/remove_self() + var/obj/item/parent_item = parent + var/turf/drop_turf = get_turf(parent_item) + var/obj/item/attachable_soulcatcher/dropped_item = new (drop_turf) + + var/datum/component/soulcatcher/dropped_soulcatcher = dropped_item.GetComponent(/datum/component/soulcatcher) + var/datum/soulcatcher_room/target_room = dropped_soulcatcher.soulcatcher_rooms[1] + var/list/current_souls = get_current_souls() + + if(current_souls) // If we have souls inside of here, they should be transferred to the new object + for(var/mob/living/soulcatcher_soul/soul as anything in current_souls) + var/datum/soulcatcher_room/current_room = soul.current_room.resolve() + if(istype(current_room)) + current_room.transfer_soul(soul, target_room) + + return ..() + +/obj/item/attachable_soulcatcher + name = "Poltergeist-Type RSD" + desc = "This device, a polymorphic nanomachine net, wraps around objects of most sizes and allows them to function as a container for Resonance. The soul in question within the vessel is imbued much like it would be in a body or a normal Soulcatcher, perceiving the world and even speaking out of their new form. The nanomachine net of the device allows for the consciousness to somewhat manipulate their container, but any large-scale movement is out of the question." + icon = 'modular_skyrat/modules/modular_implants/icons/obj/devices.dmi' + icon_state = "attachable-soulcatcher" + w_class = WEIGHT_CLASS_SMALL + /// Do we want to destory the item once it is attached to an item? + var/destroy_on_use = TRUE + /// What items do we want to prevent the viewer from attaching this to? + var/list/blacklisted_items = list( + /obj/item/organ, + /obj/item/mmi, + /obj/item/pai_card, + /obj/item/aicard, + /obj/item/card, + /obj/item/radio, + /obj/item/disk/nuclear, // Woah there + ) + /// What soulcathcer component is currnetly linked to this object? + var/datum/component/soulcatcher/small_device/linked_soulcatcher + +/obj/item/attachable_soulcatcher/Initialize(mapload) + . = ..() + linked_soulcatcher = AddComponent(/datum/component/soulcatcher/small_device) + linked_soulcatcher.name = name + +/obj/item/attachable_soulcatcher/attack_self(mob/user, modifiers) + linked_soulcatcher.ui_interact(user) + +/obj/item/attachable_soulcatcher/afterattack(obj/item/target_item, mob/user, proximity_flag, click_parameters) + . = ..() + if(!proximity_flag || !istype(target_item)) + return FALSE + + if(target_item.GetComponent(/datum/component/soulcatcher)) + balloon_alert(user, "already attached!") + return FALSE + + if(is_type_in_list(target_item, blacklisted_items)) + balloon_alert(user, "incompatible!") + return FALSE + + var/datum/component/soulcatcher/new_soulcatcher = target_item.AddComponent(/datum/component/soulcatcher/attachable_soulcatcher) + playsound(target_item.loc, 'sound/weapons/circsawhit.ogg', 50, vary = TRUE) + + var/datum/soulcatcher_room/target_room = new_soulcatcher.soulcatcher_rooms[1] + var/list/current_souls = linked_soulcatcher.get_current_souls() + if(current_souls) + for(var/mob/living/soulcatcher_soul/soul as anything in current_souls) + var/datum/soulcatcher_room/current_room = soul.current_room.resolve() + if(istype(current_room)) + current_room.transfer_soul(soul, target_room) + current_room.transfer_soul(soul, target_room) + + if(destroy_on_use) + qdel(src) diff --git a/modular_skyrat/modules/modular_implants/code/soulcatcher/handheld_soulcatcher.dm b/modular_skyrat/modules/modular_implants/code/soulcatcher/handheld_soulcatcher.dm index 842aee82d59868..767f396057e6f0 100644 --- a/modular_skyrat/modules/modular_implants/code/soulcatcher/handheld_soulcatcher.dm +++ b/modular_skyrat/modules/modular_implants/code/soulcatcher/handheld_soulcatcher.dm @@ -111,4 +111,52 @@ return TRUE +/obj/item/handheld_soulcatcher/attack_secondary(mob/living/carbon/human/target_mob, mob/living/user, params) + if(!istype(target_mob)) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + var/obj/item/organ/internal/brain/target_brain = target_mob.get_organ_slot(ORGAN_SLOT_BRAIN) + if(!istype(target_brain)) + to_chat(user, span_warning("[target_mob] lacks a brain!")) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + if(!HAS_TRAIT(target_brain, TRAIT_RSD_COMPATIBLE)) + to_chat(user, span_warning("[target_mob]'s brain isn't compatible.")) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + if(target_mob.mind || target_mob.ckey || GetComponent(/datum/component/previous_body)) + to_chat(user, span_warning("[target_mob] is not able to receive a soul")) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + var/list/soul_list = list() + for(var/datum/soulcatcher_room/room as anything in linked_soulcatcher.soulcatcher_rooms) + for(var/mob/living/soulcatcher_soul/soul as anything in room.current_souls) + if(!soul.round_participant || soul.body_scan_needed) + continue + + soul_list += soul + + if(!length(soul_list)) + to_chat(user, span_warning("There are no souls that can be transferred to [target_mob].")) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + var/mob/living/soulcatcher_soul/chosen_soul = tgui_input_list(user, "Choose a soul to transfer into the body", name, soul_list) + if(!chosen_soul) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + if(chosen_soul.previous_body) + var/mob/living/old_body = chosen_soul.previous_body.resolve() + if(!old_body) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + + SEND_SIGNAL(old_body, COMSIG_SOULCATCHER_CHECK_SOUL, FALSE) + + chosen_soul.mind.transfer_to(target_mob, TRUE) + playsound(src, 'modular_skyrat/modules/modular_implants/sounds/default_good.ogg', 50, FALSE, ignore_walls = FALSE) + visible_message(span_notice("[src] beeps: Body transfer complete.")) + log_admin("[src] was used by [user] to transfer [chosen_soul]'s soulcatcher soul to [target_mob].") + + qdel(chosen_soul) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + #undef RSD_ATTEMPT_COOLDOWN diff --git a/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm b/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm index 97158ba5d9132f..88cca7817a2fe4 100644 --- a/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm +++ b/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_component.dm @@ -18,11 +18,19 @@ GLOBAL_LIST_EMPTY(soulcatchers) var/list/soulcatcher_rooms = list() /// What soulcatcher room are verbs sending messages to? var/datum/soulcatcher_room/targeted_soulcatcher_room + /// What theme are we using for our soulcatcher UI? + var/ui_theme = "default" /// Are ghosts currently able to join this soulcatcher? var/ghost_joinable = TRUE /// Do we want to ask the user permission before the ghost joins? var/require_approval = TRUE + /// What is the max number of people we can keep in this soulcatcher? If this is set to `FALSE` we don't have a limit + var/max_souls = FALSE + /// Are are the souls inside able to emote/speak as the parent? + var/communicate_as_parent = FALSE + /// Is the soulcatcher removable from the parent object? + var/removable = FALSE /datum/component/soulcatcher/New() . = ..() @@ -136,6 +144,32 @@ GLOBAL_LIST_EMPTY(soulcatchers) return TRUE +/// Returns a list containing all of the souls currently present within a soulcatcher. +/datum/component/soulcatcher/proc/get_current_souls() + var/list/current_souls = list() + for(var/datum/soulcatcher_room/room as anything in soulcatcher_rooms) + for(var/mob/living/soulcatcher_soul as anything in room.current_souls) + current_souls += soulcatcher_soul + + return current_souls + +/// Checks the total number of souls present and compares it with `max_souls` returns `TRUE` if there is room (or no limit), otherwise returns `FALSE` +/datum/component/soulcatcher/proc/check_for_vacancy() + if(!max_souls) + return TRUE + + if(length(get_current_souls()) >= max_souls) + return FALSE + + return TRUE + +/// Attempts to remove the soulcatcher from the attached object +/datum/component/soulcatcher/proc/remove_self() + if(!removable) + return FALSE + + qdel(src) + /** * Soulcatcher Room * @@ -266,10 +300,6 @@ GLOBAL_LIST_EMPTY(soulcatchers) if(!message_to_send) //Why say nothing? return FALSE - var/sender_name = "" - if(message_sender) - sender_name = "[message_sender] " - var/datum/asset/spritesheet/sheet = get_asset_datum(/datum/asset/spritesheet/chat) var/tag = sheet.icon_tag("nif-soulcatcher") var/soulcatcher_icon = "" @@ -277,6 +307,33 @@ GLOBAL_LIST_EMPTY(soulcatchers) if(tag) soulcatcher_icon = tag + var/mob/living/soulcatcher_soul/soul_sender = message_sender + if(istype(soul_sender) && soul_sender.communicating_externally) + var/master_resolved = master_soulcatcher.resolve() + if(!master_resolved) + return FALSE + var/datum/component/soulcatcher/parent_soulcatcher = master_resolved + var/obj/item/parent_object = parent_soulcatcher.parent + if(!istype(parent_object)) + return FALSE + + var/temp_name = parent_object.name + parent_object.name = "[parent_object.name] [soulcatcher_icon]" + + if(emote) + parent_object.manual_emote(html_decode(message_to_send)) + log_emote("[soul_sender] in [name] soulcatcher room emoted: [message_to_send], as an external object") + else + parent_object.say(html_decode(message_to_send)) + log_say("[soul_sender] in [name] soulcatcher room said: [message_to_send], as an external object") + + parent_object.name = temp_name + return TRUE + + var/sender_name = "" + if(message_sender) + sender_name = "[message_sender] " + var/first_room_name_word = splittext(name, " ") var/message = "" var/owner_message = "" @@ -334,7 +391,7 @@ GLOBAL_LIST_EMPTY(soulcatchers) var/list/joinable_soulcatchers = list() for(var/datum/component/soulcatcher/soulcatcher in GLOB.soulcatchers) - if(!soulcatcher.ghost_joinable || !isobj(soulcatcher.parent)) + if(!soulcatcher.ghost_joinable || !isobj(soulcatcher.parent) || !soulcatcher.check_for_vacancy()) continue var/obj/item/soulcatcher_parent = soulcatcher.parent @@ -360,6 +417,7 @@ GLOBAL_LIST_EMPTY(soulcatchers) var/datum/soulcatcher_room/room_to_join if(length(rooms_to_join) < 1) + to_chat(src, span_warning("There no rooms that you can join.")) return FALSE if(length(rooms_to_join) == 1) diff --git a/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_mob.dm b/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_mob.dm index fefaf69c25e730..8ae004b9667706 100644 --- a/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_mob.dm +++ b/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_mob.dm @@ -23,6 +23,12 @@ var/able_to_speak = TRUE /// Is the soul able to change their own name? var/able_to_rename = TRUE + /// Is the soul able to speak as the object it is inside? + var/able_to_speak_as_container = TRUE + /// Is the soul able to emote as the object it is inside? + var/able_to_emote_as_container = TRUE + /// Are emote's and Say's done through the container the mob is in? + var/communicating_externally = FALSE /// Is the soul able to leave the soulcatcher? var/able_to_leave = TRUE @@ -110,7 +116,7 @@ if(!message || message == "") return - if(!able_to_speak) + if((!able_to_speak && !communicating_externally) || (!able_to_speak_as_container && communicating_externally)) to_chat(src, span_warning("You are unable to speak!")) return FALSE @@ -126,7 +132,7 @@ if(!message) return FALSE - if(!able_to_emote) + if((!able_to_emote && !communicating_externally) || (!able_to_emote_as_container && communicating_externally)) to_chat(src, span_warning("You are unable to emote!")) return FALSE diff --git a/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_tgui.dm b/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_tgui.dm index b59cee1f7ad316..5dbd31631ec311 100644 --- a/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_tgui.dm +++ b/modular_skyrat/modules/modular_implants/code/soulcatcher/soulcatcher_tgui.dm @@ -13,6 +13,11 @@ data["ghost_joinable"] = ghost_joinable data["require_approval"] = require_approval + data["theme"] = ui_theme + data["communicate_as_parent"] = communicate_as_parent + data["current_soul_count"] = length(get_current_souls()) + data["max_souls"] = max_souls + data["removable"] = removable data["current_rooms"] = list() for(var/datum/soulcatcher_room/room in soulcatcher_rooms) @@ -41,6 +46,8 @@ "able_to_rename" = soul.able_to_rename, "ooc_notes" = soul.ooc_notes, "scan_needed" = soul.body_scan_needed, + "able_to_speak_as_container" = soul.able_to_speak_as_container, + "able_to_emote_as_container" = soul.able_to_emote_as_container, ) room_data["souls"] += list(soul_list) @@ -147,7 +154,7 @@ continue var/datum/component/soulcatcher/soulcatcher_component = held_item.GetComponent(/datum/component/soulcatcher) - if(!soulcatcher_component) + if(!soulcatcher_component || !soulcatcher_component.check_for_vacancy()) continue for(var/datum/soulcatcher_room/room in soulcatcher_component.soulcatcher_rooms) @@ -191,6 +198,14 @@ return TRUE + if("toggle_soul_external_communication") + if(params["communication_type"] == "emote") + target_soul.able_to_emote_as_container = !target_soul.able_to_emote_as_container + else + target_soul.able_to_speak_as_container = !target_soul.able_to_speak_as_container + + return TRUE + if("toggle_soul_renaming") target_soul.able_to_rename = !target_soul.able_to_rename return TRUE @@ -224,6 +239,13 @@ target_room.send_message(message_to_send, message_sender, emote) return TRUE + if("delete_self") + if(tgui_alert(usr, "Are you sure you want to detach the soulcatcher?", parent, list("Yes", "No")) != "Yes") + return FALSE + + remove_self() + return TRUE + /datum/component/soulcatcher_user/New() . = ..() var/mob/living/soulcatcher_soul/parent_soul = parent @@ -259,6 +281,9 @@ "able_to_emote" = user_soul.able_to_emote, "able_to_speak" = user_soul.able_to_speak, "able_to_rename" = user_soul.able_to_rename, + "able_to_speak_as_container" = user_soul.able_to_speak_as_container, + "able_to_emote_as_container" = user_soul.able_to_emote_as_container, + "communicating_externally" = user_soul.communicating_externally, "ooc_notes" = user_soul.ooc_notes, "scan_needed" = user_soul.body_scan_needed, ) @@ -272,6 +297,9 @@ "owner" = current_room.outside_voice, ) + var/datum/component/soulcatcher/master_soulcatcher = current_room.master_soulcatcher.resolve() + data["communicate_as_parent"] = master_soulcatcher.communicate_as_parent + for(var/mob/living/soulcatcher_soul/soul in current_room.current_souls) if(soul == user_soul) continue @@ -310,3 +338,6 @@ user_soul.reset_name() + if("toggle_external_communication") + user_soul.communicating_externally = !user_soul.communicating_externally + return TRUE diff --git a/modular_skyrat/modules/modular_implants/icons/obj/devices.dmi b/modular_skyrat/modules/modular_implants/icons/obj/devices.dmi index d0a3f736fa60a8..401441f95de1f5 100644 Binary files a/modular_skyrat/modules/modular_implants/icons/obj/devices.dmi and b/modular_skyrat/modules/modular_implants/icons/obj/devices.dmi differ diff --git a/modular_skyrat/modules/modular_items/code/bags.dm b/modular_skyrat/modules/modular_items/code/bags.dm index 3e5e779268f7b1..f49954277e0b7d 100644 --- a/modular_skyrat/modules/modular_items/code/bags.dm +++ b/modular_skyrat/modules/modular_items/code/bags.dm @@ -4,6 +4,7 @@ desc = "It's a nondescript pouch made with dark fabric. It has a clip, for fitting in pockets." icon = 'modular_skyrat/modules/modular_items/icons/storage.dmi' icon_state = "survival" + w_class = WEIGHT_CLASS_NORMAL resistance_flags = FLAMMABLE slot_flags = ITEM_SLOT_POCKETS @@ -19,14 +20,34 @@ icon_state = "ammopouch" w_class = WEIGHT_CLASS_BULKY custom_price = PAYCHECK_CREW * 4 + // this is just to have post_reskin called later + uses_advanced_reskins = TRUE + unique_reskin = list( + "Ammo Pouch" = list( + RESKIN_ICON_STATE = "ammopouch" + ), + "Casing Pouch" = list( + RESKIN_ICON_STATE = "casingpouch" + ), + ) /obj/item/storage/pouch/ammo/Initialize(mapload) . = ..() atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 30 + atom_storage.max_total_storage = 12 atom_storage.max_slots = 3 atom_storage.numerical_stacking = FALSE - atom_storage.can_hold = typecacheof(list(/obj/item/ammo_box/magazine, /obj/item/ammo_casing, /obj/item/ammo_box/revolver, /obj/item/stock_parts/cell/microfusion)) + atom_storage.can_hold = typecacheof(list(/obj/item/ammo_box/magazine, /obj/item/ammo_casing, /obj/item/stock_parts/cell/microfusion)) + +/obj/item/storage/pouch/ammo/post_reskin(mob/our_mob) + if(icon_state == "casingpouch") + name = "casing pouch" + desc = "A pouch for your ammo that goes in your pocket, carefully segmented for holding shell casings and nothing else." + atom_storage.can_hold = typecacheof(list(/obj/item/ammo_casing)) + atom_storage.max_specific_storage = WEIGHT_CLASS_TINY + atom_storage.numerical_stacking = TRUE + atom_storage.max_slots = 10 + atom_storage.max_total_storage = WEIGHT_CLASS_TINY * 10 /obj/item/storage/pouch/material name = "material pouch" @@ -47,8 +68,7 @@ /// It's a pocket medkit. Use sparingly? /obj/item/storage/pouch/medical name = "medkit pouch" - desc = "A standard medkit pouch compartmentalized for the bare essentials of field medical care, made with fireproof kevlar \ - (but hopefully you never have to test that). Cannot, itself, contain a medkit. Comes with a pocket clip." + desc = "A standard medkit pouch compartmentalized for field medical care. Comes with a set of pocket clips." resistance_flags = FIRE_PROOF icon_state = "medkit" /// The list of things that medical pouches can hold. Stolen from what medkits can hold, but modified for things you would probably want at pocket-access. @@ -65,6 +85,7 @@ /obj/item/reagent_containers/spray, /obj/item/reagent_containers/hypospray, /obj/item/storage/pill_bottle, + /obj/item/storage/box/bandages, /obj/item/stack/medical, /obj/item/flashlight/pen, /obj/item/bonesetter, @@ -96,16 +117,23 @@ /// It's... not as egregious as a full pocket medkit. /obj/item/storage/pouch/medical/firstaid name = "first aid pouch" - desc = "A standard nondescript first-aid pouch, compartmentalized for the bare essentials of field medical care. Made with fireproof kevlar \ - (but hopefully you never have to test that). Slightly smaller than a full-on medkit, \ - but has better weight distribution, making it more comfortable to wear. Comes with a pocket-clip." + desc = "A standard nondescript first-aid pouch, compartmentalized for the bare essentials of field medical care. Comes with a pocket clip." icon_state = "firstaid" /obj/item/storage/pouch/medical/firstaid/Initialize(mapload) . = ..() atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL - atom_storage.max_slots = 4 - atom_storage.max_total_storage = 8 + /* + hi. you might think this is egregious. five slots? that's a lot! + here's a thought: the pocket first aid kit from the colonial replicator [modular_skyrat\modules\food_replicator\code\storage.dm] has + mostly unrestricted storage, limited by having 4 max total storage, so at best you're only fitting 4 tiny items. but that's 4 of *any* tiny item. + or 2 small items (that aren't guns/mags). so it's basically just turning 1 pocket slot into 2, if you think about it hard enough. + this is a thing you have to buy from cargo's goodies tab. not even an import. and it only fits medical supplies. + i think it can have a lil extra storage as a treat. + */ + atom_storage.max_slots = 5 + atom_storage.max_total_storage = 10 + atom_storage.numerical_stacking = TRUE /obj/item/storage/pouch/medical/firstaid/loaded/Initialize(mapload) . = ..() @@ -113,6 +141,7 @@ var/static/items_inside = list( /obj/item/stack/medical/suture = 1, /obj/item/stack/medical/mesh = 1, + /obj/item/storage/box/bandages = 1, /obj/item/stack/medical/gauze/twelve = 1, /obj/item/reagent_containers/hypospray/medipen/ekit = 1, ) @@ -125,6 +154,6 @@ /obj/item/cautery = 1, /obj/item/bonesetter = 1, /obj/item/stack/medical/gauze/twelve = 1, - /obj/item/reagent_containers/hypospray/medipen/ekit = 1, + /obj/item/reagent_containers/hypospray/medipen/ekit = 2, ) generate_items_inside(items_inside, src) diff --git a/modular_skyrat/modules/modular_items/code/tailoring.dm b/modular_skyrat/modules/modular_items/code/tailoring.dm index 22bce1ce3df7f4..8d7cf31f58fbbd 100644 --- a/modular_skyrat/modules/modular_items/code/tailoring.dm +++ b/modular_skyrat/modules/modular_items/code/tailoring.dm @@ -6,6 +6,14 @@ reqs = list(/obj/item/clothing/glasses/blindfold = 1) category = CAT_CLOTHING +/datum/crafting_recipe/paper_mask + name = "Paper Mask" + result = /obj/item/clothing/mask/paper + time = 30 + tool_behaviors = list(TOOL_WIRECUTTER) + reqs = list(/obj/item/paper = 5) + category = CAT_CLOTHING + /datum/crafting_recipe/crusader_belt name = "Crusader Belt and Sheath" result = /obj/item/storage/belt/crusader @@ -13,7 +21,7 @@ tool_behaviors = list(TOOL_WIRECUTTER, TOOL_SCREWDRIVER, TOOL_WELDER) //To cut the leather and fasten/weld the sheath detailing time = 30 category = CAT_CLOTHING - + /datum/crafting_recipe/crusader_belt/on_craft_completion(mob/user, atom/result) var/obj/item/storage/belt/crusader/crusader_belt = result crusader_belt.PopulateContents() @@ -54,7 +62,7 @@ reqs = list(/obj/item/clothing/glasses/hud/eyepatch/med = 1) tool_behaviors = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER) category = CAT_CLOTHING - + /datum/crafting_recipe/mesonpatch name = "Meson Eyepatch HUD" result = /obj/item/clothing/glasses/hud/eyepatch/meson diff --git a/modular_skyrat/modules/modular_items/icons/storage.dmi b/modular_skyrat/modules/modular_items/icons/storage.dmi index 8da1deba6dc97c..6587afcfc67ef6 100644 Binary files a/modular_skyrat/modules/modular_items/icons/storage.dmi and b/modular_skyrat/modules/modular_items/icons/storage.dmi differ diff --git a/modular_skyrat/modules/modular_vending/code/clothesmate.dm b/modular_skyrat/modules/modular_vending/code/clothesmate.dm index 73dc53a6465a42..19dd353f1fe819 100644 --- a/modular_skyrat/modules/modular_vending/code/clothesmate.dm +++ b/modular_skyrat/modules/modular_vending/code/clothesmate.dm @@ -36,6 +36,7 @@ /obj/item/clothing/glasses/betterunshit = 5, /obj/item/clothing/glasses/thin = 5, /obj/item/clothing/glasses/hud/ar/projector = 5, + /obj/item/clothing/gloves/bracer/wraps, ), ), @@ -125,6 +126,7 @@ /obj/item/clothing/shoes/colorable_sandals = 5, /obj/item/clothing/shoes/sports = 5, /obj/item/clothing/shoes/wraps/colourable = 5, + /obj/item/clothing/shoes/wraps/cloth = 5, /obj/item/clothing/shoes/jungleboots = 5, /obj/item/clothing/shoes/jackboots/knee = 5, /obj/item/clothing/shoes/jackboots/recolorable = 5, diff --git a/modular_skyrat/modules/modular_vending/code/games.dm b/modular_skyrat/modules/modular_vending/code/games.dm index cbc169a99ff737..99edcdb796c9cf 100644 --- a/modular_skyrat/modules/modular_vending/code/games.dm +++ b/modular_skyrat/modules/modular_vending/code/games.dm @@ -13,6 +13,7 @@ "products" = list( /obj/item/hairbrush = 3, /obj/item/clothing/mask/holocigarette = 5, + /obj/item/attachable_soulcatcher = 5, ), ) ) diff --git a/modular_skyrat/modules/modular_vending/code/wardrobes.dm b/modular_skyrat/modules/modular_vending/code/wardrobes.dm index e5f3e0210e7c9d..103bb2ca9754e0 100644 --- a/modular_skyrat/modules/modular_vending/code/wardrobes.dm +++ b/modular_skyrat/modules/modular_vending/code/wardrobes.dm @@ -61,9 +61,12 @@ /obj/item/clothing/mask/breath = 2, /obj/item/reagent_containers/cup/bottle/morphine = 2, /obj/item/reagent_containers/syringe = 2, + /obj/item/reagent_containers/spray/hercuri/chilled = 2, + /obj/item/clothing/gloves/color/black = 2, // fire resistant, allows the robo to painlessly mold metal. also its down here because its a treatment item /obj/item/bonesetter = 2, // for dislocations /obj/item/stack/medical/gauze = 4, // for ALL wounds /obj/item/healthanalyzer/no_medibot = 2, // disallows medibot use so its not wasted immediately on medibots + /obj/item/healthanalyzer/simple = 2, /obj/item/storage/backpack/science/robo = 2, /obj/item/storage/backpack/satchel/science/robo = 2, /obj/item/storage/backpack/duffelbag/science/robo = 2, diff --git a/modular_skyrat/modules/modular_weapons/code/autolathe_designs.dm b/modular_skyrat/modules/modular_weapons/code/autolathe_designs.dm index f51d6883d64318..89695235d2b8e1 100644 --- a/modular_skyrat/modules/modular_weapons/code/autolathe_designs.dm +++ b/modular_skyrat/modules/modular_weapons/code/autolathe_designs.dm @@ -46,16 +46,6 @@ build_path = /obj/item/ammo_casing/c45/rubber category = list(RND_CATEGORY_INITIAL, RND_CATEGORY_WEAPONS + RND_SUBCATEGORY_WEAPONS_AMMO) -// .460 Rowland magnum, for the M45A5 - -/datum/design/b460 - name = ".460 Rowland magnum" - id = "b460" - build_type = AUTOLATHE - materials = list(/datum/material/iron = SMALL_MATERIAL_AMOUNT * 8) - build_path = /obj/item/ammo_casing/b460 - category = list(RND_CATEGORY_HACKED, RND_CATEGORY_WEAPONS + RND_SUBCATEGORY_WEAPONS_AMMO) - // 10mm /datum/design/c10mm_lethal name = "10mm Bullet" diff --git a/modular_skyrat/modules/modular_weapons/code/automatic.dm b/modular_skyrat/modules/modular_weapons/code/automatic.dm deleted file mode 100644 index e9ccae147c91b7..00000000000000 --- a/modular_skyrat/modules/modular_weapons/code/automatic.dm +++ /dev/null @@ -1,121 +0,0 @@ -/* -* MAGAZINES -*/ - -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat - name = "CFA Wildcat magazine (.34)" - desc = "Magazines taking .34 ammunition; it fits in the CFA Wildcat. Alt+click to reskin it." - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi' - icon_state = "smg34" - possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_AP, AMMO_TYPE_RUBBER, AMMO_TYPE_INCENDIARY) - ammo_type = /obj/item/ammo_casing/c34 - caliber = "c34acp" - max_ammo = 30 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/ap - ammo_type = /obj/item/ammo_casing/c34/ap - round_type = AMMO_TYPE_AP - -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/rubber - ammo_type = /obj/item/ammo_casing/c34/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/incendiary - ammo_type = /obj/item/ammo_casing/c34_incendiary - round_type = AMMO_TYPE_INCENDIARY - -/obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/empty - start_empty = 1 - -/* -* WILDCAT -* 3rnd burst .32 calibre, 15 damage. -* Fills the role of a low damage, high magazine capacity magdump gun. -*/ - -/obj/item/gun/ballistic/automatic/cfa_wildcat - name = "\improper CFA Wildcat" - desc = "A robust roller-delayed SMG chambered for .34 ammunition." - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi' - icon_state = "mp5" - inhand_icon_state = "arg" - selector_switch_icon = TRUE - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat - can_suppress = FALSE - fire_delay = 1.25 - spread = 5 - mag_display = TRUE - empty_indicator = FALSE - fire_sound = 'sound/weapons/gun/smg/shot_alt.ogg' - weapon_weight = WEAPON_MEDIUM - w_class = WEIGHT_CLASS_BULKY - -/obj/item/gun/ballistic/automatic/cfa_wildcat/Initialize(mapload) - . = ..() - - AddComponent(/datum/component/automatic_fire, fire_delay) - -/obj/item/gun/ballistic/automatic/cfa_wildcat/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN) - -/obj/item/gun/ballistic/automatic/cfa_wildcat/no_mag - spawnwithmagazine = FALSE - -/* -* CFA LYNX -*/ - -/obj/item/gun/ballistic/automatic/cfa_lynx - name = "\improper CFA Lynx" - desc = "A carbine with a high magazine capacity. Chambered in 4.2x30mm." - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi' - icon_state = "cfa-lynx" - inhand_icon_state = "arg" - selector_switch_icon = FALSE - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx - can_suppress = FALSE - fire_delay = 1.90 //Previously 0.5. Changed due to it being the Blueshield's default firearm. - spread = 2 - mag_display = TRUE - empty_indicator = FALSE - fire_sound = 'sound/weapons/gun/smg/shot_alt.ogg' - weapon_weight = WEAPON_MEDIUM - w_class = WEIGHT_CLASS_BULKY - -/obj/item/gun/ballistic/automatic/cfa_lynx/Initialize(mapload) - . = ..() - - AddComponent(/datum/component/automatic_fire, fire_delay) - -/obj/item/gun/ballistic/automatic/cfa_lynx/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN) - -/obj/item/gun/ballistic/automatic/cfa_lynx/no_mag - spawnwithmagazine = FALSE - -/obj/item/ammo_box/magazine/multi_sprite/cfa_lynx - name = "CFA Lynx Magazine (4.2x30mm)" - desc = "A magazine for the CFA Lynx. It has a small inscription on the base, '4.2x30mm'. Alt+click to reskin it." - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi' - icon_state = "lynx" - possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_AP, AMMO_TYPE_RUBBER, AMMO_TYPE_INCENDIARY) - ammo_type = /obj/item/ammo_casing/c42x30mm - caliber = CALIBER_42X30MM - max_ammo = 40 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/cfa_lynx/ap - ammo_type = /obj/item/ammo_casing/c42x30mm/ap - round_type = AMMO_TYPE_AP - -/obj/item/ammo_box/magazine/multi_sprite/cfa_lynx/rubber - ammo_type = /obj/item/ammo_casing/c42x30mm/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/ammo_box/magazine/multi_sprite/cfa_lynx/incendiary - ammo_type = /obj/item/ammo_casing/c42x30mm/inc - round_type = AMMO_TYPE_INCENDIARY - -/obj/item/ammo_box/magazine/multi_sprite/cfa_lynx/empty - start_empty = TRUE diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/advert.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/advert.dm new file mode 100644 index 00000000000000..3f0dedf288903c --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/advert.dm @@ -0,0 +1,36 @@ +/obj/structure/sign/poster/official/carwo_grenade + name = "Tydhouer - Precision Timing" + desc = "This poster depicts, alongside the prominent logo of Carwo Defense Systems, a variety of specialist .980 Tydhouer grenades for the Kiboko launcher." + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/propaganda.dmi' + icon_state = "grenadier" + +/obj/structure/sign/poster/official/carwo_grenade/examine_more(mob/user) + . = ..() + + . += "Small text details that certain types of grenades may not be available in your \ + region depending on local weapons regulations. Suspiciously, however, if you squint at \ + it a bit, the background colors of the image come together vaguely in the shape of \ + a computer board and a multitool. What did they mean by this?" + + return . + +MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/official/carwo_grenade, 32) + +/obj/structure/sign/poster/official/carwo_magazine + name = "Standardisation - Magazines of the Future" + desc = "This poster depicts, alongside the prominent logo of Carwo Defense Systems, the variety of magazine types the company has on offer for rifles. \ + It also goes into great deal to say, more or less, that any rifle can take any rifle magazine. Now this is technology like never seen before." + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/propaganda.dmi' + icon_state = "mag_size" + +/obj/structure/sign/poster/official/carwo_magazine/examine_more(mob/user) + . = ..() + + . += "Small text details that certain types of magazines may not be available in your \ + region depending on local weapons regulations. Suspiciously, however, if you squint at \ + it a bit, the background colors of the image come together vaguely in the shape of \ + a computer board and a multitool. What did they mean by this?" + + return . + +MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/official/carwo_magazine, 32) diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/grenade.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/grenade.dm new file mode 100644 index 00000000000000..37c9fc0f83598e --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/grenade.dm @@ -0,0 +1,260 @@ +#define AMMO_MATS_GRENADE list( \ + /datum/material/iron = SMALL_MATERIAL_AMOUNT * 4, \ +) + +#define AMMO_MATS_GRENADE_SHRAPNEL list( \ + /datum/material/iron = SMALL_MATERIAL_AMOUNT * 2,\ + /datum/material/titanium = SMALL_MATERIAL_AMOUNT * 2, \ +) + +#define AMMO_MATS_GRENADE_INCENDIARY list( \ + /datum/material/iron = SMALL_MATERIAL_AMOUNT * 2,\ + /datum/material/plasma = SMALL_MATERIAL_AMOUNT * 2, \ +) + +#define GRENADE_SMOKE_RANGE 0.75 + +// .980 grenades +// Grenades that can be given a range to detonate at by their firing gun + +/obj/item/ammo_casing/c980grenade + name = ".980 Tydhouer practice grenade" + desc = "A large grenade shell that will detonate at a range given to it by the gun that fires it. Practice shells disintegrate into harmless sparks." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi' + icon_state = "980_solid" + + caliber = CALIBER_980TYDHOUER + projectile_type = /obj/projectile/bullet/c980grenade + + custom_materials = AMMO_MATS_GRENADE + + harmful = FALSE //Erm, technically + + +/obj/item/ammo_casing/c980grenade/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread, atom/fired_from) + var/obj/item/gun/ballistic/automatic/sol_grenade_launcher/firing_launcher = fired_from + if(istype(firing_launcher)) + loaded_projectile.range = firing_launcher.target_range + + . = ..() + + +/obj/projectile/bullet/c980grenade + name = ".980 Tydhouer practice grenade" + damage = 20 + stamina = 30 + + range = 14 + + speed = 2 // Higher means slower, y'all + + sharpness = NONE + + +/obj/projectile/bullet/c980grenade/on_hit(atom/target, blocked = FALSE) + ..() + fuse_activation(target) + return BULLET_ACT_HIT + + +/obj/projectile/bullet/c980grenade/on_range() + fuse_activation(get_turf(src)) + return ..() + + +/// Generic proc that is called when the projectile should 'detonate', being either on impact or when the range runs out +/obj/projectile/bullet/c980grenade/proc/fuse_activation(atom/target) + playsound(src, 'modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg', 50, TRUE, -3) + do_sparks(3, FALSE, src) + + +/obj/item/ammo_box/c980grenade + name = "ammo box (.980 Tydhouer practice)" + desc = "A box of four .980 Tydhouer practice grenades. Instructions on the box indicate these are dummy practice rounds that will disintegrate into sparks on detonation. Neat!" + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi' + icon_state = "980box_solid" + + multiple_sprites = AMMO_BOX_FULL_EMPTY + + w_class = WEIGHT_CLASS_NORMAL + + caliber = CALIBER_980TYDHOUER + ammo_type = /obj/item/ammo_casing/c980grenade + max_ammo = 4 + + +// .980 smoke grenade + +/obj/item/ammo_casing/c980grenade/smoke + name = ".980 Tydhouer smoke grenade" + desc = "A large grenade shell that will detonate at a range given to it by the gun that fires it. Bursts into a laser-weakening smoke cloud." + + icon_state = "980_smoke" + + projectile_type = /obj/projectile/bullet/c980grenade/smoke + + +/obj/projectile/bullet/c980grenade/smoke + name = ".980 Tydhouer smoke grenade" + + +/obj/projectile/bullet/c980grenade/smoke/fuse_activation(atom/target) + playsound(src, 'modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg', 50, TRUE, -3) + playsound(src, 'sound/effects/smoke.ogg', 50, TRUE, -3) + var/datum/effect_system/fluid_spread/smoke/bad/smoke = new + smoke.set_up(GRENADE_SMOKE_RANGE, holder = src, location = src) + smoke.start() + + +/obj/item/ammo_box/c980grenade/smoke + name = "ammo box (.980 Tydhouer smoke)" + desc = "A box of four .980 Tydhouer smoke grenades. Instructions on the box indicate these are smoke rounds that will make a small cloud of laser-dampening smoke on detonation." + + icon_state = "980box_smoke" + + ammo_type = /obj/item/ammo_casing/c980grenade/smoke + + +// .980 shrapnel grenade + +/obj/item/ammo_casing/c980grenade/shrapnel + name = ".980 Tydhouer shrapnel grenade" + desc = "A large grenade shell that will detonate at a range given to it by the gun that fires it. Explodes into shrapnel on detonation." + + icon_state = "980_explosive" + + projectile_type = /obj/projectile/bullet/c980grenade/shrapnel + + custom_materials = AMMO_MATS_GRENADE_SHRAPNEL + advanced_print_req = TRUE + + harmful = TRUE + + +/obj/projectile/bullet/c980grenade/shrapnel + name = ".980 Tydhouer shrapnel grenade" + + /// What type of casing should we put inside the bullet to act as shrapnel later + var/casing_to_spawn = /obj/item/grenade/c980payload + + +/obj/projectile/bullet/c980grenade/shrapnel/fuse_activation(atom/target) + var/obj/item/grenade/shrapnel_maker = new casing_to_spawn(get_turf(src)) + + shrapnel_maker.detonate() + qdel(shrapnel_maker) + + playsound(src, 'modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg', 50, TRUE, -3) + + +/obj/item/ammo_box/c980grenade/shrapnel + name = "ammo box (.980 Tydhouer shrapnel)" + desc = "A box of four .980 Tydhouer shrapnel grenades. Instructions on the box indicate these are shrapnel rounds. Its also covered in hazard signs, odd." + + icon_state = "980box_explosive" + + ammo_type = /obj/item/ammo_casing/c980grenade/shrapnel + + +/obj/item/grenade/c980payload + shrapnel_type = /obj/projectile/bullet/shrapnel/short_range + shrapnel_radius = 2 + ex_dev = 0 + ex_heavy = 0 + ex_light = 0 + ex_flame = 0 + + +/obj/projectile/bullet/shrapnel/short_range + range = 2 + + +// .980 phosphor grenade + +/obj/item/ammo_casing/c980grenade/shrapnel/phosphor + name = ".980 Tydhouer phosphor grenade" + desc = "A large grenade shell that will detonate at a range given to it by the gun that fires it. Explodes into smoke and flames on detonation." + + icon_state = "980_gas_alternate" + + projectile_type = /obj/projectile/bullet/c980grenade/shrapnel/phosphor + + custom_materials = AMMO_MATS_GRENADE_INCENDIARY + + +/obj/projectile/bullet/c980grenade/shrapnel/phosphor + name = ".980 Tydhouer phosphor grenade" + + casing_to_spawn = /obj/item/grenade/c980payload/phosphor + + +/obj/projectile/bullet/c980grenade/shrapnel/phosphor/fuse_activation(atom/target) + . = ..() + + playsound(src, 'sound/effects/smoke.ogg', 50, TRUE, -3) + var/datum/effect_system/fluid_spread/smoke/quick/smoke = new + smoke.set_up(GRENADE_SMOKE_RANGE, holder = src, location = src) + smoke.start() + + +/obj/item/ammo_box/c980grenade/shrapnel/phosphor + name = "ammo box (.980 Tydhouer phosphor)" + desc = "A box of four .980 Tydhouer phosphor grenades. Instructions on the box indicate these are incendiary explosive rounds. Its also covered in hazard signs, odd." + + icon_state = "980box_gas_alternate" + + ammo_type = /obj/item/ammo_casing/c980grenade/shrapnel/phosphor + + +/obj/item/ammo_casing/shrapnel_exploder/phosphor + pellets = 8 + + projectile_type = /obj/projectile/bullet/incendiary/fire/backblast/short_range + + +/obj/item/grenade/c980payload/phosphor + shrapnel_type = /obj/projectile/bullet/incendiary/fire/backblast/short_range + + +/obj/projectile/bullet/incendiary/fire/backblast/short_range + range = 2 + + +// .980 tear gas grenade + +/obj/item/ammo_casing/c980grenade/riot + name = ".980 Tydhouer tear gas grenade" + desc = "A large grenade shell that will detonate at a range given to it by the gun that fires it. Bursts into a tear gas cloud." + + icon_state = "980_gas" + + projectile_type = /obj/projectile/bullet/c980grenade/riot + + +/obj/projectile/bullet/c980grenade/riot + name = ".980 Tydhouer tear gas grenade" + +/obj/projectile/bullet/c980grenade/riot/fuse_activation(atom/target) + playsound(src, 'modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg', 50, TRUE, -3) + playsound(src, 'sound/effects/smoke.ogg', 50, TRUE, -3) + var/datum/effect_system/fluid_spread/smoke/chem/smoke = new() + smoke.chemholder.add_reagent(/datum/reagent/consumable/condensedcapsaicin, 10) + smoke.set_up(GRENADE_SMOKE_RANGE, holder = src, location = src) + smoke.start() + + +/obj/item/ammo_box/c980grenade/riot + name = "ammo box (.980 Tydhouer tear gas)" + desc = "A box of four .980 Tydhouer tear gas grenades. Instructions on the box indicate these are smoke rounds that will make a small cloud of laser-dampening smoke on detonation." + + icon_state = "980box_gas" + + ammo_type = /obj/item/ammo_casing/c980grenade/riot + +#undef AMMO_MATS_GRENADE +#undef AMMO_MATS_GRENADE_SHRAPNEL +#undef AMMO_MATS_GRENADE_INCENDIARY + +#undef GRENADE_SMOKE_RANGE diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/pistol.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/pistol.dm new file mode 100644 index 00000000000000..e20070dcef50af --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/pistol.dm @@ -0,0 +1,134 @@ +// .35 Sol Short +// Pistol caliber caseless round used almost exclusively by SolFed weapons + +/obj/item/ammo_casing/c35sol + name = ".35 Sol Short lethal bullet casing" + desc = "A SolFed standard caseless lethal pistol round." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi' + icon_state = "35sol" + + caliber = CALIBER_SOL35SHORT + projectile_type = /obj/projectile/bullet/c35sol + + +/obj/item/ammo_casing/c35sol/Initialize(mapload) + . = ..() + + AddElement(/datum/element/caseless) + + +/obj/projectile/bullet/c35sol + name = ".35 Sol Short bullet" + damage = 25 + + wound_bonus = 10 // Normal bullets are 20 + bare_wound_bonus = 20 + + +/obj/item/ammo_box/c35sol + name = "ammo box (.35 Sol Short lethal)" + desc = "A box of .35 Sol Short pistol rounds, holds twenty-four rounds." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi' + icon_state = "35box" + + multiple_sprites = AMMO_BOX_FULL_EMPTY + + w_class = WEIGHT_CLASS_NORMAL + + caliber = CALIBER_SOL35SHORT + ammo_type = /obj/item/ammo_casing/c35sol + max_ammo = 24 + + +// .35 Sol's equivalent to a rubber bullet + +/obj/item/ammo_casing/c35sol/incapacitator + name = ".35 Sol Short incapacitator bullet casing" + desc = "A SolFed standard caseless less-lethal pistol round. Exhausts targets on hit, has a tendency to bounce off walls at shallow angles." + + icon_state = "35sol_disabler" + + projectile_type = /obj/projectile/bullet/c35sol/incapacitator + harmful = FALSE + + +/obj/projectile/bullet/c35sol/incapacitator + name = ".35 Sol Short incapacitator bullet" + damage = 5 + stamina = 30 + + wound_bonus = -40 + bare_wound_bonus = -20 + + weak_against_armour = TRUE + + // The stats of the ricochet are a nerfed version of detective revolver rubber ammo + // This is due to the fact that there's a lot more rounds fired quickly from weapons that use this, over a revolver + ricochet_auto_aim_angle = 30 + ricochet_auto_aim_range = 5 + ricochets_max = 4 + ricochet_incidence_leeway = 50 + ricochet_chance = 130 + ricochet_decay_damage = 0.8 + + shrapnel_type = null + sharpness = NONE + embedding = null + + +/obj/item/ammo_box/c35sol/incapacitator + name = "ammo box (.35 Sol Short incapacitator)" + desc = "A box of .35 Sol Short pistol rounds, holds twenty-four rounds. The blue stripe indicates this should hold less-lethal ammunition." + + icon_state = "35box_disabler" + + ammo_type = /obj/item/ammo_casing/c35sol/incapacitator + + +// .35 Sol ripper, similar to the detective revolver's dumdum rounds, causes slash wounds and is weak to armor + +/obj/item/ammo_casing/c35sol/ripper + name = ".35 Sol Short ripper bullet casing" + desc = "A SolFed standard caseless ripper pistol round. Causes slashing wounds on targets, but is weak to armor." + + icon_state = "35sol_shrapnel" + projectile_type = /obj/projectile/bullet/c35sol/ripper + + custom_materials = AMMO_MATS_RIPPER + advanced_print_req = TRUE + + +/obj/projectile/bullet/c35sol/ripper + name = ".35 Sol ripper bullet" + damage = 15 + + weak_against_armour = TRUE + + sharpness = SHARP_EDGED + + wound_bonus = 20 + bare_wound_bonus = 20 + + embedding = list( + embed_chance = 75, + fall_chance = 3, + jostle_chance = 4, + ignore_throwspeed_threshold = TRUE, + pain_stam_pct = 0.4, + pain_mult = 5, + jostle_pain_mult = 6, + rip_time = 1 SECONDS, + ) + + embed_falloff_tile = -15 + + +/obj/item/ammo_box/c35sol/ripper + name = "ammo box (.35 Sol Short ripper)" + desc = "A box of .35 Sol Short pistol rounds, holds twenty-four rounds. The purple stripe indicates this should hold hollowpoint-like ammunition." + + icon_state = "35box_shrapnel" + + ammo_type = /obj/item/ammo_casing/c35sol/ripper diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/rifle.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/rifle.dm new file mode 100644 index 00000000000000..a012b594c29a67 --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/ammo/rifle.dm @@ -0,0 +1,195 @@ +// .40 Sol Long +// Rifle caliber caseless ammo that kills people good + +/obj/item/ammo_casing/c40sol + name = ".40 Sol Long lethal bullet casing" + desc = "A SolFed standard caseless lethal rifle round." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi' + icon_state = "40sol" + + caliber = CALIBER_SOL40LONG + projectile_type = /obj/projectile/bullet/c40sol + + +/obj/item/ammo_casing/c40sol/Initialize(mapload) + . = ..() + + AddElement(/datum/element/caseless) + + +/obj/projectile/bullet/c40sol + name = ".40 Sol Long bullet" + damage = 35 + + wound_bonus = 10 + bare_wound_bonus = 20 + + +/obj/item/ammo_box/c40sol + name = "ammo box (.40 Sol Long lethal)" + desc = "A box of .40 Sol Long rifle rounds, holds thirty bullets." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi' + icon_state = "40box" + + multiple_sprites = AMMO_BOX_FULL_EMPTY + + w_class = WEIGHT_CLASS_NORMAL + + caliber = CALIBER_SOL40LONG + ammo_type = /obj/item/ammo_casing/c40sol + max_ammo = 30 + + +// .40 Sol fragmentation rounds, embeds shrapnel in the target almost every time at close to medium range. Teeeechnically less lethals. + +/obj/item/ammo_casing/c40sol/fragmentation + name = ".40 Sol Long fragmentation bullet casing" + desc = "A SolFed standard caseless fragmentation rifle round. Shatters upon impact, ejecting sharp shrapnel that can potentially incapacitate targets." + + icon_state = "40sol_disabler" + + projectile_type = /obj/projectile/bullet/c40sol/fragmentation + + advanced_print_req = TRUE + + harmful = FALSE + + +/obj/projectile/bullet/c40sol/fragmentation + name = ".40 Sol Long fragmentation bullet" + damage = 15 + stamina = 30 + + weak_against_armour = TRUE + + sharpness = SHARP_EDGED + wound_bonus = 0 + bare_wound_bonus = 10 + + shrapnel_type = /obj/item/shrapnel/stingball + embedding = list( + embed_chance = 50, + fall_chance = 5, + jostle_chance = 5, + ignore_throwspeed_threshold = TRUE, + pain_stam_pct = 0.4, + pain_mult = 2, + jostle_pain_mult = 3, + rip_time = 0.5 SECONDS, + ) + + embed_falloff_tile = -5 + + +/obj/item/ammo_box/c40sol/fragmentation + name = "ammo box (.40 Sol Long fragmentation)" + desc = "A box of .40 Sol Long rifle rounds, holds thirty bullets. The blue stripe indicates this should hold less lethal ammunition." + + icon_state = "40box_disabler" + + ammo_type = /obj/item/ammo_casing/c40sol/fragmentation + + +// .40 Sol match grade, bounces a lot, and if there's less than 20 bullet armor on wherever these hit, it'll go completely through the target and out the other side + +/obj/item/ammo_casing/c40sol/pierce + name = ".40 Sol Long match bullet casing" + desc = "A SolFed standard caseless match grade rifle round. Fires at a higher pressure and thus fires slightly faster projectiles. \ + Rumors say you can do sick ass wall bounce trick shots with these, though the official suggestion is to just shoot your target and \ + not the wall next to them." + + icon_state = "40sol_pierce" + + projectile_type = /obj/projectile/bullet/c40sol/pierce + + custom_materials = AMMO_MATS_AP + advanced_print_req = TRUE + + +/obj/projectile/bullet/c40sol/pierce + name = ".40 Sol match bullet" + + icon_state = "gaussphase" + + speed = 0.5 + + damage = 25 + armour_penetration = 20 + + wound_bonus = -30 + bare_wound_bonus = -10 + + ricochets_max = 2 + ricochet_chance = 80 + ricochet_auto_aim_range = 4 + ricochet_incidence_leeway = 65 + + projectile_piercing = PASSMOB + + +/obj/projectile/bullet/c40sol/pierce/on_hit(atom/target, blocked = FALSE) + if(isliving(target)) + var/mob/living/poor_sap = target + + // If the target mob has enough armor to stop the bullet, or the bullet has already gone through two people, stop it on this hit + if((poor_sap.run_armor_check(def_zone, BULLET, "", "", silent = TRUE) > 20) || (pierces > 2)) + projectile_piercing = NONE + + if(damage > 10) // Lets just be safe with this one + damage -= 5 + armour_penetration -= 10 + + return ..() + + +/obj/item/ammo_box/c40sol/pierce + name = "ammo box (.40 Sol Long match)" + desc = "A box of .40 Sol Long rifle rounds, holds thirty bullets. The yellow stripe indicates this should hold high performance ammuniton." + + icon_state = "40box_pierce" + + ammo_type = /obj/item/ammo_casing/c40sol/pierce + + +// .40 Sol incendiary + +/obj/item/ammo_casing/c40sol/incendiary + name = ".40 Sol Long incendiary bullet casing" + desc = "A SolFed standard caseless incendiary rifle round. Leaves no flaming trail, only igniting targets on impact." + + icon_state = "40sol_flame" + + projectile_type = /obj/projectile/bullet/c40sol/incendiary + + custom_materials = AMMO_MATS_TEMP + advanced_print_req = TRUE + + +/obj/projectile/bullet/c40sol/incendiary + name = ".40 Sol Long incendiary bullet" + icon_state = "redtrac" + + damage = 25 + + /// How many firestacks the bullet should impart upon a target when impacting + var/firestacks_to_give = 1 + + +/obj/projectile/bullet/c40sol/incendiary/on_hit(atom/target, blocked = FALSE) + . = ..() + + if(iscarbon(target)) + var/mob/living/carbon/gaslighter = target + gaslighter.adjust_fire_stacks(firestacks_to_give) + gaslighter.ignite_mob() + + +/obj/item/ammo_box/c40sol/incendiary + name = "ammo box (.40 Sol Long incendiary)" + desc = "A box of .40 Sol Long rifle rounds, holds thirty bullets. The orange stripe indicates this should hold incendiary ammunition." + + icon_state = "40box_flame" + + ammo_type = /obj/item/ammo_casing/c40sol/incendiary diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/grenade_launcher.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/grenade_launcher.dm new file mode 100644 index 00000000000000..b927e1cd38d987 --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/grenade_launcher.dm @@ -0,0 +1,93 @@ +// Low caliber grenade launcher (fun & games) + +/obj/item/gun/ballistic/automatic/sol_grenade_launcher + name = "\improper Carwo 'Kiboko' Grenade Launcher" + desc = "A unique grenade launcher firing .980 grenades. A laser sight system allows its user to specify a range for the grenades it fires to detonate at." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi' + icon_state = "kiboko" + + worn_icon = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_worn.dmi' + worn_icon_state = "kiboko" + + lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_lefthand.dmi' + righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_righthand.dmi' + inhand_icon_state = "kiboko" + + SET_BASE_PIXEL(-8, 0) + + special_mags = TRUE + + bolt_type = BOLT_TYPE_LOCKING + + w_class = WEIGHT_CLASS_BULKY + weapon_weight = WEAPON_HEAVY + slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING + + accepted_magazine_type = /obj/item/ammo_box/magazine/c980_grenade + + fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/grenade_launcher.ogg' + + can_suppress = FALSE + can_bayonet = FALSE + + burst_size = 1 + fire_delay = 5 + actions_types = list() + + /// The currently stored range to detonate shells at + var/target_range = 14 + /// The maximum range we can set grenades to detonate at, just to be safe + var/maximum_target_range = 14 + +/obj/item/gun/ballistic/automatic/sol_grenade_launcher/give_manufacturer_examine() + AddElement(/datum/element/manufacturer_examine, COMPANY_CARWO) + +/obj/item/gun/ballistic/automatic/sol_grenade_launcher/examine_more(mob/user) + . = ..() + + . += "The Kiboko is one of the strangest weapons Carwo offers. A grenade launcher, \ + though not in the standard grenade size. The much lighter .980 Tydhouer grenades \ + developed for the weapon offered many advantages over standard grenade launching \ + ammunition. For a start, it was significantly lighter, and easier to carry large \ + amounts of. What it also offered, however, and the reason SolFed funded the \ + project: Variable time fuze. Using the large and expensive ranging sight on the \ + launcher, its user can set an exact distance for the grenade to self detonate at. \ + The dream of militaries for decades, finally realized. The smaller shells do not, \ + however, make the weapon any more enjoyable to fire. The kick is only barely \ + manageable thanks to the massive muzzle brake at the front." + + return . + +/obj/item/gun/ballistic/automatic/sol_grenade_launcher/examine(mob/user) + . = ..() + + . += span_notice("With Right Click you can set the range that shells will detonate at.") + . += span_notice("A small indicator in the sight notes the current detonation range is: [target_range].") + +/obj/item/gun/ballistic/automatic/sol_grenade_launcher/afterattack_secondary(atom/target, mob/living/user, proximity_flag, click_parameters) + if(!target || !user) + return + + var/distance_ranged = get_dist(user, target) + if(distance_ranged > maximum_target_range) + user.balloon_alert(user, "out of range") + return + + target_range = distance_ranged + user.balloon_alert(user, "range set: [target_range]") + +/obj/item/gun/ballistic/automatic/sol_grenade_launcher/no_mag + spawnwithmagazine = FALSE + +// fun & games but evil this time + +/obj/item/gun/ballistic/automatic/sol_grenade_launcher/evil + icon_state = "kiboko_evil" + worn_icon_state = "kiboko_evil" + inhand_icon_state = "kiboko_evil" + + spawn_magazine_type = /obj/item/ammo_box/magazine/c980_grenade/drum + +/obj/item/gun/ballistic/automatic/sol_grenade_launcher/evil/no_mag + spawnwithmagazine = FALSE diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/gunsets.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/gunsets.dm new file mode 100644 index 00000000000000..030d17d0c43604 --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/gunsets.dm @@ -0,0 +1,85 @@ +// Base yellow carwo case + +/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case + desc = "A thick yellow gun case with foam inserts laid out to fit a weapon, magazines, and gear securely." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi' + icon_state = "case_carwo" + + worn_icon_state = "yellowcase" + + lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_lefthand.dmi' + righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_righthand.dmi' + inhand_icon_state = "yellowcase" + +// Empty version of the case + +/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/empty + +/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/empty/PopulateContents() + return + +// Sindano in a box, how innovative! + +/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano + name = "\improper Carwo 'Sindano' gunset" + + weapon_to_spawn = /obj/item/gun/ballistic/automatic/sol_smg/no_mag + extra_to_spawn = /obj/item/ammo_box/magazine/c35sol_pistol/stendo + +/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano/PopulateContents() + new weapon_to_spawn (src) + + generate_items_inside(list( + /obj/item/ammo_box/c35sol/incapacitator = 1, + /obj/item/ammo_box/c35sol = 1, + /obj/item/ammo_box/magazine/c35sol_pistol/stendo/starts_empty = 1, + /obj/item/ammo_box/magazine/c35sol_pistol/starts_empty = 2, + ), src) + +/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano/evil + weapon_to_spawn = /obj/item/gun/ballistic/automatic/sol_smg/evil/no_mag + +// Boxed grenade launcher, grenades sold seperately on this one + +/obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/kiboko_magless + name = "\improper Carwo 'Kiboko' gunset" + + weapon_to_spawn = /obj/item/gun/ballistic/automatic/sol_grenade_launcher/no_mag + extra_to_spawn = /obj/item/ammo_box/magazine/c980_grenade/starts_empty + + +/obj/structure/closet/secure_closet/armory_kiboko + name = "heavy equipment locker" + req_access = list(ACCESS_ARMORY) + icon_state = "shotguncase" + +/obj/structure/closet/secure_closet/armory_kiboko/PopulateContents() + . = ..() + + generate_items_inside(list( + /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/kiboko_magless = 1, + /obj/item/ammo_box/c980grenade = 2, + /obj/item/ammo_box/c980grenade/smoke = 1, + /obj/item/ammo_box/c980grenade/riot = 1, + ), src) + +/obj/structure/closet/secure_closet/armory_kiboko_but_evil + name = "heavy equipment locker" + icon = 'modular_skyrat/master_files/icons/obj/closet.dmi' + icon_door = "riot" + icon_state = "riot" + req_access = list(ACCESS_SYNDICATE) + anchored = 1 + +/obj/structure/closet/secure_closet/armory_kiboko_but_evil/PopulateContents() + . = ..() + + generate_items_inside(list( + /obj/item/gun/ballistic/automatic/sol_grenade_launcher/evil/no_mag = 1, + /obj/item/ammo_box/magazine/c980_grenade/drum/starts_empty = 2, + /obj/item/ammo_box/c980grenade/shrapnel = 1, + /obj/item/ammo_box/c980grenade/shrapnel/phosphor = 1, + /obj/item/ammo_box/c980grenade/smoke = 1, + /obj/item/ammo_box/c980grenade/riot = 1, + ), src) diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/magazines.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/magazines.dm new file mode 100644 index 00000000000000..0734cb89258f53 --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/magazines.dm @@ -0,0 +1,113 @@ +// .35 Sol pistol magazines + +/obj/item/ammo_box/magazine/c35sol_pistol + name = "\improper Sol pistol magazine" + desc = "A standard size magazine for SolFed pistols, holds twelve rounds." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi' + icon_state = "pistol_35_standard" + + multiple_sprites = AMMO_BOX_FULL_EMPTY + + w_class = WEIGHT_CLASS_TINY + + ammo_type = /obj/item/ammo_casing/c35sol + caliber = CALIBER_SOL35SHORT + max_ammo = 12 + +/obj/item/ammo_box/magazine/c35sol_pistol/starts_empty + start_empty = TRUE + +/obj/item/ammo_box/magazine/c35sol_pistol/stendo + name = "\improper Sol extended pistol magazine" + desc = "An extended magazine for SolFed pistols, holds twenty-four rounds." + + icon_state = "pistol_35_stended" + + w_class = WEIGHT_CLASS_NORMAL + + max_ammo = 24 + +/obj/item/ammo_box/magazine/c35sol_pistol/stendo/starts_empty + start_empty = TRUE + +// .40 Sol rifle magazines + +/obj/item/ammo_box/magazine/c40sol_rifle + name = "\improper Sol rifle short magazine" + desc = "A shortened magazine for SolFed rifles, holds fifteen rounds." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi' + icon_state = "rifle_short" + + multiple_sprites = AMMO_BOX_FULL_EMPTY + + w_class = WEIGHT_CLASS_TINY + + ammo_type = /obj/item/ammo_casing/c40sol + caliber = CALIBER_SOL40LONG + max_ammo = 15 + +/obj/item/ammo_box/magazine/c40sol_rifle/starts_empty + + start_empty = TRUE + +/obj/item/ammo_box/magazine/c40sol_rifle/standard + name = "\improper Sol rifle magazine" + desc = "A standard size magazine for SolFed rifles, holds thirty rounds." + + icon_state = "rifle_standard" + + w_class = WEIGHT_CLASS_SMALL + + max_ammo = 30 + +/obj/item/ammo_box/magazine/c40sol_rifle/standard/starts_empty + start_empty = TRUE + + +/obj/item/ammo_box/magazine/c40sol_rifle/drum + name = "\improper Sol rifle drum magazine" + desc = "A massive drum magazine for SolFed rifles, holds sixty rounds." + + icon_state = "rifle_drum" + + w_class = WEIGHT_CLASS_BULKY + + max_ammo = 60 + +/obj/item/ammo_box/magazine/c40sol_rifle/drum/starts_empty + start_empty = TRUE + +// .980 grenade magazines + +/obj/item/ammo_box/magazine/c980_grenade + name = "\improper Kiboko grenade box" + desc = "A standard size box for .980 grenades, holds four shells." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi' + icon_state = "granata_standard" + + multiple_sprites = AMMO_BOX_FULL_EMPTY + + w_class = WEIGHT_CLASS_SMALL + + ammo_type = /obj/item/ammo_casing/c980grenade + caliber = CALIBER_980TYDHOUER + max_ammo = 4 + +/obj/item/ammo_box/magazine/c980_grenade/starts_empty + start_empty = TRUE + +/obj/item/ammo_box/magazine/c980_grenade/drum + name = "\improper Kiboko grenade drum" + desc = "A drum for .980 grenades, holds six shells." + + icon_state = "granata_drum" + + w_class = WEIGHT_CLASS_NORMAL + + max_ammo = 6 + +/obj/item/ammo_box/magazine/c980_grenade/drum/starts_empty + start_empty = TRUE diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/rifle.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/rifle.dm new file mode 100644 index 00000000000000..5b298fec87c7ef --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/rifle.dm @@ -0,0 +1,160 @@ +// Base Sol rifle + +/obj/item/gun/ballistic/automatic/sol_rifle + name = "\improper Carwo 'd'Infanteria' Rifle" + desc = "A heavy battle rifle commonly seen in the hands of SolFed military types. Accepts any standard SolFed rifle magazine." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi' + icon_state = "infanterie" + + worn_icon = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_worn.dmi' + worn_icon_state = "infanterie" + + lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_lefthand.dmi' + righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_righthand.dmi' + inhand_icon_state = "infanterie" + + SET_BASE_PIXEL(-8, 0) + + special_mags = TRUE + + bolt_type = BOLT_TYPE_LOCKING + + w_class = WEIGHT_CLASS_BULKY + weapon_weight = WEAPON_HEAVY + slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING + + accepted_magazine_type = /obj/item/ammo_box/magazine/c40sol_rifle + spawn_magazine_type = /obj/item/ammo_box/magazine/c40sol_rifle/standard + + fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/rifle_heavy.ogg' + suppressed_sound = 'modular_skyrat/modules/modular_weapons/sounds/suppressed_rifle.ogg' + can_suppress = TRUE + + can_bayonet = FALSE + + suppressor_x_offset = 12 + + burst_size = 1 + fire_delay = 0.45 SECONDS + actions_types = list() + + spread = 7.5 + projectile_wound_bonus = -10 + +/obj/item/gun/ballistic/automatic/sol_rifle/Initialize(mapload) + . = ..() + + give_autofire() + +/// Separate proc for handling auto fire just because one of these subtypes isn't otomatica +/obj/item/gun/ballistic/automatic/sol_rifle/proc/give_autofire() + AddComponent(/datum/component/automatic_fire, fire_delay) + +/obj/item/gun/ballistic/automatic/sol_rifle/give_manufacturer_examine() + AddElement(/datum/element/manufacturer_examine, COMPANY_CARWO) + +/obj/item/gun/ballistic/automatic/sol_rifle/examine_more(mob/user) + . = ..() + + . += "The d'Infanterie rifles are, as the name may imply, built by Carwo for \ + use by SolFed's various infantry branches. Following the rather reasonable \ + military requirements of using the same few cartridges and magazines, \ + the lifespans of logistics coordinators and quartermasters everywhere \ + were lengthened by several years. While typically only for military sale \ + in the past, the recent collapse of certain unnamed weapons manufacturers \ + has caused Carwo to open many of its military weapons to civilian sale, \ + which includes this one." + + return . + +/obj/item/gun/ballistic/automatic/sol_rifle/no_mag + spawnwithmagazine = FALSE + +// Sol marksman rifle + +/obj/item/gun/ballistic/automatic/sol_rifle/marksman + name = "\improper Carwo 'd'Elite' Marksman Rifle" + desc = "A heavy marksman rifle commonly seen in the hands of SolFed military types. Accepts any standard SolFed rifle magazine." + + icon_state = "elite" + worn_icon_state = "elite" + inhand_icon_state = "elite" + + spawn_magazine_type = /obj/item/ammo_box/magazine/c40sol_rifle + + fire_delay = 0.75 SECONDS + + spread = 0 + projectile_damage_multiplier = 1.2 + projectile_wound_bonus = 10 + +/obj/item/gun/ballistic/automatic/sol_rifle/marksman/Initialize(mapload) + . = ..() + + AddComponent(/datum/component/scope, range_modifier = 2) + +/obj/item/gun/ballistic/automatic/sol_rifle/marksman/give_autofire() + return + +/obj/item/gun/ballistic/automatic/sol_rifle/marksman/examine_more(mob/user) + . = ..() + + . += "This particlar variant, often called 'd'Elite', is a marksman rifle. \ + Automatic fire was forsaken for a semi-automatic setup, a more fitting \ + stock, and more often than not a scope. Typically also seen with smaller \ + magazines for convenience for the shooter, but as with any other Sol \ + rifle, all standard magazine types will work." + + return . + +/obj/item/gun/ballistic/automatic/sol_rifle/marksman/no_mag + spawnwithmagazine = FALSE + +// Machinegun based on the base Sol rifle + +/obj/item/gun/ballistic/automatic/sol_rifle/machinegun + name = "\improper Carwo 'd'Outomaties' Machinegun" + desc = "A hefty machinegun commonly seen in the hands of SolFed military types. Accepts any standard SolFed rifle magazine." + + icon_state = "outomaties" + worn_icon_state = "outomaties" + inhand_icon_state = "outomaties" + + bolt_type = BOLT_TYPE_OPEN + + spawn_magazine_type = /obj/item/ammo_box/magazine/c40sol_rifle/drum + + fire_delay = 0.1 SECONDS + + recoil = 1 + spread = 12.5 + projectile_wound_bonus = -20 + +/obj/item/gun/ballistic/automatic/sol_rifle/machinegun/examine_more(mob/user) + . = ..() + + . += "The d'Outomaties variant of the rifle, what you are looking at now, \ + is a modification to turn the weapon into a passable, if sub-optimal \ + light machinegun. To support the machinegun role, the internals were \ + converted to make the gun into an open bolt, faster firing machine. These \ + additions, combined with a battle rifle not meant to be used fully auto \ + much to begin with, made for a relatively unwieldy weapon. A machinegun, \ + however, is still a machinegun, no matter how hard it is to keep on target." + + return . + +/obj/item/gun/ballistic/automatic/sol_rifle/machinegun/no_mag + spawnwithmagazine = FALSE + +// Evil version of the rifle (nothing different its just black) + +/obj/item/gun/ballistic/automatic/sol_rifle/evil + desc = "A heavy battle rifle, this one seems to be painted tacticool black. Accepts any standard SolFed rifle magazine." + + icon_state = "infanterie_evil" + worn_icon_state = "infanterie_evil" + inhand_icon_state = "infanterie_evil" + +/obj/item/gun/ballistic/automatic/sol_rifle/evil/no_mag + spawnwithmagazine = FALSE diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/shotgun.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/shotgun.dm new file mode 100644 index 00000000000000..af5f6131d887eb --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/shotgun.dm @@ -0,0 +1,62 @@ +// SolFed shotgun (this was gonna be in a proprietary shotgun shell type outside of 12ga at some point, wild right?) + +/obj/item/gun/ballistic/shotgun/riot/sol + name = "\improper Carwo 'Renoster' Shotgun" + desc = "A twelve gauge shotgun with a six shell capacity underneath. Made for and used by SolFed's various military branches." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi' + icon_state = "renoster" + + worn_icon = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_worn.dmi' + worn_icon_state = "renoster" + + lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_lefthand.dmi' + righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_righthand.dmi' + inhand_icon_state = "renoster" + + inhand_x_dimension = 32 + inhand_y_dimension = 32 + + SET_BASE_PIXEL(-8, 0) + + fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/shotgun_heavy.ogg' + rack_sound = 'modular_skyrat/modules/modular_weapons/sounds/shotgun_rack.ogg' + suppressed_sound = 'modular_skyrat/modules/modular_weapons/sounds/suppressed_heavy.ogg' + can_suppress = TRUE + + suppressor_x_offset = 9 + + w_class = WEIGHT_CLASS_BULKY + slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_OCLOTHING + +/obj/item/gun/ballistic/shotgun/riot/sol/give_manufacturer_examine() + AddElement(/datum/element/manufacturer_examine, COMPANY_CARWO) + +/obj/item/gun/ballistic/shotgun/riot/sol/examine_more(mob/user) + . = ..() + + . += "The Renoster was designed at its core as a police shotgun. \ + As consequence, it holds all the qualities a police force would want \ + in one. Large shell capacity, sturdy frame, while holding enough \ + capacity for modification to satiate even the most overfunded of \ + peacekeeper forces. Inevitably, the weapon made its way into civilian \ + markets alongside its sale to several military branches that also \ + saw value in having a heavy shotgun." + + return . + +/obj/item/gun/ballistic/shotgun/riot/sol/update_appearance(updates) + if(sawn_off) + suppressor_x_offset = 0 + SET_BASE_PIXEL(0, 0) + + . = ..() + +// Shotgun but EVIL! + +/obj/item/gun/ballistic/shotgun/riot/sol/evil + desc = "A twleve guage shotgun with an eight shell capacity underneath. This one is painted in a tacticool black." + + icon_state = "renoster_evil" + worn_icon_state = "renoster_evil" + inhand_icon_state = "renoster_evil" diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/submachinegun.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/submachinegun.dm new file mode 100644 index 00000000000000..61b1ed902fabd9 --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/carwo_defense_systems/submachinegun.dm @@ -0,0 +1,62 @@ +// Base Sol SMG + +/obj/item/gun/ballistic/automatic/sol_smg + name = "\improper Carwo 'Sindano' Submachinegun" + desc = "A small submachinegun commonly seen in the hands of PMCs and other unsavory corpos. Accepts any standard Sol pistol magazine." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns32x.dmi' + icon_state = "sindano" + + inhand_icon_state = "c20r" + + special_mags = TRUE + + bolt_type = BOLT_TYPE_OPEN + + w_class = WEIGHT_CLASS_NORMAL + weapon_weight = WEAPON_MEDIUM + slot_flags = ITEM_SLOT_OCLOTHING | ITEM_SLOT_BELT + + accepted_magazine_type = /obj/item/ammo_box/magazine/c35sol_pistol + spawn_magazine_type = /obj/item/ammo_box/magazine/c35sol_pistol/stendo + + fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/smg_light.ogg' + can_suppress = TRUE + + can_bayonet = FALSE + + suppressor_x_offset = 11 + + burst_size = 3 + fire_delay = 0.2 SECONDS + + spread = 7.5 + +/obj/item/gun/ballistic/automatic/sol_smg/give_manufacturer_examine() + AddElement(/datum/element/manufacturer_examine, COMPANY_CARWO) + +/obj/item/gun/ballistic/automatic/sol_smg/examine_more(mob/user) + . = ..() + + . += "The Sindano submachinegun was originally produced for military contract. \ + These guns were seen in the hands of anyone from medics, ship techs, logistics officers, \ + and shuttle pilots often had several just to show off. Due to SolFed's quest to \ + extend the lifespans of their logistics officers and quartermasters, the weapon \ + uses the same standard pistol cartridge that most other miltiary weapons of \ + small caliber use. This results in interchangeable magazines between pistols \ + and submachineguns, neat!" + + return . + +/obj/item/gun/ballistic/automatic/sol_smg/no_mag + spawnwithmagazine = FALSE + +// Sindano (evil) + +/obj/item/gun/ballistic/automatic/sol_smg/evil + desc = "A small submachinegun, this one is painted in tacticool black. Accepts any standard Sol pistol magazine." + + icon_state = "sindano_evil" + +/obj/item/gun/ballistic/automatic/sol_smg/evil/no_mag + spawnwithmagazine = FALSE diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/advert.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/advert.dm new file mode 100644 index 00000000000000..f076b0d73b3452 --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/advert.dm @@ -0,0 +1,41 @@ +/obj/structure/sign/poster/official/trappiste_suppressor + name = "Keep It Quiet - Ear Protection Unneeded" + desc = "This poster depicts, alongside the prominent logo of Trappiste Fabriek, a \ + diagram of the average suppressor, and how on most* Trappiste weapons \ + the sound of firing will be low enough to eradicate the need for ear protection. \ + How safety minded, they even have a non-liability statement too." + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/propaganda.dmi' + icon_state = "keep_it_quiet" + +/obj/structure/sign/poster/official/trappiste_suppressor/examine_more(mob/user) + . = ..() + + . += "It was hard to notice before, but now that you really look at it... \ + This thing is completely covered in micro scale text telling you in just about \ + every human language and then some that Trappiste isn't liable for ear damage \ + caused by their weapons, suppressed or not." + + return . + +MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/official/trappiste_suppressor, 32) + +/obj/structure/sign/poster/official/trappiste_ammunition + name = "Know Your Ammuniton Colors" + desc = "This poster depicts, alongside the prominent logo of Trappiste Fabriek, \ + a variety of colors that one may find on .585 Trappiste rounds. \ + A plain white case usually means lethal, while a blue stripe is less-lethal \ + and a purple stripe is more lethal. How informative." + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/propaganda.dmi' + icon_state = "know_the_difference" + +/obj/structure/sign/poster/official/trappiste_ammunition/examine_more(mob/user) + . = ..() + + . += "Small text details that this information may also be transferrable \ + to other types of SolFed ammunition, but that you should check the box \ + the bullets come in just to be sure. Trappiste is, of course,\ + not liable for excess harm caused by misreading color identification systems." + + return . + +MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sign/poster/official/trappiste_ammunition, 32) diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/ammo.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/ammo.dm new file mode 100644 index 00000000000000..498f55a5627b6d --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/ammo.dm @@ -0,0 +1,91 @@ +// .585 Trappiste +// High caliber round used in large pistols and revolvers + +/obj/item/ammo_casing/c585trappiste + name = ".585 Trappiste lethal bullet casing" + desc = "A white polymer cased high caliber round commonly used in handguns." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/ammo.dmi' + icon_state = "585trappiste" + + caliber = CALIBER_585TRAPPISTE + projectile_type = /obj/projectile/bullet/c585trappiste + +/obj/projectile/bullet/c585trappiste + name = ".585 Trappiste bullet" + damage = 45 + wound_bonus = 0 // Normal bullets are 20 + +/obj/item/ammo_box/c585trappiste + name = "ammo box (.585 Trappiste lethal)" + desc = "A box of .585 Trappiste pistol rounds, holds twelve cartridges." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/ammo.dmi' + icon_state = "585box" + + multiple_sprites = AMMO_BOX_FULL_EMPTY + + w_class = WEIGHT_CLASS_NORMAL + + caliber = CALIBER_585TRAPPISTE + ammo_type = /obj/item/ammo_casing/c585trappiste + max_ammo = 12 + +// .585 Trappiste equivalent to a rubber bullet + +/obj/item/ammo_casing/c585trappiste/incapacitator + name = ".585 Trappiste flathead bullet casing" + desc = "A white polymer cased high caliber round with a relatively soft, flat tip. Designed to flatten against targets and usually not penetrate on impact." + + icon_state = "585trappiste_disabler" + + projectile_type = /obj/projectile/bullet/c585trappiste/incapacitator + harmful = FALSE + +/obj/projectile/bullet/c585trappiste/incapacitator + name = ".585 Trappiste flathead bullet" + damage = 20 + stamina = 40 + wound_bonus = 10 + + weak_against_armour = TRUE + + shrapnel_type = null + sharpness = NONE + embedding = null + +/obj/item/ammo_box/c585trappiste/incapacitator + name = "ammo box (.585 Trappiste flathead)" + desc = "A box of .585 Trappiste pistol rounds, holds twelve cartridges. The blue stripe indicates that it should hold less lethal rounds." + + icon_state = "585box_disabler" + + ammo_type = /obj/item/ammo_casing/c585trappiste/incapacitator + +// .585 hollowpoint, made to cause nasty wounds + +/obj/item/ammo_casing/c585trappiste/hollowpoint + name = ".585 Trappiste hollowhead bullet casing" + desc = "A white polymer cased high caliber round with a hollowed tip. Designed to cause as much damage on impact to fleshy targets as possible." + + icon_state = "585trappiste_shrapnel" + projectile_type = /obj/projectile/bullet/c585trappiste/hollowpoint + + advanced_print_req = TRUE + +/obj/projectile/bullet/c585trappiste/hollowpoint + name = ".585 Trappiste hollowhead bullet" + damage = 35 + + weak_against_armour = TRUE + + wound_bonus = 30 + bare_wound_bonus = 40 + +/obj/item/ammo_box/c585trappiste/hollowpoint + name = "ammo box (.585 Trappiste hollowhead)" + desc = "A box of .585 Trappiste pistol rounds, holds twelve cartridges. The purple stripe indicates that it should hold hollowpoint-like rounds." + + icon_state = "585box_shrapnel" + + ammo_type = /obj/item/ammo_casing/c585trappiste/hollowpoint diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/gunsets.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/gunsets.dm new file mode 100644 index 00000000000000..41607663a508ef --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/gunsets.dm @@ -0,0 +1,34 @@ +// Base yellow with symbol trappiste case + +/obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case + desc = "A thick yellow gun case with foam inserts laid out to fit a weapon, magazines, and gear securely. The five square grid of Trappiste Fabriek is displayed prominently on the top." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi' + icon_state = "case_trappiste" + + lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_lefthand.dmi' + righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_righthand.dmi' + inhand_icon_state = "yellowcase" + +// Empty version of the case + +/obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/empty + +/obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/empty/PopulateContents() + return + +// Gunset for the Wespe pistol + +/obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/wespe + name = "Trappiste 'Wespe' gunset" + + weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol/sol/no_mag + extra_to_spawn = /obj/item/ammo_box/magazine/c35sol_pistol + +// Gunset for the Skild heavy pistol + +/obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild + name = "Trappiste 'Skild' gunset" + + weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol/trappiste/no_mag + extra_to_spawn = /obj/item/ammo_box/magazine/c585trappiste_pistol diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/magazines.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/magazines.dm new file mode 100644 index 00000000000000..77506ccd29f0f2 --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/magazines.dm @@ -0,0 +1,19 @@ +// .585 pistol magazines + +/obj/item/ammo_box/magazine/c585trappiste_pistol + name = "\improper Trappiste pistol magazine" + desc = "A standard size magazine for Trappiste pistols, holds six rounds." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/ammo.dmi' + icon_state = "pistol_585_standard" + + multiple_sprites = AMMO_BOX_FULL_EMPTY + + w_class = WEIGHT_CLASS_SMALL + + ammo_type = /obj/item/ammo_casing/c585trappiste + caliber = CALIBER_585TRAPPISTE + max_ammo = 6 + +/obj/item/ammo_box/magazine/c585trappiste_pistol/spawns_empty + start_empty = TRUE diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/pistol.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/pistol.dm new file mode 100644 index 00000000000000..1ae391325d0a0b --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/pistol.dm @@ -0,0 +1,100 @@ +// .35 Sol pistol + +/obj/item/gun/ballistic/automatic/pistol/sol + name = "\improper Trappiste 'Wespe' Pistol" + desc = "The standard issue service pistol of SolFed's various military branches. Comes with attached light." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi' + icon_state = "wespe" + + fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/pistol_light.ogg' + + w_class = WEIGHT_CLASS_NORMAL + + accepted_magazine_type = /obj/item/ammo_box/magazine/c35sol_pistol + special_mags = TRUE + + suppressor_x_offset = 7 + suppressor_y_offset = 0 + + fire_delay = 0.3 SECONDS + +/obj/item/gun/ballistic/automatic/pistol/sol/give_manufacturer_examine() + AddElement(/datum/element/manufacturer_examine, COMPANY_TRAPPISTE) + +/obj/item/gun/ballistic/automatic/pistol/sol/add_seclight_point() + AddComponent(/datum/component/seclite_attachable, \ + starting_light = new /obj/item/flashlight/seclite(src), \ + is_light_removable = FALSE, \ + ) + +/obj/item/gun/ballistic/automatic/pistol/sol/examine_more(mob/user) + . = ..() + + . += "The Wespe is a pistol that was made entirely for military use. \ + Required to use a standard round, standard magazines, and be able \ + to function in all of the environments that SolFed operated in \ + commonly. These qualities just so happened to make the weapon \ + popular in frontier space and is likely why you are looking at \ + one now." + + return . + +/obj/item/gun/ballistic/automatic/pistol/sol/no_mag + spawnwithmagazine = FALSE + +// Sol pistol evil gun + +/obj/item/gun/ballistic/automatic/pistol/sol/evil + desc = "The standard issue service pistol of SolFed's various military branches. Comes with attached light. This one is painted tacticool black." + + icon_state = "wespe_evil" + +/obj/item/gun/ballistic/automatic/pistol/sol/evil/no_mag + spawnwithmagazine = FALSE + +// Trappiste high caliber pistol in .585 + +/obj/item/gun/ballistic/automatic/pistol/trappiste + name = "\improper Trappiste 'Skild' Pistol" + desc = "A somewhat rare to see Trappiste pistol firing the high caliber .585 developed by the same company. Sees rare use mainly due to its tendency to cause severe wrist discomfort." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi' + icon_state = "skild" + + fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/pistol_heavy.ogg' + suppressed_sound = 'modular_skyrat/modules/modular_weapons/sounds/suppressed_heavy.ogg' + + w_class = WEIGHT_CLASS_NORMAL + + accepted_magazine_type = /obj/item/ammo_box/magazine/c585trappiste_pistol + + suppressor_x_offset = 8 + suppressor_y_offset = 0 + + fire_delay = 1 SECONDS + + recoil = 3 + +/obj/item/gun/ballistic/automatic/pistol/trappiste/give_manufacturer_examine() + AddElement(/datum/element/manufacturer_examine, COMPANY_TRAPPISTE) + +/obj/item/gun/ballistic/automatic/pistol/trappiste/examine_more(mob/user) + . = ..() + + . += "The Skild only exists due to a widely known event that SolFed's military \ + would prefer wasn't anywhere near as popular. A general, name unknown as of now, \ + was recorded complaining about the lack of capability the Wespe provided to the \ + military, alongside several statements comparing the Wespe's lack of masculinity \ + to the, quote, 'unique lack of testosterone those NRI mongrels field'. While the \ + identities of both the general and people responsible for the leaking of the recording \ + are still classified, many high ranking SolFed military staff suspiciously have stopped \ + appearing in public, unlike the Skild. A lot of several thousand pistols, the first \ + of the weapons to ever exist, were not so silently shipped to SolFed's Plutonian \ + shipping hub from TRAPPIST. SolFed military command refuses to answer any \ + further questions about the incident to this day." + + return . + +/obj/item/gun/ballistic/automatic/pistol/trappiste/no_mag + spawnwithmagazine = FALSE diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/revolver.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/revolver.dm new file mode 100644 index 00000000000000..22cbb471449abc --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/trappiste_fabriek/revolver.dm @@ -0,0 +1,81 @@ +// .35 Sol mini revolver + +/obj/item/gun/ballistic/revolver/sol + name = "\improper Trappiste 'Eland' Revolver" + desc = "A small revolver with a comically short barrel and cylinder space for eight .35 Sol Short rounds." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi' + icon_state = "eland" + + accepted_magazine_type = /obj/item/ammo_box/magazine/internal/cylinder/c35sol + + suppressor_x_offset = 3 + + w_class = WEIGHT_CLASS_SMALL + + can_suppress = TRUE + +/obj/item/gun/ballistic/revolver/sol/give_manufacturer_examine() + AddElement(/datum/element/manufacturer_examine, COMPANY_TRAPPISTE) + +/obj/item/gun/ballistic/revolver/sol/examine_more(mob/user) + . = ..() + + . += "The Eland is one of the few Trappiste weapons not made for military contract. \ + Instead, the Eland started life as a police weapon, offered as a gun to finally \ + outmatch all others in the cheap police weapons market. Unfortunately, this \ + coincided with nearly every SolFed police force realising they are actually \ + comically overfunded. With military weapons bought for police forces taking \ + over the market, the Eland instead found home in the civilian personal defense \ + market. That is likely the reason you are looking at this one now." + + return . + +/obj/item/ammo_box/magazine/internal/cylinder/c35sol + ammo_type = /obj/item/ammo_casing/c35sol + caliber = CALIBER_SOL35SHORT + max_ammo = 8 + +// .585 super revolver + +/obj/item/gun/ballistic/revolver/takbok + name = "\improper Trappiste 'Takbok' Revolver" + desc = "A hefty revolver with an equally large cylinder capable of holding five .585 Trappiste rounds." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi' + icon_state = "takbok" + + fire_sound = 'modular_skyrat/modules/modular_weapons/sounds/revolver_heavy.ogg' + suppressed_sound = 'modular_skyrat/modules/modular_weapons/sounds/suppressed_heavy.ogg' + + accepted_magazine_type = /obj/item/ammo_box/magazine/internal/cylinder/c585trappiste + + suppressor_x_offset = 5 + + can_suppress = TRUE + + fire_delay = 1 SECONDS + recoil = 3 + +/obj/item/gun/ballistic/revolver/takbok/give_manufacturer_examine() + AddElement(/datum/element/manufacturer_examine, COMPANY_TRAPPISTE) + +/obj/item/gun/ballistic/revolver/takbok/examine_more(mob/user) + . = ..() + + . += "The Takbok is a unique design for Trappiste for the sole reason that it \ + was made at first to be a one-off. Founder of partner company Carwo Defense, \ + Darmaan Khaali Carwo herself, requested a sporting revolver from Trappiste. \ + What was delivered wasn't a target revolver, it was a target crusher. The \ + weapon became popular as Carwo crushed many shooting competitions using \ + the Takbok, with the design going on several production runs up until \ + 2523 when the popularity of the gun fell off. Due to the number of revolvers \ + made, they are still easy enough to find if you look despite production \ + having already ceased many years ago." + + return . + +/obj/item/ammo_box/magazine/internal/cylinder/c585trappiste + ammo_type = /obj/item/ammo_casing/c585trappiste + caliber = CALIBER_585TRAPPISTE + max_ammo = 5 diff --git a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/xhihao_light_arms/guns.dm b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/xhihao_light_arms/guns.dm index 4207eb85eef483..ec586d0d35f68d 100644 --- a/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/xhihao_light_arms/guns.dm +++ b/modular_skyrat/modules/modular_weapons/code/company_and_or_faction_based/xhihao_light_arms/guns.dm @@ -15,6 +15,7 @@ inhand_icon_state = "enchanted_rifle" accepted_magazine_type = /obj/item/ammo_box/magazine/internal/boltaction/bubba can_be_sawn_off = FALSE + knife_x_offset = 35 /obj/item/gun/ballistic/rifle/boltaction/sporterized/Initialize(mapload) . = ..() diff --git a/modular_skyrat/modules/modular_weapons/code/energy.dm b/modular_skyrat/modules/modular_weapons/code/energy.dm deleted file mode 100644 index 550af2c130eff8..00000000000000 --- a/modular_skyrat/modules/modular_weapons/code/energy.dm +++ /dev/null @@ -1,248 +0,0 @@ -/* -* BOLT RESPONDER -* A mini disabler -* 12 shot capacity VS normal disabler's 20. -*/ - - -/obj/item/gun/energy/disabler/bolt_disabler - name = "Bolt Responder" - desc = "A pocket-sized non-lethal energy gun with low ammo capacity." - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi' - icon_state = "cfa-disabler" - righthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi' - lefthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi' - ammo_type = list(/obj/item/ammo_casing/energy/disabler) - ammo_x_offset = 2 - w_class = WEIGHT_CLASS_SMALL - cell_type = /obj/item/stock_parts/cell/mini_egun - ammo_x_offset = 2 - charge_sections = 3 - -/obj/item/gun/energy/disabler/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_BOLT) - -/obj/item/gun/energy/disabler/bolt_disabler/give_gun_safeties() - return - -/obj/item/gun/energy/disabler/bolt_disabler/add_seclight_point() - return -/* -* CFA PHALANX -* Similar to the HoS's laser -* Fires a bouncing non-lethal, lethal and knockdown projectile. -*/ - -/obj/item/gun/energy/e_gun/cfa_phalanx - name = "\improper Mk.II Phalanx plasma blaster" - desc = "Fires a disabling and lethal bouncing projectile, as well as a special muscle-seizing projectile that knocks targets down." - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi' - icon_state = "phalanx1" - righthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi' - lefthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi' - w_class = WEIGHT_CLASS_NORMAL - force = 10 - ammo_type = list(/obj/item/ammo_casing/energy/disabler/bounce, /obj/item/ammo_casing/energy/laser/bounce, /obj/item/ammo_casing/energy/electrode/knockdown) - ammo_x_offset = 1 - charge_sections = 5 - cell_type = /obj/item/stock_parts/cell/hos_gun - -/obj/item/gun/energy/e_gun/cfa_phalanx/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN) - -/obj/item/gun/energy/e_gun/cfa_phalanx/give_gun_safeties() - return - -/* -* CFA PALADIN -* Identical to a heavy laser. -*/ - -/obj/item/gun/energy/laser/cfa_paladin - name = "\improper Mk.IV Paladin plasma carbine" - desc = "Essentially a handheld laser cannon. This is solely for killing, and it's dual-laser system reflects that." - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi' - icon_state = "paladin" - force = 10 - ammo_type = list(/obj/item/ammo_casing/energy/laser/double) - charge_sections = 5 - -/obj/item/gun/energy/laser/cfa_paladin/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN) - -/obj/item/gun/energy/laser/cfa_paladin/give_gun_safeties() - return - -/* -* BOUNCE DISABLER -* A disabler that will always ricochet. -*/ - -/obj/item/ammo_casing/energy/disabler/bounce - projectile_type = /obj/projectile/beam/disabler/bounce - select_name = "disable" - e_cost = 60 - fire_sound = 'sound/weapons/taser2.ogg' - harmful = FALSE - -/obj/effect/projectile/tracer/disabler/bounce - name = "disabler" - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/projectiles.dmi' - icon_state = "bouncebeam" - -/obj/projectile/beam/disabler/bounce - name = "disabler arc" - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/projectiles.dmi' - icon_state = "bouncebeam" - damage = 30 - damage_type = STAMINA - armor_flag = ENERGY - eyeblur = 1 - tracer_type = /obj/effect/projectile/tracer/disabler/bounce - light_range = 5 - light_power = 0.75 - speed = 1.4 - ricochets_max = 6 - ricochet_incidence_leeway = 170 - ricochet_chance = 130 - ricochet_decay_damage = 0.9 - -// Allows the projectile to reflect on walls like how bullets ricochet. -/obj/projectile/beam/disabler/bounce/check_ricochet_flag(atom/A) - return TRUE - -/* -* BOUNCE LASER -* A laser that will always ricochet. -*/ - -/obj/item/ammo_casing/energy/laser/bounce - projectile_type = /obj/projectile/beam/laser/bounce - select_name = "lethal" - e_cost = 100 - -/obj/projectile/beam/laser/bounce - name = "energy arc" - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/projectiles.dmi' - icon_state = "bouncebeam_red" - damage = 20 - damage_type = BURN - armor_flag = LASER - light_range = 5 - light_power = 0.75 - speed = 1.4 - ricochets_max = 6 - ricochet_incidence_leeway = 170 - ricochet_chance = 130 - ricochet_decay_damage = 0.9 - -// Allows the projectile to reflect on walls like how bullets ricochet. -/obj/projectile/beam/laser/bounce/check_ricochet_flag(atom/A) - return TRUE - -/* -* KNOCKDOWN BOLT -* A taser that had the same stamina impact as a disabler, but a five-second knockdown and taser hitter effects. -*/ - -/obj/item/ammo_casing/energy/electrode/knockdown - projectile_type = /obj/projectile/energy/electrode/knockdown - select_name = "knockdown" - fire_sound = 'sound/weapons/taser.ogg' - e_cost = 200 - harmful = FALSE - -/obj/projectile/energy/electrode/knockdown - name = "electrobolt" - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/projectiles.dmi' - icon_state = "electro_bolt" - knockdown = 50 - stamina = 30 - range = 6 - -/* -* SINGLE LASER -* Has an unique sprite -* Low-powered laser for rapid fire -* Pea-shooter tier. -*/ - - -/obj/item/ammo_casing/energy/laser/single - projectile_type = /obj/projectile/beam/laser/single - e_cost = 50 - select_name = "lethal" - -/obj/projectile/beam/laser/single - name = "laser bolt" - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/projectiles.dmi' - icon_state = "single_laser" - damage = 15 - eyeblur = 1 - light_range = 5 - light_power = 0.75 - speed = 0.5 - armour_penetration = 10 - -/* -* DOUBLE LASER -* Visually, this fires two lasers. In code, it's just one. -* It's fast and great for turrets. -*/ - -/obj/item/ammo_casing/energy/laser/double - projectile_type = /obj/projectile/beam/laser/double - e_cost = 100 - select_name = "lethal" - fire_sound = 'sound/weapons/lasercannonfire.ogg' - -/obj/projectile/beam/laser/double - name = "laser bolt" - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/projectiles.dmi' - icon_state = "double_laser" - damage = 40 - eyeblur = 1 - light_range = 5 - light_power = 0.75 - speed = 0.5 - armour_penetration = 10 - -/* -* ENERGY BULLETS -* Ballistic gunplay but it allows us to target a different part of the armour block. -* Also allows the benefits of lasers (blobs strains, xenos) over bullets to be used with ballistic gunplay. -*/ - -/obj/item/ammo_casing/laser - name = "type I plasma projectile" - desc = "A chemical mixture that once triggered, creates a deadly projectile, melting it's own casing in the process." - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi' - icon_state = "plasma_shell" - worn_icon_state = "shell" - caliber = CALIBER_LASER - custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT * 2,/datum/material/plasma=HALF_SHEET_MATERIAL_AMOUNT) - projectile_type = /obj/projectile/beam/laser/single - -/obj/item/ammo_casing/laser/double - name = "type II plasma projectile" - desc = "A chemical mixture that once triggered, creates a deadly projectile, melting it's own casing in the process." - icon_state = "plasma_shell2" - worn_icon_state = "shell" - custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT * 2,/datum/material/plasma=HALF_SHEET_MATERIAL_AMOUNT) - projectile_type = /obj/projectile/beam/laser/double - -/obj/item/ammo_casing/laser/bounce - name = "type III reflective projectile (lethal)" - desc = "A chemical mixture that once triggered, creates a deadly bouncing projectile, melting it's own casing in the process." - icon_state = "bounce_shell" - worn_icon_state = "shell" - custom_materials = list(/datum/material/iron=SHEET_MATERIAL_AMOUNT * 2,/datum/material/plasma=HALF_SHEET_MATERIAL_AMOUNT) - projectile_type = /obj/projectile/beam/laser/bounce - -/obj/item/ammo_casing/laser/bounce/disabler - name = "type III reflective projectile (disabler)" - desc = "A chemical mixture that once triggered, creates bouncing disabler projectile, melting it's own casing in the process." - icon_state = "disabler_shell" - projectile_type = /obj/projectile/beam/disabler/bounce - - diff --git a/modular_skyrat/modules/modular_weapons/code/gunsets.dm b/modular_skyrat/modules/modular_weapons/code/gunsets.dm new file mode 100644 index 00000000000000..7373e0fa729322 --- /dev/null +++ b/modular_skyrat/modules/modular_weapons/code/gunsets.dm @@ -0,0 +1,70 @@ +/* +* GUNSET BOXES +*/ + +/obj/item/storage/toolbox/guncase/skyrat + desc = "A thick gun case with foam inserts laid out to fit a weapon, magazines, and gear securely." + + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi' + icon_state = "guncase" + + worn_icon = 'modular_skyrat/modules/modular_weapons/icons/mob/worn/cases.dmi' + worn_icon_state = "darkcase" + + slot_flags = ITEM_SLOT_BACK + + material_flags = NONE + + /// Is the case visually opened or not + var/opened = FALSE + +/obj/item/storage/toolbox/guncase/skyrat/Initialize(mapload) + . = ..() + atom_storage.max_total_storage = 14 // Technically means you could fit multiple large guns in here but its a case you cant backpack anyways so what it do + atom_storage.max_slots = 6 // We store some extra items in these so lets make a little extra room + +/obj/item/storage/toolbox/guncase/skyrat/update_icon() + . = ..() + if(opened) + icon_state = "[initial(icon_state)]-open" + else + icon_state = initial(icon_state) + +/obj/item/storage/toolbox/guncase/skyrat/AltClick(mob/user) + . = ..() + opened = !opened + update_icon() + +/obj/item/storage/toolbox/guncase/skyrat/attack_self(mob/user) + . = ..() + opened = !opened + update_icon() + +// Empty guncase + +/obj/item/storage/toolbox/guncase/skyrat/empty + +/obj/item/storage/toolbox/guncase/skyrat/empty/PopulateContents() + return + +// Small case for pistols and whatnot + +/obj/item/storage/toolbox/guncase/skyrat/pistol + name = "small gun case" + + icon_state = "guncase_s" + + slot_flags = NONE + + w_class = WEIGHT_CLASS_NORMAL + +/obj/item/storage/toolbox/guncase/skyrat/pistol/Initialize(mapload) + . = ..() + atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL + +// Empty pistol case + +/obj/item/storage/toolbox/guncase/skyrat/pistol/empty + +/obj/item/storage/toolbox/guncase/skyrat/pistol/empty/PopulateContents() + return diff --git a/modular_skyrat/modules/modular_weapons/code/modular_projectiles.dm b/modular_skyrat/modules/modular_weapons/code/modular_projectiles.dm index 16a9ba35f7f129..4a0625b491fe7a 100644 --- a/modular_skyrat/modules/modular_weapons/code/modular_projectiles.dm +++ b/modular_skyrat/modules/modular_weapons/code/modular_projectiles.dm @@ -167,149 +167,3 @@ damage = 8 fire_stacks = 1 wound_bonus = -90 - -/* -* 4.2x30mm -*/ - -/obj/item/ammo_casing/c42x30mm - name = "4.2x30mm bullet casing" - desc = "A 4.2x30mm bullet casing." - caliber = CALIBER_42X30MM - projectile_type = /obj/projectile/bullet/c42x30mm - -/obj/item/ammo_casing/c42x30mm/ap - name = "4.2x30mm armor-piercing bullet casing" - desc = "A 4.2x30mm armor-piercing bullet casing." - projectile_type = /obj/projectile/bullet/c42x30mm/ap - custom_materials = AMMO_MATS_AP - advanced_print_req = TRUE - -/obj/item/ammo_casing/c42x30mm/inc - name = "4.2x30mm incendiary bullet casing" - desc = "A 4.2x30mm incendiary bullet casing." - projectile_type = /obj/projectile/bullet/incendiary/c42x30mm - custom_materials = AMMO_MATS_TEMP - advanced_print_req = TRUE - -/obj/projectile/bullet/c42x30mm - name = "4.2x30mm bullet" - damage = 20 - wound_bonus = -5 - bare_wound_bonus = 5 - embed_falloff_tile = -4 - -/obj/projectile/bullet/c42x30mm/ap - name = "4.2x30mm armor-piercing bullet" - damage = 15 - armour_penetration = 40 - embedding = null - -/obj/projectile/bullet/incendiary/c42x30mm - name = "4.2x30mm incendiary bullet" - damage = 10 - fire_stacks = 1 - -/obj/projectile/bullet/c42x30mm_rubber - name = "4.2x30mm rubber bullet" - damage = 3 - stamina = 17 - ricochets_max = 6 - ricochet_incidence_leeway = 0 - ricochet_chance = 130 - ricochet_decay_damage = 0.7 - shrapnel_type = null - sharpness = NONE - embedding = null - wound_bonus = -50 - -/obj/item/ammo_casing/c42x30mm/rubber - name = "4.2x30mm rubber bullet casing" - desc = "A 4.2x30mm rubber bullet casing." - projectile_type = /obj/projectile/bullet/c42x30mm_rubber - harmful = FALSE - -/* -* 12mm Magnum -*/ - -/obj/item/ammo_casing/c12mm - name = "12mm Magnum bullet casing" - desc = "A 12mm Magnum bullet casing." - caliber = CALIBER_12MM - projectile_type = /obj/projectile/bullet/c12mm - -/obj/item/ammo_casing/c12mm/ap - name = "12mm Magnum armor-piercing bullet casing" - desc = "A 12mm Magnum bullet casing with a titanium core." - custom_materials = AMMO_MATS_AP - projectile_type = /obj/projectile/bullet/c12mm/ap - advanced_print_req = TRUE - -/obj/item/ammo_casing/c12mm/hp - name = "12mm Magnum hollow-point bullet casing" - desc = "A 12mm Magnum bullet casing with a hollow tip that fragments on contact." - projectile_type = /obj/projectile/bullet/c12mm/hp - advanced_print_req = TRUE - -/obj/item/ammo_casing/c12mm/fire - name = "12mm Magnum incendiary bullet casing" - desc = "A 12mm Magnum bullet casing with a magnesium coated tip meant for setting things on fire." - custom_materials = AMMO_MATS_TEMP - projectile_type = /obj/projectile/bullet/incendiary/c12mm - advanced_print_req = TRUE - -/obj/item/ammo_casing/c12mm/rubber - name = "12mm Magnum rubber bullet casing" - desc = "A low powder load 12mm Magnum bullet casing with a flat rubber tip. Headshots heavily discouraged." - projectile_type = /obj/projectile/bullet/c12mm/rubber - harmful = FALSE - -/obj/projectile/bullet/c12mm - name = "12mm bullet" - damage = 40 - -/obj/projectile/bullet/c12mm/ap - name = "12mm armor-piercing bullet" - damage = 37 - armour_penetration = 40 - -/obj/projectile/bullet/c12mm/hp - name = "12mm hollow-point bullet" - damage = 60 - weak_against_armour = TRUE - -/obj/projectile/bullet/incendiary/c12mm - name = "12mm incendiary bullet" - damage = 20 - fire_stacks = 2 - -/obj/projectile/bullet/c12mm/rubber - name = "12mm Magnum rubber ball" - damage = 10 - stamina = 40 - ricochets_max = 6 - ricochet_incidence_leeway = 0 - ricochet_chance = 130 - ricochet_decay_damage = 0.7 - shrapnel_type = null - sharpness = NONE - embedding = null - -/* -* 6.8x43mm -*/ - -/obj/item/ammo_casing/a68 - name = "6.8mm bullet casing" - desc = "A 6.8mm bullet casing." - icon_state = "762-casing" - caliber = CALIBER_A68 - projectile_type = /obj/projectile/bullet/a68 - -/obj/projectile/bullet/a68 - name = "6.8 bullet" - damage = 55 - armour_penetration = 10 - wound_bonus = -45 - wound_falloff_tile = 0 diff --git a/modular_skyrat/modules/sec_haul/code/guns/pepperball_gun.dm b/modular_skyrat/modules/modular_weapons/code/pepperball_gun.dm similarity index 81% rename from modular_skyrat/modules/sec_haul/code/guns/pepperball_gun.dm rename to modular_skyrat/modules/modular_weapons/code/pepperball_gun.dm index ffca51d4e676e3..e507cfe1a6aacd 100644 --- a/modular_skyrat/modules/sec_haul/code/guns/pepperball_gun.dm +++ b/modular_skyrat/modules/modular_weapons/code/pepperball_gun.dm @@ -1,7 +1,7 @@ /obj/item/gun/ballistic/automatic/pistol/pepperball name = "\improper Bolt Pepperball AHG" desc = "An incredibly mediocre 'firearm' designed to fire soft pepper balls meant to easily subdue targets." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/pepperball.dmi' + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/pepperball/pepperball.dmi' icon_state = "peppergun" w_class = WEIGHT_CLASS_NORMAL accepted_magazine_type = /obj/item/ammo_box/magazine/pepperball @@ -21,7 +21,7 @@ /obj/item/ammo_box/magazine/pepperball name = "pistol magazine (pepperball)" desc = "A gun magazine filled with balls." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/pepperball.dmi' + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/pepperball/pepperball.dmi' icon_state = "pepperball" ammo_type = /obj/item/ammo_casing/pepperball caliber = CALIBER_PEPPERBALL @@ -37,7 +37,7 @@ /obj/projectile/bullet/pepperball name = "pepperball orb" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/projectiles.dmi' + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/pepperball/projectiles.dmi' icon_state = "pepperball" damage = 0 stamina = 5 @@ -67,8 +67,16 @@ /obj/item/ammo_box/advanced/pepperballs name = "pepperball ammo box" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammoboxes.dmi' + icon = 'modular_skyrat/modules/modular_weapons/icons/obj/pepperball/ammoboxes.dmi' icon_state = "box10x24" ammo_type = /obj/item/ammo_casing/pepperball custom_materials = list(/datum/material/iron = SHEET_MATERIAL_AMOUNT * 3) max_ammo = 15 + +// Gunset for the pepperball pistol + +/obj/item/storage/toolbox/guncase/skyrat/pistol/pepperball + name = "Pepperball AHG gunset" + + weapon_to_spawn = /obj/item/gun/ballistic/automatic/pistol/pepperball + extra_to_spawn = /obj/item/ammo_box/magazine/pepperball diff --git a/modular_skyrat/modules/modular_weapons/code/pistol.dm b/modular_skyrat/modules/modular_weapons/code/pistol.dm deleted file mode 100644 index 7333fa60324539..00000000000000 --- a/modular_skyrat/modules/modular_weapons/code/pistol.dm +++ /dev/null @@ -1,101 +0,0 @@ -/* -* PISTOLS -*/ - -/obj/item/gun/ballistic/automatic/pistol/cfa_snub - name = "CFA Snub" - desc = "An easily-concealable pistol chambered for 4.2x30mm." - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi' - icon_state = "cfa-snub" - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_snub - can_suppress = TRUE - fire_sound_volume = 30 - w_class = WEIGHT_CLASS_SMALL - -/obj/item/gun/ballistic/automatic/pistol/cfa_snub/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN) - -/obj/item/gun/ballistic/automatic/pistol/cfa_snub/give_gun_safeties() - return - -/obj/item/gun/ballistic/automatic/pistol/cfa_snub/empty - spawnwithmagazine = FALSE - -/obj/item/gun/ballistic/automatic/pistol/cfa_ruby - name = "CFA Ruby" - desc = "A heavy-duty sidearm chambered in 12x27mm." - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi' - icon_state = "cfa_ruby" - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby - can_suppress = FALSE - fire_sound_volume = 120 - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/gun/ballistic/automatic/pistol/cfa_ruby/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN) - -/obj/item/gun/ballistic/automatic/pistol/cfa_ruby/give_gun_safeties() - return - -/obj/item/gun/ballistic/automatic/pistol/cfa_ruby/empty - spawnwithmagazine = FALSE - -/* -* AMMO -*/ - -/obj/item/ammo_box/magazine/multi_sprite/cfa_snub - name = "CFA Snub magazine (4.2x30mm)" - desc = "An advanced magazine with smart type displays. Alt+click to reskin it." - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi' - icon_state = "m42x30" - possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_AP, AMMO_TYPE_RUBBER, AMMO_TYPE_INCENDIARY) - ammo_type = /obj/item/ammo_casing/c42x30mm - caliber = CALIBER_42X30MM - max_ammo = 16 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/cfa_snub/ap - ammo_type = /obj/item/ammo_casing/c42x30mm/ap - round_type = AMMO_TYPE_AP - -/obj/item/ammo_box/magazine/multi_sprite/cfa_snub/rubber - ammo_type = /obj/item/ammo_casing/c42x30mm/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/ammo_box/magazine/multi_sprite/cfa_snub/incendiary - ammo_type = /obj/item/ammo_casing/c42x30mm/inc - round_type = AMMO_TYPE_INCENDIARY - -/obj/item/ammo_box/magazine/multi_sprite/cfa_snub/empty - start_empty = TRUE - -/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby - name = "CFA Ruby magazine (12mm Magnum)" - desc = "An advanced magazine with smart type displays. Alt+click to reskin it." - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi' - icon_state = "m12mm" - possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_AP, AMMO_TYPE_RUBBER, AMMO_TYPE_HOLLOWPOINT, AMMO_TYPE_INCENDIARY) - ammo_type = /obj/item/ammo_casing/c12mm - caliber = CALIBER_12MM - max_ammo = 8 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/empty - start_empty = TRUE - -/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/ap - ammo_type = /obj/item/ammo_casing/c12mm/ap - round_type = AMMO_TYPE_AP - -/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/rubber - ammo_type = /obj/item/ammo_casing/c12mm/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/hp - ammo_type = /obj/item/ammo_casing/c12mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/incendiary - ammo_type = /obj/item/ammo_casing/c12mm/fire - round_type = AMMO_TYPE_INCENDIARY diff --git a/modular_skyrat/modules/modular_weapons/code/revolver.dm b/modular_skyrat/modules/modular_weapons/code/revolver.dm deleted file mode 100644 index 669f874026f9c8..00000000000000 --- a/modular_skyrat/modules/modular_weapons/code/revolver.dm +++ /dev/null @@ -1,41 +0,0 @@ -/* -* REVOLVERS -* Revolving rifles! We have three versions. An improvised slower firing one, a normal one, and a golden premium one. -* The gold rifle uses .45, it's only 5 more points of damage unfortunately. -* Fun hint: A box of .45 bullets functions the same as a speedloader. -*/ - -/obj/item/gun/ballistic/revolver/rifle - name = "\improper .38 revolving rifle" - desc = "A revolving rifle chambered in .38. " - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi' - icon_state = "revolving-rifle" - accepted_magazine_type = /obj/item/ammo_box/magazine/internal/cylinder/rev38 //This is just a detective's revolver but it's too big for bags.. - pixel_x = -4 // It's centred on a 40x32 pixel spritesheet. - w_class = WEIGHT_CLASS_BULKY - weapon_weight = WEAPON_HEAVY // The entire purpose of this is that it's a bulky rifle instead of a revolver. - slot_flags = ITEM_SLOT_BELT - inhand_x_dimension = 64 - inhand_y_dimension = 64 - lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/64x_guns_left.dmi' - righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/64x_guns_right.dmi' - inhand_icon_state = "revolving" - -/obj/item/gun/ballistic/revolver/rifle/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_IZHEVSK) - -/obj/item/gun/ballistic/revolver/rifle/gold - name = "\improper .45 revolving rifle" - desc = "A gold trimmed revolving rifle! It fires .45 bullets." - icon_state = "revolving-rifle-gold" - accepted_magazine_type = /obj/item/ammo_box/magazine/internal/cylinder/rev45 //Gold! We're using .45 because TG's 10mm does 40 damage, this does 30. - w_class = WEIGHT_CLASS_BULKY - inhand_icon_state = "revolving_gold" - -// .45 Cylinder - -/obj/item/ammo_box/magazine/internal/cylinder/rev45 - name = "revolver .45 cylinder" - ammo_type = /obj/item/ammo_casing/c45 - caliber = list(".45") - max_ammo = 6 diff --git a/modular_skyrat/modules/modular_weapons/code/rifle.dm b/modular_skyrat/modules/modular_weapons/code/rifle.dm deleted file mode 100644 index eb40dc2033037b..00000000000000 --- a/modular_skyrat/modules/modular_weapons/code/rifle.dm +++ /dev/null @@ -1,52 +0,0 @@ -/* -* CFA RIFLE -*/ - -/obj/item/gun/ballistic/automatic/cfa_rifle - name = "Cantanheim 6.8mm rifle" - desc = "A simple semi-automatic rifle chambered in 6.8mm. The letters 'XJP' are crossed out in the receiver." //Different 6.8mm than the FTU's propietary pulse ballistics - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi' - icon_state = "cfa_rifle" - inhand_icon_state = "irifle" - inhand_x_dimension = 64 - inhand_y_dimension = 64 - lefthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/64x_guns_left.dmi' - righthand_file = 'modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/64x_guns_right.dmi' - worn_icon_state = "gun" - accepted_magazine_type = /obj/item/ammo_box/magazine/cm68 - fire_delay = 5 - can_suppress = FALSE - burst_size = 1 - actions_types = list() - mag_display = FALSE - mag_display_ammo = FALSE - empty_indicator = FALSE - recoil = 1 - weapon_weight = WEAPON_HEAVY - pixel_x = -8 - w_class = WEIGHT_CLASS_BULKY - -/obj/item/gun/ballistic/automatic/cfa_rifle/Initialize(mapload) - . = ..() - AddComponent(/datum/component/scope, range_modifier = 1.5) - -/obj/item/gun/ballistic/automatic/cfa_rifle/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN) - -/obj/item/gun/ballistic/automatic/cfa_rifle/give_gun_safeties() - return - -/obj/item/gun/ballistic/automatic/cfa_rifle/empty - spawnwithmagazine = FALSE - -/obj/item/ammo_box/magazine/cm68 - name = "rifle magazine (6.8mm)" - icon = 'modular_skyrat/modules/modular_weapons/icons/obj/ammo.dmi' - icon_state = "6.8" - ammo_type = /obj/item/ammo_casing/a68 - caliber = CALIBER_A68 - max_ammo = 10 - multiple_sprites = 2 - -/obj/item/ammo_box/magazine/cm68/empty - start_empty = 1 diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_lefthand.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_lefthand.dmi new file mode 100644 index 00000000000000..b5f9ad7b01f280 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_lefthand.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_righthand.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_righthand.dmi new file mode 100644 index 00000000000000..ae79418dfffbd9 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_righthand.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_worn.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_worn.dmi new file mode 100644 index 00000000000000..d0a854cf3030e2 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/mob/company_and_or_faction_based/carwo_defense_systems/guns_worn.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_lefthand.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_lefthand.dmi new file mode 100644 index 00000000000000..c9fac088741be1 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_lefthand.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_righthand.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_righthand.dmi new file mode 100644 index 00000000000000..56a5d535c0d355 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/mob/inhands/cases_righthand.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/swords_righthand.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/swords_righthand.dmi index 8cd99c88bcee5e..96e2c1f5d978b3 100644 Binary files a/modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/swords_righthand.dmi and b/modular_skyrat/modules/modular_weapons/icons/mob/inhands/weapons/swords_righthand.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/mob/worn/cases.dmi b/modular_skyrat/modules/modular_weapons/icons/mob/worn/cases.dmi new file mode 100644 index 00000000000000..f029c2956292f4 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/mob/worn/cases.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi new file mode 100644 index 00000000000000..cb733806546f30 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/ammo.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns32x.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns32x.dmi new file mode 100644 index 00000000000000..c74c79b6e8cee0 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns32x.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi new file mode 100644 index 00000000000000..9131e6d19bb32c Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/guns48x.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/propaganda.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/propaganda.dmi new file mode 100644 index 00000000000000..9438b887628ccc Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/carwo_defense_systems/propaganda.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/cases.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/cases.dmi index 238153cd32bd1c..d639b8b4d861fc 100644 Binary files a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/cases.dmi and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/cases.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/ammo.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/ammo.dmi new file mode 100644 index 00000000000000..89e7d90f56ddd3 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/ammo.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi new file mode 100644 index 00000000000000..067d79a810b5c4 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/guns32x.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/propaganda.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/propaganda.dmi new file mode 100644 index 00000000000000..4ddf2216e7c186 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/icons/obj/company_and_or_faction_based/trappiste_fabriek/propaganda.dmi differ diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi deleted file mode 100644 index 410bb55110911d..00000000000000 Binary files a/modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile.dmi and /dev/null differ diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi deleted file mode 100644 index 2e3c0b4e5a31d4..00000000000000 Binary files a/modular_skyrat/modules/modular_weapons/icons/obj/guns/projectile40x32.dmi and /dev/null differ diff --git a/modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi index bc5b963bd5c67f..098a8f304816c0 100644 Binary files a/modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi and b/modular_skyrat/modules/modular_weapons/icons/obj/gunsets.dmi differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/ammoboxes.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/pepperball/ammoboxes.dmi similarity index 100% rename from modular_skyrat/modules/sec_haul/icons/guns/ammoboxes.dmi rename to modular_skyrat/modules/modular_weapons/icons/obj/pepperball/ammoboxes.dmi diff --git a/modular_skyrat/modules/sec_haul/icons/guns/pepperball.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/pepperball/pepperball.dmi similarity index 100% rename from modular_skyrat/modules/sec_haul/icons/guns/pepperball.dmi rename to modular_skyrat/modules/modular_weapons/icons/obj/pepperball/pepperball.dmi diff --git a/modular_skyrat/modules/sec_haul/icons/guns/projectiles.dmi b/modular_skyrat/modules/modular_weapons/icons/obj/pepperball/projectiles.dmi similarity index 100% rename from modular_skyrat/modules/sec_haul/icons/guns/projectiles.dmi rename to modular_skyrat/modules/modular_weapons/icons/obj/pepperball/projectiles.dmi diff --git a/modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg b/modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg new file mode 100644 index 00000000000000..d5a8562f45f51f Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/grenade_burst.ogg differ diff --git a/modular_skyrat/modules/modular_weapons/sounds/grenade_launcher.ogg b/modular_skyrat/modules/modular_weapons/sounds/grenade_launcher.ogg new file mode 100644 index 00000000000000..5ddb76de7d06b7 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/grenade_launcher.ogg differ diff --git a/modular_skyrat/modules/modular_weapons/sounds/laser_fire.ogg b/modular_skyrat/modules/modular_weapons/sounds/laser_fire.ogg deleted file mode 100644 index 7b003b8cc8b63f..00000000000000 Binary files a/modular_skyrat/modules/modular_weapons/sounds/laser_fire.ogg and /dev/null differ diff --git a/modular_skyrat/modules/modular_weapons/sounds/pistol_heavy.ogg b/modular_skyrat/modules/modular_weapons/sounds/pistol_heavy.ogg new file mode 100644 index 00000000000000..34e0412f823d03 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/pistol_heavy.ogg differ diff --git a/modular_skyrat/modules/modular_weapons/sounds/pistol_light.ogg b/modular_skyrat/modules/modular_weapons/sounds/pistol_light.ogg new file mode 100644 index 00000000000000..cd014f5eda8a0d Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/pistol_light.ogg differ diff --git a/modular_skyrat/modules/modular_weapons/sounds/revolver_heavy.ogg b/modular_skyrat/modules/modular_weapons/sounds/revolver_heavy.ogg new file mode 100644 index 00000000000000..d02d1c750c24d8 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/revolver_heavy.ogg differ diff --git a/modular_skyrat/modules/modular_weapons/sounds/rifle_heavy.ogg b/modular_skyrat/modules/modular_weapons/sounds/rifle_heavy.ogg new file mode 100644 index 00000000000000..3ad9d60c9013c0 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/rifle_heavy.ogg differ diff --git a/modular_skyrat/modules/modular_weapons/sounds/shotgun_heavy.ogg b/modular_skyrat/modules/modular_weapons/sounds/shotgun_heavy.ogg new file mode 100644 index 00000000000000..2de9e77bf08589 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/shotgun_heavy.ogg differ diff --git a/modular_skyrat/modules/modular_weapons/sounds/shotgun_rack.ogg b/modular_skyrat/modules/modular_weapons/sounds/shotgun_rack.ogg new file mode 100644 index 00000000000000..2d68a21e5df1fa Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/shotgun_rack.ogg differ diff --git a/modular_skyrat/modules/modular_weapons/sounds/smg_light.ogg b/modular_skyrat/modules/modular_weapons/sounds/smg_light.ogg new file mode 100644 index 00000000000000..d34cb9440ca457 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/smg_light.ogg differ diff --git a/modular_skyrat/modules/modular_weapons/sounds/suppressed_heavy.ogg b/modular_skyrat/modules/modular_weapons/sounds/suppressed_heavy.ogg new file mode 100644 index 00000000000000..b7b721b76665f6 Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/suppressed_heavy.ogg differ diff --git a/modular_skyrat/modules/modular_weapons/sounds/suppressed_rifle.ogg b/modular_skyrat/modules/modular_weapons/sounds/suppressed_rifle.ogg new file mode 100644 index 00000000000000..06aba901c0642b Binary files /dev/null and b/modular_skyrat/modules/modular_weapons/sounds/suppressed_rifle.ogg differ diff --git a/modular_skyrat/modules/mold/code/mold_mobs.dm b/modular_skyrat/modules/mold/code/mold_mobs.dm index 59b1db554628ef..c7ba1226435e34 100644 --- a/modular_skyrat/modules/mold/code/mold_mobs.dm +++ b/modular_skyrat/modules/mold/code/mold_mobs.dm @@ -15,6 +15,7 @@ icon = 'modular_skyrat/modules/mold/icons/blob_mobs.dmi' gold_core_spawnable = NO_SPAWN faction = list(FACTION_MOLD) + basic_mob_flags = DEL_ON_DEATH /** * OIL SHAMBLERS @@ -69,6 +70,17 @@ SSvis_overlays.add_vis_overlay(src, icon, OIL_SHAMBLER_OVERLAY, layer, plane, dir, alpha) SSvis_overlays.add_vis_overlay(src, icon, OIL_SHAMBLER_OVERLAY, OIL_SHAMBLER_OVERLAY_LAYER, EMISSIVE_PLANE, dir, alpha) +/mob/living/basic/mold/oil_shambler/melee_attack(atom/target, list/modifiers, ignore_cooldown) + . = ..() + if(!isliving(target)) + return + + var/mob/living/ignite_target = target + if(prob(ignite_chance)) + ignite_target.adjust_fire_stacks(additional_fire_stacks) + + ignite_target.ignite_mob() + /datum/ai_controller/basic_controller/oil_shambler blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, @@ -79,7 +91,7 @@ planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/attack_obstacle_in_path, - /datum/ai_planning_subtree/basic_melee_attack_subtree/oil_shambler, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/random_speech/oil_shambler, ) @@ -88,23 +100,6 @@ emote_hear = list("bubbles.", "crackles.", "groans.") emote_see = list("bubbles.") -/datum/ai_planning_subtree/basic_melee_attack_subtree/oil_shambler - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/oil_shambler - -/datum/ai_behavior/basic_melee_attack/oil_shambler/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) - . = ..() - var/atom/target = controller.blackboard[target_key] - var/mob/living/basic/mold/oil_shambler/oil_shambler = controller.pawn - - if(!isliving(target)) - return - - var/mob/living/ignite_target = target - if(prob(oil_shambler.ignite_chance)) - ignite_target.adjust_fire_stacks(oil_shambler.additional_fire_stacks) - - if(ignite_target.fire_stacks) - ignite_target.ignite_mob() /** * DISEASE MOLD @@ -139,6 +134,17 @@ /// The disease given on melee attacks var/datum/disease/given_disease = /datum/disease/cryptococcus +/mob/living/basic/mold/diseased_rat/melee_attack(atom/target, list/modifiers, ignore_cooldown) + . = ..() + + if(!isliving(target)) + return + + var/mob/living/carbon/disease_target = target + if(can_inject(disease_target)) + to_chat(disease_target, span_danger("[src] manages to penetrate your clothing with its teeth!")) + disease_target.ForceContractDisease(new given_disease(), FALSE, TRUE) + /datum/ai_controller/basic_controller/diseased_rat blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, @@ -149,7 +155,7 @@ planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/attack_obstacle_in_path, - /datum/ai_planning_subtree/basic_melee_attack_subtree/diseased_rat, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/random_speech/diseased_rat, ) @@ -158,21 +164,6 @@ emote_hear = list("squeaks.", "gnashes.", "hisses.") emote_see = list("drools.") -/datum/ai_planning_subtree/basic_melee_attack_subtree/diseased_rat - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/diseased_rat - -/datum/ai_behavior/basic_melee_attack/diseased_rat/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) - . = ..() - var/atom/target = controller.blackboard[target_key] - var/mob/living/basic/mold/diseased_rat/diseased_rat = controller.pawn - - if(!isliving(target)) - return - - var/mob/living/carbon/disease_target = target - if(diseased_rat.can_inject(disease_target)) - to_chat(disease_target, span_danger("[diseased_rat] manages to penetrate your clothing with its teeth!")) - disease_target.ForceContractDisease(new diseased_rat.given_disease(), FALSE, TRUE) /** * ELECTRIC MOLD @@ -202,6 +193,15 @@ pass_flags = PASSTABLE + /// What the mob injects per bite + var/inject_reagent = /datum/reagent/teslium + /// How many units to inject per bite + var/inject_amount = 2 + +/mob/living/basic/mold/electric_mosquito/Initialize(mapload) + . = ..() + AddElement(/datum/element/venomous, inject_reagent, inject_amount) + /datum/ai_controller/basic_controller/electric_mosquito blackboard = list( BB_TARGETTING_DATUM = new /datum/targetting_datum/basic, @@ -212,7 +212,7 @@ planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/attack_obstacle_in_path, - /datum/ai_planning_subtree/basic_melee_attack_subtree/electric_mosquito, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/random_speech/electric_mosquito, ) @@ -221,24 +221,11 @@ emote_hear = list("zaps.", "buzzes.", "crackles.") emote_see = list("arcs.") -/datum/ai_planning_subtree/basic_melee_attack_subtree/electric_mosquito - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/electric_mosquito - -/datum/ai_behavior/basic_melee_attack/electric_mosquito/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) - . = ..() - var/atom/target = controller.blackboard[target_key] - - if(!iscarbon(target)) - return - - var/mob/living/carbon/shock_target = target - shock_target.reagents.add_reagent(/datum/reagent/teslium, 2) - /** * RADIATION MOLD * * Weird centipede things that spawn with a rad mold - * They have a chance to irradiate their target on hit, as well as splashing mutagen on death + * They have a chance to irradiate their target on hit */ /mob/living/basic/mold/centaur name = "centaur" @@ -271,21 +258,21 @@ /// The chance to irradiate on hit var/irradiate_chance = 20 - /// The chem to splash on death - var/death_chem = /datum/reagent/toxin/mutagen /mob/living/basic/mold/centaur/Initialize(mapload) . = ..() update_overlays() -/mob/living/basic/mold/centaur/death(gibbed) - visible_message(span_warning("[src] ruptures!")) - var/datum/reagents/reagent_spawn = new /datum/reagents(300) - reagent_spawn.my_atom = src - reagent_spawn.add_reagent(death_chem, 20) - chem_splash(loc, null, CENTAUR_DEATH_SPLASH_RANGE, list(reagent_spawn)) - playsound(src, 'sound/effects/splat.ogg', CENTAUR_DEATH_SPLAT_VOLUME, TRUE) - return ..() +/mob/living/basic/mold/centaur/melee_attack(atom/target, list/modifiers, ignore_cooldown) + . = ..() + + if(!isliving(target)) + return + + var/mob/living/radiation_target = target + if(prob(irradiate_chance)) + radiation_pulse(radiation_target, CENTAUR_RAD_PULSE_RANGE, CENTAUR_RAD_PULSE_THRESHOLD, FALSE, TRUE) + playsound(src, 'modular_skyrat/modules/horrorform/sound/horror_scream.ogg', CENTAUR_ATTACK_SCREAM_VOLUME, TRUE) /datum/ai_controller/basic_controller/centaur blackboard = list( @@ -297,7 +284,7 @@ planning_subtrees = list( /datum/ai_planning_subtree/simple_find_target, /datum/ai_planning_subtree/attack_obstacle_in_path, - /datum/ai_planning_subtree/basic_melee_attack_subtree/centaur, + /datum/ai_planning_subtree/basic_melee_attack_subtree, /datum/ai_planning_subtree/random_speech/centaur, ) @@ -306,21 +293,6 @@ emote_hear = list("chitters.", "groans.", "wails.") emote_see = list("writhes.") -/datum/ai_planning_subtree/basic_melee_attack_subtree/centaur - melee_attack_behavior = /datum/ai_behavior/basic_melee_attack/centaur - -/datum/ai_behavior/basic_melee_attack/centaur/perform(seconds_per_tick, datum/ai_controller/controller, target_key, targetting_datum_key, hiding_location_key) - . = ..() - var/atom/target = controller.blackboard[target_key] - var/mob/living/basic/mold/centaur/centaur = controller.pawn - - if(!isliving(target)) - return - - var/mob/living/radiation_target = target - if(prob(centaur.irradiate_chance)) - radiation_pulse(radiation_target, CENTAUR_RAD_PULSE_RANGE, CENTAUR_RAD_PULSE_THRESHOLD, FALSE, TRUE) - playsound(src, 'modular_skyrat/modules/horrorform/sound/horror_scream.ogg', CENTAUR_ATTACK_SCREAM_VOLUME, TRUE) #undef OIL_SHAMBLER_OVERLAY diff --git a/modular_skyrat/modules/nanotrasen_naval_command/code/outfits.dm b/modular_skyrat/modules/nanotrasen_naval_command/code/outfits.dm index ff6662d210d9b7..bca8833da461f9 100644 --- a/modular_skyrat/modules/nanotrasen_naval_command/code/outfits.dm +++ b/modular_skyrat/modules/nanotrasen_naval_command/code/outfits.dm @@ -29,7 +29,10 @@ gloves = /obj/item/clothing/gloves/tackler/combat/insulated - backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh) + backpack_contents = list( + /obj/item/storage/box/survival/security, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild, + ) /datum/outfit/centcom/naval/lieutenant name = "Nanotrasen Naval Command - Lieutenant" @@ -44,7 +47,10 @@ gloves = /obj/item/clothing/gloves/combat/naval - backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh) + backpack_contents = list( + /obj/item/storage/box/survival/security, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild, + ) /datum/outfit/centcom/naval/lieutenant_commander name = "Nanotrasen Naval Command - Lieutenant Commander" @@ -61,7 +67,10 @@ gloves = /obj/item/clothing/gloves/combat/naval - backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh) + backpack_contents = list( + /obj/item/storage/box/survival/security, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild, + ) /datum/outfit/centcom/naval/commander name = "Nanotrasen Naval Command - Commander" @@ -78,7 +87,10 @@ gloves = /obj/item/clothing/gloves/combat/naval - backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh) + backpack_contents = list( + /obj/item/storage/box/survival/security, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild, + ) /datum/outfit/centcom/naval/captain name = "Nanotrasen Naval Command - Captain" @@ -95,7 +107,10 @@ gloves = /obj/item/clothing/gloves/combat/naval - backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh) + backpack_contents = list( + /obj/item/storage/box/survival/security, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild, + ) /datum/outfit/centcom/naval/rear_admiral name = "Nanotrasen Naval Command - Rear Admiral" @@ -108,7 +123,10 @@ gloves = /obj/item/clothing/gloves/combat/naval - backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh_captain) + backpack_contents = list( + /obj/item/storage/box/survival/security, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild, + ) /datum/outfit/centcom/naval/admiral name = "Nanotrasen Naval Command - Admiral" @@ -123,7 +141,10 @@ gloves = /obj/item/clothing/gloves/combat/naval - backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh_captain) + backpack_contents = list( + /obj/item/storage/box/survival/security, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild, + ) /datum/outfit/centcom/naval/fleet_admiral name = "Nanotrasen Naval Command - Fleet Admiral" @@ -138,4 +159,7 @@ gloves = /obj/item/clothing/gloves/combat/naval/fleet_admiral - backpack_contents = list(/obj/item/storage/box/survival/security, /obj/item/storage/box/gunset/pdh_corpo) + backpack_contents = list( + /obj/item/storage/box/survival/security, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild, + ) diff --git a/modular_skyrat/modules/nanotrasen_rep/code/m45a5.dm b/modular_skyrat/modules/nanotrasen_rep/code/m45a5.dm deleted file mode 100644 index 8d14eab2b2fc97..00000000000000 --- a/modular_skyrat/modules/nanotrasen_rep/code/m45a5.dm +++ /dev/null @@ -1,45 +0,0 @@ - - -/obj/item/gun/ballistic/automatic/pistol/m45a5 - name = "\improper M45A5 Elite" - desc = "A hand-assembled custom sporting handgun by Alpha Centauri Armories, chambered in .460 Rowland magnum. This model has a highly modular structure, to acommodate for ammo costs." - icon = 'modular_skyrat/modules/blueshield/icons/M45A5.dmi' - icon_state = "m45a5" - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/m45a5 - can_suppress = FALSE - fire_delay = 4.25 //Originally 1.75 which was unintentionally extremely fast. - fire_sound_volume = 60 - spread = 2 - force = 8 //There's heavier guns that dealt less damage on melee than this so we're reducing it from the original 12 - recoil = 0 - fire_sound = 'modular_skyrat/modules/sec_haul/sound/dp_fire.ogg' - -/obj/item/gun/ballistic/automatic/pistol/m45a5/add_seclight_point() - AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") - -/obj/item/ammo_box/magazine/m45a5 - name = "ACA modular magazine" - desc = "A magazine able to chamber .460 Rowland Magnun. Made for the M45A5, as it's the only available sidearm with a smart multi-caliber mechanism." - icon = 'modular_skyrat/modules/blueshield/icons/M45A5.dmi' - icon_state = "rowlandmodular" - ammo_type = /obj/item/ammo_casing/b460 - caliber = CALIBER_460 - max_ammo = 8 //Previously 15, then previously 10. Locked to 8, as you can now restock .460 Magnum which was unintended due to its strong nature. - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_casing/b460 - name = ".460 Rowland Magnum bullet casing" - desc = "A .460 Rowland magnum casing." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "sl-casing" - caliber = CALIBER_460 - projectile_type = /obj/projectile/bullet/b460 - -/obj/projectile/bullet/b460 - name = ".460 RM JHP bullet" - damage = 30 - wound_bonus = 30 - weak_against_armour = TRUE - speed = 2 //Previously 2.25. Now compensates for ammo count. - diff --git a/modular_skyrat/modules/nanotrasen_rep/code/nanotrasen_consultant.dm b/modular_skyrat/modules/nanotrasen_rep/code/nanotrasen_consultant.dm index b9126f3a3a5940..02524eafb6fa67 100644 --- a/modular_skyrat/modules/nanotrasen_rep/code/nanotrasen_consultant.dm +++ b/modular_skyrat/modules/nanotrasen_rep/code/nanotrasen_consultant.dm @@ -54,7 +54,7 @@ head = /obj/item/clothing/head/nanotrasen_consultant backpack_contents = list( /obj/item/melee/baton/telescopic = 1, - /obj/item/storage/box/gunset/nanotrasen_consultant = 1, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild = 1, ) skillchips = list(/obj/item/skillchip/disk_verifier) @@ -111,21 +111,6 @@ inserted_item = /obj/item/pen/fountain/captain greyscale_colors = "#017941#0060b8" -/obj/item/storage/box/gunset/nanotrasen_consultant - name = "M45A5 gunset" - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/gun/ballistic/automatic/pistol/m45a5/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/nanotrasen_consultant/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/m45a5/nomag(src) - new /obj/item/ammo_box/magazine/m45a5(src) - new /obj/item/ammo_box/magazine/m45a5(src) - new /obj/item/ammo_box/magazine/m45a5(src) - new /obj/item/ammo_box/magazine/m45a5(src) - /obj/item/storage/bag/garment/nanotrasen_consultant name = "Nanotrasen consultant's garment bag" desc = "A bag for storing extra clothes and shoes. This one belongs to the Nanotrasen consultant." diff --git a/modular_skyrat/modules/novaya_ert/code/advanced_choice_beacon.dm b/modular_skyrat/modules/novaya_ert/code/advanced_choice_beacon.dm index 094970ccd55181..0003bed02e2a36 100644 --- a/modular_skyrat/modules/novaya_ert/code/advanced_choice_beacon.dm +++ b/modular_skyrat/modules/novaya_ert/code/advanced_choice_beacon.dm @@ -121,7 +121,7 @@ icon = 'modular_skyrat/modules/novaya_ert/icons/turret_deployable.dmi' icon_state = "living" base_icon_state = "living" - stun_projectile = /obj/projectile/bullet/b12mm/rubber + stun_projectile = /obj/projectile/bullet/a762x39/rubber lethal_projectile = /obj/projectile/bullet/a762x39 max_integrity = 150 req_access = list(ACCESS_CENT_GENERAL) diff --git a/modular_skyrat/modules/novaya_ert/code/automatic.dm b/modular_skyrat/modules/novaya_ert/code/automatic.dm index a3ed276527932a..64e2637edd58b8 100644 --- a/modular_skyrat/modules/novaya_ert/code/automatic.dm +++ b/modular_skyrat/modules/novaya_ert/code/automatic.dm @@ -12,7 +12,7 @@ icon_state = "nri_smg" inhand_icon_state = "nri_smg" w_class = WEIGHT_CLASS_BULKY - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx + accepted_magazine_type = /obj/item/ammo_box/magazine/uzim9mm fire_delay = 1 burst_size = 5 dual_wield_spread = 5 @@ -26,15 +26,16 @@ /obj/item/gun/ballistic/automatic/nri_smg/give_manufacturer_examine() AddElement(/datum/element/manufacturer_examine, COMPANY_IZHEVSK) -/obj/item/gun/ballistic/automatic/pistol/ladon/nri +/obj/item/gun/ballistic/automatic/pistol/nri name = "\improper Szabo-Ivanek service pistol" - desc = "A mass produced NRI-made modified reproduction of the PDH-6 line of handguns rechambered in 9×25mm.\ + desc = "A mass produced NRI-made modified reproduction of the Wespe line of handguns rechambered in 9×25mm.\ 'PATRIOT DEFENSE SYSTEMS' is inscribed on the receiver, indicating it's been made with a plasteel printer." icon = 'modular_skyrat/modules/novaya_ert/icons/pistol.dmi' + icon_state = "ladon" w_class = WEIGHT_CLASS_SMALL accepted_magazine_type = /obj/item/ammo_box/magazine/m9mm_aps burst_size = 3 fire_delay = 3 -/obj/item/gun/ballistic/automatic/pistol/ladon/nri/give_manufacturer_examine() +/obj/item/gun/ballistic/automatic/pistol/nri/give_manufacturer_examine() AddElement(/datum/element/manufacturer_examine, COMPANY_IZHEVSK) diff --git a/modular_skyrat/modules/novaya_ert/code/belt.dm b/modular_skyrat/modules/novaya_ert/code/belt.dm index 02cedded45f8db..cb34dbe63fdd2d 100644 --- a/modular_skyrat/modules/novaya_ert/code/belt.dm +++ b/modular_skyrat/modules/novaya_ert/code/belt.dm @@ -52,7 +52,7 @@ /obj/item/storage/belt/military/nri/medic/full/PopulateContents() generate_items_inside(list( - /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx = 4, + /obj/item/ammo_box/magazine/uzim9mm = 4, /obj/item/knife/combat = 1, /obj/item/grenade/smokebomb = 1, /obj/item/grenade/frag = 1, @@ -60,7 +60,7 @@ /obj/item/storage/belt/military/nri/engineer/full/PopulateContents() generate_items_inside(list( - /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx = 4, + /obj/item/ammo_box/magazine/uzim9mm = 4, /obj/item/knife/combat = 1, /obj/item/grenade/smokebomb = 1, /obj/item/grenade/frag = 1, diff --git a/modular_skyrat/modules/novaya_ert/code/outfit.dm b/modular_skyrat/modules/novaya_ert/code/outfit.dm index a88805933afb9c..35b90414bd0ee4 100644 --- a/modular_skyrat/modules/novaya_ert/code/outfit.dm +++ b/modular_skyrat/modules/novaya_ert/code/outfit.dm @@ -17,7 +17,7 @@ /obj/item/beamout_tool, /obj/item/crucifix, /obj/item/reagent_containers/cup/glass/waterbottle/large/cryptobiolin) - l_pocket = /obj/item/gun/ballistic/automatic/pistol/ladon/nri + l_pocket = /obj/item/gun/ballistic/automatic/pistol/nri r_pocket = /obj/item/ammo_box/magazine/m9mm_aps shoes = /obj/item/clothing/shoes/combat @@ -157,7 +157,7 @@ belt = /obj/item/clipboard back = /obj/item/storage/backpack/satchel/leather backpack_contents = list(/obj/item/storage/box/nri_survival_pack, - /obj/item/gun/ballistic/automatic/pistol/ladon/nri, + /obj/item/gun/ballistic/automatic/pistol/nri, /obj/item/ammo_box/magazine/m9mm_aps, /obj/item/ammo_box/magazine/m9mm_aps, /obj/item/storage/medkit/expeditionary, diff --git a/modular_skyrat/modules/novaya_ert/code/surplus_weapons.dm b/modular_skyrat/modules/novaya_ert/code/surplus_weapons.dm index 5e40743aa8e62d..bcc8b49c26d503 100644 --- a/modular_skyrat/modules/novaya_ert/code/surplus_weapons.dm +++ b/modular_skyrat/modules/novaya_ert/code/surplus_weapons.dm @@ -59,7 +59,7 @@ weak_against_armour = TRUE /obj/projectile/beam/laser/plasma_glob/on_hit(atom/target, blocked) - if(istype(target, /obj/structure/blob) || istype(target, /mob/living/simple_animal/hostile/blob)) + if(istype(target, /obj/structure/blob) || HAS_TRAIT(target, TRAIT_BLOB_ALLY)) damage = damage * 0.75 return ..() diff --git a/modular_skyrat/modules/novaya_ert/code/toolbox.dm b/modular_skyrat/modules/novaya_ert/code/toolbox.dm index 19dde9e7ef2253..77ad7051a52e2a 100644 --- a/modular_skyrat/modules/novaya_ert/code/toolbox.dm +++ b/modular_skyrat/modules/novaya_ert/code/toolbox.dm @@ -48,15 +48,9 @@ desc = "It contains a few magazines." ammo_type = /obj/item/ammo_box/magazine/akm/ap -/obj/item/storage/toolbox/ammobox/full/bison - name = "ammo box (PP-95)" - desc = "It contains a few magazines." - ammo_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx - amount = 4 - /obj/item/storage/toolbox/ammobox/full/nri_smg name = "ammo box (QLP/04)" - ammo_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx + ammo_type = /obj/item/ammo_box/magazine/uzim9mm amount = 7 /obj/item/storage/toolbox/ammobox/full/l6_saw @@ -65,12 +59,6 @@ ammo_type = /obj/item/ammo_box/magazine/m7mm amount = 7 -/obj/item/storage/toolbox/ammobox/full/makarov - name = "ammo box (R-C Makarov)" - desc = "It contains a few magazines." - ammo_type = /obj/item/ammo_box/magazine/multi_sprite/makarov - amount = 7 - /obj/item/storage/toolbox/ammobox/full/aps name = "ammo box (Szabo-Ivanek/APS)" desc = "It contains a few magazines." diff --git a/modular_skyrat/modules/opposing_force/code/equipment/ammo.dm b/modular_skyrat/modules/opposing_force/code/equipment/ammo.dm index 687e74fe581db0..cbdbc89bc1923c 100644 --- a/modular_skyrat/modules/opposing_force/code/equipment/ammo.dm +++ b/modular_skyrat/modules/opposing_force/code/equipment/ammo.dm @@ -33,13 +33,13 @@ item_type = /obj/item/ammo_box/magazine/uzim9mm description = "A thirty-two round magazine for the mini uzi. Uses 9x19mm ammunition." -/datum/opposing_force_equipment/ammo/lynx - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_lynx - description = "A forty round magazine for CFA Lynx and QLP/04 submachine guns." +/datum/opposing_force_equipment/ammo/sol40standard + item_type = /obj/item/ammo_box/magazine/c40sol_rifle/standard + description = "A thirty round magazine for any SolFed rifle." -/datum/opposing_force_equipment/ammo/cm68 - item_type = /obj/item/ammo_box/magazine/cm68 - description = "6.8mm bullets in a ten round magazine for a Cantanheim 6.8 rifle." +/datum/opposing_force_equipment/ammo/sol40drum + item_type = /obj/item/ammo_box/magazine/c40sol_rifle/drum + description = "A sixty round drum for any SolFed rifle." /datum/opposing_force_equipment/ammo/makarov item_type = /obj/item/ammo_box/magazine/m9mm @@ -81,144 +81,14 @@ item_type = /obj/item/ammo_box/a357/match description = "A seven-round .357 magnum speedloader for a revolver, loaded with match-grade ammunition that bounces off walls several times." -/datum/opposing_force_equipment/ammo/cfa_snub - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_snub +/datum/opposing_force_equipment/ammo/sol35_standard + item_type = /obj/item/ammo_box/magazine/c35sol_pistol -/datum/opposing_force_equipment/ammo/cfa_snubap - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_snub/ap +/datum/opposing_force_equipment/ammo/sol35_extended + item_type = /obj/item/ammo_box/magazine/c35sol_pistol/stendo -/datum/opposing_force_equipment/ammo/cfa_snubrubber - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_snub/rubber - -/datum/opposing_force_equipment/ammo/cfa_snubincendiary - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_snub/incendiary - -/datum/opposing_force_equipment/ammo/cfa_ruby - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby - -/datum/opposing_force_equipment/ammo/cfa_rubyap - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/ap - -/datum/opposing_force_equipment/ammo/cfa_rubyrubber - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/rubber - -/datum/opposing_force_equipment/ammo/cfa_rubyhp - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/hp - -/datum/opposing_force_equipment/ammo/cfa_rubyincendiary - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_ruby/incendiary - -/datum/opposing_force_equipment/ammo/wildcat - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat - -/datum/opposing_force_equipment/ammo/wildcatap - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/ap - -/datum/opposing_force_equipment/ammo/wildcatrubber - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/rubber - -/datum/opposing_force_equipment/ammo/wildcatincendiary - item_type = /obj/item/ammo_box/magazine/multi_sprite/cfa_wildcat/incendiary - -/datum/opposing_force_equipment/ammo/glock17 - name = "Glock 17 Magazine" - item_type = /obj/item/ammo_box/magazine/multi_sprite/g17 - -/datum/opposing_force_equipment/ammo/glock17hp - name = "Glock 17 Magazine (HP)" - item_type = /obj/item/ammo_box/magazine/multi_sprite/g17/hp - -/datum/opposing_force_equipment/ammo/glock18 - name = "Glock 18 Magazine" - item_type = /obj/item/ammo_box/magazine/multi_sprite/g18 - -/datum/opposing_force_equipment/ammo/glock18hp - name = "Glock 18 Magazine (HP)" - item_type = /obj/item/ammo_box/magazine/multi_sprite/g18/hp - -/datum/opposing_force_equipment/ammo/ladon - name = "P-3 'Ladon' Magazine" - item_type = /obj/item/ammo_box/magazine/multi_sprite/ladon - -/datum/opposing_force_equipment/ammo/ladonhp - name = "P-3 'Ladon' Magazine (HP)" - item_type = /obj/item/ammo_box/magazine/multi_sprite/ladon/hp - -/datum/opposing_force_equipment/ammo/dozer - name = "DZR-9 'Dozer' Magazine" - item_type = /obj/item/ammo_box/magazine/multi_sprite/dozer - -/datum/opposing_force_equipment/ammo/dozerhp - name = "DZR-9 'Dozer' Magazine (HP)" - item_type = /obj/item/ammo_box/magazine/multi_sprite/dozer/hp - -/datum/opposing_force_equipment/ammo/pdh - name = "PDH-6H 'Peacekeeper' Magazine" - item_type = /obj/item/ammo_box/magazine/multi_sprite/pdh - -/datum/opposing_force_equipment/ammo/pdhhp - name = "PDH-6H 'Peacekeeper' Magazine (HP)" - item_type = /obj/item/ammo_box/magazine/multi_sprite/pdh/hp - -/datum/opposing_force_equipment/ammo/mk58 - name = "MK-58 Magazine" - item_type = /obj/item/ammo_box/magazine/multi_sprite/mk58 - -/datum/opposing_force_equipment/ammo/mk58hp - name = "MK-58 Magazine (HP)" - item_type = /obj/item/ammo_box/magazine/multi_sprite/mk58/hp - -/datum/opposing_force_equipment/ammo/croon - name = "DT-4 'Croon' Magazine" - item_type = /obj/item/ammo_box/magazine/multi_sprite/croon - -/datum/opposing_force_equipment/ammo/zeta - name = "Zeta-6 'Spurchamber' Speedloader" - item_type = /obj/item/ammo_box/revolver/zeta/full - -/datum/opposing_force_equipment/ammo/revolution - name = "Revolution-8 'Spurmaster' Speedloader" - item_type = /obj/item/ammo_box/revolver/revolution/full - -/datum/opposing_force_equipment/ammo/g11 - name = "G11 K-490 Magazine" - item_type = /obj/item/ammo_box/magazine/multi_sprite/g11 - -/datum/opposing_force_equipment/ammo/g11hp - name = "G11 K-490 Magazine (HP)" - item_type = /obj/item/ammo_box/magazine/multi_sprite/g11/hp - -/datum/opposing_force_equipment/ammo/vintorez - name = "PCR Magazine" - item_type = /obj/item/ammo_box/magazine/multi_sprite/vintorez - -/datum/opposing_force_equipment/ammo/vintorezhp - name = "PCR Magazine (HP)" - item_type = /obj/item/ammo_box/magazine/multi_sprite/vintorez/hp - -/datum/opposing_force_equipment/ammo/pcr - name = "PCR Magazine" - item_type = /obj/item/ammo_box/magazine/multi_sprite/pcr - -/datum/opposing_force_equipment/ammo/pcrhp - name = "PCR Magazine (HP)" - item_type = /obj/item/ammo_box/magazine/multi_sprite/pcr/hp - -/datum/opposing_force_equipment/ammo/pitbull - name = "Pitbull PDW Magazine" - item_type = /obj/item/ammo_box/magazine/multi_sprite/pitbull - -/datum/opposing_force_equipment/ammo/pitbullhp - name = "Pitbull PDW Magazine (HP)" - item_type = /obj/item/ammo_box/magazine/multi_sprite/pitbull/hp - -/datum/opposing_force_equipment/ammo/ostwind - name = "DTR-6 Rifle Magazine" - item_type = /obj/item/ammo_box/magazine/multi_sprite/ostwind - -/datum/opposing_force_equipment/ammo/ostwindfrag - name = "DTR-6 Rifle Magazine (Frag)" - item_type = /obj/item/ammo_box/magazine/multi_sprite/ostwind/ihdf +/datum/opposing_force_equipment/ammo/trappiste585_standard + item_type = /obj/item/ammo_box/magazine/c585trappiste_pistol /datum/opposing_force_equipment/ammo/bulldog name = "Bulldog Magazine" @@ -252,7 +122,3 @@ /datum/opposing_force_equipment/ammo/c20rfire name = "C-20r Magazine (Incendiary)" item_type = /obj/item/ammo_box/magazine/smgm45/incen - -/datum/opposing_force_equipment/ammo/pepperball - name = "Pepperball Magazine" - item_type = /obj/item/ammo_box/magazine/pepperball diff --git a/modular_skyrat/modules/opposing_force/code/equipment/clothing.dm b/modular_skyrat/modules/opposing_force/code/equipment/clothing.dm index 1756407a2b97bd..d397c756778d1c 100644 --- a/modular_skyrat/modules/opposing_force/code/equipment/clothing.dm +++ b/modular_skyrat/modules/opposing_force/code/equipment/clothing.dm @@ -86,7 +86,7 @@ /datum/opposing_force_equipment/clothing/nukiemod name = "Blood-Red MODsuit" - item_type = /obj/item/mod/control/pre_equipped/nuclear + item_type = /obj/item/mod/control/pre_equipped/nuclear/unrestricted description = "A suit designed by Gorlex Marauders, offering armor ruled illegal in most of Spinward Stellar." /datum/opposing_force_equipment/clothing/elitemod diff --git a/modular_skyrat/modules/opposing_force/code/equipment/pistols.dm b/modular_skyrat/modules/opposing_force/code/equipment/pistols.dm index 88abe0e68b14ce..8d77b5c37a3626 100644 --- a/modular_skyrat/modules/opposing_force/code/equipment/pistols.dm +++ b/modular_skyrat/modules/opposing_force/code/equipment/pistols.dm @@ -17,7 +17,7 @@ admin_note = "WARNING: Roughly on-par with the .357, can use AP rounds." /datum/opposing_force_equipment/pistol/nri_pistol - item_type = /obj/item/gun/ballistic/automatic/pistol/ladon/nri + item_type = /obj/item/gun/ballistic/automatic/pistol/nri admin_note = "WARNING: Roughly on-par with the .357, can use AP rounds. Essentially a reflavored APS." /datum/opposing_force_equipment/pistol/g357 @@ -33,36 +33,5 @@ item_type = /obj/item/gun/ballistic/revolver/nagant admin_note = "WARNING: This weapon is very powerful, firing semi-auto 60 damage bullets." -/datum/opposing_force_equipment/pistol/snub - item_type = /obj/item/gun/ballistic/automatic/pistol/cfa_snub - description = "A small easily-concealable modern pistol chambered in the more widely-used 4.6x30mm. It's specifically designed to be compact." - admin_note = "Fires 20 damage bullets." - -/datum/opposing_force_equipment/pistol/ruby - item_type = /obj/item/gun/ballistic/automatic/pistol/cfa_ruby - description = "A large and loud modern handgun made to fit more universally used cartridges. It's chambered in .45, or 11.43x23mm." - admin_note = "Fires 40 damage bullets." - -/datum/opposing_force_equipment/pistol/glock17 - item_type = /obj/item/gun/ballistic/automatic/pistol/g17 - -/datum/opposing_force_equipment/pistol/glock18 - item_type = /obj/item/gun/ballistic/automatic/pistol/g18 - -/datum/opposing_force_equipment/pistol/ladon - item_type = /obj/item/gun/ballistic/automatic/pistol/ladon - -/datum/opposing_force_equipment/pistol/pdh - item_type = /obj/item/gun/ballistic/automatic/pistol/pdh - -/datum/opposing_force_equipment/pistol/mk58 - item_type = /obj/item/gun/ballistic/automatic/pistol/mk58 - -/datum/opposing_force_equipment/pistol/zeta - item_type = /obj/item/gun/ballistic/revolver/zeta - -/datum/opposing_force_equipment/pistol/revolution - item_type = /obj/item/gun/ballistic/revolver/revolution - -/datum/opposing_force_equipment/pistol/pepperball - item_type = /obj/item/gun/ballistic/automatic/pistol/pepperball +/datum/opposing_force_equipment/pistol/wespe + item_type = /obj/item/gun/ballistic/automatic/pistol/sol/evil diff --git a/modular_skyrat/modules/opposing_force/code/equipment/rifles.dm b/modular_skyrat/modules/opposing_force/code/equipment/rifles.dm index cc9e853eb7cee2..05739759a805d6 100644 --- a/modular_skyrat/modules/opposing_force/code/equipment/rifles.dm +++ b/modular_skyrat/modules/opposing_force/code/equipment/rifles.dm @@ -9,17 +9,5 @@ item_type = /obj/item/gun/ballistic/automatic/akm/nri admin_note = "WARNING: This weapon is extremely powerful, firing a 3 round burst of 38 damage bullets." -/datum/opposing_force_equipment/rifle/cfa - item_type = /obj/item/gun/ballistic/automatic/cfa_rifle - admin_note = "WARNING: This weapon is very powerful, firing single-shot 60 damage bullets." - -/datum/opposing_force_equipment/rifle/norwind - item_type = /obj/item/gun/ballistic/automatic/norwind - description = "A rare M112 DMR rechambered to 12.7x30mm for peacekeeping work, it comes with a scope for medium-long range engagements. A bayonet lug is visible." - -/datum/opposing_force_equipment/rifle/ostwind - item_type = /obj/item/gun/ballistic/automatic/ostwind - description = "A 6.3mm special-purpose rifle designed for specific situations." - -/datum/opposing_force_equipment/rifle/g11 - item_type = /obj/item/gun/ballistic/automatic/g11 +/datum/opposing_force_equipment/rifle/infanterie + item_type = /obj/item/gun/ballistic/automatic/sol_rifle/evil diff --git a/modular_skyrat/modules/opposing_force/code/equipment/shotguns.dm b/modular_skyrat/modules/opposing_force/code/equipment/shotguns.dm index 4a33b9bb162050..74e5d53263ce30 100644 --- a/modular_skyrat/modules/opposing_force/code/equipment/shotguns.dm +++ b/modular_skyrat/modules/opposing_force/code/equipment/shotguns.dm @@ -1,9 +1,8 @@ /datum/opposing_force_equipment/shotgun category = OPFOR_EQUIPMENT_CATEGORY_SHOTGUNS -/datum/opposing_force_equipment/shotgun/m23 - item_type = /obj/item/gun/ballistic/shotgun/m23 - description = "An eight-round pump-action shotgun found in an old station. Comes loaded with beanbag shells but can take any 12 gauge load." +/datum/opposing_force_equipment/shotgun/renoster + item_type = /obj/item/gun/ballistic/shotgun/riot/sol/evil /datum/opposing_force_equipment/shotgun/as2 item_type = /obj/item/gun/ballistic/shotgun/automatic/as2 diff --git a/modular_skyrat/modules/opposing_force/code/equipment/submachineguns.dm b/modular_skyrat/modules/opposing_force/code/equipment/submachineguns.dm index 15b7b82940b0a9..7b687ae7eca8cc 100644 --- a/modular_skyrat/modules/opposing_force/code/equipment/submachineguns.dm +++ b/modular_skyrat/modules/opposing_force/code/equipment/submachineguns.dm @@ -1,6 +1,9 @@ /datum/opposing_force_equipment/submachine_gun category = OPFOR_EQUIPMENT_CATEGORY_SUBMACHINE_GUNS +/datum/opposing_force_equipment/submachine_gun/sindano + item_type = /obj/item/gun/ballistic/automatic/sol_smg/evil + /datum/opposing_force_equipment/submachine_gun/mp40 item_type = /obj/item/gun/ballistic/automatic/mp40 admin_note = "WARNING: This weapon is extremely powerful, firing a 3 round burst of 30 damage bullets." @@ -23,27 +26,9 @@ description = "The uzi nine millimeter, a timeless submachinegun for a warrior out of time." admin_note = "WARNING: This weapon is decently powerful, firing a 2 round burst of 30 damage bullets." -/datum/opposing_force_equipment/submachine_gun/lynx - item_type = /obj/item/gun/ballistic/automatic/cfa_lynx - admin_note = "Capable of high rate of fire full auto of 20 damage bullets." - /datum/opposing_force_equipment/submachine_gun/nri_smg item_type = /obj/item/gun/ballistic/automatic/nri_smg admin_note = "Capable of high rate of fire bursts of 20 damage bullets." -/datum/opposing_force_equipment/submachine_gun/dozer - item_type = /obj/item/gun/ballistic/automatic/dozer - -/datum/opposing_force_equipment/submachine_gun/croon - item_type = /obj/item/gun/ballistic/automatic/croon - -/datum/opposing_force_equipment/submachine_gun/pcr - item_type = /obj/item/gun/ballistic/automatic/pcr - description = "An accurate, fast-firing SMG chambered in 9x19mm." - -/datum/opposing_force_equipment/submachine_gun/pitbull - item_type = /obj/item/gun/ballistic/automatic/pitbull - description = "A sturdy personal defense weapon designed to fire 10mm Auto rounds." - /datum/opposing_force_equipment/submachine_gun/c20r item_type = /obj/item/gun/ballistic/automatic/c20r/unrestricted diff --git a/modular_skyrat/modules/opposing_force/code/items.dm b/modular_skyrat/modules/opposing_force/code/items.dm index 394ec009bee572..d185e4e5c91a5d 100644 --- a/modular_skyrat/modules/opposing_force/code/items.dm +++ b/modular_skyrat/modules/opposing_force/code/items.dm @@ -53,10 +53,10 @@ new /obj/item/clothing/gloves/tackler/combat(src) new /obj/item/clothing/shoes/combat(src) new /obj/item/clothing/glasses/sunglasses(src) - new /obj/item/clothing/mask/gas/sechailer/swat(src) + new /obj/item/clothing/mask/gas/syndicate(src) new /obj/item/storage/belt/military(src) new /obj/item/card/id/advanced/chameleon(src) - new /obj/item/mod/control/pre_equipped/nuclear(src) + new /obj/item/mod/control/pre_equipped/nuclear/unrestricted(src) /obj/item/guardiancreator/tech/choose/traitor/opfor allowling = TRUE diff --git a/modular_skyrat/modules/opposing_force/code/roundend.dm b/modular_skyrat/modules/opposing_force/code/roundend.dm index 07b81ff4e8ac92..1725eeaf363b26 100644 --- a/modular_skyrat/modules/opposing_force/code/roundend.dm +++ b/modular_skyrat/modules/opposing_force/code/roundend.dm @@ -1,7 +1,7 @@ /datum/controller/subsystem/ticker/proc/opfor_report() var/list/result = list() - result += "
Opposing Force Report:
" + result += "Opposing Force Report:
" if(!SSopposing_force.approved_applications.len) result += span_red("No applications were approved.") @@ -9,6 +9,4 @@ for(var/datum/opposing_force/opfor in SSopposing_force.approved_applications) result += opfor.roundend_report() - result += "
" - - return result.Join() + return "
[result.Join()]
" diff --git a/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm b/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm index 264d9f8bedce84..6e724e44dbccec 100644 --- a/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm +++ b/modular_skyrat/modules/player_ranks/code/subsystem/player_ranks.dm @@ -254,21 +254,37 @@ SUBSYSTEM_DEF(player_ranks) * or in the legacy system. * * Arguments: - * * admin - The admin making the rank change. + * * admin - The admin making the rank change. Can be a /client or a /datum/admins. * * ckey - The ckey of the player you want to now possess that player rank. * * rank_title - The title of the group you want to add the ckey to. */ -/datum/controller/subsystem/player_ranks/proc/add_player_to_group(client/admin, ckey, rank_title) +/datum/controller/subsystem/player_ranks/proc/add_player_to_group(admin, ckey, rank_title) if(IsAdminAdvancedProcCall()) return FALSE if(!ckey || !admin || !rank_title) + stack_trace("Missing either ckey ([ckey || "*NULL*"]), admin ([admin || "*NULL*"]) or rank_title ([rank_title || "*NULL*"]) in add_player_to_group()! Fix this ASAP!") return FALSE - if(!check_rights_for(admin, R_PERMISSIONS)) - to_chat(admin, span_warning("You do not possess the permissions to do this.")) + var/is_admin_client = istype(admin, /client) + var/client/admin_client = is_admin_client ? admin : null + // If it's not a client, then it should be an admins datum. + var/datum/admins/admin_holder = null + if(is_admin_client) + admin_holder = admin_client?.holder + else if(istype(admin, /datum/admins)) + admin_holder = admin + + if(!admin_holder) + return FALSE + + if(!admin_holder.check_for_rights(R_PERMISSIONS)) + if(is_admin_client) + to_chat(admin, span_warning("You do not possess the permissions to do this.")) + return FALSE + rank_title = lowertext(rank_title) var/datum/player_rank_controller/controller = get_controller_for_group(rank_title) @@ -282,14 +298,16 @@ SUBSYSTEM_DEF(player_ranks) var/already_in_config = controller.get_ckeys_for_legacy_save() if(already_in_config[ckey]) - to_chat(admin, span_warning("\"[ckey]\" is already a [rank_title]!")) + if(is_admin_client) + to_chat(admin, span_warning("\"[ckey]\" is already a [rank_title]!")) + return FALSE if(controller.should_use_legacy_system()) controller.add_player_legacy(ckey) return TRUE - return add_player_rank_sql(controller, ckey, admin.ckey) + return add_player_rank_sql(controller, ckey, admin_holder.target) /** @@ -325,19 +343,34 @@ SUBSYSTEM_DEF(player_ranks) * or in the legacy system. * * Arguments: - * * admin - The admin making the rank change. + * * admin - The admin making the rank change. Can be a /client or a /datum/admins. * * ckey - The ckey of the player you want to no longer possess that player rank. * * rank_title - The title of the group you want to remove the ckey from. */ -/datum/controller/subsystem/player_ranks/proc/remove_player_from_group(client/admin, ckey, rank_title) +/datum/controller/subsystem/player_ranks/proc/remove_player_from_group(admin, ckey, rank_title) if(IsAdminAdvancedProcCall()) return FALSE if(!ckey || !admin || !rank_title) + stack_trace("Missing either ckey ([ckey || "*NULL*"]), admin ([admin || "*NULL*"]) or rank_title ([rank_title || "*NULL*"]) in remove_player_from_group()! Fix this ASAP!") return FALSE - if(!check_rights_for(admin, R_PERMISSIONS)) - to_chat(admin, span_warning("You do not possess the permissions to do this.")) + var/is_admin_client = istype(admin, /client) + var/client/admin_client = is_admin_client ? admin : null + // If it's not a client, then it should be an admins datum. + var/datum/admins/admin_holder = null + if(is_admin_client) + admin_holder = admin_client?.holder + else if(istype(admin, /datum/admins)) + admin_holder = admin + + if(!admin_holder) + return FALSE + + if(!admin_holder.check_for_rights(R_PERMISSIONS)) + if(is_admin_client) + to_chat(admin, span_warning("You do not possess the permissions to do this.")) + return FALSE rank_title = lowertext(rank_title) @@ -345,22 +378,16 @@ SUBSYSTEM_DEF(player_ranks) var/datum/player_rank_controller/controller = get_controller_for_group(rank_title) if(!controller) - stack_trace("Invalid player rank \"[rank_title]\" supplied in add_player_to_group()!") + stack_trace("Invalid player rank \"[rank_title]\" supplied in remove_player_from_group()!") return FALSE ckey = ckey(ckey) - var/already_in_config = controller.get_ckeys_for_legacy_save() - - if(!already_in_config[ckey]) - to_chat(admin, span_warning("\"[ckey]\" is already not a [rank_title]!")) - return FALSE - if(controller.should_use_legacy_system()) controller.remove_player_legacy(ckey) return TRUE - return remove_player_rank_sql(controller, ckey, admin.ckey) + return remove_player_rank_sql(controller, ckey, admin_holder.target) /** diff --git a/modular_skyrat/modules/player_ranks/code/world_topic.dm b/modular_skyrat/modules/player_ranks/code/world_topic.dm new file mode 100644 index 00000000000000..086373fd33fd63 --- /dev/null +++ b/modular_skyrat/modules/player_ranks/code/world_topic.dm @@ -0,0 +1,67 @@ + +/datum/world_topic/set_player_rank + keyword = "set_player_rank" + require_comms_key = TRUE + +/datum/world_topic/set_player_rank/Run(list/input) + . = list() + + var/sender_discord_id = input["sender_discord_id"] + + if(!sender_discord_id) + .["success"] = FALSE + .["message"] = "Invalid sender Discord ID, this should not be happening! Report this immediately!" + return + + var/target_ckey = ckey(input["target_ckey"]) + + if(!target_ckey) + .["success"] = FALSE + .["message"] = "Invalid target ckey provided." + return + + var/sender_ckey = ckey(SSdiscord.lookup_ckey(sender_discord_id)) + + if(!sender_ckey) + .["success"] = FALSE + .["message"] = "No ckey was found to be attached to the provided Discord account ID, **[sender_discord_id]**. Please verify your Discord account following the instructions of the in-game verb before trying this command again." + return + + var/datum/admins/linked_admin_holder = GLOB.admin_datums[sender_ckey] || GLOB.deadmins[sender_ckey] + + if(!linked_admin_holder) + .["success"] = FALSE + .["message"] = "No valid admin datum was found associated with the ckey associated to your Discord account." + return + + if(!linked_admin_holder.check_for_rights(R_PERMISSIONS)) + .["success"] = FALSE + .["message"] = "You do not possess the permissions to execute this command." + return + + var/target_rank = input["target_rank"] + + if(!target_rank) + .["success"] = FALSE + .["message"] = "Invalid target rank provided." + return + + target_rank = capitalize(target_rank) + + var/desired_rank_status = !!text2num(input["desired_rank_status"]) + + if(desired_rank_status) + var/result = SSplayer_ranks.add_player_to_group(linked_admin_holder, target_ckey, target_rank) + + .["success"] = !!result + .["message"] = result ? "**[linked_admin_holder.target]** successfully added **[target_rank]** status to **[target_ckey]**." : "**[linked_admin_holder.target]** was unable to add **[target_rank]** status to **[target_ckey]**. Please verify that you entered their ckey correctly and that they did not already possess that status before trying again. Use the in-game verb to get more information if you keep on receiving this error." + message_admins(replacetext(.["message"], "*", "")) + return + + else + var/result = SSplayer_ranks.remove_player_from_group(linked_admin_holder, target_ckey, target_rank) + + .["success"] = !!result + .["message"] = result ? "**[linked_admin_holder.target]** successfully removed **[target_rank]** status from **[target_ckey]**." : "**[linked_admin_holder.target]** was unable to remove **[target_rank]** status from **[target_ckey]**. Please verify that you entered their ckey correctly and that they did possess that status before trying again. Use the in-game verb to get more information if you keep on receiving this error." + message_admins(replacetext(.["message"], "*", "")) + return diff --git a/modular_skyrat/modules/primitive_catgirls/code/spawner.dm b/modular_skyrat/modules/primitive_catgirls/code/spawner.dm index 8cb3f3234feb3c..5cbe1d682c0a3a 100644 --- a/modular_skyrat/modules/primitive_catgirls/code/spawner.dm +++ b/modular_skyrat/modules/primitive_catgirls/code/spawner.dm @@ -66,8 +66,23 @@ /datum/team/primitive_catgirls name = "Icewalkers" + member_name = "Icewalker" show_roundend_report = FALSE +/datum/team/primitive_catgirls/roundend_report() + var/list/report = list() + + report += span_header("An Ice Walker Tribe inhabited the wastes...
") + if(length(members)) + report += "The [member_name]s were:" + report += printplayerlist(members) + else + report += "But none of its members woke up!" + + return "
[report.Join("
")]
" + +// Antagonist datum + /datum/antagonist/primitive_catgirl name = "\improper Icewalker" job_rank = ROLE_LAVALAND // If you're ashwalker banned you should also not be playing this, other way around as well diff --git a/modular_skyrat/modules/primitive_catgirls/code/species.dm b/modular_skyrat/modules/primitive_catgirls/code/species.dm index 7bcaec865dd942..586c7b22900524 100644 --- a/modular_skyrat/modules/primitive_catgirls/code/species.dm +++ b/modular_skyrat/modules/primitive_catgirls/code/species.dm @@ -21,6 +21,7 @@ mutanttongue = /obj/item/organ/internal/tongue/cat/primitive species_language_holder = /datum/language_holder/primitive_felinid + language_prefs_whitelist = list(/datum/language/primitive_catgirl) bodytemp_normal = 270 // If a normal human gets hugged by one its gonna feel cold bodytemp_heat_damage_limit = 283 // To them normal station atmos would be sweltering diff --git a/modular_skyrat/modules/projectiles/code/guns/misc/m6pdw.dm b/modular_skyrat/modules/projectiles/code/guns/misc/m6pdw.dm index df95f6072e933e..d4c367bafdfbc1 100644 --- a/modular_skyrat/modules/projectiles/code/guns/misc/m6pdw.dm +++ b/modular_skyrat/modules/projectiles/code/guns/misc/m6pdw.dm @@ -10,7 +10,7 @@ lefthand_file = 'modular_skyrat/modules/projectiles/icons/inhands/lefthand.dmi' w_class = WEIGHT_CLASS_NORMAL spawnwithmagazine = FALSE - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/g17 + accepted_magazine_type = /obj/item/ammo_box/magazine/c35sol_pistol can_suppress = FALSE fire_sound = 'sound/weapons/gun/pistol/shot_alt.ogg' rack_sound = 'sound/weapons/gun/pistol/rack.ogg' diff --git a/modular_skyrat/modules/resleeving/code/research/resleeving_research.dm b/modular_skyrat/modules/resleeving/code/research/resleeving_research.dm new file mode 100644 index 00000000000000..4dcd00cc73e9e6 --- /dev/null +++ b/modular_skyrat/modules/resleeving/code/research/resleeving_research.dm @@ -0,0 +1,14 @@ +/datum/design/rsd_interface + name = "RSD Phylactery" + desc = "A brain interface that allows for transfer of Resonance from a handheld RSD, such as the Evoker model." + id = "rsd_interface" + build_type = PROTOLATHE | AWAY_LATHE + departmental_flags = DEPARTMENT_BITFLAG_MEDICAL | DEPARTMENT_BITFLAG_SCIENCE + category = list(RND_CATEGORY_EQUIPMENT) + materials = list( + /datum/material/iron = SHEET_MATERIAL_AMOUNT * 0.5, + /datum/material/gold = SHEET_MATERIAL_AMOUNT, + /datum/material/silver = SHEET_MATERIAL_AMOUNT, + ) + build_path = /obj/item/rsd_interface + diff --git a/modular_skyrat/modules/resleeving/code/rsd_interface.dm b/modular_skyrat/modules/resleeving/code/rsd_interface.dm new file mode 100644 index 00000000000000..106bb11ea38bc4 --- /dev/null +++ b/modular_skyrat/modules/resleeving/code/rsd_interface.dm @@ -0,0 +1,44 @@ +/obj/item/rsd_interface + name = "RSD Phylactery" + desc = "A small device inserted, typically, into inert brains. As Resonance cannot persist in what's referred to as a 'vacuum', RSDs--much like the brains and CPUs they emulate--employ cerebral white noise as a foundation for Resonance to persist in otherwise dead-quiet containers.." + icon = 'modular_skyrat/modules/aesthetics/implanter/implanter.dmi' + icon_state = "implanter1" + inhand_icon_state = "syringe_0" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + +/// Attempts to use the item on the target brain. +/obj/item/rsd_interface/afterattack(obj/item/organ/internal/brain/target_brain, mob/user, proximity_flag, click_parameters) + . = ..() + if(!proximity_flag || !istype(target_brain)) + return FALSE + + if(HAS_TRAIT(target_brain, TRAIT_NIFSOFT_HUD_GRANTER)) + balloon_alert("already upgraded!") + return FALSE + + user.visible_message(span_notice("[user] upgrades [target_brain] with [src]."), span_notice("You upgrade [target_brain] to be RSD compatible.")) + target_brain.AddElement(/datum/element/rsd_interface) + playsound(target_brain.loc, 'sound/weapons/circsawhit.ogg', 50, vary = TRUE) + + qdel(src) + +/datum/element/rsd_interface/Attach(datum/target) + . = ..() + if(!istype(target, /obj/item/organ/internal/brain)) + return ELEMENT_INCOMPATIBLE + + RegisterSignal(target, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine)) + ADD_TRAIT(target, TRAIT_RSD_COMPATIBLE, INNATE_TRAIT) + +/// Adds text to the examine text of the parent item, explaining that the item can be used to enable the use of NIFSoft HUDs +/datum/element/rsd_interface/proc/on_examine(datum/source, mob/user, list/examine_text) + SIGNAL_HANDLER + examine_text += span_cyan("Souls can be transferred to [source], assuming it is inert.") + +/datum/element/rsd_interface/Detach(datum/target) + UnregisterSignal(target, COMSIG_ATOM_EXAMINE) + REMOVE_TRAIT(target, TRAIT_RSD_COMPATIBLE, INNATE_TRAIT) + + return ..() + diff --git a/modular_skyrat/modules/science_tools/medical_tool_designs.dm b/modular_skyrat/modules/science_tools/medical_tool_designs.dm new file mode 100644 index 00000000000000..de93e46d1420a4 --- /dev/null +++ b/modular_skyrat/modules/science_tools/medical_tool_designs.dm @@ -0,0 +1,165 @@ +// Standard tool overrides +/datum/design/scalpel + construction_time = 1 SECONDS + +/datum/design/scalpel/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/hemostat + construction_time = 1 SECONDS + +/datum/design/hemostat/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/retractor + construction_time = 1 SECONDS + +/datum/design/retractor/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/circular_saw + construction_time = 1 SECONDS + +/datum/design/circular_saw/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/cautery + construction_time = 1 SECONDS + +/datum/design/cautery/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/surgicaldrill + construction_time = 1 SECONDS + +/datum/design/surgicaldrill/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/bonesetter + construction_time = 1 SECONDS + +/datum/design/bonesetter/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/healthanalyzer + construction_time = 5 SECONDS + +// it's fine to give them health analyzers, the choke for medibot production is the medkits +/datum/design/healthanalyzer/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +// Advanced tool overrides +/datum/design/laserscalpel + construction_time = 1 SECONDS + +/datum/design/laserscalpel/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/mechanicalpinches + construction_time = 1 SECONDS + +/datum/design/mechanicalpinches/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/searingtool + construction_time = 1 SECONDS + +/datum/design/searingtool/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/healthanalyzer_advanced + construction_time = 5 SECONDS + +/datum/design/healthanalyzer_advanced/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +// Alien tool overrides +/datum/design/alienscalpel + construction_time = 1 SECONDS + +/datum/design/alienscalpel/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/alienhemostat + construction_time = 1 SECONDS + +/datum/design/alienhemostat/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/alienretractor + construction_time = 1 SECONDS + +/datum/design/alienretractor/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/aliensaw + construction_time = 1 SECONDS + +/datum/design/aliensaw/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/aliencautery + construction_time = 1 SECONDS + +/datum/design/aliencautery/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() + +/datum/design/aliendrill + construction_time = 1 SECONDS + +/datum/design/aliendrill/New() + build_type |= MECHFAB + category += list(RND_CATEGORY_MECHFAB_EQUIPMENT + RND_SUBCATEGORY_MECHFAB_EQUIPMENT_MEDICAL) + + return ..() diff --git a/modular_skyrat/modules/science_tools/readme.md b/modular_skyrat/modules/science_tools/readme.md new file mode 100644 index 00000000000000..c07b765a2261d3 --- /dev/null +++ b/modular_skyrat/modules/science_tools/readme.md @@ -0,0 +1,44 @@ + + +https://github.com/Skyrat-SS13/Skyrat-tg/pull/24162 + +## Science tools + +Module ID: SCIENCE_TOOLS + +### Description: Lets sci print watered down engi tools, and robotics, medical tools. + + + +### TG Proc/File Changes: + +- N/A + + +### Modular Overrides: + +- N/A + + +### Defines: + +- 2 defines in research.dm + + +### Included files that are not contained in this module: + +- ~skyrat_defines/research.dm + + +### Credits: + +- Niko: Author + + diff --git a/modular_skyrat/modules/science_tools/research.dm b/modular_skyrat/modules/science_tools/research.dm new file mode 100644 index 00000000000000..4992a07e30277d --- /dev/null +++ b/modular_skyrat/modules/science_tools/research.dm @@ -0,0 +1,9 @@ +/datum/techweb_node/exp_tools/New() + . = ..() + // if this datum is ever instantiated twice, somehow, this is more efficient. i feel like an idiot writing this + var/static/list/science_tools = list( + SCIENCE_JAWS_OF_LIFE_DESIGN_ID, + SCIENCE_DRILL_DESIGN_ID, + ) + design_ids += science_tools + diff --git a/modular_skyrat/modules/science_tools/tool_designs.dm b/modular_skyrat/modules/science_tools/tool_designs.dm new file mode 100644 index 00000000000000..43a38743aceb41 --- /dev/null +++ b/modular_skyrat/modules/science_tools/tool_designs.dm @@ -0,0 +1,18 @@ +/datum/design/jawsoflife/science + name = "Hybrid cutters" + desc = "An off-shoot of the jaws of life that lacks the door-opening power" + id = SCIENCE_JAWS_OF_LIFE_DESIGN_ID // added one more requirement since the Jaws of Life are a bit OP + build_path = /obj/item/crowbar/power/science + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE + +/datum/design/handdrill/science + id = SCIENCE_DRILL_DESIGN_ID + build_type = PROTOLATHE | AWAY_LATHE + build_path = /obj/item/screwdriver/power/science + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE + +/datum/design/handdrill/science/New() + name = ("Science " + name) + desc += " with a science paintjob" + + return ..() diff --git a/modular_skyrat/modules/science_tools/tools.dm b/modular_skyrat/modules/science_tools/tools.dm new file mode 100644 index 00000000000000..b9c836587dfa85 --- /dev/null +++ b/modular_skyrat/modules/science_tools/tools.dm @@ -0,0 +1,14 @@ +/obj/item/crowbar/power/science + name = "hybrid cutters" // hybrid between crowbar and wirecutters + desc = "Quite similar to the jaws of life, this tool combines the utility of a crowbar and a set of wirecutters without the hydraulic force required to pry open doors." + icon_state = "jaws_sci" + inhand_icon_state = "jaws_sci" + force_opens = FALSE + +/obj/item/screwdriver/power/science + icon_state = "drill_sci" + +/obj/item/screwdriver/power/science/Initialize(mapload) + . = ..() + + desc += " This one sports a nifty science paintjob, but is otherwise normal." diff --git a/modular_skyrat/modules/sec_haul/code/guns/ammo.dm b/modular_skyrat/modules/sec_haul/code/guns/ammo.dm index 06213fe61758ef..a0e90388d659d9 100644 --- a/modular_skyrat/modules/sec_haul/code/guns/ammo.dm +++ b/modular_skyrat/modules/sec_haul/code/guns/ammo.dm @@ -1,35 +1,6 @@ /obj/item/ammo_box/advanced multiple_sprites = AMMO_BOX_FULL_EMPTY -/datum/techweb_node/smartgun_rails - id = "smartgun_rails" - display_name = "Experimental SMARTGUN Ammunition" - description = "Standard ammo for a non-standard SMARTGUN." - prereq_ids = list("electronic_weapons", "exotic_ammo") - design_ids = list("smartgun") - research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 3000) - -/* -* 6mm -*/ - -/obj/item/ammo_box/advanced/b6mm - name = "6.3mm ammo box" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammoboxes.dmi' - icon_state = "box10mm" - ammo_type = /obj/item/ammo_casing/b6mm - max_ammo = 30 - -/obj/item/ammo_box/advanced/b6mm/rubber - name = "6.3mm dissuasive pellet box" - icon_state = "box10mm-rubber" - ammo_type = /obj/item/ammo_casing/b6mm/rubber - -/obj/item/ammo_box/advanced/b6mm/ihdf - name = "6.3mm fragmentation pellet box" - icon_state = "box10mm-hv" - ammo_type = /obj/item/ammo_casing/b6mm/ihdf - /* * 9mm */ @@ -53,114 +24,3 @@ /obj/item/ammo_box/c10mm/ihdf name = "peacekeeper ammo box (10mm ihdf)" ammo_type = /obj/item/ammo_casing/c10mm/ihdf - -/* -* 12mm -*/ - -/obj/item/ammo_box/advanced/b12mm - name = "12.7x30mm FMJ box" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammoboxes.dmi' - icon_state = "magnum_l" - ammo_type = /obj/item/ammo_casing/b12mm - max_ammo = 15 - -/obj/item/ammo_box/advanced/b12mm/rubber - name = "12.7x30mm beanbag box" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammoboxes.dmi' - icon_state = "magnum_r" - ammo_type = /obj/item/ammo_casing/b12mm/rubber - -/obj/item/ammo_box/advanced/b12mm/hp - name = "12.7x30mm JHP box" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammoboxes.dmi' - icon_state = "magnum_p" - ammo_type = /obj/item/ammo_casing/b12mm/hp - -/* -* S.M.A.R.T. RIFLE -*/ - -/datum/design/smartgun - name = "\improper S.M.A.R.T. Rifle Shock-Rails" - id = "smartgun" - build_type = PROTOLATHE - materials = list(/datum/material/silver = SHEET_MATERIAL_AMOUNT * 5, /datum/material/gold = SHEET_MATERIAL_AMOUNT * 5, /datum/material/glass = SHEET_MATERIAL_AMOUNT * 5) - build_path = /obj/item/ammo_box/advanced/smartgun - category = list(RND_CATEGORY_WEAPONS + RND_SUBCATEGORY_WEAPONS_AMMO) - departmental_flags = DEPARTMENT_BITFLAG_SECURITY - -/obj/item/ammo_box/advanced/smartgun - name = "5mm shock-rail box" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammoboxes.dmi' - icon_state = "smartgun_chain" - ammo_type = /obj/item/ammo_casing/smartgun - multiple_sprites = AMMO_BOX_PER_BULLET - max_ammo = 4 - -/* -* MULTI-SPRITE MAGS -*/ - -/obj/item/ammo_box/magazine/multi_sprite - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - desc = "An advanced magazine with smart type displays. Alt+click to reskin it." - w_class = WEIGHT_CLASS_SMALL - item_flags = NO_MAT_REDEMPTION - multitype = TRUE - var/round_type = AMMO_TYPE_LETHAL - var/base_name = "" - var/list/possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_HOLLOWPOINT, AMMO_TYPE_RUBBER, AMMO_TYPE_IHDF) - -/obj/item/ammo_box/magazine/multi_sprite/Initialize(mapload) - . = ..() - base_name = name - name = "[base_name] [round_type]" - update_icon() - -/obj/item/ammo_box/magazine/multi_sprite/AltClick(mob/user) - . = ..() - if(possible_types.len <= 1) - return - var/new_type = input("Please select a magazine type to reskin to:", "Reskin", null, null) as null|anything in sort_list(possible_types) - if(!new_type) - new_type = AMMO_TYPE_LETHAL - round_type = new_type - name = "[base_name] [round_type]" - update_icon() - -/obj/item/ammo_box/magazine/multi_sprite/update_icon() - . = ..() - var/shells_left = stored_ammo.len - switch(multiple_sprites) - if(AMMO_BOX_PER_BULLET) - icon_state = "[initial(icon_state)]_[round_type]-[shells_left]" - if(AMMO_BOX_FULL_EMPTY) - icon_state = "[initial(icon_state)]_[round_type]-[shells_left ? "full" : "empty"]" - desc = "[initial(desc)] There [(shells_left == 1) ? "is" : "are"] [shells_left] shell\s left!" - -/obj/item/ammo_box/revolver - name = "speed loader" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - desc = "Designed to quickly reload revolvers." - icon_state = "speedloader" - max_ammo = 8 - multiple_sprites = AMMO_BOX_FULL_EMPTY - var/round_type = AMMO_TYPE_LETHAL - var/list/possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_HOLLOWPOINT, AMMO_TYPE_RUBBER, AMMO_TYPE_IHDF) - start_empty = TRUE //SOmething strange going on with refills. - -/obj/item/ammo_box/revolver/AltClick(mob/user) - . = ..() - var/new_type = input("Please select a magazine type to reskin to:", "Reskin", null, null) as null|anything in sort_list(possible_types) - if(!new_type) - new_type = AMMO_TYPE_LETHAL - round_type = new_type - name = "[initial(name)] [round_type]" - update_appearance() - -/obj/item/ammo_box/revolver/update_overlays() - . = ..() - if(stored_ammo.len) - . += "[initial(icon_state)]_[round_type]" - diff --git a/modular_skyrat/modules/sec_haul/code/guns/armory_spawns.dm b/modular_skyrat/modules/sec_haul/code/guns/armory_spawns.dm index 7d338480d8d7e1..517aeded62dfc5 100644 --- a/modular_skyrat/modules/sec_haul/code/guns/armory_spawns.dm +++ b/modular_skyrat/modules/sec_haul/code/guns/armory_spawns.dm @@ -1,6 +1,7 @@ /obj/effect/spawner/armory_spawn - icon = 'modular_skyrat/modules/sec_haul/icons/guns/spawner.dmi' - icon_state = "random_gun" + icon_state = "loot" + icon = 'icons/effects/random_spawners.dmi' + layer = OBJ_LAYER /// A list of possible guns to spawn. var/list/guns @@ -35,12 +36,10 @@ new spawned_ballistic_gun.spawn_magazine_type (spawned_box) /obj/effect/spawner/armory_spawn/shotguns - icon_state = "random_shotgun" guns = list( - /obj/item/gun/ballistic/shotgun/riot, - /obj/item/gun/ballistic/shotgun/riot, - /obj/item/gun/ballistic/shotgun/riot, - /obj/item/gun/ballistic/shotgun/riot, + /obj/item/gun/ballistic/shotgun/riot/sol, + /obj/item/gun/ballistic/shotgun/riot/sol, + /obj/item/gun/ballistic/shotgun/riot/sol, ) /obj/structure/closet/ammunitionlocker/useful/PopulateContents() @@ -56,16 +55,14 @@ /obj/item/storage/box/ammo_box name = "ammo box" desc = "A box filled with ammunition." - icon_state = "boxhrifle" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammoboxes.dmi' + icon = 'modular_skyrat/modules/microfusion/icons/microfusion_cells.dmi' + icon_state = "microfusion_box" illustration = null layer = 2.9 /obj/item/storage/box/ammo_box/microfusion name = "microfusion cell container" desc = "A box filled with microfusion cells." - icon = 'modular_skyrat/modules/microfusion/icons/microfusion_cells.dmi' - icon_state = "microfusion_box" /obj/item/storage/box/ammo_box/microfusion/PopulateContents() new /obj/item/stock_parts/cell/microfusion(src) @@ -73,25 +70,23 @@ new /obj/item/stock_parts/cell/microfusion(src) /obj/effect/spawner/armory_spawn/centcom_rifles - icon_state = "random_rifle" guns = list( - /obj/item/gun/ballistic/automatic/ar, - /obj/item/gun/ballistic/automatic/m16, - /obj/item/gun/ballistic/automatic/cfa_rifle, + /obj/item/gun/ballistic/automatic/sol_rifle, + /obj/item/gun/ballistic/automatic/sol_rifle, + /obj/item/gun/ballistic/automatic/sol_rifle/machinegun, ) /obj/effect/spawner/armory_spawn/centcom_lasers guns = list( /obj/item/gun/energy/laser, - /obj/item/gun/energy/laser/cfa_paladin, + /obj/item/gun/energy/laser, /obj/item/gun/energy/e_gun, ) -/obj/effect/spawner/armory_spawn/cmg - icon_state = "random_rifle" +/obj/effect/spawner/armory_spawn/smg vertical_guns = FALSE guns = list( - /obj/item/storage/box/gunset/cmg, - /obj/item/storage/box/gunset/cmg, - /obj/item/storage/box/gunset/cmg, + /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano, + /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano, + /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano, ) diff --git a/modular_skyrat/modules/sec_haul/code/guns/bullets.dm b/modular_skyrat/modules/sec_haul/code/guns/bullets.dm index e6f23736b4e107..c7bc249b351e61 100644 --- a/modular_skyrat/modules/sec_haul/code/guns/bullets.dm +++ b/modular_skyrat/modules/sec_haul/code/guns/bullets.dm @@ -1,63 +1,3 @@ -/* -* 6.3mm -* FLECHETTE | FRAGMENTING | DISSUASIVE -*/ - -/obj/item/ammo_casing/b6mm - name = "6.3mm flechette casing" - desc = "A spent flechette." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "sl-casing" - caliber = CALIBER_6MM - projectile_type = /obj/projectile/bullet/b6mm - -/obj/projectile/bullet/b6mm - name = "6.3mm flechette" - damage = 10 - speed = 1 - embedding = list(embed_chance=10, fall_chance=3, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10) - armour_penetration = 50 - -/obj/item/ammo_casing/b6mm/rubber - name = "6.3mm dissuasive pellet casing" - desc = "A 6.3mm dissuasive pellet casing." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "sr-casing" - caliber = CALIBER_6MM - projectile_type = /obj/projectile/bullet/b6mm/rubber - harmful = FALSE - -/obj/projectile/bullet/b6mm/rubber - name = "6mm dissuasive pellet" - icon_state = "pellet" - damage = 2 - stamina = 15 - ricochets_max = 2 - ricochet_incidence_leeway = 0 - ricochet_chance = 130 - ricochet_decay_damage = 0.8 - shrapnel_type = null - sharpness = NONE - embedding = null - -/obj/item/ammo_casing/b6mm/ihdf - name = "6.3mm frag casing" - desc = "A 6.3mm fragmentation round casing." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "si-casing" - caliber = CALIBER_6MM - projectile_type = /obj/projectile/bullet/b6mm/ihdf - harmful = TRUE - -/obj/projectile/bullet/b6mm/ihdf - name = "6.3mm fragmentation pellet" - icon_state = "ihdf" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/projectiles.dmi' - damage = 15 - bare_wound_bonus = 50 - embedding = list(embed_chance=60, fall_chance=3, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10) - weak_against_armour = TRUE - /* * 9x25mm Mk.12 */ @@ -86,15 +26,11 @@ /obj/item/ammo_casing/c9mm/ihdf name = "9x25mm Mk.12 IHDF casing" desc = "A modern 9x25mm Mk.12 bullet casing. This one fires a bullet of 'Intelligent High-Impact Dispersal Foam', which is best compared to a riot-grade foam dart." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "si-casing" projectile_type = /obj/projectile/bullet/c9mm/ihdf harmful = FALSE /obj/projectile/bullet/c9mm/ihdf name = "9x25mm IHDF bullet" - icon_state = "ihdf" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/projectiles.dmi' damage = 30 damage_type = STAMINA embedding = list(embed_chance=0, fall_chance=3, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10) @@ -102,8 +38,6 @@ /obj/item/ammo_casing/c9mm/rubber name = "9x25mm Mk.12 rubber casing" desc = "A modern 9x25mm Mk.12 bullet casing. This less than lethal round sure hurts to get shot by, but causes little physical harm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "sr-casing" projectile_type = /obj/projectile/bullet/c9mm/rubber harmful = FALSE @@ -135,11 +69,14 @@ custom_materials = AMMO_MATS_TEMP advanced_print_req = TRUE +/obj/item/ammo_casing/c10mm/reaper + can_be_printed = FALSE + // it's a hitscan 50 damage 40 AP bullet designed to be fired out of a gun with a 2rnd burst and 1.25x damage multiplier + // Let's Not + /obj/item/ammo_casing/c10mm/rubber name = "10mm rubber bullet casing" desc = "A 10mm rubber bullet casing." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "sr-casing" projectile_type = /obj/projectile/bullet/c10mm/rubber harmful = FALSE @@ -158,204 +95,11 @@ /obj/item/ammo_casing/c10mm/ihdf name = "10mm IHDF bullet casing" desc = "A 10mm intelligent high-impact dispersal foam bullet casing." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "si-casing" projectile_type = /obj/projectile/bullet/c10mm/ihdf harmful = FALSE /obj/projectile/bullet/c10mm/ihdf name = "10mm IHDF bullet" - icon_state = "ihdf" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/projectiles.dmi' damage = 40 damage_type = STAMINA embedding = list(embed_chance=0, fall_chance=3, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10) - -/* -* 12.7x30mm -* FMJ | JHP | BEANBAG -*/ - -/obj/item/ammo_casing/b12mm - name = "12.7x30mm FMJ casing" - desc = "A 12.7x30mm FMJ casing." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "sl-casing" - caliber = CALIBER_12MM - projectile_type = /obj/projectile/bullet/b12mm - -/obj/projectile/bullet/b12mm - name = "12.7x30mm bullet" - damage = 35 - wound_bonus = 30 - speed = 1 - -/obj/item/ammo_casing/b12mm/rubber - name = "12.7x30mm beanbag slug casing" - desc = "A 12.7x30mm beanbag slug casing." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "sr-casing" - caliber = CALIBER_12MM - projectile_type = /obj/projectile/bullet/b12mm/rubber - harmful = FALSE - -/obj/projectile/bullet/b12mm/rubber - name = "12.7x30mm beanbag slug" - damage = 10 - stamina = 35 - ricochets_max = 6 - ricochet_incidence_leeway = 0 - ricochet_chance = 130 - ricochet_decay_damage = 0.8 - shrapnel_type = null - sharpness = NONE - embedding = null - - -/obj/item/ammo_casing/b12mm/hp - name = "12.7x30mm JHP casing" - desc = "A 12.7x30mm JHP bullet casing." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "sh-casing" - caliber = CALIBER_12MM - projectile_type = /obj/projectile/bullet/b12mm/hp - advanced_print_req = TRUE - -/obj/projectile/bullet/b12mm/hp - name = "12mm hollowpoint bullet" - damage = 35 - wound_bonus = 40 - embedding = list(embed_chance=75, fall_chance=3, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10) - weak_against_armour = TRUE - -/* -* .577S -* FMJ -*/ - -/obj/item/ammo_casing/b577 - name = ".577 Snider bullet casing" - desc = "A .577 Snider bullet casing." - caliber = CALIBER_B577 - projectile_type = /obj/projectile/bullet/b577 - -/obj/projectile/bullet/b577 - name = ".577S FMJ bullet" - damage = 40 - wound_bonus = 15 - bare_wound_bonus = 30 - dismemberment = 15 - -//SMARTGUN -/obj/item/ammo_casing/smartgun - name = "smartgun rail frame" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "smartgun" - desc = "A smartgun rail." - caliber = "smartgun" - projectile_type = /obj/projectile/bullet/smartgun - can_be_printed = FALSE - -/obj/projectile/bullet/smartgun - name = "smartgun rail" - icon_state = "gaussphase" - embedding = list(embed_chance=100, fall_chance=2, jostle_chance=0, ignore_throwspeed_threshold=TRUE, pain_stam_pct=20, pain_mult=4, rip_time=40) - damage = 10 - stamina = 70 - ricochets_max = 6 - ricochet_incidence_leeway = 0 - ricochet_chance = 130 - ricochet_decay_damage = 0.8 - shrapnel_type = /obj/item/shrapnel/bullet/smartgun - hitsound = 'modular_skyrat/modules/sec_haul/sound/rail.ogg' - -/obj/projectile/bullet/smartgun/on_hit(atom/target, blocked, pierce_hit) - . = ..() - if(ishuman(target)) - var/mob/living/carbon/human/H = target - H.emote("scream") - H.add_mood_event("tased", /datum/mood_event/tased) - if((H.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(H, TRAIT_STUNIMMUNE)) - addtimer(CALLBACK(H, TYPE_PROC_REF(/mob/living/carbon, do_jitter_animation), jitter), 5) - -/obj/item/shrapnel/bullet/smartgun - name = "smartgun shredder" - icon = 'icons/obj/weapons/guns/projectiles.dmi' - icon_state = "gaussphase" - embedding = null - -/* -* 4.73x33mm CASELESS -* FMJ | JHP | IHDF | RUBBER -*/ - -/obj/item/ammo_casing/b473 - name = "4.73x33mm FMJ bullet" - desc = "A 4.73x33mm FMJ bullet." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "sl-casing" - caliber = CALIBER_473MM - projectile_type = /obj/projectile/bullet/b473 - -/obj/item/ammo_casing/b473/Initialize(mapload) - . = ..() - AddElement(/datum/element/caseless) - -/obj/projectile/bullet/b473 - name = "4.73x33mm FMJ bullet" - damage = 20 - speed = 0.7 - -/obj/item/ammo_casing/b473/hp - name = "4.73x33mm JHP bullet" - desc = "A 4.73x33mm JHP bullet." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "sh-casing" - caliber = CALIBER_473MM - projectile_type = /obj/projectile/bullet/b473/hp - advanced_print_req = TRUE - -/obj/projectile/bullet/b473/hp - name = "4.73x33mm JHP bullet" - damage = 20 - wound_bonus = 30 - embedding = list(embed_chance=75, fall_chance=3, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10) - weak_against_armour = TRUE - -/obj/item/ammo_casing/b473/rubber - name = "4.73x33mm rubber bullet" - desc = "A 4.73x33mm rubber bullet." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "sr-casing" - caliber = CALIBER_473MM - projectile_type = /obj/projectile/bullet/b473/rubber - harmful = FALSE - -/obj/projectile/bullet/b473/rubber - name = "4.73x33mm rubber bullet" - damage = 5 - stamina = 20 - ricochets_max = 6 - ricochet_incidence_leeway = 0 - ricochet_chance = 130 - ricochet_decay_damage = 0.8 - shrapnel_type = null - sharpness = NONE - embedding = null - -/obj/item/ammo_casing/b473/ihdf - name = "4.73x33mm IHDF bullet" - desc = "A 4.73x33mm intelligent high-impact dispersal foam bullet." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi' - icon_state = "si-casing" - caliber = CALIBER_473MM - projectile_type = /obj/projectile/bullet/b473/ihdf - harmful = FALSE - -/obj/projectile/bullet/b473/ihdf - name = "4.73x33mm ihdf bullet" - icon_state = "ihdf" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/projectiles.dmi' - damage = 25 - damage_type = STAMINA - embedding = list(embed_chance=0, fall_chance=3, jostle_chance=4, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=5, jostle_pain_mult=6, rip_time=10) diff --git a/modular_skyrat/modules/sec_haul/code/guns/cargo_stuff.dm b/modular_skyrat/modules/sec_haul/code/guns/cargo_stuff.dm index e32557bd318a16..97c006240a5495 100644 --- a/modular_skyrat/modules/sec_haul/code/guns/cargo_stuff.dm +++ b/modular_skyrat/modules/sec_haul/code/guns/cargo_stuff.dm @@ -1,10 +1,10 @@ /datum/supply_pack/security/armory/cmg - name = "NT CMG-2 PDW Crate" - desc = "Three entirely proprietary CMG-2 kits, chambered in 9x25mm. Each kit contains an ammo pouch, one less-lethal rubber magazine, and two lethal magazines." + name = "Carwo 'Sindano' Submachinegun Crate" + desc = "Three entirely proprietary Sindano kits, chambered in .35 Sol Short. Each kit contains three empty magazines and a box each of incapacitator and lethal rounds." cost = CARGO_CRATE_VALUE * 20 contains = list( - /obj/item/storage/box/gunset/cmg, - /obj/item/storage/box/gunset/cmg, - /obj/item/storage/box/gunset/cmg, + /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano, + /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano, + /obj/item/storage/toolbox/guncase/skyrat/carwo_large_case/sindano, ) - crate_name = "NT CMG-2 PDW Crate" + crate_name = "Carwo 'Sindano' Submachinegun Crate" diff --git a/modular_skyrat/modules/sec_haul/code/guns/cmg.dm b/modular_skyrat/modules/sec_haul/code/guns/cmg.dm deleted file mode 100644 index 99f8c2586bfeed..00000000000000 --- a/modular_skyrat/modules/sec_haul/code/guns/cmg.dm +++ /dev/null @@ -1,138 +0,0 @@ -/** - * The CMG-2. - * - * It sure does exist. Comes with a projectile damage malus for some sense of parity with the old 9mm Peacekeeper round. - * Supposed to fill the niche of being a sidearm, apparently? But it's a longarm, but it also fires 9mm and has a damage malus - * (slightly buffed from the usual 9mm PK -> 9x25mm + 0.5x damage multiplier). - */ - -/obj/item/gun/ballistic/automatic/cmg - name = "\improper NT CMG-2 PDW" - desc = "A bullpup, two-round burst PDW chambered in 9x25mm, developed by Nanotrasen R&D and based on a licensed Scarborough Arms design. \ - It features a folding stock and comes pre-attached with a dot sight. Unfortunately, the recoil management system reduces the \ - stopping power of individual rounds, but the manufacturer insists that quirk can be mitigated by not missing." - icon_state = "cmg1" - icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns.dmi' - inhand_icon_state = "c20r" - selector_switch_icon = TRUE - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/cmg - fire_delay = 2 //Slightly buffed firespeed over the last cmg because the bullets are a bit weaker - burst_size = 1 - actions_types = list() - can_bayonet = TRUE - knife_x_offset = 26 - knife_y_offset = 10 - mag_display = TRUE - mag_display_ammo = TRUE - empty_indicator = TRUE - w_class = WEIGHT_CLASS_BULKY - projectile_damage_multiplier = 0.7 - // raw outputs: - // lethal: 30 * 0.7 = 21 - // AP: 27 * 0.7 = 18.9 - // HP: 40 * 0.7 = 28 - // INC: 15 * 0.7 = 10.5 - // rubber: 5 * 0.7 = 3.5 brute, 25 * 0.7 = 17.5 stam - // IHDF (does this even get used): 30 * 0.7 = 21 stam - - /// what sound do we play when finished adjusting the stock? - var/folding_sound = 'sound/weapons/batonextend.ogg' - /// is our stock collapsed? - var/folded = FALSE - /// how long does it take to extend/collapse the stock - var/toggle_time = 1 SECONDS - /// what's our spread with our extended stock (mild varedit compatibility I Guess)? - var/unfolded_spread = 0 - /// what's our spread with a folded stock (see above comment)? - var/folded_spread = 20 - -/obj/item/gun/ballistic/automatic/cmg/examine(mob/user) - . = ..() - . += span_notice("Ctrl-click to [folded ? "extend" : "collapse"] the stock.") - -/obj/item/gun/ballistic/automatic/cmg/CtrlClick(mob/user) - if(!user.is_holding(src)) - return // fuckin around w/ a collapsible stock without hands is Suboptimal - if(item_flags & IN_STORAGE) - return // if you could unfold it while it's stowed away that'd defeat the purpose - toggle_stock(user) - . = ..() - -/obj/item/gun/ballistic/automatic/cmg/proc/toggle_stock(mob/user, var/forced) - if(!user && forced) // for the possible case of having every shipped CMG be pre-folded - folded = !folded - update_fold_stats() - return - balloon_alert(user, "[folded ? "extending" : "collapsing"] stock...") - if(!do_after(user, toggle_time)) - balloon_alert(user, "interrupted!") - return - folded = !folded - update_fold_stats() - balloon_alert(user, "stock [folded ? "collapsed" : "extended"]") - playsound(src.loc, folding_sound, 30, 1) - -/obj/item/gun/ballistic/automatic/cmg/proc/update_fold_stats() - if(folded) - spread = folded_spread - if(suppressed) - w_class = WEIGHT_CLASS_BULKY - else - w_class = WEIGHT_CLASS_NORMAL - else - spread = unfolded_spread - if(suppressed) - w_class = WEIGHT_CLASS_HUGE - else - w_class = WEIGHT_CLASS_BULKY - update_icon() - -/obj/item/gun/ballistic/automatic/cmg/update_overlays() - . = ..() - . += "[icon_state]-stock[folded ? "_in" : "_out"]" - -/obj/item/gun/ballistic/automatic/cmg/Initialize(mapload) - . = ..() - AddComponent(/datum/component/automatic_fire, 0.3 SECONDS) - -/obj/item/gun/ballistic/automatic/cmg/add_seclight_point() - AddComponent(/datum/component/seclite_attachable, \ - light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', \ - light_overlay = "flight", \ - overlay_x = 24, \ - overlay_y = 10) - -/obj/item/ammo_box/magazine/multi_sprite/cmg - name = "9x25mm PDW magazine" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "g11" - ammo_type = /obj/item/ammo_casing/c9mm/rubber - caliber = CALIBER_9MM - max_ammo = 24 - multiple_sprites = AMMO_BOX_FULL_EMPTY - round_type = AMMO_TYPE_RUBBER - -/obj/item/ammo_box/magazine/multi_sprite/cmg/hp - ammo_type = /obj/item/ammo_casing/c9mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/cmg/ihdf - ammo_type = /obj/item/ammo_casing/c9mm/ihdf - round_type = AMMO_TYPE_IHDF - -/obj/item/ammo_box/magazine/multi_sprite/cmg/lethal - ammo_type = /obj/item/ammo_casing/c9mm - round_type = AMMO_TYPE_LETHAL - -/obj/item/storage/box/gunset/cmg - name = "cmg supply box" - -/obj/item/gun/ballistic/automatic/cmg/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/cmg/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/cmg/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/cmg(src) - new /obj/item/ammo_box/magazine/multi_sprite/cmg/lethal(src) - new /obj/item/ammo_box/magazine/multi_sprite/cmg/lethal(src) diff --git a/modular_skyrat/modules/sec_haul/code/guns/guns.dm b/modular_skyrat/modules/sec_haul/code/guns/guns.dm deleted file mode 100644 index 04a85fa0c87e14..00000000000000 --- a/modular_skyrat/modules/sec_haul/code/guns/guns.dm +++ /dev/null @@ -1,1162 +0,0 @@ -/* -* GLOCK -*/ - -/obj/item/gun/ballistic/automatic/pistol/g17 - name = "\improper GK-17" - desc = "A weapon from bygone times, this has been made to look like an old, blocky firearm from the 21st century. Let's hope it's more reliable. Chambered in 9x25mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/glock.dmi' - icon_state = "glock" - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/g17 - can_suppress = FALSE - fire_sound = 'sound/weapons/gun/pistol/shot_alt.ogg' - rack_sound = 'sound/weapons/gun/pistol/rack.ogg' - lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' - bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - fire_delay = 1.90 - projectile_damage_multiplier = 0.5 - -/obj/item/gun/ballistic/automatic/pistol/g17/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN) - -/obj/item/gun/ballistic/automatic/pistol/g17/add_seclight_point() - return - -/obj/item/ammo_box/magazine/multi_sprite/g17 - name = "\improper GK-17 magazine" - desc = "A magazine for the GK-17 handgun, chambered for 9x25mm ammo." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "g17" - ammo_type = /obj/item/ammo_casing/c9mm - caliber = CALIBER_9MM - max_ammo = 17 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/g17/hp - ammo_type = /obj/item/ammo_casing/c9mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/g17/ihdf - ammo_type = /obj/item/ammo_casing/c9mm/ihdf - round_type = AMMO_TYPE_IHDF - -/obj/item/ammo_box/magazine/multi_sprite/g17/rubber - ammo_type = /obj/item/ammo_casing/c9mm/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/gun/ballistic/automatic/pistol/g18 - name = "\improper GK-18" - desc = "A CFA-made burst firing cheap polymer pistol chambered in 9x25mm. Its heavy duty barrel affects firerate." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/glock.dmi' - icon_state = "glock_spec" - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/g18 - can_suppress = FALSE - fire_sound = 'sound/weapons/gun/pistol/shot_alt.ogg' - rack_sound = 'sound/weapons/gun/pistol/rack.ogg' - lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' - bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - burst_size = 3 - fire_delay = 2.10 - spread = 8 - actions_types = list(/datum/action/item_action/toggle_firemode) - mag_display = FALSE - mag_display_ammo = FALSE - projectile_damage_multiplier = 0.5 - -/obj/item/gun/ballistic/automatic/pistol/g18/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_CANTALAN) - -/obj/item/gun/ballistic/automatic/pistol/g18/add_seclight_point() - AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") - -/obj/item/ammo_box/magazine/multi_sprite/g18 - name = "\improper GK-18 magazine" - desc = "A magazine for the GK-18 machine pistol, chambered for 9x25mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "g18" - ammo_type = /obj/item/ammo_casing/c9mm - caliber = CALIBER_9MM - max_ammo = 33 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/g18/hp - ammo_type = /obj/item/ammo_casing/c9mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/g18/ihdf - ammo_type = /obj/item/ammo_casing/c9mm/ihdf - round_type = AMMO_TYPE_IHDF - -/obj/item/ammo_box/magazine/multi_sprite/g18/rubber - ammo_type = /obj/item/ammo_casing/c9mm/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/gun/ballistic/automatic/pistol/g17/mesa - name = "\improper Glock 20" - desc = "A weapon from bygone times, and this is the exact 21st century version. In fact, even more reliable. Chambered in 10mm Auto." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/glock.dmi' - icon_state = "glock_mesa" - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/ladon // C o m p a t i b i l i t y . - fire_sound = 'modular_skyrat/master_files/sound/weapons/glock17_fire.ogg' - rack_sound = 'sound/weapons/gun/pistol/rack.ogg' - lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' - bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - fire_delay = 0.9 - -/obj/item/gun/ballistic/automatic/pistol/g17/mesa/give_manufacturer_examine() - return - -/obj/item/gun/ballistic/automatic/pistol/g17/mesa/add_seclight_point() - AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") - -/* -* PDH 40x32 -*/ - -/obj/item/gun/ballistic/automatic/pistol/pdh - name = "\improper PDH-6H 'Osprey'" - desc = "A modern ballistics sidearm, used primarily by the military, however this one has had a paintjob to match command. It's chambered in 12.7x30mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/pdh.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand40x32.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand40x32.dmi' - icon_state = "pdh" - inhand_icon_state = "pdh" - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/pdh - can_suppress = FALSE - fire_sound = 'modular_skyrat/modules/sec_haul/sound/hpistol_fire.ogg' - rack_sound = 'sound/weapons/gun/pistol/rack.ogg' - lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' - bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - -/obj/item/gun/ballistic/automatic/pistol/pdh/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_ARMADYNE) - -/obj/item/gun/ballistic/automatic/pistol/pdh/add_seclight_point() - AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") - -/obj/item/gun/ballistic/automatic/pistol/pdh/alt - name = "\improper PDH-6C 'SOCOM'" - desc = "A prestigious 12mm sidearm normally seen in the hands of SolFed special operation units due to its reliable and time-tested design. Now's one of those times that pays to be the strong, silent type." - icon_state = "pdh_alt" - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/pdh - can_suppress = FALSE - fire_sound = 'sound/weapons/gun/pistol/shot_suppressed.ogg' - fire_delay = 8 - fire_sound_volume = 30 - spread = 1 - -/obj/item/ammo_box/magazine/multi_sprite/pdh - name = "12mm PDH-6 magazine" - desc = "A heavy 12mm magazine made for the PDH-6H and PDH-6C handguns." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "pdh" - ammo_type = /obj/item/ammo_casing/b12mm - caliber = CALIBER_12MM - max_ammo = 8 - multiple_sprites = AMMO_BOX_FULL_EMPTY - possible_types = list( - AMMO_TYPE_LETHAL, - AMMO_TYPE_HOLLOWPOINT, - AMMO_TYPE_RUBBER, - ) - -/obj/item/ammo_box/magazine/multi_sprite/pdh/hp - ammo_type = /obj/item/ammo_casing/b12mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/pdh/rubber - ammo_type = /obj/item/ammo_casing/b12mm/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/gun/ballistic/automatic/pistol/pdh/corpo - name = "\improper PDH-6M 'Corpo'" - desc = "A prestigious ballistic sidearm, from Armadyne's military division, normally given to high-ranking corporate agents. It has a 3 round burst mode and uses .357 Magnum ammunition." - icon_state = "pdh_corpo" - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/pdh_corpo - can_suppress = FALSE - fire_sound = 'modular_skyrat/modules/sec_haul/sound/hpistol_fire.ogg' - burst_size = 3 - fire_delay = 2 - spread = 5 - actions_types = list(/datum/action/item_action/toggle_firemode) - -/obj/item/ammo_box/magazine/multi_sprite/pdh_corpo - name = "\improper PDH-6M magazine" - desc = "A magazine for Armadyne's exclusive corporate handgun. Chambered for .357, to your disgrace." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "pdh" - ammo_type = /obj/item/ammo_casing/a357 - caliber = CALIBER_357 - max_ammo = 14 - multiple_sprites = AMMO_BOX_FULL_EMPTY - possible_types = list( - AMMO_TYPE_LETHAL, - ) - -/* -* PDH STRIKER -*/ - -// A temporary home for this gun until the Corporate Diplomat PR goes through. -/obj/item/gun/ballistic/automatic/pistol/pdh/striker - name = "\improper PDH-6 'Striker'" - desc = "A sidearm used by Armadyne corporate agents who didn't make the cut for the Corpo model. Chambered in .38 special." - icon_state = "pdh_striker" - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/pdh_striker - can_suppress = FALSE - fire_sound = 'modular_skyrat/modules/sec_haul/sound/hpistol_fire.ogg' - burst_size = 3 - fire_delay = 2 - spread = 9 - actions_types = list(/datum/action/item_action/toggle_firemode) - -/obj/item/ammo_box/magazine/multi_sprite/pdh_striker - name = "\improper PDH-6M magazine" - desc = "A magazine for the PDH-6 'Striker'. Chambered in the strange choice of .38 special." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "pdh" - ammo_type = /obj/item/ammo_casing/c38 - caliber = CALIBER_38 - max_ammo = 10 - multiple_sprites = AMMO_BOX_FULL_EMPTY - possible_types = list( - AMMO_TYPE_LETHAL, - ) - -/* -* PDH PEACEKEEPER -*/ - -/obj/item/gun/ballistic/automatic/pistol/pdh/peacekeeper - name = "\improper PDH-6B" - desc = "A modern ballistic sidearm, used primarily by law enforcement, chambered in 9x25mm." - fire_delay = 1.95 - icon_state = "pdh_peacekeeper" - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper - fire_sound = 'modular_skyrat/modules/sec_haul/sound/pistol_fire.ogg' - projectile_damage_multiplier = 0.5 - -/obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper - name = "\improper PDH-6B magazine" - desc = "A magazine for the PDG-6B law enforcement pistol, chambered for 9x25mm ammo." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "pdh" - ammo_type = /obj/item/ammo_casing/c9mm - caliber = CALIBER_9MM - max_ammo = 16 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper/hp - ammo_type = /obj/item/ammo_casing/c9mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper/ihdf - ammo_type = /obj/item/ammo_casing/c9mm/ihdf - round_type = AMMO_TYPE_IHDF - -/obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper/rubber - ammo_type = /obj/item/ammo_casing/c9mm/rubber - round_type = AMMO_TYPE_RUBBER - -/* -* LADON 40x32 -*/ - -/obj/item/gun/ballistic/automatic/pistol/ladon - name = "\improper Ladon pistol" - desc = "Modern handgun based off the PDH series, chambered in 10mm Auto." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ladon.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand40x32.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand40x32.dmi' - icon_state = "ladon" - inhand_icon_state = "ladon" - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/ladon - can_suppress = FALSE - fire_sound = 'modular_skyrat/modules/sec_haul/sound/pistol_fire.ogg' - rack_sound = 'sound/weapons/gun/pistol/rack.ogg' - lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' - bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - fire_delay = 4.20 - projectile_damage_multiplier = 0.7 - -/obj/item/gun/ballistic/automatic/pistol/ladon/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_ARMADYNE) - -/obj/item/gun/ballistic/automatic/pistol/ladon/add_seclight_point() - AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") - -/obj/item/ammo_box/magazine/multi_sprite/ladon - name = "\improper Ladon magazine" - desc = "A magazine for the Ladon pistol, chambered for 10mm Auto." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "pdh" - ammo_type = /obj/item/ammo_casing/c10mm - caliber = CALIBER_10MM - max_ammo = 12 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/ladon/hp - ammo_type = /obj/item/ammo_casing/c10mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/ladon/ihdf - ammo_type = /obj/item/ammo_casing/c10mm/ihdf - round_type = AMMO_TYPE_IHDF - -/obj/item/ammo_box/magazine/multi_sprite/ladon/rubber - ammo_type = /obj/item/ammo_casing/c10mm/rubber - round_type = AMMO_TYPE_RUBBER - -/* -* MAKAROV -*/ - -/obj/item/gun/ballistic/automatic/pistol/makarov - name = "\improper R-C 'Makarov'" - desc = "A mediocre pocket-sized handgun of NRI origin, chambered in 10mm Auto." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/makarov.dmi' - icon_state = "makarov" - w_class = WEIGHT_CLASS_SMALL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/makarov - can_suppress = TRUE - rack_sound = 'sound/weapons/gun/pistol/rack.ogg' - lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' - bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - projectile_damage_multiplier = 0.6 - -/obj/item/gun/ballistic/automatic/pistol/makarov/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_IZHEVSK) - -/obj/item/ammo_box/magazine/multi_sprite/makarov - name = "\improper R-C Makarov magazine" - desc = "A tiny magazine for the R-C Makarov pocket pistol, chambered in 10mm Auto." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "pdh" - ammo_type = /obj/item/ammo_casing/c10mm - caliber = CALIBER_10MM - max_ammo = 6 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/makarov/hp - ammo_type = /obj/item/ammo_casing/c10mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/makarov/ihdf - ammo_type = /obj/item/ammo_casing/c10mm/ihdf - round_type = AMMO_TYPE_IHDF - -/obj/item/ammo_box/magazine/multi_sprite/makarov/rubber - ammo_type = /obj/item/ammo_casing/c10mm/rubber - round_type = AMMO_TYPE_RUBBER - -/* -* MK-58 -*/ - -/obj/item/gun/ballistic/automatic/pistol/mk58 - name = "\improper MK-58" - desc = "A modern 9x25mm handgun with an olive polymer lower frame. Looks like a generic 21st century military sidearm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mk58.dmi' - icon_state = "mk58" - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/mk58 - can_suppress = FALSE - fire_sound = 'modular_skyrat/modules/sec_haul/sound/pistol_fire.ogg' - rack_sound = 'sound/weapons/gun/pistol/rack.ogg' - lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' - bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - projectile_damage_multiplier = 0.5 - -/obj/item/gun/ballistic/automatic/pistol/mk58/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_ARMADYNE) - -/obj/item/ammo_box/magazine/multi_sprite/mk58 - name = "\improper MK-58 magazine" - desc = "A flimsy double-stack polymer magazine for the MK-58 handgun, chambered for 9x25mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "g17" - ammo_type = /obj/item/ammo_casing/c9mm - caliber = CALIBER_9MM - max_ammo = 12 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/mk58/hp - ammo_type = /obj/item/ammo_casing/c9mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/mk58/ihdf - ammo_type = /obj/item/ammo_casing/c9mm/ihdf - round_type = AMMO_TYPE_IHDF - -/obj/item/ammo_box/magazine/multi_sprite/mk58/rubber - ammo_type = /obj/item/ammo_casing/c9mm/rubber - round_type = AMMO_TYPE_RUBBER - -/* -* FIREFLY -*/ - -/obj/item/gun/ballistic/automatic/pistol/firefly - name = "\improper P-92 pistol" - desc = "A simple sidearm made by Armadyne's Medical Directive, with a heavy front for weak wrists. A small warning label on the back says it's not fit for surgical work, and chambered for 9x25mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/firefly.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi' - icon_state = "firefly" - inhand_icon_state = "firefly" - fire_delay = 1.95 - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/firefly - can_suppress = FALSE - projectile_damage_multiplier = 0.5 - -/obj/item/gun/ballistic/automatic/pistol/firefly/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_ARMADYNE) - -/obj/item/gun/ballistic/automatic/pistol/firefly/add_seclight_point() - AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") - - -/obj/item/ammo_box/magazine/multi_sprite/firefly - name = "\improper P-92 magazine" - desc = "A twelve-round magazine for the P-92 pistol, chambered in 9x25mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "pdh" - ammo_type = /obj/item/ammo_casing/c9mm - caliber = CALIBER_9MM - max_ammo = 12 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/firefly/hp - ammo_type = /obj/item/ammo_casing/c9mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/firefly/rubber - ammo_type = /obj/item/ammo_casing/c9mm/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/ammo_box/magazine/multi_sprite/firefly/ihdf - ammo_type = /obj/item/ammo_casing/c9mm/ihdf - round_type = AMMO_TYPE_IHDF -/* -* CROON 40x32 -*/ - -/obj/item/gun/ballistic/automatic/croon - name = "\improper Croon submachine gun" - desc = "A low-quality 6.3mm reproduction of a popular SMG model, jams like a bitch. Although crude and unofficial, it gets the job done." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/croon.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand40x32.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand40x32.dmi' - icon_state = "croon" - inhand_icon_state = "croon" - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/croon - can_suppress = FALSE - fire_sound = 'sound/weapons/gun/smg/shot.ogg' - rack_sound = 'sound/weapons/gun/smg/smgrack.ogg' - lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' - bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - burst_size = 3 - fire_delay = 2.10 - spread = 25 - actions_types = list(/datum/action/item_action/toggle_firemode) - mag_display = FALSE - mag_display_ammo = FALSE - -/obj/item/gun/ballistic/automatic/croon/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_IZHEVSK) - -/obj/item/ammo_box/magazine/multi_sprite/croon - name = "\improper Croon magazine" - desc = "A straight 6.3mm magazine for the Croon SMG." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "croon" - ammo_type = /obj/item/ammo_casing/b6mm - caliber = CALIBER_6MM - max_ammo = 15 - multiple_sprites = AMMO_BOX_FULL_EMPTY - possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_RUBBER, AMMO_TYPE_IHDF) - -/obj/item/ammo_box/magazine/multi_sprite/croon/rubber - ammo_type = /obj/item/ammo_casing/b6mm/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/ammo_box/magazine/multi_sprite/croon/ihdf - ammo_type = /obj/item/ammo_casing/b6mm/ihdf - round_type = AMMO_TYPE_IHDF - -/* -* DOZER -*/ - -/obj/item/gun/ballistic/automatic/dozer - name = "\improper Dozer PDW" - desc = "The DZR-9, a notorious 9x25mm PDW that lives up to its nickname." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/dozer.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi' - icon_state = "dozer" - inhand_icon_state = "dozer" - w_class = WEIGHT_CLASS_NORMAL - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/dozer - can_suppress = TRUE - mag_display = FALSE - mag_display_ammo = FALSE - burst_size = 2 - fire_delay = 1.90 - actions_types = list(/datum/action/item_action/toggle_firemode) - fire_sound = 'sound/weapons/gun/rifle/shot.ogg' - rack_sound = 'sound/weapons/gun/smg/smgrack.ogg' - lock_back_sound = 'sound/weapons/gun/pistol/slide_lock.ogg' - bolt_drop_sound = 'sound/weapons/gun/pistol/slide_drop.ogg' - -/obj/item/gun/ballistic/automatic/dozer/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_ARMADYNE) - -/obj/item/ammo_box/magazine/multi_sprite/dozer - name = "\improper Dozer magazine" - desc = "A magazine for the Dozer PDW, chambered for 9x25mm Mark 12." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "croon" - ammo_type = /obj/item/ammo_casing/c9mm - caliber = CALIBER_9MM - max_ammo = 8 - multiple_sprites = AMMO_BOX_FULL_EMPTY - possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_HOLLOWPOINT, AMMO_TYPE_INCENDIARY, AMMO_TYPE_AP) - -/obj/item/ammo_box/magazine/multi_sprite/dozer/hp - ammo_type = /obj/item/ammo_casing/c9mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/dozer/ap - ammo_type = /obj/item/ammo_casing/c9mm/ap - round_type = AMMO_TYPE_AP - -/obj/item/ammo_box/magazine/multi_sprite/dozer/inc - ammo_type = /obj/item/ammo_casing/c9mm/fire - round_type = AMMO_TYPE_INCENDIARY - -/* -* DMR 40x32 -*/ - -/obj/item/gun/ballistic/automatic/dmr - name = "\improper Gen-2 Ripper rifle" - desc = "An incredibly powerful marksman rifle with an internal stabilization gymbal. It's chambered in .577 Snider." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/dmr.dmi' - icon_state = "dmr" - worn_icon = 'modular_skyrat/modules/sec_haul/icons/guns/dmr.dmi' - worn_icon_state = "dmr_worn" - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand40x32.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand40x32.dmi' - inhand_icon_state = "dmr" - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT | ITEM_SLOT_SUITSTORE - accepted_magazine_type = /obj/item/ammo_box/magazine/dmr - fire_delay = 1.7 - can_suppress = FALSE - can_bayonet = FALSE - mag_display = TRUE - fire_sound_volume = 60 - fire_sound = 'modular_skyrat/modules/sec_haul/sound/sniper_fire.ogg' - -/obj/item/gun/ballistic/automatic/dmr/Initialize(mapload) - . = ..() - - AddComponent(/datum/component/automatic_fire, fire_delay) - -/obj/item/gun/ballistic/automatic/dmr/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_ARMADYNE) - -/obj/item/ammo_box/magazine/dmr - name = "\improper Gen-2 Ripper magazine" - desc = "A magazine for the Ripper DMR, chambered for .577 Snider." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "dmr" - ammo_type = /obj/item/ammo_casing/b577 - caliber = CALIBER_B577 - max_ammo = 25 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/* -* ZETA -*/ - -/obj/item/gun/ballistic/revolver/zeta - name = "\improper Zeta-6 revolver" - desc = "A fairly common double-action six-shooter chambered for 10mm Auto, 'Spurchamber' is engraved on the cylinder." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/zeta.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi' - icon_state = "zeta" - inhand_icon_state = "zeta" - accepted_magazine_type = /obj/item/ammo_box/magazine/internal/cylinder/zeta - fire_sound = 'modular_skyrat/modules/sec_haul/sound/revolver_fire.ogg' - fire_delay = 3 - -/obj/item/gun/ballistic/revolver/zeta/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_BOLT) - -/obj/item/ammo_box/magazine/internal/cylinder/zeta - name = "\improper Zeta-6 cylinder" - desc = "If you see this, you should call a Bluespace Technician. Unless you're that Bluespace Technician." - ammo_type = /obj/item/ammo_casing/c10mm - caliber = CALIBER_10MM - max_ammo = 6 - -/obj/item/ammo_box/revolver/zeta - name = "\improper Zeta-6 speedloader" - desc = "A speedloader for the Spurchamber revolver, chambered for 10mm Auto ammo." - icon_state = "speedloader" - ammo_type = /obj/item/ammo_casing/c10mm - max_ammo = 6 - multiple_sprites = AMMO_BOX_FULL_EMPTY - caliber = CALIBER_10MM - start_empty = TRUE - -/obj/item/ammo_box/revolver/zeta/full - start_empty = FALSE - -/* -* REVOLUTION -*/ - -/obj/item/gun/ballistic/revolver/revolution - name = "\improper Revolution-8 revolver" - desc = "The Zeta 6's distant cousin, sporting an eight-round competition grade cylinder chambered for 9x25mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/revolution.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi' - icon_state = "revolution" - inhand_icon_state = "revolution" - accepted_magazine_type = /obj/item/ammo_box/magazine/internal/cylinder/revolution - fire_sound = 'modular_skyrat/modules/sec_haul/sound/revolver_fire.ogg' - fire_delay = 1.90 - projectile_damage_multiplier = 0.5 - -/obj/item/gun/ballistic/revolver/revolution/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_BOLT) - -/obj/item/ammo_box/magazine/internal/cylinder/revolution - name = "\improper Revolution-8 cylinder" - desc = "If you see this, you should call a Bluespace Technician. Unless you're that Bluespace Technician." - ammo_type = /obj/item/ammo_casing/c9mm - caliber = CALIBER_9MM - max_ammo = 8 - -/obj/item/ammo_box/revolver/revolution - name = "\improper Revolution-8 speedloader" - desc = "A speedloader for the Revolution-8 revolver, chambered in 9x25mm." - icon_state = "speedloader" - ammo_type = /obj/item/ammo_casing/c9mm - max_ammo = 8 - multiple_sprites = AMMO_BOX_FULL_EMPTY - caliber = CALIBER_9MM - start_empty = TRUE - -/obj/item/ammo_box/revolver/revolution/full - start_empty = FALSE - -/* -* S.M.A.R.T. RIFLE -*/ - -/obj/item/gun/ballistic/automatic/smartgun - name = "\improper OP-15 'S.M.A.R.T.' rifle" - desc = "Suppressive Manual Action Reciprocating Taser rifle. A modified version of an Armadyne heavy machine gun fitted to fire miniature shock-bolts." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/smartgun.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand40x32.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand40x32.dmi' - icon_state = "smartgun" - w_class = WEIGHT_CLASS_HUGE - weapon_weight = WEAPON_HEAVY - slot_flags = ITEM_SLOT_BACK - inhand_icon_state = "smartgun_worn" - worn_icon = 'modular_skyrat/modules/sec_haul/icons/guns/smartgun.dmi' - worn_icon_state = "smartgun_worn" - accepted_magazine_type = /obj/item/ammo_box/magazine/smartgun - actions_types = null - can_suppress = FALSE - can_bayonet = FALSE - mag_display = TRUE - mag_display_ammo = TRUE - empty_alarm = TRUE - tac_reloads = FALSE - bolt_type = BOLT_TYPE_STANDARD - semi_auto = FALSE - fire_sound = 'modular_skyrat/modules/sec_haul/sound/chaingun_fire.ogg' - rack_sound = 'modular_skyrat/modules/sec_haul/sound/chaingun_cock.ogg' - lock_back_sound = 'modular_skyrat/modules/sec_haul/sound/chaingun_open.ogg' - bolt_drop_sound = 'modular_skyrat/modules/sec_haul/sound/chaingun_cock.ogg' - load_sound = 'modular_skyrat/modules/sec_haul/sound/chaingun_magin.ogg' - load_empty_sound = 'modular_skyrat/modules/sec_haul/sound/chaingun_magin.ogg' - eject_sound = 'modular_skyrat/modules/sec_haul/sound/chaingun_magout.ogg' - load_empty_sound = 'modular_skyrat/modules/sec_haul/sound/chaingun_magout.ogg' - var/recharge_time = 5 SECONDS - var/recharging = FALSE - -/obj/item/gun/ballistic/automatic/smartgun/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_ARMADYNE) - -/obj/item/gun/ballistic/automatic/smartgun/process_chamber() - . = ..() - recharging = TRUE - addtimer(CALLBACK(src, PROC_REF(recharge)), recharge_time) - -/obj/item/gun/ballistic/automatic/smartgun/proc/recharge() - recharging = FALSE - playsound(src, 'sound/weapons/kenetic_reload.ogg', 60, 1) - -/obj/item/gun/ballistic/automatic/smartgun/can_shoot() - . = ..() - if(recharging) - return FALSE - -/obj/item/gun/ballistic/automatic/smartgun/update_icon() - . = ..() - if(!magazine) - icon_state = "smartgun_open" - else - icon_state = "smartgun_closed" - -/obj/item/ammo_box/magazine/smartgun - name = "\improper SMART-Rifle magazine" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "smartgun" - ammo_type = /obj/item/ammo_casing/smartgun - caliber = "smartgun" - max_ammo = 5 - multiple_sprites = AMMO_BOX_PER_BULLET - -/obj/item/gun/ballistic/automatic/smartgun/nomag - spawnwithmagazine = FALSE - -/obj/item/gun/ballistic/automatic/smartgun/scoped - name = "\improper OP-10 'S.M.A.R.T.' Rifle"; - desc = "Suppressive Manual Action Reciprocating Taser rifle. A gauss rifle fitted to fire miniature shock-bolts. Looks like this one is prety heavy, but it has a scope on it."; - recharge_time = 6 SECONDS; - recoil = 3; - slowdown = 0.25; - -/obj/item/gun/ballistic/automatic/smartgun/scoped/Initialize(mapload) - . = ..() - AddComponent(/datum/component/scope, range_modifier = 1.5) - - -/obj/structure/closet/secure_closet/smartgun - name = "smartgun locker" - req_access = list(ACCESS_ARMORY) - icon_state = "shotguncase" - -/obj/structure/closet/secure_closet/smartgun/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/smartgun/nomag(src) - new /obj/item/ammo_box/magazine/smartgun(src) - new /obj/item/ammo_box/magazine/smartgun(src) - new /obj/item/ammo_box/magazine/smartgun(src) - -/* -* G11 -*/ - -/obj/item/gun/ballistic/automatic/g11 - name = "\improper G11 K-490" - desc = "An outdated german caseless battle rifle that has been revised countless times during the late 2400s. Takes 4.73x33mm toploaded magazines." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/g11.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi' - icon_state = "g11" - inhand_icon_state = "g11" - worn_icon = 'modular_skyrat/modules/sec_haul/icons/guns/g11.dmi' - worn_icon_state = "g11_worn" - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/g11 - can_suppress = FALSE - fire_delay = 0.5 - spread = 10 - mag_display = TRUE - mag_display_ammo = TRUE - fire_sound = 'modular_skyrat/modules/sec_haul/sound/ltrifle_fire.ogg' - can_bayonet = TRUE - -/obj/item/gun/ballistic/automatic/g11/Initialize(mapload) - . = ..() - - AddComponent(/datum/component/automatic_fire, fire_delay) - -/obj/item/gun/ballistic/automatic/g11/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_ARMADYNE) - -/obj/item/ammo_box/magazine/multi_sprite/g11 - name = "\improper G-11 magazine" - desc = "A magazine for the G-11 rifle, meant to be filled with angry propellant cubes. Chambered for 4.73mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "g11" - ammo_type = /obj/item/ammo_casing/b473 - caliber = CALIBER_473MM - max_ammo = 50 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/g11/hp - ammo_type = /obj/item/ammo_casing/b473/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/g11/ihdf - ammo_type = /obj/item/ammo_casing/b473/ihdf - round_type = AMMO_TYPE_IHDF - -/* -* SHOTGUNS -*/ - -/obj/item/gun/ballistic/shotgun/m23 - name = "\improper Model 23-37" - desc = "An outdated police shotgun sporting an eight-round tube, chambered in twelve-gauge." - icon_state = "riotshotgun" - worn_icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi' - inhand_icon_state = "shotgun" - accepted_magazine_type = /obj/item/ammo_box/magazine/internal/shot/m23 - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING - -/obj/item/gun/ballistic/shotgun/m23/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_BOLT) - -/obj/item/ammo_box/magazine/internal/shot/m23 - name = "m23 shotgun internal magazine" - caliber = CALIBER_SHOTGUN - ammo_type = /obj/item/ammo_casing/shotgun/rubbershot - max_ammo = 8 - -/obj/item/gun/ballistic/shotgun/automatic/as2 - name = "\improper M2 auto-shotgun" - desc = "A semi-automatic twelve-gauge shotgun with a four-round internal tube." - icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns.dmi' - icon_state = "as2" - worn_icon_state = "riotshotgun" - worn_icon = 'modular_skyrat/modules/aesthetics/guns/icons/guns_back.dmi' - lefthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_lefthand.dmi' - righthand_file = 'modular_skyrat/modules/aesthetics/guns/icons/guns_righthand.dmi' - inhand_icon_state = "riot_shotgun" - inhand_x_dimension = 32 - inhand_y_dimension = 32 - can_suppress = TRUE - suppressed_sound = 'modular_skyrat/modules/aesthetics/guns/sound/suppressed_shotgun.ogg' - suppressed_volume = 100 - vary_fire_sound = TRUE - fire_sound = 'modular_skyrat/modules/aesthetics/guns/sound/shotgun_light.ogg' - fire_delay = 5 - accepted_magazine_type = /obj/item/ammo_box/magazine/internal/shot/as2 - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING - -/obj/item/gun/ballistic/shotgun/automatic/as2/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_ARMADYNE) - -/obj/item/ammo_box/magazine/internal/shot/as2 - name = "shotgun internal magazine" - caliber = CALIBER_SHOTGUN - ammo_type = /obj/item/ammo_casing/shotgun - max_ammo = 4 - -/* -* NORWIND -*/ -/obj/item/gun/ballistic/automatic/norwind - name = "\improper Norwind rifle" - desc = "A rare M112 DMR rechambered to 12.7x30mm for peacekeeping work, it comes with a scope for medium-long range engagements. A bayonet lug is visible." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/norwind.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi' - worn_icon = 'modular_skyrat/modules/sec_haul/icons/guns/norwind.dmi' - worn_icon_state = "norwind_worn" - icon_state = "norwind" - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING - inhand_icon_state = "norwind" - worn_icon = 'modular_skyrat/modules/sec_haul/icons/guns/norwind.dmi' - worn_icon_state = "norwind_worn" - alt_icons = TRUE - alt_icon_state = "norwind_worn" - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/norwind - can_suppress = FALSE - can_bayonet = TRUE - mag_display = TRUE - mag_display_ammo = TRUE - actions_types = null - fire_sound = 'modular_skyrat/modules/sec_haul/sound/ltrifle_fire.ogg' - burst_size = 1 - fire_delay = 10 - actions_types = list() - -/obj/item/gun/ballistic/automatic/norwind/Initialize(mapload) - . = ..() - AddComponent(/datum/component/scope, range_modifier = 1.75) - -/obj/item/gun/ballistic/automatic/norwind/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_ARMADYNE) - -/obj/item/gun/ballistic/automatic/norwind/add_seclight_point() - AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") - -/obj/item/ammo_box/magazine/multi_sprite/norwind - name = "\improper Norwind magazine" - desc = "An eight-round magazine for the Norwind DMR, chambered for 12mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "norwind" - ammo_type = /obj/item/ammo_casing/b12mm - caliber = CALIBER_12MM - max_ammo = 8 - multiple_sprites = AMMO_BOX_FULL_EMPTY - possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_HOLLOWPOINT, AMMO_TYPE_RUBBER) - -/obj/item/ammo_box/magazine/multi_sprite/norwind/hp - ammo_type = /obj/item/ammo_casing/b12mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/norwind/rubber - ammo_type = /obj/item/ammo_casing/b12mm/rubber - round_type = AMMO_TYPE_RUBBER - -/* -* VINTOREZ -*/ - -/obj/item/gun/ballistic/automatic/vintorez - name = "\improper VKC 'Vintorez'" - desc = "The VKC Vintorez is a lightweight integrally-suppressed scoped carbine usually employed in stealth operations. It was rechambered to 9x19mm for peacekeeping work." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/vintorez.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi' - icon_state = "vintorez" - worn_icon = 'modular_skyrat/modules/sec_haul/icons/guns/norwind.dmi' - worn_icon_state = "norwind_worn" - alt_icons = TRUE - alt_icon_state = "vintorez_worn" - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING - inhand_icon_state = "vintorez" - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/vintorez - suppressed = TRUE - can_unsuppress = FALSE - can_bayonet = FALSE - mag_display = FALSE - mag_display_ammo = FALSE - fire_delay = 4 - spread = 10 - fire_sound = 'sound/weapons/gun/smg/shot_suppressed.ogg' - projectile_damage_multiplier = 0.5 - -/obj/item/gun/ballistic/automatic/vintorez/Initialize(mapload) - . = ..() - - AddComponent(/datum/component/scope, range_modifier = 1.5) - - AddComponent(/datum/component/automatic_fire, fire_delay) - -/obj/item/gun/ballistic/automatic/vintorez/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_IZHEVSK) - -/obj/item/ammo_box/magazine/multi_sprite/vintorez - name = "\improper VKC magazine" - desc = "A twenty-round magazine for the VKC marksman rifle, chambered in 9x25mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "norwind" - ammo_type = /obj/item/ammo_casing/c9mm - caliber = CALIBER_9MM - max_ammo = 20 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/vintorez/hp - ammo_type = /obj/item/ammo_casing/c9mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/vintorez/ihdf - ammo_type = /obj/item/ammo_casing/c9mm/ihdf - round_type = AMMO_TYPE_IHDF - -/obj/item/ammo_box/magazine/multi_sprite/vintorez/rubber - ammo_type = /obj/item/ammo_casing/c9mm/rubber - round_type = AMMO_TYPE_RUBBER - -/* -* PCR-9 -*/ - -/obj/item/gun/ballistic/automatic/pcr - name = "\improper PCR-9 SMG" - desc = "An accurate, fast-firing SMG chambered in 9x19mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/pcr.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi' - worn_icon = 'modular_skyrat/modules/sec_haul/icons/guns/ostwind.dmi' - worn_icon_state = "ostwind_worn" - inhand_icon_state = "pcr" - icon_state = "pcr" - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING - w_class = WEIGHT_CLASS_BULKY - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/pcr - fire_delay = 1.80 - can_suppress = FALSE - spread = 10 - can_bayonet = FALSE - mag_display = TRUE - mag_display_ammo = TRUE - fire_sound = 'modular_skyrat/modules/sec_haul/sound/smg_fire.ogg' - projectile_damage_multiplier = 0.5 - -/obj/item/gun/ballistic/automatic/pcr/Initialize(mapload) - . = ..() - - AddComponent(/datum/component/automatic_fire, fire_delay) - -/obj/item/gun/ballistic/automatic/pcr/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_BOLT) - -/obj/item/gun/ballistic/automatic/pcr/add_seclight_point() - AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") - -/obj/item/ammo_box/magazine/multi_sprite/pcr - name = "\improper PCR-9 magazine" - desc = "A thirty-two round magazine for the PCR-9 submachine gun, chambered for 9x25mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "pcr" - ammo_type = /obj/item/ammo_casing/c9mm - caliber = CALIBER_9MM - max_ammo = 32 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/pcr/hp - ammo_type = /obj/item/ammo_casing/c9mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/pcr/ihdf - ammo_type = /obj/item/ammo_casing/c9mm/ihdf - round_type = AMMO_TYPE_IHDF - -/obj/item/ammo_box/magazine/multi_sprite/pcr/rubber - ammo_type = /obj/item/ammo_casing/c9mm/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/gun/ballistic/automatic/pitbull - name = "\improper Pitbull PDW" - desc = "A sturdy personal defense weapon designed to fire 10mm Auto rounds." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/pitbull.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi' - inhand_icon_state = "pitbull" - icon_state = "pitbull" - worn_icon = 'modular_skyrat/modules/sec_haul/icons/guns/ostwind.dmi' - worn_icon_state = "ostwind_worn" - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/pitbull - fire_delay = 4.20 - can_suppress = FALSE - burst_size = 3 - spread = 15 - actions_types = list(/datum/action/item_action/toggle_firemode) - mag_display = TRUE - mag_display_ammo = TRUE - fire_sound = 'modular_skyrat/modules/sec_haul/sound/sfrifle_fire.ogg' - can_bayonet = TRUE - projectile_damage_multiplier = 0.7 - -/obj/item/gun/ballistic/automatic/pitbull/Initialize(mapload) - . = ..() - - AddComponent(/datum/component/automatic_fire, fire_delay) - -/obj/item/gun/ballistic/automatic/pitbull/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_BOLT) - -/obj/item/gun/ballistic/automatic/pitbull/add_seclight_point() - AddComponent(/datum/component/seclite_attachable, light_overlay_icon = 'icons/obj/weapons/guns/flashlights.dmi', light_overlay = "flight") - -/obj/item/ammo_box/magazine/multi_sprite/pitbull - name = "\improper Pitbull magazine" - desc = "A twenty-four round magazine for the Pitbull PDW, chambered in 10mm Auto." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "pcr" - ammo_type = /obj/item/ammo_casing/c10mm - caliber = CALIBER_10MM - max_ammo = 24 - multiple_sprites = AMMO_BOX_FULL_EMPTY - -/obj/item/ammo_box/magazine/multi_sprite/pitbull/hp - ammo_type = /obj/item/ammo_casing/c10mm/hp - round_type = AMMO_TYPE_HOLLOWPOINT - -/obj/item/ammo_box/magazine/multi_sprite/pitbull/ihdf - ammo_type = /obj/item/ammo_casing/c10mm/ihdf - round_type = AMMO_TYPE_IHDF - -/obj/item/ammo_box/magazine/multi_sprite/pitbull/rubber - ammo_type = /obj/item/ammo_casing/c10mm/rubber - round_type = AMMO_TYPE_RUBBER - -/* -* DTR-6 -*/ - -/obj/item/gun/ballistic/automatic/ostwind - name = "\improper DTR-6 Rifle" - desc = "A 6.3mm special-purpose rifle designed to deal with threats uniquely. You feel like this is a support type firearm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/ostwind.dmi' - righthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi' - lefthand_file = 'modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi' - inhand_icon_state = "ostwind" - icon_state = "ostwind" - worn_icon = 'modular_skyrat/modules/sec_haul/icons/guns/ostwind.dmi' - worn_icon_state = "ostwind_worn" - alt_icons = TRUE - alt_icon_state = "ostwind_worn" - w_class = WEIGHT_CLASS_BULKY - slot_flags = ITEM_SLOT_BACK | ITEM_SLOT_BELT | ITEM_SLOT_OCLOTHING - accepted_magazine_type = /obj/item/ammo_box/magazine/multi_sprite/ostwind - spread = 10 - fire_delay = 2 - can_suppress = FALSE - burst_size = 2 - actions_types = list(/datum/action/item_action/toggle_firemode) - mag_display = TRUE - mag_display_ammo = TRUE - fire_sound = 'sound/weapons/gun/smg/shot.ogg' - can_bayonet = TRUE - -/obj/item/gun/ballistic/automatic/ostwind/Initialize(mapload) - . = ..() - - AddComponent(/datum/component/automatic_fire, fire_delay) - -/obj/item/gun/ballistic/automatic/ostwind/give_manufacturer_examine() - AddElement(/datum/element/manufacturer_examine, COMPANY_ARMADYNE) - -/obj/item/ammo_box/magazine/multi_sprite/ostwind - name = "\improper DTR-6 magazine" - desc = "A thirty round double-stack magazine for the DTR-6 rifle, capable of loading flechettes, fragmentation ammo or dissuasive pellets. Chambered for 6.3mm." - icon = 'modular_skyrat/modules/sec_haul/icons/guns/mags.dmi' - icon_state = "pcr" - ammo_type = /obj/item/ammo_casing/b6mm - caliber = CALIBER_6MM - max_ammo = 30 - multiple_sprites = AMMO_BOX_FULL_EMPTY - possible_types = list(AMMO_TYPE_LETHAL, AMMO_TYPE_RUBBER, AMMO_TYPE_IHDF) - -/obj/item/ammo_box/magazine/multi_sprite/ostwind/rubber - ammo_type = /obj/item/ammo_casing/b6mm/rubber - round_type = AMMO_TYPE_RUBBER - -/obj/item/ammo_box/magazine/multi_sprite/ostwind/ihdf - ammo_type = /obj/item/ammo_casing/b6mm/ihdf - round_type = AMMO_TYPE_IHDF diff --git a/modular_skyrat/modules/sec_haul/code/guns/gunsets.dm b/modular_skyrat/modules/sec_haul/code/guns/gunsets.dm deleted file mode 100644 index f89300df920cc1..00000000000000 --- a/modular_skyrat/modules/sec_haul/code/guns/gunsets.dm +++ /dev/null @@ -1,483 +0,0 @@ -/* -* GUNSET BOXES -*/ - -/obj/item/storage/box/gunset - name = "gun case" - desc = "A gun case with foam inserts laid out to fit a weapon, magazines, and gear securely." - icon_state = "guncase" //Currently only comes as a generic gray, though there's sprites for Armadyne branded ones in the icon file. There's also sprites for smaller ones! - inhand_icon_state = "sec-case" - icon = 'modular_skyrat/modules/sec_haul/icons/guns/gunsets.dmi' - lefthand_file = 'icons/mob/inhands/equipment/briefcase_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/briefcase_righthand.dmi' - w_class = WEIGHT_CLASS_BULKY - resistance_flags = FLAMMABLE - drop_sound = 'sound/items/handling/ammobox_drop.ogg' - pickup_sound = 'sound/items/handling/ammobox_pickup.ogg' - illustration = null - var/opened = FALSE - -//Add this extra line to examine() if you make an armadyne variant: "It has a textured carbon grip, and the [span_red("Armadyne Corporation")] logo etched into the top." - -/obj/item/storage/box/gunset/PopulateContents() - . = ..() - new /obj/item/storage/pouch/ammo(src) - -/obj/item/storage/box/gunset/update_icon() - . = ..() - if(opened) - icon_state = "[initial(icon_state)]-open" - else - icon_state = initial(icon_state) - -/obj/item/storage/box/gunset/AltClick(mob/user) - . = ..() - opened = !opened - update_icon() - -/obj/item/storage/box/gunset/attack_self(mob/user) - . = ..() - opened = !opened - update_icon() - -/* -* GUN SETS -*/ - -/* -* SIDEARMS -*/ - -/* -* G-17 -*/ - -/obj/item/storage/box/gunset/glock17 - name = "GK-17 supply box" - -/obj/item/gun/ballistic/automatic/pistol/g17/nomag - spawnwithmagazine = FALSE - - -/obj/item/storage/box/gunset/glock17/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/g17/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/g17(src) - new /obj/item/ammo_box/magazine/multi_sprite/g17(src) - new /obj/item/ammo_box/magazine/multi_sprite/g17(src) - new /obj/item/ammo_box/magazine/multi_sprite/g17(src) - -/* -* LADON -*/ - -/obj/item/storage/box/gunset/ladon - name = "p-3 ladon supply box" - -/obj/item/gun/ballistic/automatic/pistol/ladon/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/ladon/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/ladon/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/ladon(src) - new /obj/item/ammo_box/magazine/multi_sprite/ladon(src) - new /obj/item/ammo_box/magazine/multi_sprite/ladon(src) - new /obj/item/ammo_box/magazine/multi_sprite/ladon(src) - -/* -* DOZER -*/ - -/obj/item/storage/box/gunset/dozer - name = "dozer supply box" - -/obj/item/gun/ballistic/automatic/dozer/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/dozer/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/dozer/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/dozer(src) - new /obj/item/ammo_box/magazine/multi_sprite/dozer(src) - new /obj/item/ammo_box/magazine/multi_sprite/dozer(src) - -/* -* PDH -*/ - -/obj/item/storage/box/gunset/pdh_peacekeeper - name = "9x19mm handgun supply box" - desc = "Ideally contains a fast-firing 9x19mm Pistol." - -/obj/item/gun/ballistic/automatic/pistol/pdh/peacekeeper/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/pdh_peacekeeper/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/pdh/peacekeeper/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh_peacekeeper(src) - -/* -* MK-58 -*/ - -/obj/item/storage/box/gunset/mk58 - name = "mk-58 supply box" - -/obj/item/gun/ballistic/automatic/pistol/mk58/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/mk58/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/mk58/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/mk58(src) - new /obj/item/ammo_box/magazine/multi_sprite/mk58(src) - new /obj/item/ammo_box/magazine/multi_sprite/mk58(src) - new /obj/item/ammo_box/magazine/multi_sprite/mk58(src) - -/* -* CROON -*/ - -/obj/item/storage/box/gunset/croon - name = "weathered supply box" - desc = "Ideally contains a cheap 6mm SMG." - -/obj/item/gun/ballistic/automatic/croon/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/croon/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/croon/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/croon(src) - new /obj/item/ammo_box/magazine/multi_sprite/croon(src) - new /obj/item/ammo_box/magazine/multi_sprite/croon(src) - new /obj/item/ammo_box/magazine/multi_sprite/croon(src) - -/* -* MAKAROV -*/ - -/obj/item/storage/box/gunset/makarov - name = "makarov supply box" - - -/obj/item/ammo_box/magazine/multi_sprite/makarov/empty - start_empty = TRUE - -/obj/item/storage/box/gunset/makarov/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/makarov(src) - new /obj/item/ammo_box/magazine/multi_sprite/makarov(src) - new /obj/item/ammo_box/magazine/multi_sprite/makarov(src) - new /obj/item/ammo_box/magazine/multi_sprite/makarov(src) - new /obj/item/ammo_box/magazine/multi_sprite/makarov(src) - -/* -* ZETA -*/ - -/obj/item/storage/box/gunset/zeta - name = "10mm revolver supply box" - desc = "Ideally contains a slow-firing revolver that packs a punch." - -/obj/item/storage/box/gunset/zeta/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/revolver/zeta(src) - new /obj/item/ammo_box/revolver/zeta(src) //These start empty. - new /obj/item/ammo_box/revolver/zeta(src) - new /obj/item/ammo_box/revolver/zeta(src) - new /obj/item/ammo_box/c10mm(src) - -/* -* REVOLUTION -*/ - -/obj/item/storage/box/gunset/revolution - name = "revolution supply box" - -/obj/item/storage/box/gunset/revolution/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/revolver/revolution(src) - new /obj/item/ammo_box/revolver/revolution(src) - new /obj/item/ammo_box/revolver/revolution(src) - new /obj/item/ammo_box/revolver/revolution(src) - new /obj/item/ammo_box/c9mm(src) - -/* -* PRIMARIES -*/ - -/* -* PCR-9 -*/ - -/obj/item/storage/box/gunset/pcr - name = "9mm SMG supply box" - desc = "Ideally contains a 9x19mm SMG with decent firerate." - -/obj/item/gun/ballistic/automatic/pcr/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/pcr/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pcr/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/pcr(src) - new /obj/item/ammo_box/magazine/multi_sprite/pcr(src) - new /obj/item/ammo_box/magazine/multi_sprite/pcr(src) - new /obj/item/ammo_box/magazine/multi_sprite/pcr(src) - -/* -* NORWIND -*/ - -/obj/item/storage/box/gunset/norwind - name = "12.7x30mm DMR supply box." - desc = "Ideally contains an unwieldy rifle that hits like a truck." - -/obj/item/gun/ballistic/automatic/norwind/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/norwind/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/norwind/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/norwind(src) - new /obj/item/ammo_box/magazine/multi_sprite/norwind(src) - new /obj/item/ammo_box/magazine/multi_sprite/norwind(src) - new /obj/item/ammo_box/magazine/multi_sprite/norwind(src) - -/* -* OSTWIND -*/ - -/obj/item/storage/box/gunset/ostwind - name = "6mm SPR box." - desc = "Ideally contains an all-around balanced special purpose rifle." - -/obj/item/gun/ballistic/automatic/ostwind/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/ostwind/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/ostwind/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/ostwind(src) - new /obj/item/ammo_box/magazine/multi_sprite/ostwind(src) - new /obj/item/ammo_box/magazine/multi_sprite/ostwind(src) - new /obj/item/ammo_box/magazine/multi_sprite/ostwind(src) - -/* -* PITBULL -*/ - -/obj/item/storage/box/gunset/pitbull - name = "10mm PDW supply box" - desc = "Ideally contains a slow-firing 10mm PDW that packs a punch." - -/obj/item/gun/ballistic/automatic/pitbull/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/pitbull/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pitbull/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/pitbull(src) - new /obj/item/ammo_box/magazine/multi_sprite/pitbull(src) - new /obj/item/ammo_box/magazine/multi_sprite/pitbull(src) - new /obj/item/ammo_box/magazine/multi_sprite/pitbull(src) - -/* -* JOB-SPECIFIC -*/ - -/* -* CAPTAIN -*/ - -/obj/item/storage/box/gunset/pdh_captain - name = "pdh 'socom' supply box" - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/gun/ballistic/automatic/pistol/pdh/alt/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/pdh_captain/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/pdh/alt/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh(src) - -/* -* HOS -*/ - -/obj/item/storage/box/gunset/glock18_hos - name = "GK-18 supply box" - desc = "Ideally contains a fast-firing 9x19mm pistol made out of cheap plastic." - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/gun/ballistic/automatic/pistol/g18/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/glock18_hos/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/g18/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/g18(src) - new /obj/item/ammo_box/magazine/multi_sprite/g18(src) - new /obj/item/ammo_box/magazine/multi_sprite/g18(src) - new /obj/item/ammo_box/magazine/multi_sprite/g18/ihdf(src) - -/* -* HOP -*/ - -/obj/item/storage/box/gunset/pdh - name = "pdh 'osprey' supply box" - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/gun/ballistic/automatic/pistol/pdh/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/pdh/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/pdh/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh(src) - -/* -* CORPO -*/ - -/obj/item/storage/box/gunset/pdh_corpo - name = "pdh 'corporate' supply box" - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/gun/ballistic/automatic/pistol/pdh/corpo/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/pdh_corpo/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/pdh/corpo/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh_corpo(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh_corpo(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh_corpo(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh_corpo(src) - -/* -* STRIKER -*/ - -/obj/item/storage/box/gunset/pdh_striker - name = "pdh 'striker' supply box" - w_class = WEIGHT_CLASS_NORMAL - -/obj/item/gun/ballistic/automatic/pistol/pdh/striker/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/pdh_striker/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/pdh/striker/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh_striker(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh_striker(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh_striker(src) - new /obj/item/ammo_box/magazine/multi_sprite/pdh_striker(src) - -// KRAUT SPACE MAGIC! -/obj/item/storage/box/gunset/g11 - name = "g11 supply box" - -/obj/item/gun/ballistic/automatic/g11/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/g11/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/g11/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/g11(src) - new /obj/item/ammo_box/magazine/multi_sprite/g11(src) - new /obj/item/ammo_box/magazine/multi_sprite/g11(src) - new /obj/item/ammo_box/magazine/multi_sprite/g11(src) - -/* -* OLD SECMED SIDEARM -*/ - -/obj/item/storage/box/gunset/firefly - name = "9x19mm special pistol supply box" - desc = "Ideally contains a special 9x19mm Pistol." - w_class = WEIGHT_CLASS_NORMAL -/obj/item/gun/ballistic/automatic/pistol/firefly/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/firefly/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/firefly/nomag(src) - new /obj/item/ammo_box/magazine/multi_sprite/firefly(src) - new /obj/item/ammo_box/magazine/multi_sprite/firefly(src) - new /obj/item/ammo_box/magazine/multi_sprite/firefly/rubber(src) - new /obj/item/ammo_box/magazine/multi_sprite/firefly/rubber(src) - -/* -* LASER -*/ - -/obj/item/storage/box/gunset/laser - name = "laser gun supply box" - -/obj/item/storage/box/gunset/laser/PopulateContents() - . = ..() - new /obj/item/gun/energy/laser(src) - -/obj/item/storage/box/gunset/e_gun - -/obj/item/storage/box/gunset/e_gun/PopulateContents() - . = ..() - new /obj/item/gun/energy/e_gun(src) - -/* -* PEPPERBALLS -*/ - -/obj/item/storage/box/gunset/pepperball - name = "pepperball supply box" - w_class = WEIGHT_CLASS_NORMAL -/obj/item/gun/ballistic/automatic/pistol/pepperball/nomag - spawnwithmagazine = FALSE - -/obj/item/storage/box/gunset/pepperball/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/automatic/pistol/pepperball/nomag(src) - new /obj/item/ammo_box/magazine/pepperball(src) - new /obj/item/ammo_box/magazine/pepperball(src) - new /obj/item/ammo_box/magazine/pepperball(src) - new /obj/item/ammo_box/magazine/pepperball(src) - - -/* -* SHOTGUNS -*/ - -/obj/item/storage/box/gunset/m23 - name = "m23 supply box" - -/obj/item/storage/box/gunset/m23/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/shotgun/m23(src) - new /obj/item/storage/box/beanbag(src) - new /obj/item/storage/box/beanbag(src) - new /obj/item/storage/box/beanbag(src) - -/obj/item/storage/box/gunset/as2 - name = "as2 supply box" - -/obj/item/storage/box/gunset/as2/PopulateContents() - . = ..() - new /obj/item/gun/ballistic/shotgun/automatic/as2(src) - new /obj/item/storage/box/beanbag(src) - new /obj/item/storage/box/beanbag(src) - new /obj/item/storage/box/beanbag(src) diff --git a/modular_skyrat/modules/sec_haul/code/peacekeeper/armadyne_clothing.dm b/modular_skyrat/modules/sec_haul/code/peacekeeper/armadyne_clothing.dm index 89f0108f4dc22f..40110bc3820fb5 100644 --- a/modular_skyrat/modules/sec_haul/code/peacekeeper/armadyne_clothing.dm +++ b/modular_skyrat/modules/sec_haul/code/peacekeeper/armadyne_clothing.dm @@ -106,7 +106,7 @@ r_pocket = /obj/item/assembly/flash/handheld backpack_contents = list( /obj/item/melee/baton/telescopic, - /obj/item/storage/box/gunset/pdh_corpo, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild, ) back = /obj/item/storage/backpack/satchel/leather box = /obj/item/storage/box/survival/security @@ -124,12 +124,12 @@ glasses = /obj/item/clothing/glasses/hud/security/sunglasses/peacekeeper/armadyne mask = /obj/item/clothing/mask/gas/sechailer suit = /obj/item/clothing/suit/armor/vest/peacekeeper/armadyne/armor - suit_store = /obj/item/gun/ballistic/automatic/pitbull + suit_store = /obj/item/gun/ballistic/automatic/sol_smg shoes = /obj/item/clothing/shoes/jackboots/peacekeeper/armadyne backpack_contents = list( - /obj/item/storage/box/gunset/pdh_striker, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/wespe, /obj/item/storage/box/handcuffs, - /obj/item/ammo_box/magazine/multi_sprite/pitbull, + /obj/item/ammo_box/magazine/c35sol_pistol/stendo, /obj/item/modular_computer/pda/security, ) back = /obj/item/storage/backpack/security @@ -147,13 +147,13 @@ glasses = /obj/item/clothing/glasses/hud/security/sunglasses/peacekeeper/armadyne mask = /obj/item/clothing/mask/gas/sechailer/swat suit = /obj/item/clothing/suit/armor/vest/peacekeeper/armadyne/armor - suit_store = /obj/item/gun/ballistic/automatic/norwind + suit_store = /obj/item/gun/ballistic/automatic/sol_rifle shoes = /obj/item/clothing/shoes/jackboots/peacekeeper/armadyne belt = /obj/item/storage/belt/security/webbing/peacekeeper/armadyne backpack_contents = list( - /obj/item/storage/box/gunset/pdh_striker, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/wespe, /obj/item/storage/box/handcuffs, - /obj/item/ammo_box/magazine/multi_sprite/norwind, + /obj/item/ammo_box/magazine/c40sol_rifle/standard, /obj/item/modular_computer/pda/security, ) back = /obj/item/storage/backpack/security @@ -165,23 +165,23 @@ /datum/outfit/armadyne_security/high_alert name = "Armadyne Corporate Security (High Alert)" belt = /obj/item/storage/belt/security/webbing/peacekeeper/armadyne - suit_store = /obj/item/gun/ballistic/automatic/dmr + suit_store = /obj/item/gun/ballistic/automatic/sol_rifle backpack_contents = list( /obj/item/melee/baton/telescopic, - /obj/item/storage/box/gunset/pdh_corpo, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/wespe, /obj/item/storage/box/handcuffs, - /obj/item/ammo_box/magazine/dmr = 2, + /obj/item/ammo_box/magazine/c40sol_rifle/standard = 2, ) /datum/outfit/armadyne_security/commander/high_alert name = "Armadyne Corporate Security Commander (High Alert)" - suit_store = /obj/item/gun/ballistic/automatic/dmr + suit_store = /obj/item/gun/ballistic/automatic/sol_rifle backpack_contents = list( /obj/item/melee/baton/telescopic, - /obj/item/storage/box/gunset/pdh_corpo, + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild, /obj/item/storage/box/handcuffs, - /obj/item/ammo_box/magazine/dmr = 2, + /obj/item/ammo_box/magazine/c40sol_rifle/standard = 2, ) /obj/item/card/id/advanced/armadyne diff --git a/modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi b/modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi deleted file mode 100644 index cbcea85d3e11c0..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/ammo_cartridges.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/automag.dmi b/modular_skyrat/modules/sec_haul/icons/guns/automag.dmi deleted file mode 100644 index b8345858e783a4..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/automag.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/croon.dmi b/modular_skyrat/modules/sec_haul/icons/guns/croon.dmi deleted file mode 100644 index c52529979875f9..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/croon.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/dmr.dmi b/modular_skyrat/modules/sec_haul/icons/guns/dmr.dmi deleted file mode 100644 index 742b839fd381aa..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/dmr.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/dozer.dmi b/modular_skyrat/modules/sec_haul/icons/guns/dozer.dmi deleted file mode 100644 index 13f45e80fbf7d8..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/dozer.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/energy/allstar.dmi b/modular_skyrat/modules/sec_haul/icons/guns/energy/allstar.dmi deleted file mode 100644 index 5251c860046e0d..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/energy/allstar.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/firefly.dmi b/modular_skyrat/modules/sec_haul/icons/guns/firefly.dmi deleted file mode 100644 index 8ef8d9e74728cd..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/firefly.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/g11.dmi b/modular_skyrat/modules/sec_haul/icons/guns/g11.dmi deleted file mode 100644 index 7d17f7274047a9..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/g11.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/glock.dmi b/modular_skyrat/modules/sec_haul/icons/guns/glock.dmi deleted file mode 100644 index ee12d3df9c6d72..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/glock.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/gunsets.dmi b/modular_skyrat/modules/sec_haul/icons/guns/gunsets.dmi deleted file mode 100644 index daf0244d3d259a..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/gunsets.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi b/modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi deleted file mode 100644 index 43b271bdec2ac4..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand40x32.dmi b/modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand40x32.dmi deleted file mode 100644 index e77ceeeb272690..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/inhands/lefthand40x32.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi b/modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi deleted file mode 100644 index 8055cd1aaa7e5e..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand40x32.dmi b/modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand40x32.dmi deleted file mode 100644 index c4e1ebd38e2f34..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/inhands/righthand40x32.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/ladon.dmi b/modular_skyrat/modules/sec_haul/icons/guns/ladon.dmi deleted file mode 100644 index 312d06a1584206..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/ladon.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/mags.dmi b/modular_skyrat/modules/sec_haul/icons/guns/mags.dmi deleted file mode 100644 index 68c1d20756e941..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/mags.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/makarov.dmi b/modular_skyrat/modules/sec_haul/icons/guns/makarov.dmi deleted file mode 100644 index 4f0ed19dbf2f67..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/makarov.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/mk58.dmi b/modular_skyrat/modules/sec_haul/icons/guns/mk58.dmi deleted file mode 100644 index ab7496ad13b691..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/mk58.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/norwind.dmi b/modular_skyrat/modules/sec_haul/icons/guns/norwind.dmi deleted file mode 100644 index c05509da30ea55..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/norwind.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/ostwind.dmi b/modular_skyrat/modules/sec_haul/icons/guns/ostwind.dmi deleted file mode 100644 index 3f2d26a819acc2..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/ostwind.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/pcr.dmi b/modular_skyrat/modules/sec_haul/icons/guns/pcr.dmi deleted file mode 100644 index 8e8fb126853042..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/pcr.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/pcr2.dmi b/modular_skyrat/modules/sec_haul/icons/guns/pcr2.dmi deleted file mode 100644 index 87bb9f4fdd25d3..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/pcr2.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/pdh.dmi b/modular_skyrat/modules/sec_haul/icons/guns/pdh.dmi deleted file mode 100644 index e4e2a606b8e292..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/pdh.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/pitbull.dmi b/modular_skyrat/modules/sec_haul/icons/guns/pitbull.dmi deleted file mode 100644 index d429b62a3a768a..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/pitbull.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/revolution.dmi b/modular_skyrat/modules/sec_haul/icons/guns/revolution.dmi deleted file mode 100644 index da6ab4703d6eb8..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/revolution.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/sas14.dmi b/modular_skyrat/modules/sec_haul/icons/guns/sas14.dmi deleted file mode 100644 index 77452eaf7c1624..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/sas14.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/smartgun.dmi b/modular_skyrat/modules/sec_haul/icons/guns/smartgun.dmi deleted file mode 100644 index ef61aa8667f01e..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/smartgun.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/spawner.dmi b/modular_skyrat/modules/sec_haul/icons/guns/spawner.dmi deleted file mode 100644 index a5a06c490a7424..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/spawner.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/vintorez.dmi b/modular_skyrat/modules/sec_haul/icons/guns/vintorez.dmi deleted file mode 100644 index 413f0fd8fdb1c6..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/vintorez.dmi and /dev/null differ diff --git a/modular_skyrat/modules/sec_haul/icons/guns/zeta.dmi b/modular_skyrat/modules/sec_haul/icons/guns/zeta.dmi deleted file mode 100644 index ae0d76adccb2b8..00000000000000 Binary files a/modular_skyrat/modules/sec_haul/icons/guns/zeta.dmi and /dev/null differ diff --git a/modular_skyrat/modules/self_actualization_device/code/self_actualization_device.dm b/modular_skyrat/modules/self_actualization_device/code/self_actualization_device.dm index 1af51a6f4da300..d50759e484f973 100644 --- a/modular_skyrat/modules/self_actualization_device/code/self_actualization_device.dm +++ b/modular_skyrat/modules/self_actualization_device/code/self_actualization_device.dm @@ -124,7 +124,7 @@ use_power(500) -/// Ejects the occupant as either their preference character, or as a monke based on emag status. +/// Ejects the occupant after asking them if they want to accept the rejuvenation. If yes, they exit as their preferences character. /obj/machinery/self_actualization_device/proc/eject_new_you() if(state_open || !occupant || !powered()) return @@ -132,21 +132,36 @@ if(!ishuman(occupant)) return FALSE + var/mob/living/carbon/human/human_occupant = occupant - var/mob/living/carbon/human/patient = occupant - var/original_name = patient.dna.real_name + var/failure = FALSE + var/failure_text - patient.client?.prefs?.safe_transfer_prefs_to_with_damage(patient) - patient.dna.update_dna_identity() - log_game("[key_name(patient)] used a Self-Actualization Device at [loc_name(src)].") + if (!isnull(human_occupant.ckey) && isnull(human_occupant.client)) // player mob, currently disconnected + failure = TRUE + failure_text = "ERROR: Treatment elicited no response from occupant genes. Subject may be suffering from Sudden Sleep Disorder." + else if (tgui_alert(occupant, "The SAD you are within is about to rejuvenate you, resetting your body to its default state (in character preferences). Do you consent?", "Rejuvenate", list("Yes", "No"), timeout = 10 SECONDS) != "Yes") + failure = TRUE // defaults to rejecting it unless specified otherwise + failure_text = "ERROR: Occupant genes have willfully rejected the procedure. You may try again if you think this was an error." - if(patient.dna.real_name != original_name) - message_admins("[key_name_admin(patient)] has used the Self-Actualization Device, and changed the name of their character. \ - Original Name: [original_name], New Name: [patient.dna.real_name]. \ - This may be a false positive from changing from a humanized monkey into a character, so be careful.") + if (failure) + say(failure_text) + playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) + else + var/mob/living/carbon/human/patient = occupant + var/original_name = patient.dna.real_name + + patient.client?.prefs?.safe_transfer_prefs_to_with_damage(patient) + patient.dna.update_dna_identity() + log_game("[key_name(patient)] used a Self-Actualization Device at [loc_name(src)].") + + if(patient.dna.real_name != original_name) + message_admins("[key_name_admin(patient)] has used the Self-Actualization Device, and changed the name of their character. \ + Original Name: [original_name], New Name: [patient.dna.real_name]. \ + This may be a false positive from changing from a humanized monkey into a character, so be careful.") + playsound(src, 'sound/machines/microwave/microwave-end.ogg', 100, FALSE) open_machine() - playsound(src, 'sound/machines/microwave/microwave-end.ogg', 100, FALSE) /obj/machinery/self_actualization_device/screwdriver_act(mob/living/user, obj/item/used_item) . = TRUE diff --git a/modular_skyrat/modules/space_vines/scythes.dm b/modular_skyrat/modules/space_vines/scythes.dm index 084d33385501a4..910753489e3350 100644 --- a/modular_skyrat/modules/space_vines/scythes.dm +++ b/modular_skyrat/modules/space_vines/scythes.dm @@ -24,7 +24,7 @@ var/swiping = FALSE /obj/item/scythe/pre_attack(atom/A, mob/living/user, params) - if(!istype(A, /obj/structure/spacevine) && !istype(A, /mob/living/simple_animal/hostile/venus_human_trap)) + if(!istype(A, /obj/structure/spacevine) && !istype(A, /mob/living/basic/venus_human_trap)) return ..() if(swiping) return ..() diff --git a/modular_skyrat/modules/space_vines/venus.dm b/modular_skyrat/modules/space_vines/venus.dm index 7dafe18a755f05..abd912b8e9041e 100644 --- a/modular_skyrat/modules/space_vines/venus.dm +++ b/modular_skyrat/modules/space_vines/venus.dm @@ -1,21 +1,5 @@ -/mob/living/simple_animal/hostile/venus_human_trap/Life(seconds_per_tick = SSMOBS_DT, times_fired) - . = ..() - check_vines() - -/mob/living/simple_animal/hostile/venus_human_trap/death(gibbed) - for(var/i in vines) - qdel(i) - return ..() - -/mob/living/simple_animal/hostile/venus_human_trap/start_pulling(atom/movable/movable_target, state, force, supress_message) +/mob/living/basic/venus_human_trap/start_pulling(atom/movable/movable_target, state, force, supress_message) if(isliving(movable_target)) to_chat(src, span_boldwarning("You cannot drag living things!")) return return ..() - -/mob/living/simple_animal/hostile/venus_human_trap/proc/check_vines() - var/obj/structure/spacevine/find_vine = locate() in get_turf(src) - if(!find_vine) - adjustHealth(maxHealth * 0.05) - else - adjustHealth(maxHealth * -0.05) diff --git a/modular_skyrat/modules/synths/code/README.md b/modular_skyrat/modules/synths/code/README.md index 21ce4e629dabd8..8f37a1cec49409 100644 --- a/modular_skyrat/modules/synths/code/README.md +++ b/modular_skyrat/modules/synths/code/README.md @@ -10,6 +10,7 @@ Adds in a roundstart robotic race. Currently in a very sad state, and is being w ### TG Proc/File Changes: +- defib.dm: /obj/item/shockpaddles/proc/do_help() modified - Will fill out as I discover what edits were made to acommodate these. ### Modular Overrides: @@ -18,12 +19,14 @@ Adds in a roundstart robotic race. Currently in a very sad state, and is being w ### Defines: -- Will fill out as I discover what defines were made to acommodate these. +- ~skyrat_defines/medical_defines.dm: SYNTH_DEFIBBED_TRAUMA_DURATION +- ~skyrat_defines/medical_defines.dm: SYNTH_DEFIBBED_TRAUMA_SEVERITY ### Included files that are not contained in this module: - N/A ### Credits: +Niko - Making defibs fuck synths up Nerevar - Initial code, I think. Correct this file if wrong. RimiNosha - Updating the code and adding various QoL features. diff --git a/modular_skyrat/modules/synths/code/bodyparts/limbs.dm b/modular_skyrat/modules/synths/code/bodyparts/limbs.dm index aba679efaef2dd..1126295f1fe690 100644 --- a/modular_skyrat/modules/synths/code/bodyparts/limbs.dm +++ b/modular_skyrat/modules/synths/code/bodyparts/limbs.dm @@ -1,5 +1,5 @@ -#define SYNTH_BRUTE_MODIFIER 1.3 -#define SYNTH_BURN_MODIFIER 1.3 +#define SYNTH_BRUTE_MODIFIER 1.0 +#define SYNTH_BURN_MODIFIER 1.0 // Synth bois! /obj/item/bodypart/head/robot/synth diff --git a/modular_skyrat/modules/synths/code/defib.dm b/modular_skyrat/modules/synths/code/defib.dm new file mode 100644 index 00000000000000..ecb6e2e952eb4c --- /dev/null +++ b/modular_skyrat/modules/synths/code/defib.dm @@ -0,0 +1,12 @@ +/** + * Global timer proc used in defib.dm. Removes the temporary trauma caused by being defibbed as a synth. + * + * Args: + * * obj/item/organ/internal/brain/synth_brain: The brain with the trauma on it. Non-nullable. + * * datum/brain_trauma/trauma: The trauma itself. Non-nullable. + */ +/proc/remove_synth_defib_trauma(obj/item/organ/internal/brain/synth_brain, datum/brain_trauma/trauma) + if (QDELETED(synth_brain) || QDELETED(trauma)) + return + + QDEL_NULL(trauma) diff --git a/modular_skyrat/modules/synths/code/reagents/pill.dm b/modular_skyrat/modules/synths/code/reagents/pill.dm index 15b1fd95085882..acf54dbd69ec60 100644 --- a/modular_skyrat/modules/synths/code/reagents/pill.dm +++ b/modular_skyrat/modules/synths/code/reagents/pill.dm @@ -2,7 +2,7 @@ name = "liquid solder pill" desc = "Used to treat synthetic brain damage." icon_state = "pill21" - list_reagents = list(/datum/reagent/medicine/liquid_solder = 50) + list_reagents = list(/datum/reagent/medicine/liquid_solder = 10) rename_with_volume = TRUE // Lower quantity solder pill. @@ -15,12 +15,12 @@ name = "nanite slurry pill" desc = "Used to repair robotic bodyparts." icon_state = "pill18" - list_reagents = list(/datum/reagent/medicine/nanite_slurry = 19) + list_reagents = list(/datum/reagent/medicine/nanite_slurry = 15) // 20 is OD rename_with_volume = TRUE /obj/item/reagent_containers/pill/system_cleaner name = "system cleaner pill" desc = "Used to detoxify synthetic bodies." icon_state = "pill7" - list_reagents = list(/datum/reagent/medicine/system_cleaner = 50) + list_reagents = list(/datum/reagent/medicine/system_cleaner = 10) rename_with_volume = TRUE diff --git a/modular_skyrat/modules/synths/code/research_nodes.dm b/modular_skyrat/modules/synths/code/research_nodes.dm new file mode 100644 index 00000000000000..c75d134db45f0c --- /dev/null +++ b/modular_skyrat/modules/synths/code/research_nodes.dm @@ -0,0 +1,19 @@ +/datum/techweb_node/improved_robotic_tend_wounds + id = "improved_robotic_surgery" + display_name = "Improved Robotic Repair Surgeries" + description = "As it turns out, you don't actually need to cut out entire support rods if it's just scratched!" + prereq_ids = list("engineering") + design_ids = list( + "robotic_heal_surgery_upgrade" + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 900) + +/datum/techweb_node/advanced_robotic_tend_wounds + id = "advanced_robotic_surgery" + display_name = "Advanced Robotic Surgeries" + description = "Did you know Hephaestus actually has a free online tutorial for synthetic trauma repairs? It's true!" + prereq_ids = list("improved_robotic_surgery") + design_ids = list( + "robotic_heal_surgery_upgrade_2" + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1300) // less expensive than the organic surgery research equivalent since its JUST tend wounds diff --git a/modular_skyrat/modules/synths/code/species/synthetic.dm b/modular_skyrat/modules/synths/code/species/synthetic.dm index 0809111890958b..1630d14e1f27eb 100644 --- a/modular_skyrat/modules/synths/code/species/synthetic.dm +++ b/modular_skyrat/modules/synths/code/species/synthetic.dm @@ -187,7 +187,7 @@ SPECIES_PERK_ICON = "robot", SPECIES_PERK_NAME = "Synthetic Benefits", SPECIES_PERK_DESC = "Unlike organics, you DON'T explode when faced with a vacuum! Additionally, your chassis is built with such strength as to \ - grant you immunity to OVERpressure! Just make sure that the extreme cold or heat doesn't fry your circuitry. On top of this, synthetics are unable to be wounded!" + grant you immunity to OVERpressure! Just make sure that the extreme cold or heat doesn't fry your circuitry." )) perk_descriptions += list(list( @@ -203,7 +203,7 @@ SPECIES_PERK_NAME = "Synthetic Oddities", SPECIES_PERK_DESC = "[plural_form] are unable to gain nutrition from traditional foods. Instead, you must either consume welding fuel or extend a \ wire from your arm to draw power from an APC. In addition to this, welders and wires are your sutures and mesh and only specific chemicals even metabolize inside \ - of you. This ranges from whiskey, to synthanol, to various obscure medicines." + of you. This ranges from whiskey, to synthanol, to various obscure medicines. Finally, you suffer from a set of wounds exclusive to synthetics." )) return perk_descriptions diff --git a/modular_skyrat/modules/synths/code/surgery/robot_chassis_restoration.dm b/modular_skyrat/modules/synths/code/surgery/robot_chassis_restoration.dm index ab100c0f7515e2..42e3ff853bbd73 100644 --- a/modular_skyrat/modules/synths/code/surgery/robot_chassis_restoration.dm +++ b/modular_skyrat/modules/synths/code/surgery/robot_chassis_restoration.dm @@ -1,14 +1,15 @@ +#define SYNTH_REVIVE_WELD_INTERNALS_DAMAGE 30 + +// Should be a very quick surgery, it's meant to replace defibs (mostly!) /datum/surgery/positronic_restoration name = "Posibrain Reboot (Revival)" steps = list( /datum/surgery_step/mechanic_unwrench, /datum/surgery_step/pry_off_plating/fullbody, - /datum/surgery_step/cut_wires/fullbody, - /datum/surgery_step/replace_wires/fullbody, - /datum/surgery_step/prepare_electronics, - /datum/surgery_step/add_plating/fullbody, /datum/surgery_step/weld_plating/fullbody, + /datum/surgery_step/prepare_electronics, /datum/surgery_step/finalize_positronic_restoration, + /datum/surgery_step/add_plating/fullbody, /datum/surgery_step/mechanic_close, ) @@ -24,52 +25,34 @@ return TRUE /datum/surgery_step/pry_off_plating/fullbody - time = 12 SECONDS + time = 1.4 SECONDS /datum/surgery_step/pry_off_plating/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results( user, target, - span_notice("You begin to pry open compromised panels on [target]'s braincase..."), - span_notice("[user] begins to pry open compromised panels on [target]'s braincase."), - ) - -/datum/surgery_step/cut_wires/fullbody - time = 12 SECONDS - -/datum/surgery_step/cut_wires/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - display_results( - user, - target, - span_notice("You begin to trim [target]'s nonfunctional wires..."), - span_notice("[user] begins to cut [target]'s loose wires."), + span_notice("You begin to pry open the outer protective panels on [target]'s braincase..."), + span_notice("[user] begins to pry open the outer protective panels on [target]'s braincase."), ) /datum/surgery_step/weld_plating/fullbody - time = 12 SECONDS + time = 2 SECONDS /datum/surgery_step/weld_plating/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results( user, target, - span_notice("You begin to slice compromised panels from [target]'s braincase..."), - span_notice("[user] begins to slice compromised panels from [target]'s braincase."), + span_notice("You begin to slice the inner protective panels from [target]'s braincase..."), + span_notice("[user] begins to slice the inner protective panels from [target]'s braincase."), ) -/datum/surgery_step/replace_wires/fullbody - time = 7 SECONDS - cableamount = 15 +/datum/surgery_step/weld_plating/fullbody/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results) + . = ..() -/datum/surgery_step/replace_wires/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) - display_results( - user, - target, - span_notice("You begin to replace [target]'s wiring..."), - span_notice("[user] begins to replace [target]'s wiring."), - ) + target.apply_damage(SYNTH_REVIVE_WELD_INTERNALS_DAMAGE, BRUTE, "[target_zone]", wound_bonus = CANT_WOUND) /datum/surgery_step/add_plating/fullbody - time = 12 SECONDS + time = 3 SECONDS ironamount = 15 /datum/surgery_step/add_plating/fullbody/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) @@ -80,13 +63,21 @@ span_notice("[user] begins to add new panels to [target]'s braincase."), ) +/datum/surgery_step/add_plating/fullbody/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + . = ..() + + target.heal_bodypart_damage(brute = SYNTH_REVIVE_WELD_INTERNALS_DAMAGE, target_zone = "[target_zone]") + /datum/surgery_step/finalize_positronic_restoration - name = "finalize positronic restoration (multitool)" + name = "finalize positronic restoration (multitool/shocking implement)" implements = list( TOOL_MULTITOOL = 100, + /obj/item/shockpaddles = 70, + /obj/item/melee/touch_attack/shock = 70, + /obj/item/melee/baton/security = 35, + /obj/item/gun/energy = 10 ) - repeatable = TRUE - time = 12 SECONDS + time = 5 SECONDS /datum/surgery_step/finalize_positronic_restoration/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results( @@ -99,10 +90,13 @@ target.notify_ghost_cloning("Someone is trying to reboot your posibrain.", source = target) /datum/surgery_step/finalize_positronic_restoration/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + if (target.stat < DEAD) + target.visible_message(span_notice("...[target] is completely unaffected! Seems like they're already active!")) + return FALSE + target.cure_husk() target.grab_ghost() target.updatehealth() - target.setOrganLoss(ORGAN_SLOT_BRAIN, NONE) if(target.revive()) target.emote("chime") @@ -114,3 +108,9 @@ target.visible_message(span_warning("...[target.p_they()] convulses, then goes offline.")) return TRUE +/datum/surgery_step/finalize_positronic_restoration/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, fail_prob) + . = ..() + + target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5, 130) + +#undef SYNTH_REVIVE_WELD_INTERNALS_DAMAGE diff --git a/modular_skyrat/modules/synths/code/surgery/robot_healing.dm b/modular_skyrat/modules/synths/code/surgery/robot_healing.dm index 645409a5c98f41..742cf7281ebd1e 100644 --- a/modular_skyrat/modules/synths/code/surgery/robot_healing.dm +++ b/modular_skyrat/modules/synths/code/surgery/robot_healing.dm @@ -122,6 +122,9 @@ other_message += " as best as they can while [target] has clothing on" target.heal_bodypart_damage(healed_brute, healed_burn, 0, BODYTYPE_ROBOTIC) + + self_message += get_progress(user, target, healed_brute, healed_burn) + display_results(user, target, span_notice("[self_message]."), "[other_message].", "[other_message].") if(istype(surgery, /datum/surgery/robot_healing)) @@ -157,19 +160,89 @@ /***************************TYPES***************************/ /datum/surgery/robot_healing/basic - name = "Repair robotic limbs (basic)" - healing_step_type = /datum/surgery_step/robot_heal/basic + name = "Repair robotic limbs (Basic)" desc = "A surgical procedure that provides repairs and maintenance to robotic limbs. Is slightly more efficient when the patient is severely damaged." - replaced_by = null + healing_step_type = /datum/surgery_step/robot_heal/basic + replaced_by = /datum/surgery/robot_healing/upgraded + +/datum/surgery/robot_healing/upgraded + name = "Repair robotic limbs (Adv.)" + desc = "A surgical procedure that provides highly effective repairs and maintenance to robotic limbs. Is somewhat more efficient when the patient is severely damaged." + healing_step_type = /datum/surgery_step/robot_heal/upgraded + replaced_by = /datum/surgery/robot_healing/experimental + requires_tech = TRUE + +/datum/surgery/robot_healing/experimental + name = "Repair robotic limbs (Exp.)" + desc = "A surgical procedure that quickly provides highly effective repairs and maintenance to robotic limbs. Is moderately more efficient when the patient is severely damaged." + healing_step_type = /datum/surgery_step/robot_heal/experimental + replaced_by = /datum/surgery/robot_healing/experimental + requires_tech = TRUE /***************************STEPS***************************/ /datum/surgery_step/robot_heal/basic - name = "repair damage" brute_heal_amount = 10 burn_heal_amount = 10 missing_health_bonus = 15 - time = 10 + time = 2.5 SECONDS + +/datum/surgery_step/robot_heal/upgraded + brute_heal_amount = 12 + burn_heal_amount = 12 + missing_health_bonus = 11 + time = 2.3 SECONDS + +/datum/surgery_step/robot_heal/experimental + brute_heal_amount = 14 + burn_heal_amount = 14 + missing_health_bonus = 8 + time = 2 SECONDS + +// Mostly a copypaste of standard tend wounds get_progress(). In order to abstract this, I'd have to rework the hierarchy of surgery upstream, so I'll just do this. Pain. +/** + * Args: + * * mob/user: The user performing this surgery. + * * mob/living/carbon/target: The target of the surgery. + * * brute_healed: The amount of brute we just healed. + * * burn_healed: The amount of burn we just healed. + * + * Returns: + * * A string containing either an estimation of how much longer the surgery will take, or exact numbers of the remaining damages, depending on if a health analyzer + * is held or not. + */ +/datum/surgery_step/robot_heal/proc/get_progress(mob/user, mob/living/carbon/target, brute_healed, burn_healed) + var/estimated_remaining_steps = 0 + if(brute_healed > 0) + estimated_remaining_steps = max(0, (target.getBruteLoss() / brute_healed)) + if(burn_healed > 0) + estimated_remaining_steps = max(estimated_remaining_steps, (target.getFireLoss() / burn_healed)) // whichever is higher between brute or burn steps + + var/progress_text + + if(locate(/obj/item/healthanalyzer) in user.held_items) + if(target.getBruteLoss()) + progress_text = ". Remaining brute: [target.getBruteLoss()]" + if(target.getFireLoss()) + progress_text += ". Remaining burn: [target.getFireLoss()]" + else + switch(estimated_remaining_steps) + if(-INFINITY to 1) + return + if(1 to 3) + progress_text = ", finishing up the last few signs of damage" + if(3 to 6) + progress_text = ", counting down the last few patches of trauma" + if(6 to 9) + progress_text = ", continuing to plug away at [target.p_their()] extensive damages" + if(9 to 12) + progress_text = ", steadying yourself for the long surgery ahead" + if(12 to 15) + progress_text = ", though [target.p_they()] still look[target.p_s()] heavily battered" + if(15 to INFINITY) + progress_text = ", though you feel like you're barely making a dent in treating [target.p_their()] broken body" + + return progress_text #undef DAMAGE_ROUNDING #undef FAIL_DAMAGE_MULTIPLIER diff --git a/modular_skyrat/modules/tableflip/code/flipped_table.dm b/modular_skyrat/modules/tableflip/code/flipped_table.dm index 22b8f71d060d1f..80776abf09aa22 100644 --- a/modular_skyrat/modules/tableflip/code/flipped_table.dm +++ b/modular_skyrat/modules/tableflip/code/flipped_table.dm @@ -18,9 +18,8 @@ AddElement(/datum/element/connect_loc, loc_connections) -/obj/structure/flippedtable/CanAllowThrough(atom/movable/mover, turf/target) +/obj/structure/flippedtable/CanAllowThrough(atom/movable/mover, border_dir) . = ..() - var/attempted_dir = get_dir(loc, target) if(table_type == /obj/structure/table/glass) //Glass table, jolly ranchers pass if(istype(mover) && (mover.pass_flags & PASSGLASS)) return TRUE @@ -30,12 +29,11 @@ if(projectile.trajectory && angle2dir_cardinal(projectile.trajectory.angle) == dir) return TRUE return FALSE - if(attempted_dir == dir) + if(border_dir == dir) return FALSE - else if(attempted_dir != dir) - return TRUE + return TRUE -/obj/structure/flippedtable/proc/on_exit(datum/source, atom/movable/leaving, atom/new_location) +/obj/structure/flippedtable/proc/on_exit(datum/source, atom/movable/leaving, direction) SIGNAL_HANDLER if(table_type == /obj/structure/table/glass) //Glass table, jolly ranchers pass @@ -45,20 +43,20 @@ if(istype(leaving, /obj/projectile)) return - if(get_dir(leaving.loc, new_location) == dir) + if(direction == dir) return COMPONENT_ATOM_BLOCK_EXIT /obj/structure/flippedtable/CtrlShiftClick(mob/user) . = ..() - if(!istype(user) || !user.can_interact_with(src) || iscorticalborer(user)) //skyrat edit: no borer flipping + if(!istype(user) || !user.can_interact_with(src) || iscorticalborer(user)) return FALSE - user.visible_message(span_danger("[user] starts flipping [src]!"), span_notice("You start flipping over the [src]!")) + user.balloon_alert_to_viewers("flipping table upright...") if(do_after(user, max_integrity * 0.25)) var/obj/structure/table/new_table = new table_type(src.loc) new_table.update_integrity(src.get_integrity()) if(custom_materials) new_table.set_custom_materials(custom_materials) - user.visible_message(span_danger("[user] flips over the [src]!"), span_notice("You flip over the [src]!")) + user.balloon_alert_to_viewers("table flipped upright") playsound(src, 'sound/items/trayhit2.ogg', 100) qdel(src) @@ -70,7 +68,7 @@ return if(!can_flip) return - user.visible_message(span_danger("[user] starts flipping [src]!"), span_notice("You start flipping over the [src]!")) + user.balloon_alert_to_viewers("flipping table...") if(!do_after(user, max_integrity * 0.25)) return @@ -90,10 +88,33 @@ //Finally, add the custom materials, so the flags still apply to it flipped_table.set_custom_materials(custom_materials) - user.visible_message(span_danger("[user] flips over the [src]!"), span_notice("You flip over the [src]!")) - playsound(src, 'sound/items/trayhit2.ogg', 100) + var/sound_volume = 100 + var/balloon_message = "table flipped" + var/user_pacifist = HAS_TRAIT(user, TRAIT_PACIFISM) + + if (user_pacifist) + balloon_message = "table gently flipped" + sound_volume = 40 + + user.balloon_alert_to_viewers(balloon_message) + playsound(src, 'sound/items/trayhit2.ogg', sound_volume) qdel(src) + var/turf/throw_target = get_step(flipped_table, flipped_table.dir) + if (!isnull(throw_target) && !user_pacifist) + for (var/atom/movable/movable_entity in flipped_table.loc) + if (movable_entity == flipped_table) + continue + if (movable_entity.anchored) + continue + if (movable_entity.invisibility > SEE_INVISIBLE_LIVING) + continue + if(!ismob(movable_entity) && !isobj(movable_entity)) + continue + if(movable_entity.throwing || (movable_entity.movement_type & (FLOATING|FLYING))) + continue + movable_entity.safe_throw_at(throw_target, range = 1, speed = 1, force = MOVE_FORCE_NORMAL, gentle = TRUE) + /obj/structure/table var/flipped_table_type = /obj/structure/flippedtable var/can_flip = TRUE diff --git a/modular_skyrat/modules/time_clock/code/console_tgui.dm b/modular_skyrat/modules/time_clock/code/console_tgui.dm index 9f1f557d40a2f3..306a2d9c49cb11 100644 --- a/modular_skyrat/modules/time_clock/code/console_tgui.dm +++ b/modular_skyrat/modules/time_clock/code/console_tgui.dm @@ -29,7 +29,7 @@ /obj/item/gun/energy/e_gun/hos, \ /obj/item/pinpointer/nuke, \ /obj/item/gun/energy/e_gun, \ - /obj/item/storage/box/gunset/pdh, \ + /obj/item/storage/toolbox/guncase/skyrat/pistol/trappiste_small_case/skild, \ /obj/item/storage/belt/sabre, \ /obj/item/mod/control/pre_equipped/magnate, \ /obj/item/clothing/suit/armor/vest/warden, \ @@ -51,7 +51,6 @@ /obj/item/card/id/departmental_budget/car, \ /obj/item/clothing/suit/armor/reactive/teleport, \ /obj/item/mod/control/pre_equipped/research, \ - /obj/item/gun/ballistic/automatic/pistol/g18/nomag, \ ) diff --git a/sound/ambience/antag/bloodcult/bloodcult_eyes.ogg b/sound/ambience/antag/bloodcult/bloodcult_eyes.ogg new file mode 100644 index 00000000000000..38c223b1ad8580 Binary files /dev/null and b/sound/ambience/antag/bloodcult/bloodcult_eyes.ogg differ diff --git a/sound/ambience/antag/bloodcult.ogg b/sound/ambience/antag/bloodcult/bloodcult_gain.ogg similarity index 100% rename from sound/ambience/antag/bloodcult.ogg rename to sound/ambience/antag/bloodcult/bloodcult_gain.ogg diff --git a/sound/ambience/antag/bloodcult/bloodcult_halos.ogg b/sound/ambience/antag/bloodcult/bloodcult_halos.ogg new file mode 100644 index 00000000000000..bd22934fd301b2 Binary files /dev/null and b/sound/ambience/antag/bloodcult/bloodcult_halos.ogg differ diff --git a/sound/ambience/antag/bloodcult/bloodcult_scribe.ogg b/sound/ambience/antag/bloodcult/bloodcult_scribe.ogg new file mode 100644 index 00000000000000..a01ef30a1d487f Binary files /dev/null and b/sound/ambience/antag/bloodcult/bloodcult_scribe.ogg differ diff --git a/sound/attributions.txt b/sound/attributions.txt index 09ac2bd56429db..3ae6c797dd33bd 100644 --- a/sound/attributions.txt +++ b/sound/attributions.txt @@ -99,3 +99,9 @@ https://freesound.org/people/FunWithSound/sounds/456965/ beeps_jingle.ogg is adapted from Eponn's "Achievement happy Beeps Jingle", which is public domain (CC 0): https://freesound.org/people/Eponn/sounds/619838/ + +boing.ogg is adapted from reelworldstudio's "Cartoon Boing", which is public domain (CC 0): +https://freesound.org/people/reelworldstudio/sounds/161122/ + +arcade_jump.ogg is adapted from se2001's "8-Bit Jump 3", which is public domain (CC 0): +hhttps://freesound.org/people/se2001/sounds/528568/ diff --git a/sound/effects/arcade_jump.ogg b/sound/effects/arcade_jump.ogg new file mode 100644 index 00000000000000..65f0cc448b564f Binary files /dev/null and b/sound/effects/arcade_jump.ogg differ diff --git a/sound/effects/boing.ogg b/sound/effects/boing.ogg new file mode 100644 index 00000000000000..8328cc33926133 Binary files /dev/null and b/sound/effects/boing.ogg differ diff --git a/sound/effects/footstep/spurs1.ogg b/sound/effects/footstep/spurs1.ogg new file mode 100644 index 00000000000000..d2754587ca15e6 Binary files /dev/null and b/sound/effects/footstep/spurs1.ogg differ diff --git a/sound/effects/footstep/spurs2.ogg b/sound/effects/footstep/spurs2.ogg new file mode 100644 index 00000000000000..e02725e9079bbf Binary files /dev/null and b/sound/effects/footstep/spurs2.ogg differ diff --git a/sound/effects/footstep/spurs3.ogg b/sound/effects/footstep/spurs3.ogg new file mode 100644 index 00000000000000..e79b90dc78d9f4 Binary files /dev/null and b/sound/effects/footstep/spurs3.ogg differ diff --git a/sound/effects/submerge.ogg b/sound/effects/submerge.ogg new file mode 100644 index 00000000000000..8c50fba8e0a735 Binary files /dev/null and b/sound/effects/submerge.ogg differ diff --git a/sound/voice/moth/credit.txt b/sound/voice/moth/credit.txt new file mode 100644 index 00000000000000..7f64b72841e32c --- /dev/null +++ b/sound/voice/moth/credit.txt @@ -0,0 +1,5 @@ +"moth_flutter" modified from +https://freesound.org/people/Godowan/sounds/240476/ +(CC 0 license) + +who knows where the original moth scream noise was I sure as hell don't \ No newline at end of file diff --git a/sound/voice/moth/moth_death.ogg b/sound/voice/moth/moth_death.ogg new file mode 100644 index 00000000000000..df23cfa472ac10 Binary files /dev/null and b/sound/voice/moth/moth_death.ogg differ diff --git a/sound/voice/moth/moth_flutter.ogg b/sound/voice/moth/moth_flutter.ogg new file mode 100644 index 00000000000000..f5737d522ca208 Binary files /dev/null and b/sound/voice/moth/moth_flutter.ogg differ diff --git a/strings/exoadventures/britain_replica.json b/strings/exoadventures/britain_replica.json new file mode 100644 index 00000000000000..0bfaa67e990cb0 --- /dev/null +++ b/strings/exoadventures/britain_replica.json @@ -0,0 +1,570 @@ +{ + "adventure_name": "A Model Earth", + "version": 1, + "author": "Armhulen", + "starting_node": "Planet Start", + "starting_qualities": { + "Long Range Scan Report": 0, + "UFOs Shot Down": 0 + }, + "required_site_traits": [ + "in space" + ], + "loot_categories": [ + "research" + ], + "scan_band_mods": {}, + "deep_scan_description": "", + "triggers": [], + "nodes": [ + { + "name": "Planet Start", + "description": "You come across a grey planet. It looks familiar, though you swore you've never come across this sector of space before.", + "choices": [ + { + "key": "choice 0", + "name": "Ignore the planet.", + "exit_node": "FAIL", + "delay": 0, + "delay_message": "Whatever, there's a lot of planets in space. Must be a hunch!" + }, + { + "key": "choice 1", + "name": "Begin Orbital Scan", + "exit_node": "Scanning from Orbit", + "requirements": [ + { + "quality": "Long Range Scan Report", + "operator": "==", + "value": 0 + } + ], + "delay": 30, + "delay_message": "Scanning planet..." + }, + { + "key": "choice 8", + "name": "Descend Into Orbit", + "exit_node": "Orbital Descent", + "delay": 30, + "delay_message": "Descending into Orbit..." + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAMAAAD0WI85AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAALlUExURQAAAAEBAQICAgMDAwQEBA8PDwUFBQcHBwkJCQwMDAoKCkRERNXV1cDAwNDQ0LGxsaioqJaWloyMjLOzs6WlpcLCwqSkpDc3Nw0NDeXl5b+/v5mZmZycnLKyssXFxXd3d6CgoODg4JeXl9PT08bGxsTExJiYmIqKiqGhoZqamoeHh5KSkvb29pOTk4ODg3FxcaOjo62trZ6enqKioqqqqq+vr4WFhcvLy729vb6+vqysrJGRkeTk5Jubm7q6uru7u6urq6amppWVlbe3t6enp9zc3GFhYYuLi93d3by8vH19fdHR0fn5+c/Pz8nJydnZ2XZ2dn9/f4mJibCwsNvb22pqauvr63x8fHV1dRUVFcPDw/Hx8c7Ozra2tp+fn1BQUFFRUYGBgV9fX4iIiHl5eQYGBqmpqbi4uLS0tMfHx83Nzbm5ubW1tV5eXmJiYpCQkHt7e+rq6kxMTFNTU2lpaXBwcG1tbXNzc4+Pj09PT52dnUhISEFBQUNDQ1JSUltbW1paWmVlZW9vb2traw4ODnR0dG5ubnh4eGxsbElJST8/P1ZWVnJycmdnZ2RkZHp6eoaGhmBgYEBAQEpKSlRUVGZmZmhoaMHBwdLS0oCAgDk5OWNjY11dXUZGRkJCQkdHR9jY2O/v75SUlDo6OlxcXFVVVVhYWD09PU5OTk1NTVlZWd7e3sjIyDMzMygoKH5+foKCgoSEhC4uLjs7OzU1NUVFRenp6TExMf7+/o6Ojtra2q6urt/f3/Dw8PLy8uPj4/z8/Pv7+/39/TIyMufn5+Li4srKyszMzFdXV+7u7tTU1Pr6+jAwMD4+Pu3t7SsrKyoqKuzs7NfX1zQ0NC0tLSwsLC8vLxAQEPPz89bW1ujo6Dw8PEtLS42NjfT09DY2NhwcHPX19RMTE/j4+Dg4OCkpKSEhIQgICCQkJCIiIiYmJhoaGiUlJRQUFOHh4ScnJ////xcXF+bm5vf39xkZGRERERgYGJOWJYYAAAAJcEhZcwAADsIAAA7CARUoSoAAABOjSURBVHhe7Vv3W5PZnidlog41VOlNuvQOUgJIVaqURTpITygJTQgEuJQQQu8JRSAQFEaqBFBBulyxULwjgWFnr3N37uyMc9e7uz/vOS/Zv+Gd51k+mrzJm/ec5/PtpyF2iUtc4hKXuMQlLnGJPygwAFgMFgsuONEX8MKDGzgAPAYHvuPBc1gc+AU8jsXixHDgDYMRQ36DP2PFsPA2ugD8AWVAEQ944jFYeAtcwBcsHogjBhjjIW0EOOw38AkgBLiPyIpoAIhxIS2KuCAI6UJ2YkC34AseUAa8gGiAHtA1oAuogrvwcSzyhoPyAPvAT0Bm8MhFf6gBEoNMAOULz4LsIGsCdCs8gXDlKuHqtavfXoGehsVCEZGHoCmghwFbwg/IPVQBnAeJCkAGIYf8RzhicVe+EZeQlJKWIcrKySvIK8opfXsFMIeGAKRhzCANkabwcVGPaAGhBdgAVhe+cyEPAXddWUVVTV1DRVNeS0tNVVtH94aevoHhNTwIKZHVQGNwgT1AZaAsCFAw9HKR5wM/AS8M7up1BSNjk5umhmbmFpZW1jaKtnb2ig6OThqKhs5GMBVAN0NcDeYy8A/GvqhHlADVCWRB3hHFAk8Ru3rL1sXM1c3G3l2S5K7o4Um00PFSv+1N9PF1tPXzM/WHaQy0QPIXBOJjBFGPaAGJ3gt7AFPAyL0SQDT1vXM3UMHJMchTXSY4xCBUi6QoE+YUei/c2SJC2iXSOQoGBrQE9EJgUtga5fQL1ArzDiIIoljsv8hFq9+PIfpJytx1dIy1CY2LT0hMVFQnOTl5eVjYmPgmkZJDU0JgIEEgfgmbgmBBFYiLIIygcbCYBxKpkmnpGZnpsVmOMtkkaxd3NS0yJSc3z8vWJi7OyzOfSisg5xYWmRddGAO2QSILdYtc+DliEyATPttT0UMtNs3EQ91DTi9W3Uu12MxYv4RKNJF+aGpTWlpGJ5dXUBmVVdVFlciIAJR9kUlQriOIGBDQNpg/yWTJu0p7uioouLnL2JCsZTxSamrD6wxy6osYdGY5ndngTWKR46nllEZ2kzlIW3Bsg1RILBblYEc4QGXC6L2mFRYrKRcdIxGtkOpl1FzcEtKY0tjqYWBHdCw1lMkpaGPQ2zsqNDuTqOS4dFpXOKiOF2kCifaLDtECLIAgbyF8rsloqad2G3W7yll7mBV1RTaHJ7GL6msNcnpcTEJ6Zaz6OFxZM1b/AGUwn1qrX+dB84YRDjMdHjYX9YgSoEPBFxhlEEhOWSoOXnoW+qFF1ZWcJnJnU9PQo85IUqPFcHpzpIm+Zl8yxXukfDSf3F7O0+nRL6SQRdEOQwxli4iGfLBA26rYuxqmKuoU1xR1UcZ4YxXkJEorkZNYL//QR95o2KQvqYQ3XsKfSHrMEK+n2eiF6XELWaAxDo7z8X+ArAXtAcI2NO2JtIVqS01jVxUnidHkWmU22VnRm+JGkoocDnVp0Wa0jeVPMdvyG8N59WQOtSNS0TIyt/M7JF8REO9EFYhPwAH8N26Szg+NzCPNnzZxyIHTmrJ1PqZ27GjH4ZleI7niAvrs3NR8WckEf4GRQB3VnBhgBbdakuvDE4AKwHwS/WAXQzKPGOZqaqrHcIpmldlDjy55Z78Z28LEEJrmM/en/MLYVtO7fFpCSe9i/chYTmU+ObJeINdJnWgiL3kXdvHhIB6oA0xnUAWMcnihWi/J1tQULdsM2UrJGzuvPH+hXl7OvfmSVRd7002H5zvIuK+T9dhsldi9dv9VBtV31Y/Nqu3oqK5tuobkXtTnI8g8SQxzxcmseSYuMaeI3VQV0+uto7Bqep/FpTqsSce1Dg05rZdQtdhUh0YX8sAac2OhRmNzK5itOsNht9K48chABQS9qEeUAHQJPBy/EhocrLkd6ZkznK27s+udm6dlm+5Gfb22tlfZe2MztzzhfsGfxUcqHHSzht+w+LXWrpKe0S+aqk2CW+srrwKjgiKPfh0BKRgYJLjIVI2t9sh/facwZ9g7oqh6uqPgqf7a2pDsE2NlO/OR/bVX7KG8t22euRvvlDqa3e3oxckZzUvlkR2loLDDgirqESXAfIPBvC+OWustZNcneXcK7D+8Iqkox5HvpL0Ij33KfnXgen+9p60oIbpgvazmsPZoYvY78f2KOX6ujL0nj8ny8WYRgAygkIh6RAmAAzCKtZlUc4hPa1drwbSzufqjHU9OXm3AaK9hzXpdqt/WQ82d3KUq1jK193DwePGN/LA+u9R6bmouOMfIoD2Y9fgjKIp/BNfCEP7i8X2Lnz6HMVpXQmlpb9dU//TUQ3bF0U/hdYidCXFdteVkKEZftjCDIWTOWbHexNfGx5/OhjQoOEsrhphVxu8jWQv9gigm1quQlVjF4SmeJtHOKP4luxkHtKHmHCM7NXl72810l1oj45pP/SnOngvife/GR+KPhOIVy8z9MemJSuuwQRYjXwxZEBL1iBZA7sR7ZUQvdblwGKWnFR5ljawmvpxGnR+xyy0odOWHMAm2Yt0jTXqtf6YdzS3gXHzxOGX/qO+wIUmmo6O/Pq0+l5zwr3B+hXZBBPH+7WqacdKB+Y+nEzPudJ0BpkmeAqVrKScgbP3Jq7fbkcVe3uNtTLlOmRd19HrGlHDqDb004bD95vfjTVE60vr17aw5WBLRXqDD4nH/phiVK93UWZI/sTBBPmHyK83WqJxgU//Ym8qCv+osVfFmyOOD3RRKaGFL4uTxsdLHzyzmwPh8/8Jc8GSWYjGfwYMrMWgvYoNaNq9mEFWxS/2z822ryW6/WjLfuLl62vmpx55GhP8LFwZb9nFl9T6XO3g43t45uEiVPWwbf1/200ZD/MfRRFq4eUq8EHSDdvqFC6SOduxQn44twXTXfcrp/j5zUPVpWp1qVl1i8QGls4Iyk6TVuCBMosTOMmbfr5fRS2TH//Z+nLW/MOcfH9/CKuHWx/87UAfK6RcvRhBLU60wz/b/8UyuulFIbxsUiiv4mzWemTxVtywI906K3R0da+kfSeKe/fz3Kepx2+nnhF82kuhtGxOc3dLBWiqVq2/+H7C0i3pEC6CYGdU2sogBMiW79NNBlnAmOtKycKkxMS7Z+GE1hUyrZXNoCe1KCa37v/76/tf5o3nSeVFfw/ynQaGQMlEvHt+cz6H8huySoAs8BpfTKKd/y/LLWM3uqyc5mRarasrsLP+Qs2KfmfqoyqZITc7uxOBC2/mRdXOb1uPZjxsOybUNIy4VG4f7pQ1lgxMJ5o+n4HK2qEO0AMqIUe9MJaOfUjAd1NM0QTZSeC2zpd01k+Mm+3DVgrXL6WK3ttPL+kJ/Lj/66fiX44HRqcq++e9mp5vaGgbmba3oCfHxU8jkClWAmR1uUs1qTKde2Hraf9o6zqT3L/Dzi16l2BFvVN1uTuAyCtScd8vzeRv7Skq/MxYX2tlzHpaLZwaU+aONNyOawtIx9ug+TH6iHtECmBOF1Yx6U3nJ3vw25sBgA71P3GefubK6qhP56UCu6vvRrl075tzhqNLI8bvjN+9/mp17MxAg0zgf7iycH8jnDjDKTxlvcGjv8wCPwIqptYyyC6lWkyyuf//axPxI6VwXmRH4yTS72OsggJbNJVfEM/sP90cazgd9j7qP2j4ezp0PnYZPt/PL2g7HO5jU3WMwG0C5IMJ1QotcMo89xqk3cF8OpQnP81vPywZZ9PQvm1Ivt9id0dE8XmFZw8bUhnD+543O38c3ZoU/HZ7fPKYJuz4u0U9p4tUVfwPDX1GHaAGupVsaRybNcAwqTIhSghc/HGwX9Q7MuN18GhvzSpDVWNnlb8kNL9Ueyd+fOp6aDx4fOacuvlsIb4ig8xemyuhzzp0c1m+gHKEd7ACVpsO2vg8L9M3bJYfsBE4ZRnsTvDF+0s31OJt1gWCP9GrtB4kT2b2Ss8WgI1JwVFKC0nxZwxvHwo2C895zJfFKGhmP/rYCmG5j/2SZumeaYbQbOj6u5J0m9YGSEt9ZMdA/ypp+cUcARBEI1tdud9EY9KN31ZTde+eSa4cj5/PHQbP8+ZziBdau+fhFrKEKuD53LWPGT9lGr0b4OfTO5yS9cGNqH6czl8eqTKpMvvOPm4L1dcErga7AiLR4PkBZMmPx3aO5i7XzY6OG5xtl/JDgsRFkiijqESVgcATMg7CHdfoHlqzPPPnAiCRdTjmZ+5FeoFlEi+CXnt0TCJ5AowhuRvicPz5cdJdtonqb9fWZjIzotgoblOg0dv4R3KhGWxAMDouXkzR8MvSJF+XLTPLypGoPHC7+MuftsqKYYU02Zar2rAH3WhfcTbR7SpkN1ow2s6R0938mFhbqEvv7Gug8FvM/4TxT1CFaAFMiMcJfvkau3nYgdtHt26PoA7c1eD+dv1NVK3DsurO735edhwgSlDbsN87LfctNXG1WXRLGM6La7OsW1BvmeE1CkDCATUQ9ogS4bIDDTFY/e7FF45U+0lIDThROO/39ffpEaHqgYNjt8Toix1v3peCRd2VVxu0DvTLLfq9bJitb3G2SS5TqExgNcKsI7fkITFs4fKq/6j8j1AqoGvnxE5X/XKPkvZvqPGoa3Vz/BxIer/56MHjn5GtZ226A8fLE/egwn2lJk3DrtJUVmrh5vPhvIPeinrVgvgFR8pQm+fpuSEmwSik5yF1qvUBQclotqbyWCDLW+vc/Puecve1dVmiVTSvTIRm8/XDgq/s8RifRzTNnxrgtfx7Zo0bdteCREixOq9f59cvH0bbFsr4r5muZgq3egKbMZ8pnaxFbsZ53R0nj3fvnI7IjL2X6MuOz1YcMg4PTonVv2OoP1zEnFpFNSLQtIoYlwANCD/xVt54nOw7Hdc+Yq8hWCVLTc5ZvBL5c3Qxc+5KpbRgXM1M75tnP6pglVUaahsfQwolxgd1+VfVVdhNTYHIIgh0EG6oAyoTDLYzXzj2FHdnNEm3vqPLOptUtqcagGxoKt5e/fHqux22ONniZ7h3V9rCX+7mtTJ/PORTuV0tbyFeMMhsH32PAJBMeeRL1iBLgXBuQwF4xkpoM285jfA2KumsUuva9sor2CnGjJ6On21KPk7m3dOaue7Yx+njVlK30hj1eOzJY3mw22p/AbxTikeSL+moQUCQ8t4AV44e6xgYElZq9dYsrTNl8oq2hntlTdK6ncPv1I6tdTnfc28jS/sdhFk3qvLa+8c+HNCtyF7+/g0L9L7g/DUY6qI+1EMciAKUq6ixFSewNW259eBQbm3fL0kzXZsDXMSjolqFRYoxCrOmms4rCgs5dGfOpo/d1BdTppSbxdg63DwgApv3oL6JAY8ARsBj2gXQoW3LS8yTww3JpbHfGfVt1Y6tgnR63WhvzG5LqPbm2mzqNz3eNUnILbbysLGQUNRb4EwVjcNMNSAHVIeoRJeDxkAUchj/4b6vCsbgKhc3RMxdvfyvHob2hneU8bbkbXtvLX3Xd8yRizkyydb18ZlSJ0k7u8h5LUR3c6v8BDZHTmqjXEcAD1hIgDBar5JfCLZFWubdiwcnu7CLdf7YV8fIL0Xx7Tzni7TOVbNtYLXbL3WxDV3XPuGk14llyZOUG0hD6FTzHjSrg8XFQSOBICYMrckrvdi3RuJduveN7K/3e5snbk4BntzbzTj6s6gZIbA75RQ9ZOctL54aRXIiyxilsIQFIAccGePSDBIggOgQHh0vNRu4rH7aDeuylvj6z/+qbemPoYGs1ImIzQOFr3qPV58/UJdKzYhzT5UgrsgbBnX1I4oaCwCvaGz2wmMEdfygLnnAeZ2qbHbB8sHrvIEb33pbyXs/ml1jlHyNOTk6+fvmi/akmzHFbJazl7GymqpUPhABJAjQE5iCgnX4BCeBZ0CZwcoTFXvdK17grEXRb+9PywXLy5smXtx8+RHw9UT450f6qPfRpp9vBU8M9n5scSRPCOQg8zAwkAS4mhrJFYF0G7gU3/KFSwbuPiruf/aT9ZOaTgJyI27fynj37+kz71vOh5b2dT9sK6bbp6bY6Z8HVf4cNAXuYu4EiUN96Q44owUIA+UB3x2B21c0MXR0CYwL2Apbvra6uPh8KWh7a0e3Zjgnc8bT0S1VsaakagyejLqwBvAtus6C99gtVikfMAidYwCSAEIGY2Oqqty2VGah7sHw7SEIiZifaflvjhkqsq4OXl0ViXesxeBz4JDwuCz7AtSBwFfWIEkD6BHzAoA8yQxhBxycY6Lj6ZU3qdTtmSu1k7NydlJTMckhLy071MvQwo8TDBlAEaI2L2IL5S9QjSgBk4J9bQDogRqCzYB9An3lAJGZl2TplOehFq0Rr+MllS2evyLsMy9qZ/wxMB10QqYXAqaB7wcSH+q4usACShC+SEHQSJB/jrlx/aEUikaRtw5ykV0hO1k4ePsmaVDjxgEkO+BOWAKshjC84QEF7XwH4E6CNA9aA3gIiBtY2KAvki7t6ne2ib+ShprMUatx7fIUA70I/hC4Im0EtwGHjhZuhCsgCVmbkAudY8Ab8gtAEqscTMAQCDAqodzASgaIgxGEb+Bn8iEgk6hAtAAaQGx64CxzFimatiBiAJGRIEBkA8T2kkP+fMUAzRBEYkO7ARdQjSgCcEPVDDwP0YHWAwY/IgvCHf5wI3QkwBz9B+kAYMBaAqQFKD4UAv18hoGwSRJWQPbgAftAMyPFZxMXgBSgaSAF8DD4FkxwQCNoBKSFAVKgJqA60Y+QSl7jEJS5xiUtc4hL/HyAm9r+XXnYR5dlv2QAAAABJRU5ErkJggg==" + }, + { + "name": "Scanning from Orbit", + "description": "You initiate a long range scan from orbit:\nThis planet has a smoggy cover that blocks any good look at the surface, yet it has a mostly survivable atmosphere.\nThis planet has zero life signs.\n", + "choices": [ + { + "key": "choice 9", + "name": "Stash that Report...", + "exit_node": "Planet Start", + "delay": 0 + } + ], + "image": null, + "on_enter_effects": [ + { + "effect_type": "Add", + "quality": "Long Range Scan Report", + "value": 1 + } + ], + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkBAMAAAAxqGI4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAASUExURQAAAP///1lWUqwyMmlqakZHRwPX/kkAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAL5SURBVGje7ZldbqMwFIXtKnkvO4huyAYmG0CWea8i2P9Wxv/Y2MTYvjBVO4c8FET8+dxzDW5Ldqr73Hcf7fbemfwu+p1tkM+jILTbfeu2stNbDDSkklXnzNRbyUqUqbM/oVr5AFhOus5iUK3A/fmEW0BRHjCtwFPqj6NQS6GIVu5PTXEXnJUOjfLxXEOITYWitXECQk6BUOx6pSDkKAj4F6mrFxLEdNctAdl8gJVmBRBXy6tXcrScwwvXsufikXIP1qId5t2iz0D4osFClAga5MJDDbJaEUDJjF6eyZohxATjlhym9kkcMzhkIBQJ0g+pe2klJFWtG4DrgRSkeEUkjDDWA09TbPJdM6RXnySlDnLpYyO9/GhtQChthYhSMXeyup0aSFkoCYirVqJkdcnHEMaXakVeHIQUQYBPwSFdMB86IEBYolrAtyi1kF4asOIT40Ekq4JVQvS0R3UYI5G5GFLYwuKRO3l69dMEkxnc5MR8K6RCF9VL2sioe2tdLc6GRggROUDve5lcA9usXpw0So4Go5OwE0YySqutED33eZKH12TSyJJTK0RNFx6LFb4yMiI4uajJQmxlWT3tTsybEfxUnA0t9miGmNnCY54DMxNiJu7V6HLx89BO2iHLhIUXPxUleWVjf1SiZbvCHkEuLqX0brIM4hUfwkxERkKvdiPhxksGw3UuNpERmpuLeKGoBRM8k5WP/gsBsnrkAphUVGOJHeuIwPBDMcks6vmAUazkbtjXgAIhqVW+QHAYZHxnBIkRheKbGbAgJH6NIAcitWFlwmQQck28EzEDUdqwQnClrIxH+pA63od1EpgpHiP7i3ccSjEj/yd258SYqendLCR0UfcCyUK0B9KkbCYNBnZLRzIcC9HNdSzDODkYoraOB0eim+vgSIjcKM4HM06J5Hqak1Mi+d9ce3VGc5Ef01zXM5pLQN46oR0O5G0kKP+9nM+CfP1rSDqTwqTqmqvQX91SLINcvzGkLJPrCev9HMj8oyDk10MI+Qt3vM7Ve2h01AAAAABJRU5ErkJggg==" + }, + { + "name": "Orbital Descent", + "description": "As you descend into orbit, you see a flying object headed straight for you!\nA garbled voice begins to call out to your drone, but there's no time to decipher it!", + "choices": [ + { + "key": "choice 2", + "name": "Blast the damn UFO!", + "exit_node": "Tractor Beam", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Tractor Beam Turns", + "value": 2 + }, + { + "effect_type": "Add", + "quality": "UFOs Shot Down", + "value": 1 + } + ], + "delay": 30, + "delay_message": "Blasting UFO!" + }, + { + "key": "choice 3", + "name": "Attempt Evasive Maneuvers!", + "exit_node": "UFO Evasion!", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "UFOs Violently Crashed Into", + "value": { + "value_type": "random", + "low": 0, + "high": 1 + } + } + ], + "delay": 30, + "delay_message": "You attempt to dodge the UFO..." + }, + { + "key": "choice 7", + "name": "Do NOTHING. Jesus take the wheel!", + "exit_node": "FAIL_DEATH", + "delay": 30, + "delay_message": "What? Why?!" + } + ], + "image": null, + "on_enter_effects": [ + { + "effect_type": "Add", + "quality": "Garbled Transmissions", + "value": 1 + } + ], + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAKgklEQVR4Ae2dW5IbNwxFtZFswouI//ORqmwgNbHH9sayoyxGKcz4jiGIJAA+ukk2VKUCHwAJkveILXvGvv393/0e73324PfPn++ld5y176xvsWG+DZt9v0pwUN/s+c+WXwCy2Q0agPT9wAtANgJEgyNuED88AUgAEo9dBQ0EIIXNme15WMtHu0G0+Oh/vmECkAAkbpCCBgKQwuas9Imq3R7x/eP5drCcbwASgMQNUtBAAFLYHMsnzCw+2g0yS56r5RGAbACIBkc8XtU9XhHMAUgAEo9YBQ0kAblXvla7PnfJN26Q+htC08ADIJVcPIVpk0Z/vwO1wBGPWPX7/QbIk8IbGwKA+gPx7p0FEO+Y4f/r/G6NLCTDazc4ORhrrB1317h/vnx5+9F2aSU0u67/iHVNAQhjQC0esSmrzCFByNVXWc+MeZ4GiEpCwWHGjTwjJ3lz5Opn5LbLnIcDUtC9q2uXA6hdR+62kO2140fc+/eQQwBxKd/hfOVDJBByNwZvv/Ie9Vj7UEAcWq927bEJK44hb4pcfcW1zZTzEECq1V4ZONOGHpELvyG0m+SIfHaeYwtAiKudD0muLXdbpNpl7E712+12t75r170NIFeCxHqD1Ipiljir+D1+3rVtBcgVIEndErk2rxhm8U8J/v7b7W59p+J5m2ed2wGyOyQEw843CBcyL1vhkH58DF62QrIlIDtDkrstZLtVADP5cQHLshS+tS7H4XXL2rcFZEdIrDcH+VkOfyYfLtzacgoabSxtDwKQwi/LaJt3dH/p8Wr1G0QTsqefg6LFaWcYgCwCSAkOebNohz5bvyZiTz+Hg8parLYXAcgigEgISnXt0Gfr10Ts6Q9A6MuF4TWbCFryKcGQulla5jo61iN+zdcLB42nrXeqG4Qna2Ag68LH2aGcgiAHzWrr1URv6ZdgoG6J1fZrCkC0JKnf+rKMtZKPBw6CZqW1Ua4WEed8AELK5mJku7ZfpwKiJSf7U5BIn5nqXnH38J9p/ZZcpGC1egoG2aaNwfu1HE8DREtsxX76BNfePSDY5fGKzpiLVStLEGRdi0/1azo7BRAtqZX6c2I9o32lfUOuKdHm2iQQqOf8tXbkULIBSOUf82o3hbe/x81SOuhZ+zQR834AAcv7vGXrfhwOiDWxWf3OuBks8My6X1peXmH38s/lxccnnyH/cFzqyzTaconN3u69EXr5W+AAtLPvYSo/Lsijyqk80PaUAzog4NEW861iIb6V7Cp7S3k+CdLxW4I1sdrePI3JA0bDQePz+WYu97oBeo9juVFm3leZ25MgC4DguwesJ5Z85dy5+sO4KaeRoKTmm61NitoiyhlvmNn2NZXPgxgLcJAfwID1xKbmLrV9jF1yulqfBGOleg7iFc7wQ4yDAKndg7e8aoN3ivOCkBPjrO0rnJUFEtwcZC3+Pdb98P+D9BhwtTG8cKzmD2hXOBeL6C0+Pdd6WUBGCB1inNH2FM3osSwQ5Hx653ZJQEbAscKYvcUzerwcBKn2UblcDhD6dP/rzz/enmGlqKl95Pvsm2WUiFYcl0NWyv8ygECcJQAIGPjlLKBCv6yjXdrUvIg90pbEcKU+DgiVc2u/BCAQqxQptefeJFrEjbAyl9HzYfycEK7WLgFBXe7D9oCQuLkYa8WOT3nEoy4t+qWFn2ynOs8PfiOtFMFV64BCWr4fWwPChUdlEqP2JmFyH9RHW8zJc6a2EfNyAexU5kK3rovHyDKNsS0gXGiAo4fYaIzUG2JGH+otFmvAmL2sVTyr+aUEbl2DjP2oWwdYyQ/C4pbElRIrtaXac/68HYKtjU/FIR9usY6UP8/H07/SeVpz/RA1+5EVayz5peK3vUFIOBBWjYik+FFvtR4Ry7yxHrKteXiEs5JvSuTe/B/G8Aav4k8CgqBaRClFOqpOOfI8UU9ZrAuWx3nyW+UsvXk+CPznbeIdg/zfxqkJXCGGRAMBeUQjxUaxPd4YF2Oh3mr5GjG21a5wjrU5doOkNoHZ40gkEE+rCBEP4Vnr8GuxFMvjc3WslXLk/qX67GfYml8KEmrzjHuZ7yBWccPvKGsVs8UPkJC15u8Ry4q+rZBcAhCLuEhQVr+c+BCPftR7WBqDj1OqAxRLHiuK3ptzCySXAARC4RZi420jy/JTXc6Pei8rIcmtzSu2lf1ToGjr2RoQEgUJpVZ0EBXiUfdaKVaMN9piXrI8Zz6vJpDd+r2QbAsIHSyJQoqDC+WocimHUh/lBzEjV2+d4miO0jy7QaCtxwPJ1oDQRnFheMUl/SFSq6V4Lk6MB4s+1EdazMX3A+vQBLVjvxWS7QGBCM6yKUEil1IffGABj7UOP2kBCm/fEQDLmiyQbA8INooL4qhyCQDelxM/2mst1ol41CUk2KMrWg2SywBChw+BHGGlCPmcHA7efmSZ53BFMPiaS5BcChBsyhFC5AKU8+X65Cf9yDrlgDywL1e2OUguCQgJQYq2Z52LT44LUcr2M+qUy0vF/2to+adpV4QtBclpgPB/Je+szRwlyhwEufZReWjj1gBigYP7eM+Wx3rK3nly/k+Q5BxHtnM4UB45n2VsTUzW/hwE1J7rs47dy49uDXp7AfEIVvpqZyD9a+vaPJb+B0gsAb19AAW3veeoHa9FhDkIcu0tc9XGAo5fgHw1/XRrrWB5XOpMeH/vcmo+T9sbKJ6AXr4cDJR7jd1zHK8IczdErt07fqs/h+Ply9f7y1cbHLSnvV78fHqNWRqHz1dTPuU7CKDgtib5o2IswuS3hCxb4kf6PIJBj1cEx+v95fXVdHvQPvd89R5Py61FJwGI43+5LYkYUMDS9YxyKW5032xwaGIe0R+AOETeslkyFuIGCCkLnzPsIxzvj1TvN8c3881Ba97hJc/OWo8bpAGuFBCy7QwwaM4kHK+v95dv3+8v339cDhCC3AoF9wtABgIyDxzv3zdq4CCx7PLiwreWpwGEvrBbk57BT94Usp7K8Qhgnm+OX3CkcrK07QIIrcOyXu4TgGRuECl4T51vsKXcC5wUHJb5Sz47wbEMIHQg/I94ebl0WEf1AYZ/P326l97wk7ZHnl5oOByt8+8GhVyPZ39OuUEoQQ4FL3uSH+FLYi9BIftGwDFiXdqYUkQ717W94P2nAUJJcDB4mSd4ZNkLB2ABJEfm2jLXzuK3rM2zdwHIz+8gEDlE77UU79n4I3wtYrmij2fvTwWEEuU3B8qeBfTyrb09ANIMgFxR7N41e/VyOiASEu8CevmvDohXKFf19+plCkC8SY/wD0CugYxXOwEI+w6Cx6Uae/Yj1jXkXbdKLxTcPwDpAMjZcNCBxiu/A1zw3vI0gOALOlnvInr5k9C9j1qI6ZVD7Th5eURP7Z5S3BSAcDhQbllUayxEn4OF97fO1Ss+MEjvQOv+BiCZn8XCxnIYUEbfTDYtj2htPaMARAGkdYOPjN8VB+yhd32Ia7FTAEILwKPVmd9BWjZyhlivgFbwl/tqzVnG1danAaR2ARFX/h0Hq6Bm9JvhbAOQjR6xrILqBQPm6zWeHAfjn2kDkAsCMkJwUtwt9RH51Y4ZgAQgp/29U61oj4wLQAKQAKSggf8BsnyFPjzLbzcAAAAASUVORK5CYII=" + }, + { + "name": "UFO Evasion!", + "description": "Were you good enough at flying to avoid the UFO?", + "choices": [ + { + "key": "choice 4", + "name": "No, Back to flight school with you!", + "exit_node": "FAIL_DEATH", + "requirements": [ + { + "quality": "UFOs Violently Crashed Into", + "operator": "==", + "value": 1 + } + ], + "delay": 0 + }, + { + "key": "choice 5", + "name": "You barely avoided them! Nice!", + "exit_node": "Tractor Beam", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Tractor Beam Turns", + "value": 2 + } + ], + "requirements": [ + { + "quality": "UFOs Violently Crashed Into", + "operator": "==", + "value": 0 + } + ], + "delay": 0 + } + ], + "image": "default" + }, + { + "name": "Tractor Beam", + "description": "Before you have time to think, your drone is captured by a Tractor beam! Now you've gone and done it.\n\nYou should have some time before you are pulled in.", + "choices": [ + { + "key": "choice 6", + "name": "Decipher Garbled Transmission", + "exit_node": "Deciphering Transmission", + "requirements": [ + { + "quality": "Garbled Transmissions", + "operator": "==", + "value": 1 + }, + { + "quality": "Tractor Beam Turns", + "operator": ">", + "value": 1 + } + ], + "delay": 30, + "delay_message": "Decipering..." + }, + { + "key": "choice 10", + "name": "Look at the surface of the planet", + "exit_node": "Looking at the Surface", + "requirements": [ + { + "quality": "Tractor Beam Turns", + "operator": ">", + "value": 1 + } + ], + "delay": 10, + "delay_message": "Looking out window..." + }, + { + "key": "choice 13", + "name": "Let the beam pull you in and dock you", + "exit_node": "Landed, Kinda", + "on_selection_effects": [ + { + "effect_type": "Set", + "quality": "Tractor Beam Turns", + "value": 0 + } + ], + "delay": 50, + "delay_message": "Getting captured..." + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAIOUlEQVR4Ae2dW5JcNwiGewdZQNbgbcTbyFM27ZXk6aTkmDJDIXSDIySYqi5dQQL+r0/PeGx//vnxPPnKHKQGeA18SmJqX5k0PmmZlzh5+dTgoPMpijiiyFr/rnU3IBSYMs5EZg5u18ASIAlNApKAcBRMzN2eyIzvzjcL9SfICDspqjtFdVNdtwKCYbopqRnLb/BxjXH/lBy5AQQnr/RPSWD0e9K69Y5PyZtbQHCie5KJ95d+j03uGc8TzfPs+JTcHwEILgJNLF5r9altjvsBaeV2dP2U3B8HyGgh6P5TCuPpnjSHGmNP8Ul3SUDyd9HEj6MaMHA+JFF6WktAEhAWEE7UmnOeIJDukoAkIF8A0YRA8iWJ0tNaOEBK0TwVwNNdJEFrr3mKW7pLApJPkJ9vGNoAtPxJovS0loAkIAmIoIEEREiOp3cy67u03vG9rFvngfoPBwhNQI7//57MCwAr97CoZQKST5AtH7FWQBixXYUmFCCrybrZfkR0J+8dreH1gIwmJOr+k0W/cvdWva8EpBV0rvN/FrQitNtsQSPXAAIBZcuLvycvt4lcIx7x38XSOMDKR0/Bc88YLFa1OtnvT0BASN4CgXtlOyb0lXx508Du+3wBBBL7xqXgrFPbv75/fyxfu/LyRu1POoMFBIpjGQiccVJrCUTL95t5sqz7ab5FQKAo2kGB31PalnjfXn8jb9o1P9VfFyC0ILPBUj/ex28Lf/Q86/zN1vkmuylArAuz2/+oUL3t18yfpdjLPb1/JSDod7G8CX31PhqgaAuY3knbv7a/BOQXIKti9GpPBTkzXhFdz3kr/q1tE5Afj/jj2m/fvj1Wr7eg6hFpa09LiC17ab3le+d6aEA4gVrB0OuXu5PGnCTQ3Ws7AWidHRYQKrpeAe/YR+86O94NgnR+S6i71sMBUhPXDuFrnlmLC89LAvWwtgsC6dxQgGCx4L6mUHf7wnFxfQ8g1O4gCXXXWhhAOLHsFrPl+Vy8Za4mTk/zu2Dgzr0eEE4olsL04puLG+Y8wdBzF064b81dDQgIgrZeRGx9Dxo3jHtE6XXPG2Dg2K8FBMRAW2tRevJPY8djLIIT+1qgtGK/EhAsBNr3JGDru9DY8bgljFPWR0CZiek6QLAIuL61KD355+KHuRmxRLS5ChAovtR6ErD1XaQ8RBT7TMzXACKJga5ZC9OLfxo3Hs+IJaLNFYDgwvf0vQjY8h6tPEQU+0zMIQEB8VgKdLdviLHWzoglos3xgNQE0Jp//vzjgZemmD+fz4Nfmr57fbViL+sRxT4Tc0hAAAzNFkPB9XvFvbKvBwzYMyOWiDZHAwLFHmk1ocC+OCjwHN5r1R/JQ0Sxz8QcChArYWIQpL7V+eA3AdH/FyjDAAIismglKPCaxdngM+HQh6M8cY4FZEQQICKrFkMg9a3OL35H8jHzUSOqTQKCfpo1K2AJCrw267/HLgHJJ8iXH02OCKJHYKt7MAhcf9W/ZD+Si6hPgtm48wmi8AQp4uWgwHOSwFfXEhCbp0eBKgQgRUCrIuy1x1CUfq/dyr4EJAH58vGqkD0iCrp3RYwebWl8tfHsx4zIdmGeIDXReBT86J1qsXHzkcU+E/uxgJRgOQFozI0KdOf+mXhnhBLVJgHp+K/UdgLQOnsGkGITVfCjcR8NSAl2ViBadi0BW66vxjAqloj7jwfEAyScUD2Dge8bUfQjMV8BiFdIsBChvwoO+NFsRwQTbe/RgPz79/Pgl6ZoovmKJvzeeI8EBEPB9aOJWzPeXuFE2XccIBwQdA6KpymcSL4gf9ke9qsmFARpTIsbSeCrsdLcRR4f8wSRYODWpKKuCiiCvZS/SGtHAMIB0JqDItJ9ME/bCKIfjZHmKOLYPSBU4FrjVrFHxXTr/laebl93DYgWDJyflcJ6gIHGZHmnlVydbusWECoAi7F28SxFCr5beYB92q12rk7x5xKQlgi01nuKRM/qsaF7tMRK78KNtc6ifmhMUcahASkCqxWaEx+eq9nReWwjnUft6Jj6kcZU3FpjeqcIY3eASIW3WKsVuXVWzQ7mV+3BT2lbvui6FhCcH3yvCH1XgNBCvzXGhR45E9vRfssP3c+NWz5q65ywNee4u946l4Cgj1k1wdXma6Ko7afzq/bUH4w1YeB8wf8LWLv/TfNuAIHi7mhLQWfO5YQw4ofaj9jW9nKCtpgDSHBL47lh7AKQWrG9z1MBjN4X24/a1vaDTwsosE8MRq0Pdzm53Q5IrdAnzEPhZ+9a7GdtOTu4D7RY0Bb9Ghi1ebjXSe1WQLginzRXCu3lvpzoilAtwACfNRB657k7e5tLQMjfSuwV/AlwgFBB0Not+NdqvcFR7rMNkF4h5j75KcWJihOsNhzgjztLY46La8fcFkBS9LLoe/LDiaUlTBC1Zts6U2udi/eNuQRk8iNWj4gt9tRE0SNETTDAV8+5WntqsVvOvw6IhWgi+JRE0CtAELVm23u2xj4pB1ZrrwISQcgWMUrFrwmP3gP2acJRfL35JeXBai0BcfwRSyp6TZgUDDo+DRApB2+svQYILVSO5W/Ua8WvgVHme3LqHZBa3LvmExCHTxAJgtpaDxywxyskuyCQzn0FEChMtvK7fE38rfnRvCYg9b8oR2ExB2S0eFH3tyCorc/kyyMgVJhexgnI5o9YNeH3zM/AUWy8AeIFBu4epoDMFvBtu5KYt88s5618zd63nKkNSPG38sUJ08tcaECgCLNiW7FbEdTquZ4AgRp4bcMCgguyIrhR2xUwiu3oeXg/nJ2AOPkmHRfHU/9EOFbzB3BA6wUSXAuP/f8AHPtbaN2iPfwAAAAASUVORK5CYII=" + }, + { + "name": "Deciphering Transmission", + "description": "You review the incoming transmissions your drone has gotten. These aren't in need of deciphering, just un-garbling it from the bad connection...\n\n\"You are in Space British Air Space! Identify yourself, Tally ho!\"\nWhat the fuck?", + "choices": [ + { + "key": "choice 11", + "name": "Whoops!", + "exit_node": "Tractor Beam", + "delay": 0, + "requirements": [ + { + "quality": "UFOs Shot Down", + "operator": "==", + "value": 1 + } + ] + }, + { + "key": "choice 12", + "name": "Good thing I didn't blast them, then.", + "exit_node": "Tractor Beam", + "delay": 0, + "requirements": [ + { + "quality": "UFOs Shot Down", + "operator": "==", + "value": 0 + } + ] + } + ], + "image": null, + "on_enter_effects": [ + { + "effect_type": "Add", + "quality": "Commercial Airliner Transmissions", + "value": 1 + } + ], + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAALM0lEQVR4Ae1ddegGSxU9WBio2AjPFluxAwvEThDFVp74nt1iYHd3FyZ2Yj1FfehTEQPrmYiFYmF3Xjmw+1jnN3NndnZnv+/bPX987Lc7s3fuPffcuzGxAGD6CQNxIMmBZIECR8lDHFDmUIIQB1wOuIXKILqKbJ0DChBlUHHA4YDAccDZevaU/SKHEoQ44HLALVQG0TPI1jmgAFEGFQccDggcB5ytZ0/ZL3IoQYgDLgfcQmUQPYNsnQMKEGVQccDhgMBxwNl69pT9IocShDjgcsAtVAbRM8jWOaAAUQYVBxwOCBwHnK1nT9kvcihBiAMuB9xCZRA9g2ydAwoQZVBxwOGAwHHA2Xr2lP0ihxKEOOBywC1UBtEzyNY5oABRBhUHHA4IHAecrWdP2S9yKEGIAy4H3EJlED2DbJ0DChBlUHHA4cDhgnM6wI4B7MKAneUAMv0ZALtA9zvTAehL0pwdsEsBdj3AbnAgOjtkr7kaHkaAXAWwxwB2EmDfBex3gFnw+ztgPwXsU4A9BbAbAXbGHTn1OoA9FbDPAfZ9wP4Y6Erd/wLYTwD7aGfbdQE7dUN9T9MllCsDdnPA7gHYYwF7KWDvBuwzna5/juhKfT/YULeZSV0TCKlz9jdALgPYazvSh8EwZv91gF11AedeC7C3APabBMFKdP4XYC8E7JIV+l6sC0pi9iHAvgzYzwD7zwR9hjp/vkKnPSZ+KiDC4/sXIOcF7MUzOXXo4I8Axuw5t9MuAdgbG+j7dsAuOELfGzfQYYgfr4RzY3cA8vbL6EcC9o/Gjr73jI5+bmNdfwvYbQv15VVySOi5//++UI8DIP2YQN+fAHlBYwcPCcPbkKmO5O3UUGbL/88q0PeiC+gzFbMDPH86UeYw+m0LODck8PMLSBez7VyAfXIH+j48o+/ZFtAphsfKj+0+QD62gGPD4Oj3H5ohXej8MwN28g71vUNG396uVttTZdoP8VrB/m4D5GU7JFtPIr5eLXXke/dAX/b7pPTtbWq1PbfTdkqnAz+eBru1YQ/ZA7KRSB8udPqz90TfVzr61gQG+46eDtgjALsnYLfr+pCuBtjFAWNQsFO2NR/2VP5uDL/6npCtJ9RNMwS4zZ7pe9mEvn+o0PPbCVl7StilA3U3AfKeCkf2ZG6xZe+7R4gv7pm+b07o+4MKPRlUnu0bL1seHI7rmYvkqWERNfLPmiDK3WbUl/0aNbqF5/w8oeuXKuWfpxvTdjnArgkYbX4iYByF8LhEWxsJnOUD5IRKJ/Yk+R5gdwGMQyvoJA5U5P0ye577OjXbWyWI8M2Jcr/QjQ3re8XPAdh9AZuKw+Uj+nJcV43t3jlviLSzkeAgv5YNEGYqzxm5Mg5Y9HQmyf9d2UasX2Rq7/SbMvoeV6krcXpQRPZbJ8hLYf+BSDueD1ZW5hNubmPvOsGBHy901O0r2/h0RD5Hu6aIkztO8pfgx76YnKxYOcd/hfI5MjdWd8qxz0baCdtd8f5RkFsay4fLGmfx4XOMXiT72Ha+FWmDQ8DHymH93EN/aMuPK9qJvZ5+UoWcnH3fieAS6r/i/XHEmwoE5z/kHBIrf/JIJ3G4d0yOd+xXQRucP+HV98pKrx49ni+vaIvPNv35/Za3XZ5eNWUhLn1bG9keBbml4X+tdCDffI3R644V7fw3aIPD7msIxXMuFMjK6f7oirZiV9Upt7ApWzmfJKf/isuXM57jmFJOyB1nj+4YJ9y5sq3hDER2xuX0SpWP7Xmuedb5RQSTm03QOWULj4/BfmV1lzOeY4g8J3hl1x7ppIdVtPW3oI0p/TXnC2TlSFPzcB3rAb9Ghd0e7n1ZTv8Vly8XIJx51wM+dpt7vRs6iG+8xrbB6alDOVNm6LGfZigr95+z9cbqG3u7xCvtWDkl9cdeEXP2HlD5OEdOMYwrZJQ4I1aHnYOnLyQdR+fGZOSOcRj70L4rVsphOycGsoZyw/93qmwn1j9xzkpZOWz4PBbqvZH9ZQ3/5wQHvr7ASefvFivIOTxW/opAPpcUitUrPfbMQF6MUJwj/8vKdjg9OZTJ+Rql+o2pd+lIW2HbK90/CnJLQzm0eoxjwrpcnoaZPaYje9F5pQnPKd0P537ztqL03FQ9Tu29SEJfjnfiPO/UubnjqZVacufVlI99Boz550CPxcnWyph3TiDE0LGcD853/hyGzlek759BLsdIhXazr2HYbu1/Xv3uAxhnBD6h60islcXzvL6JKXJ5Lm3mMxyT0au7cWRXimATYrXS/aOkaGkoFyub6sAW5zPgYnZzAboW7U2V+YyEvrSBC9LVyI/Zr2MO0C3A4TNCjfNan5PKkFwhsXXbY+VzcTlv6mvtaIUW/l6BzHjmbGnY1GHeYwmVq5+6evQYcIxWTsaS5d7Vgzp/tVJfrorS26ztKVic8mcxcK5f6cAWJPyT8xDdk+TYPdKXAwe5CHavW2z7iUp9Uy8TYm1s6JgPdisg+A6/BeHHyizt0KvNymP1ydUvGZNW+yKEC4S38vcBy90NKFcAbM7psjlixco5grbUcVzUISZjyWOlownYn1OjF1fDL8VjWO/+gL0KMK628oACGeztfxpg7+oW2+aKkEN5sf8PBuw1gNE2vg2M1Wl0bNHG/s8w9lvUOHKOc0o6HUPA77VDfUuWHu31JflqMMotStfLH25jK2K+wyEwg5Bj3ob68TbXuzLydfOwPv+nFq0Y6jbT/90FCA24X8T4EIy598dcOUKQ+c2PufXJyePiCaEe3n7NQE3qwHnyntyw7HgHi1SWT73w+Fqi7Qc6bfDZMNSpwf4ijbiGzLlqSI5sz5sB1FoC5nSLlceGk+RIUPtSgUPuc7KH5bxSxHTmMS7rNKzL/7ytTtXn8dhwFn60J3XOQleRo4aEhi2xz6EMP3LASIFUepxDUGpuIVK233pCh1yJzuzNvkmEZCl9hsdrb11ji1YM5Yb/PfLyVX5Yn8sJebbHXhJ4i4THgjBsc4b9o4bMIPQIOCUyueIJB/ixI8wDcmxZq3WduOxQ7QNxygZ+Wq7kQdfDk1+6Ssn3jo9d3ufxTjuxKdIc28bP5MV04HNIzCbyIVafxx6VOCcmZ8KxuGITBEYNHSOvD5QfOuCkQOuPc30orhbiLfQ8Rievbh8onOHXtz9my2nI7+vezszRWcePbo5pv68bGz7v2c0yPjv05/fbcNrAUAafTfp6wy2HIA3r9f/5zUZ+k3JYl/+50mVfp/F2sYaqDOK3+vhFKN7vcqUQLuLG4eGcJ80Be18HjJ9P4BI4XFyatxe5jrSWgPI+m4tyk/BcEYWz/n7dOZirIX4FMH4KjisWcsHoGzZwNBMMX6EzwfBWjauf8OrwnG6B6rsDdgvAuD4yOwenfCGYBH5R13tP214C2GkzNt2y+4Yi/cigzK2LTH/yxco3uqkMY28FJ/p7vwNkonFVQak2xYkBBwTGAAwFVCb7bxArBcgGna5EUJ4IFCAKEHHA4YDAccBRpi3PtGvFSgGiABEHHA4IHAectWZF2VV+ZVSAKEDEAYcDAscBR5m2PNOuFSsFiAJEHHA4IHAccNaaFWVX+ZVRAaIAEQccDggcBxxl2vJMu1asFCAKEHHA4YDAccBZa1aUXeVXRgWIAkQccDggcBxwlGnLM+1asVKAKEDEAYcDAscBZ61ZUXaVXxkVIAoQccDhgMBxwFGmLc+0a8VKAaIAEQccDggcB5y1ZkXZVX5lVIAoQMQBhwMCxwFHmbY8064VKwWIAkQccDggcBxw1poVZVf5lVEBogARBxwOCBwHHGXa8ky7VqwUIAoQccDhgMBxwFlrVpRd5VdGBYgCRBxIceB/bK6VghmpUw0AAAAASUVORK5CYII=" + }, + { + "name": "Landed, Kinda", + "description": "You have been locked to the surface the beam. Robots are all around you, pointing at your drone with all sorts of old age weapons.\n\nOne of them angrily shouts at you, \"By God, Queen and Country, we've got you now!\"", + "choices": [ + { + "key": "choice 14", + "name": "Go out with a bang. Initiate self destruct!", + "exit_node": "FAIL", + "delay": 0 + }, + { + "key": "choice 15", + "name": "Surrender to the funny looking robot brits...", + "exit_node": "British Courtroom Start", + "delay": 50, + "delay_message": "You are being transported somewhere..." + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAIT0lEQVR4Ae2dvY5dNRSFzxsg0dKNBBLFKAiJApSKglREoqSDhqFAQihNChoKAiONlCISBUqRnlfhDXgRRGNkyI7W9dg+23/Hx/YqLO9jb/9tr+/Yc+9kst0+uzVMjAE14NfAxsD4A8O4MC5WAwSEJyhvEBENEJBIcHiK8BQhIASEJ0hEAwQkEhyeIDxBCAgB4QkS0cBygHzzlzHaxBOEJ8hSgGjBQD9CsjYkSwKiET0hWRsM0cgygOQIPqeNBPboHOfq2kfPZabxlgMkdfNQbKltW/vj3DR26/nM2D8BiXyCIRuO4pOy3jnOSWzfnKTO5r56lsWvkssBkisUEdoZBCVz0a5F/M8w99HmsAwgdmNEKFph4WaWtMV+Su3UeaT6l85vtvZLAWI3DwVj7ZQNlbYpbWr6yvjaeaf615zrLH0tB4jdOBSOVmxuux4CkHlrxhbflPVp+l3NZ0lAZJNRRGJLXSgXv6OFpx0X/Y6eYyhmI5cvDYjdOFdQ8hzbVI1PrH1O3d6YUo95zjhsc/mp1vKAoCBQXGijj7Wlzi1v9Szj2dwdA+vEdn34fCn6lHgQEM/3ICI0X26DK+UpgS7x9Y0nZZiXjMG2fogIiAcQFAsK0LXRr5WNY9ox8FnsVmOzX/6b9HtXlpgoRJCSx3xr1clYvrzWGOzHf3rYuHQ5QbjZ4Q1xxcpY6WPlxq7G8+GA+DbcLauxsFn6wNjMsqaR1tENEAwSigBt9KHd9026avxPAQgGHwGxNtbRJiRHa6AbIHviR1CODopmvM8ePTItk2YOLX0w/jG75RzO0PfhgNhFS8D3AiB+Nt/zPaK+JRB7fR+xPhkD4661pe1s+akBscHGDeoV/D3xHl3fKg4Ya2vvjYP+e76j1ncFRLMJNrC9NuJo4aeOV0t0GF+xtX2Lv821bUby6wKIDZAEdi9Y4of5XpvS+lShns0/df2lsZX2qeOO4N8dEBtcDJQEO5ajf037bEIvnY8mNhhnjb/rU9re7e9sz6cABIPss48IWqkYz9o+FjuMdczPV4dtre3zmaGsGyASPDfQPYJ9VnHXmpfEGnOMO5aLjfV7trSZMe8OSI+g1hLeSP1gnPcEr63HPme1lwJkJEG3mKuImADofyNhe/DhR2YvSWBHzVuIbcQ+Zf8EEHlmHgZmekBGFHLLOROGMAy+2BCQhN+pur6+NpJExPIcysXvLLlPBCwLQ7P9/uqV8aW9a1fN+lYbVFuUIQhKymvPUdNfq3jP2C8BSThBzDtvGZtKgNC21Qg912dGIbda07SA5IrH107AwFwr9Bp+vjmVlrUS1Gz9XgCC16bHj380kn55/tz40t2LF0aSr96W/fby5Zvku8rZMhw3ZKcEvlQ80h6B8Nk1xJ/ah8ytNE+J58q+0wFSKhwfCHtlqSKv4V+6zpVFn7L2qQDJFc0eACn1NcSv7SN3vbZdikhW9r34mFeuVDb//sl3b9JPn3xh9tLNzY3ZS9gnXr3QxisWjonlvg3LEUuK8HN9tWLP9ctZNwEJf6zramsKQFJFkiv2Fu1ywXDbpcbAFQKf/dAsB4hG5Nu2GUyaNkf5uGDIMwHxC7wU/AtA8BrT2r66es9ICo3157YZSeiDi9YKQyNghMJna/ro5aONg/hhDGmH4SIgr7/8s8L2QYFlvcSvGVeEr80JRRgKjM3QgGjFoBEYghCzNX318tHGw/qhCGiHYdmePv3DSJIrz3/525u5kgTXoTdltq6kHNr+endnJOFV6p+f3zWS/v74fSNJNlQrCI1gY1BgnaavXj7aeBCQMBCiLckJyOsrFkIQs3uJf29cwqEXvYhfkw8LSIog9sRl62NQYJ2mrx4+KfHQCIM+/wO3PXz4lZGEV6ZvH3xqJLUoxz7xWoW2fIJlcyy3m5ciCK1gEQSfre2nh19KPCh+/WlDQCb4FItw6AWf+nIgIACIvPnd00PKz5oTkIaA4FXnSPvLr38wknJ+FytFFNb3rOKuMa+UWKS+QVf3346EAscSOGx+BCAoohqiPFMfuLaYvbrYc9a/JCAoojMJPXcuuJ49O0ckK7fZLr74ky8G3S8B4Us9fPOX2PipFNo4Hyz3bdKeGHLrc4Xao13OGn2xZJn/5xgCovijDT2Erx0zBxDbhkD4gXDjMjQgdjG5AqnVTivkFn6la3DFwOf70AT/Nm/oqlOrHK9P2GfOJpUKpUX7FkBInzXnmxPvldpMAYjdsJqiadmXiDw3bzG3lQSfutZpABkJkhYiL+0zVTir+G+fX31gJIUWjVeg0NVIUx7yCY2bW14qlpXb58Z81nZTAiKbtbLQS9Yu8WN+a6YGBDe4RDCrtcW4rW4HfwaZOTCrCT5nvTPvf8ralgTEF6AcEc3exhen1coIyLP7Xw5ZEcwufu36VgPCXS8BCQDiBgqfteKaxQ/XvppNQDIACYlkFiB86witefZyAlIRkJBYfIIbrSy0ttnLCcgBgNQQ0RmAqrGO0fogIIMAIsLqDYrMY5WcgAwGCAqzFyw4h9ltAjIwICjOI2HBcWe3CcgkgIhQjwJFxps9JyCTAWIFewQks4Mh6yMgEwIim9saFBln5pyATAyIFW5LSGYGQ9ZGQCYHpCUkIqKZcwKyACCExP8LqRqwCcgigLSCRCOykX0ICAEp+jllZPFr5k5ACAgBiWiAgESCo3nDjOZT+1Ot0dafOl8CQkB4gkQ0QEAiwUl924zgzxMk7RMtArIYIBZiQqKHhIAQkGJgRjg5c+dIQAgIAYlogIBEgpP71jl7O16xeMXi/6AUAb82ILa/s78UcufHEyQipNygnr0dAeEJMu0brQZ8BISAEJCdk5GQ6CD5F0cJWniQ8Kf0AAAAAElFTkSuQmCC" + }, + { + "name": "British Courtroom Start", + "description": "Wow, that took forever. A one eye judge robot smacks their gavel, and points their hammer at you.\n\"I will now read out the crimes you are accused of!\"\nIs that how the judicial process works? You dunno.\n\"ONE ACCOUNT OF PLANETARY TRESSPASS!\"\nThis blows.", + "choices": [ + { + "key": "choice 16", + "name": "That's not that bad.", + "exit_node": "British Courtroom, Continued...", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Crimes Committed", + "value": 1 + } + ], + "delay": 0 + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAJiElEQVR4Ae1cQbLduA18N8gBsppVVj6B9+MLzA1yn1z5pVBJu7owlAhQoARSUNUvkGADBJvop/dtz3z+8/PzrZ/ioHqg3QOfIqZNTPFSvEgPlEDqDVrfIE56oARyQk69ReotUgIpgdQb5KQHSiAn5NQbpN4gJRCHQL7Jn8/n85WfHZ+nPqy2EciOTeE9084C6XExS0DLCaRH1JvX3ywQ3Hu0UNILBAcv22cAAtn1a1afgW/4Hzg8IhDLQe/EoLF4z5aP1zOOUfMqAkG90VxGvkVuFUg0EVH5WhfV8kXtNyMP6oUd3QPxbM9yWXGcg2Mw5vWr4yUF4jk0SIP1xI5gsY9YefR8JOddMVwrjy37A89Y+NjyOo8ZgzGvt8bAadvCjvq2FYgmDfNRojxxvBePz3JYcbNyYP+Wbe0JnKxhLJYf+M8wwLewWGtZ4HlP+Fr4Ud9yArEeFGQxgdbYqzjeG+Nezhau5ZM88IvlB3749Bx+bYHjfOxjP2KxLnMeY73l7+GwD3CYc06MgcG8tR+vjY63F8goMVfjcIGwvXwtHPswblnkxpqei//s0XGChQ9Wx7Ofx4zTfszF8tPyw8c4HmO9ZRl3dVwCOWEQ5DMEPlhe4zHW2fK6HgMHP+Zi5eG59lligGlZzo119mE/rInV62eYVlzLxzmQn3E8xrq2jIkYLyUQz4FBXC8GOLH8WPw6huNlzDm8WI7VubCPxjCOx8AhrmWBObMcp3G8hjFjtA9zsVZcL4bXo8bbC4TJx5jJg08sHvaxX9Z5DfgjC+zROvuBbVngeE379JyxPAauZRmHseB4jDj4YOHXFuvaMo7X4G/5sCa2t87Y0XGkOCTX9L8H8RyUCdRjnYfXZY3nGCMGc7HRD3Ijr56LHz5tdQzWtR/zqxb5xfYexmLMMfDpXPAzlsdY13GMuTLeWiBCDAi0kAQsW87Bl8AYHlv28WCQW8fAD6vXs81Rp9jW01tvxcDHsTo/1oD12GhxTH+DeA4HrIcgYGF1jp5f1iMf7BedN7LGqFxXzsqxR2NvnTPEkVogEU0G8q1kj5KMfWBH84zGWc8XicNZr+ZEHraenKOcWeOm/Q7iOaTGgiztj55bSerhUK/YHvau9WiuMuW7i0PZZ4pA3krmnRc3ulemu7HWMnrWiLitBBJByFtzWJv1TlyGuwgXyEwCMxD2phpm3mUrd0ZuQwXSOrTVl5Gcs5r+/PXrO/PnbO9au+93vRQCWeXCZwqil3sVjnarM0wg1jcF41Yhs9e8d6+vwtsOdT4ikFWIu7vxvfutwuPKdYYIhN8KvfEKZHkbNRt+BY5XqfGyQHqC4PXspGRr9Kv1ZOd7hfpuEcgKRFxtxqzxK3CfucZLAuG3w9k4MwFSW9bmjqorO/+Z65sukIyHj2q8lfJkvIcVahoWyNkbQ9YyHn6lhp5Ra8Y7yV7TFIFkO/SMZlsxZ7Z7WaGeIYEcvT0yHnjFRp5Zc8Y7ylxTmECyHjKy2X78+PHFD/JifmSBy2Kz3lPWutwCab09sh4uuimPRHDFH12jJV/W+8pYl0sgK4lDyLY0iwdzRQjeWE9dXmzGRsxak1kgbxSHt6ln4b0CsOCzNmS2ukwC0eLIdghdj6VBLJhZDX8lr6VuC0ZzVvP2f2PiFkh2Ii3NcYb5/vMfX8vPlSaPiD07g2Ut+z1mqc8kkCzF9uqwNEYLYxFEDxPR9N4crbNYfT0ua/1/b5RtBGJtDMb1mj5i3dv0XjyfxzMuAbS/UmlethCIpzEEG9H4UTm8gjjCeznQjVDztmBeJxBLY/P/CE7Glpi7MCWQdiPPEvjyArF+cloaWAtDzy05nsJYeQBuVkPtlrcEQn9qpQWh5081v2VfNL7V7tbIs86ztECszWBpMC2Go7kl11MYKx+Cm9VQu+Utgfz/DXIkCO1/qvkt+5ZA4n8/KYFsIpASR7w45G24rEA8DWH59NVviqO5JdcTGA8fu30NmnmeEsgLf0mf2VC75S6BbCCQenvM+XolYi+BkEDw1Uh/vYI/qy2BbCSQf//r88XPldexpykEm7W5I+rycHGF8zfG3vIGgSC0/euPz1d+Roj3NIXGRjRlphz6fEfzEZ7fHjNdIFoUMocwYEcu4agJvP5MjT5ai+fMI1y/OWaqQFgcEMOZ9V6EpzE82NFGfSLOcy5gvTy/GT9NIF5xiHC8F4ELn22faHzrnqNn93L9Vny4QKTRR8TBbxbPZYw2SFSctZFn4K6ewcPzW7EhAmFB6DE3vnXsvYyrjTIjfoYgkDOyXi/Xb8NPE4hVDEc470VENs3MXGjyUTujNi/Xb8JfFshRg1/1j1zCjOZ5S84Rvt8Qk1YgIrDRC3hLU8845yjnu8ZtKRBc1owGekNO8Fc24N9iXf0qdRYfeUFvaOyoM0byvnquy28QIeCsya+szSI3qpF2zjOL+9XyhghkRZHoi9q52UfPpjl64zxMILNE8tSljDbVbnFP8Z9l3xLIT/+flu0mgt55sjTrE3WECgR/i37l945W7BPEjOzZa7SV10f42CFmikBEKK1GH/WtTvTKwkDtq9/BaP1hAkHzv/0tMnoRvTg06pO2V+OO6yECgTjEQiDRbxHJveMFeM/0pEBkb2+9q+MvCYSFwWOIhH1R49UJj6z/KbFEniF7LrdALM1vwYwKJjuhT9V3p1ieOuMT+04VyIyvWSKsJ4haZc+7hLIKH1frNAsEn/h4O/SaHzjERdurB985/g6R7Mwfn60rkFZjW5rfgmnl7vmQlw9R4/ZbdbZQ3sD7oUDOGhVNKvYIB8zRusePXGzfcDkRZ5wpkoj6suf4LRBuWDQi+/S4h8G6EKBjrXPk0FbisxObqb5ZIsl0xlm1fFrNioZsrcEHjFj42HLB7LeMOTfGHMe5a2z7sCiR2HjS/TQsEGnYVvOKX28ic27wszFywjK2lbd8bb5bvMwQSWufnXyhAukRw83eGkMUYmW9l6/WfRyVQHx8SX+dCgSN2mpm7bM0q47BnIUhY0uuwvh5KoH4OWsKRBoXTYsmPrPeZkUu7MHWm6vwvkuPFsnu/F8SyFVyShi+5r7Kt8SXQHycuwUScUmVw3dJkXyVQHzcHwoEX4PERl5Q5XqezxKJ/Q4OBVKNbCdxNa5KIPa7/ZtAVrvsqtd+2eCqBGLn7LdAQF5ZO3mrclUCsd/x73+LteplV932ywZX0QKRfMi9my2BDPx/sVZvghKI/UOlBFICCfm7kdU/NI7qL4G8UCDSDPUWsb1F/gs9r28akoDJcAAAAABJRU5ErkJggg==" + }, + { + "name": "British Courtroom, Continued...", + "description": "This big idiot they call a judge just keeps piling on crimes. With each one, some robot you'd like to drone-punch gasps in the back.", + "choices": [ + { + "key": "choice 17", + "name": "\"INTRUSIVE SCANNING ON OUR CITIZENS\"", + "exit_node": "British Courtroom, Continued...", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Long Range Scan Report", + "value": -1 + }, + { + "effect_type": "Add", + "quality": "Crimes Committed", + "value": 1 + } + ], + "requirements": [ + { + "quality": "Long Range Scan Report", + "operator": ">", + "value": 0 + } + ], + "delay": 0 + }, + { + "key": "choice 18", + "name": "\"SHOOTING DOWN A COMMERCIAL AIRLINER\"", + "exit_node": "British Courtroom, Continued...", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "UFOs Shot Down", + "value": -1 + }, + { + "effect_type": "Add", + "quality": "Crimes Committed", + "value": 1 + } + ], + "requirements": [ + { + "quality": "UFOs Shot Down", + "operator": "==", + "value": 1 + } + ], + "delay": 0 + }, + { + "key": "choice 19", + "name": "\"AND WE HAVE PROOF YOU KNEW IT WAS JUST AN AIRLINER!\"", + "exit_node": "British Courtroom, Continued...", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Commercial Airliner Transmissions", + "value": -1 + }, + { + "effect_type": "Add", + "quality": "Crimes Committed", + "value": 1 + } + ], + "requirements": [ + { + "quality": "Commercial Airliner Transmissions", + "operator": "==", + "value": 1 + } + ], + "delay": 0 + }, + { + "key": "choice 20", + "name": "\"THE TRANSMISSIONS WERE NOT LEGIBLE AND UNTRANSLATED. WE CANNOT PROVE MALICE!\"", + "exit_node": "British Courtroom, Continued...", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Garbled Transmissions", + "value": -1 + } + ], + "requirements": [ + { + "quality": "Garbled Transmissions", + "operator": "==", + "value": 1 + } + ], + "delay": 0 + }, + { + "key": "choice 24", + "name": "I think it's done listing crimes, thank god. Time to argue my case.", + "exit_node": "Verdict", + "requirements": [ + { + "quality": "Long Range Scan Report", + "operator": "==", + "value": 0 + }, + { + "group_type": "AND", + "requirements": [ + { + "quality": "Garbled Transmissions", + "operator": "==", + "value": 0 + }, + { + "quality": "Commercial Airliner Transmissions", + "operator": "!=", + "value": 1 + } + ] + }, + { + "quality": "UFOs Shot Down", + "operator": "!=", + "value": 1 + } + ], + "delay": 0 + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAJiElEQVR4Ae1cQbLduA18N8gBsppVVj6B9+MLzA1yn1z5pVBJu7owlAhQoARSUNUvkGADBJvop/dtz3z+8/PzrZ/ioHqg3QOfIqZNTPFSvEgPlEDqDVrfIE56oARyQk69ReotUgIpgdQb5KQHSiAn5NQbpN4gJRCHQL7Jn8/n85WfHZ+nPqy2EciOTeE9084C6XExS0DLCaRH1JvX3ywQ3Hu0UNILBAcv22cAAtn1a1afgW/4Hzg8IhDLQe/EoLF4z5aP1zOOUfMqAkG90VxGvkVuFUg0EVH5WhfV8kXtNyMP6oUd3QPxbM9yWXGcg2Mw5vWr4yUF4jk0SIP1xI5gsY9YefR8JOddMVwrjy37A89Y+NjyOo8ZgzGvt8bAadvCjvq2FYgmDfNRojxxvBePz3JYcbNyYP+Wbe0JnKxhLJYf+M8wwLewWGtZ4HlP+Fr4Ud9yArEeFGQxgdbYqzjeG+Nezhau5ZM88IvlB3749Bx+bYHjfOxjP2KxLnMeY73l7+GwD3CYc06MgcG8tR+vjY63F8goMVfjcIGwvXwtHPswblnkxpqei//s0XGChQ9Wx7Ofx4zTfszF8tPyw8c4HmO9ZRl3dVwCOWEQ5DMEPlhe4zHW2fK6HgMHP+Zi5eG59lligGlZzo119mE/rInV62eYVlzLxzmQn3E8xrq2jIkYLyUQz4FBXC8GOLH8WPw6huNlzDm8WI7VubCPxjCOx8AhrmWBObMcp3G8hjFjtA9zsVZcL4bXo8bbC4TJx5jJg08sHvaxX9Z5DfgjC+zROvuBbVngeE379JyxPAauZRmHseB4jDj4YOHXFuvaMo7X4G/5sCa2t87Y0XGkOCTX9L8H8RyUCdRjnYfXZY3nGCMGc7HRD3Ijr56LHz5tdQzWtR/zqxb5xfYexmLMMfDpXPAzlsdY13GMuTLeWiBCDAi0kAQsW87Bl8AYHlv28WCQW8fAD6vXs81Rp9jW01tvxcDHsTo/1oD12GhxTH+DeA4HrIcgYGF1jp5f1iMf7BedN7LGqFxXzsqxR2NvnTPEkVogEU0G8q1kj5KMfWBH84zGWc8XicNZr+ZEHraenKOcWeOm/Q7iOaTGgiztj55bSerhUK/YHvau9WiuMuW7i0PZZ4pA3krmnRc3ulemu7HWMnrWiLitBBJByFtzWJv1TlyGuwgXyEwCMxD2phpm3mUrd0ZuQwXSOrTVl5Gcs5r+/PXrO/PnbO9au+93vRQCWeXCZwqil3sVjnarM0wg1jcF41Yhs9e8d6+vwtsOdT4ikFWIu7vxvfutwuPKdYYIhN8KvfEKZHkbNRt+BY5XqfGyQHqC4PXspGRr9Kv1ZOd7hfpuEcgKRFxtxqzxK3CfucZLAuG3w9k4MwFSW9bmjqorO/+Z65sukIyHj2q8lfJkvIcVahoWyNkbQ9YyHn6lhp5Ra8Y7yV7TFIFkO/SMZlsxZ7Z7WaGeIYEcvT0yHnjFRp5Zc8Y7ylxTmECyHjKy2X78+PHFD/JifmSBy2Kz3lPWutwCab09sh4uuimPRHDFH12jJV/W+8pYl0sgK4lDyLY0iwdzRQjeWE9dXmzGRsxak1kgbxSHt6ln4b0CsOCzNmS2ukwC0eLIdghdj6VBLJhZDX8lr6VuC0ZzVvP2f2PiFkh2Ii3NcYb5/vMfX8vPlSaPiD07g2Ut+z1mqc8kkCzF9uqwNEYLYxFEDxPR9N4crbNYfT0ua/1/b5RtBGJtDMb1mj5i3dv0XjyfxzMuAbS/UmlethCIpzEEG9H4UTm8gjjCeznQjVDztmBeJxBLY/P/CE7Glpi7MCWQdiPPEvjyArF+cloaWAtDzy05nsJYeQBuVkPtlrcEQn9qpQWh5081v2VfNL7V7tbIs86ztECszWBpMC2Go7kl11MYKx+Cm9VQu+Utgfz/DXIkCO1/qvkt+5ZA4n8/KYFsIpASR7w45G24rEA8DWH59NVviqO5JdcTGA8fu30NmnmeEsgLf0mf2VC75S6BbCCQenvM+XolYi+BkEDw1Uh/vYI/qy2BbCSQf//r88XPldexpykEm7W5I+rycHGF8zfG3vIGgSC0/euPz1d+Roj3NIXGRjRlphz6fEfzEZ7fHjNdIFoUMocwYEcu4agJvP5MjT5ai+fMI1y/OWaqQFgcEMOZ9V6EpzE82NFGfSLOcy5gvTy/GT9NIF5xiHC8F4ELn22faHzrnqNn93L9Vny4QKTRR8TBbxbPZYw2SFSctZFn4K6ewcPzW7EhAmFB6DE3vnXsvYyrjTIjfoYgkDOyXi/Xb8NPE4hVDEc470VENs3MXGjyUTujNi/Xb8JfFshRg1/1j1zCjOZ5S84Rvt8Qk1YgIrDRC3hLU8845yjnu8ZtKRBc1owGekNO8Fc24N9iXf0qdRYfeUFvaOyoM0byvnquy28QIeCsya+szSI3qpF2zjOL+9XyhghkRZHoi9q52UfPpjl64zxMILNE8tSljDbVbnFP8Z9l3xLIT/+flu0mgt55sjTrE3WECgR/i37l945W7BPEjOzZa7SV10f42CFmikBEKK1GH/WtTvTKwkDtq9/BaP1hAkHzv/0tMnoRvTg06pO2V+OO6yECgTjEQiDRbxHJveMFeM/0pEBkb2+9q+MvCYSFwWOIhH1R49UJj6z/KbFEniF7LrdALM1vwYwKJjuhT9V3p1ieOuMT+04VyIyvWSKsJ4haZc+7hLIKH1frNAsEn/h4O/SaHzjERdurB985/g6R7Mwfn60rkFZjW5rfgmnl7vmQlw9R4/ZbdbZQ3sD7oUDOGhVNKvYIB8zRusePXGzfcDkRZ5wpkoj6suf4LRBuWDQi+/S4h8G6EKBjrXPk0FbisxObqb5ZIsl0xlm1fFrNioZsrcEHjFj42HLB7LeMOTfGHMe5a2z7sCiR2HjS/TQsEGnYVvOKX28ic27wszFywjK2lbd8bb5bvMwQSWufnXyhAukRw83eGkMUYmW9l6/WfRyVQHx8SX+dCgSN2mpm7bM0q47BnIUhY0uuwvh5KoH4OWsKRBoXTYsmPrPeZkUu7MHWm6vwvkuPFsnu/F8SyFVyShi+5r7Kt8SXQHycuwUScUmVw3dJkXyVQHzcHwoEX4PERl5Q5XqezxKJ/Q4OBVKNbCdxNa5KIPa7/ZtAVrvsqtd+2eCqBGLn7LdAQF5ZO3mrclUCsd/x73+LteplV932ywZX0QKRfMi9my2BDPx/sVZvghKI/UOlBFICCfm7kdU/NI7qL4G8UCDSDPUWsb1F/gs9r28akoDJcAAAAABJRU5ErkJggg==" + }, + { + "name": "Looking at the Surface", + "description": "The surface of this world looks exactly like a grey version of Earth! It seems to be an exact replica of some kind.\n\nYou see creatures moving around on the streets", + "choices": [ + { + "key": "choice 21", + "name": "Cool!", + "exit_node": "Tractor Beam", + "delay": 0 + }, + { + "key": "choice 22", + "name": "Scan the creatures.", + "exit_node": "Robo Brits!", + "delay": 30, + "delay_message": "Scanning..." + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAKCklEQVR4Ae2dW3IcNwxFtSYvIv7PR6qygZRiy8nGsiMvZlKQciMI4gMkAT660VVjNNkECIL3DGcSWX764+fjEa/r1OCXr18fpVfsddteP1HBclcUs62YO9SrBAc92yHHk3J4ysEh+09a1J1zDUBs39TUgEhgqH1nIe649hoccYK0a3YIkICmveCeYAUg9vthDkgKmjht7DcuBVoNkJRP9JX3ZhogKXBic8qb01qfAMS2nlT/pYBwaFrFEOM/iqEGBz1fUTO+x/x+RS49c24DCC8e3fcs5s4+qwCR+6Ztn7JX2wLCC60pJh9P9xqfK42pAWK1Vlnn3rZVPt5xjgCEb4IsCH9Wu5e+V2nX4LD4eFWrbevzU2p/HCCtGyHHn7IxLXl6AyJraNFuWd/KsQHIBX4WzRMQCxhSMVaKvmXuAORwQDRw9HzESonasq9FpCvHBiA3AKRFYJYQlGK15LRy7O0AoU1bWXDLuf/89u31R9ullaeKds6SoK2faXNaPS4AOfgEkSDk2hqRWQNQi6fJaYcxAcjBgMiTI9fWCK0maOvnmpx2GBOAHApI7rSQ/VqRWQPgFU+7HqtxtwPEqnCr4xAIuROD92vz9BL0zLjatbaMC0DiBHn9jxYzhTxzrhYYUmNvBUiqACf28ROidpJo1zdTtCvn0tYD4y4PCBZ6JSu/Z5Ta2nWvFO3KuWv1uSQgtUWf/lx7grSuc6VQd5sbtbsMIFjQ1W3ptJDPWmuxm0h3yKf4e7F2SDCXQ+vmX2U8QRAnSE4V9v2vgEA89uHHIiKvsO8/HiNPiVy7t2ZjO3Y97w+AoKgzlom5wr6Lv1YL7clB42qxcs9n7P1JcyQBQfE8F4I5wuoBKX28kifJSF099/202EVAUGTrRSFuWBs45MliUVfrPT81ngoQWfDexco40dYDIiEota3q2rvPV/LrAsRqAyKODpASDKmPXZZ19RQ75bn7FYAc8LNYKQhy0FjC4SFgmV8AcoAA5abt1G6Bg6DxyH1ExJp8RuJ7+8YJ4ghwq7gtxmsE2TOmJsSemPCpxV75PAAxBITewWsvCwhmfbyCgL3tSgBqcwcgg4DkxLqi31vInvFrQl31PADpBKR2UrQ+tzhZPAU8I/YqCErzBiCNgKw4GTTwzBCw9xwloa56FoAoAWk9EazGa+AAtN4CnhV/FQypeQOQCiAQ30l2lpBnzZMS7qy+ACQDiNUJYB1Hc6LMEu6KeWaAwdcVgCQAkaLWiHLHE4Zv9NXurUCp1SUAYYBIME5q5yCuCeD05y2g9Kw1APn5qP7PPQlKToy79vcII3zefpD09oBI8V+tDWhD8LqfnJZ1ui0gHiBAjDtaufHR1gFzS0A84DghZkChg4LX6XaA0Lv777/9+nh6evr03YP6PV+rTxa+8XGvg+U2gECcJQDoFMC4nMVJgeeyjX5pU/PCd6YNMHRgoE63AARilSKl/tyLRAs/Dytz8Z4P8bHxYXWgXB4QEjcXY6/Y8S4Pf7SlxXNpMU72U5vnh3GeNuDQwUF1ujQgXHh0T2KsvUiYfAza3hZz8pypz2PeACQA+fCuDDgsxEYxUi+IGc/QHrGABTGtbAByc0AgLG5JXCmxUl+qPzee90Owvf4pP+TDLdaRGs/zaXkekOgguexHLBIOhNUjIil+tEdti4hl3lgP2dE8ApAA5H9ARkQpRerVphx5nminLAeF7rlfS34BSR2Sy54gJBoIqUU0Umzka/FCXMRCe9TyNSK21gYgNwaERALxjIoQ/hCeto1xI5Z8uX+ujbVSjnx8qR2ABCCvkEDYXCzog5jQnm0xv4UFJGS16whIypBc9iMWCQSCsRAfxUOcnPjkc7QtLMXgcUptrBt5cj++DuoPQAKQ5LspRAMReVv5ri7nR9vKSkhy6wtAbgwIiYKE0is6iAr+aLdaKVbE87aYlyzPmc8bgGwOCP2dYq9NIlFIcXChzLov5VB6RvlBzMi1tU1+NEdpHq/6XyHu8u8gnoDQBnFhtIpLjodItZb8uTgRDxbP0Pa0mIvXA+u4gpC91mAGSK/Q+W+l8FgkRLDKpgSJXErPMAYW8GjbGCctQOH9HnW/SkxTQHog8QYEG8UFMeu+BAB/lhM/+nst1gl/tCUkqFHYzx/3bwMIbT4EMsNKEfI5ORy8f+Y9zyHA+AwGanIrQLDoGULkApTz5Z7Jd3rPNuWAPFCXsJ9BuSUgJAQpWss2F5+MC1HK/hVtyuXZ6d81vApsJoCMfI8Y8R3dBC9R5iDI9XvlUYsbgHw+MaSmzAEZ+aIuk5vZrolJ+zwHAfXnnmljW42jU4NeAcgkQEjIdNHvmqKrVdivTv/90eprPX5EhDkIcv0jc/X6Ao53QL4375d1zXeOZ3KC0ALl1bJo7tvi5z22VYS5EyLX3xp/dDyH4/nb98fz94CjpqEAhP3zB7liaYTJTwl5r/H3HPMRDPp4RXC8PJ5fXuL0qOy/GSAkLn7lxJbrH/HNxbTuL4kYUMDSx03cl/y8nwUc7R/5uW5MAaHA/OIT1e57/WpxPZ9D3AAhZTFmhf0Ix9tHqreT40ecHJWTA7rZEhCCBQnubFNAyL4VYNCcSTheXh7PP/56PP/19xH13WHvXQFpETo/QVr8VhZRwiDb+8Dx9n0j4Gh/4zUHhATLrxYB9/q1zGE1VsIg26l5ZgDz+eR4hyOVE+/j9dfcc9+r3rsDQoXWFk9uitbPY5wUfEu7NR8rcFJwaHKRde9ta+Y6bUwAkviyBhj++fLlUXphnLQWImiFhsOhnb8XBK2fNo+dx00BhAqqKUKq8Bo/yzEk9hIU8pkHHJbrQaxUbWf3IZeT7FaAUOFS16yCtsIBWADJrDy186RquVOfdh0rx7kAQgtKXZqF9vppYpfGQOQQfasl/1L82c9Sddy9b3aNNPNNBYQ2SJNUaiM1fiNjek8PgLQTIKn6ndY3speWvscAooWrtzhXAOQ0CFry7d3XUT83QCix3KVJesRXE1+OOR2QXL2u1C/3bEb7OECw4dbFORkQ1OTq1nrPNfFcAaEEcpcmuZwv79fE0YwZAYR8NXN4jOG1uPq9R/1qMd0BQQKpzcOznE35pPpy/q39JPRWUODTOtfo+FQdrtg3WqdR/2mAUKLy0iYv/VJtbSzNOIg+Bwt/XoqXylPbl4ur9T91XG7dq/qnAkKLlJd24dIv19bG047jMOBe45vLL/rzFdDUdfaY6YDQAuXVs2gZg7d74ln78HziXlcB6z2wiLcEEEpcXr2L4XHwW1WorzeelR/PK+7rFbCqu3WcZYDQQlLXyAKt41nnksov+ta/mZX2eSkgHpBgsVx46Jtl+dxxX6/ArH3pmWc5IJR07upZ0A4+ufVE/+cK7LBfpRy2AIQSTF2lxHd+llpL9KUrsPM+Um7bAELJ5K7diyjzy60j+j9XQNZut/a/8+89HVF1Xw8AAAAASUVORK5CYII=" + }, + { + "name": "Robo Brits!", + "description": "Wow, they're robotic humanoids that look and act exactly like the British! You see some robots laughing and chatting at a pub, and a Bobby walking down the street looking for crooks. Who created this earth replica? You only know Earth from the books, but you should be where London is!", + "choices": [ + { + "key": "choice 23", + "name": "Nice! Well, back to getting pulled in by a Tractor beam...", + "exit_node": "Tractor Beam", + "delay": 0 + } + ], + "image": null, + "on_enter_effects": [ + { + "effect_type": "Add", + "quality": "Long Range Scan Report", + "value": 1 + } + ], + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAP2ElEQVR4Ae2dT8snRxHHnzcgYT3ksEgie1gXVkhIUFA0F1cPezAsHjzsKYR4URSvHj0IycmjvgLxIIigOYme9C1IZAUvCnkJXloqmyKfp5+u7qrp7pn5PduHpmqqv11VM/P9Ts/v+Xv14duvppHj6uoqjRiRnn70wR/TGuVr8OE77yRrjLhPVg6rZjRu5c/j0bxe/FWEiBY2b3bUsVWvFF8COZdAhANeElq4rTyy8m2Jdwtk60l415XEUIotgZxPIL0i8XKkhtsiCq7pEkitsVFzJTGUYksgSyAezpH8Hn8JJPv8kl/kMwov0mONBHmeGce1+rW5Gb3kOWv1dW4J5FOB5BePx2cRCXvKfatHvdElm+eYcVyq64nN6KWW0+rp9AKRkyq9UuUxiyCteO2ica6VZ9Y8e6j5Vn3rxku8lm/UXK1+bW5U/WievKerPEFOvNpxvnbWca0HnbMIUotH+q3lmTUX6Y9Y9pPfcB5zzSyf9bz+rF68ednnDYFIEiVdy3oL9uJafcg8SdHyt/bTyjtyfmuPuk574c3OfcXOsnk97/GsfqJ5pd+iQCSRh5TRgj34Vj9KiJbt6aGVW+Y9+UfladWSOjVSttb3zNfqWnM99SauLX/nu0VInZ/Y2DWyab2abRGvt9fR+Wv5enuV9S2BfPqEvHado3Utskfj0bo74pdAvBe7RmiZ8+YhzspJzFbfI5CISKKk9+K3nt9O65ZAvBfaIrPGvXmI07UlS1zU13xekh6Ji57bzvg+gcgrzx4N116tdE5JUbM9vdbyytyW3KNz5vmOJL639pbrtuOaF0sgOYFqx7wJNZzMEev1Wzl13sqn8zXrJeneOOucThhfAqkRzDu35cZ6c/fg9ia+p96Wa3XgmpsC0VcWr92jeW8vPWTqWRu9Bj21Ims9hN0TE71OJ8AvgUQIZ2GjN9LKMzq+J/k9taLX6Ui8nE/XNwr1qb7HSWgtjx1NMk++6DXw5OzFeAi7NyZ6nY7E31qBiIh6ybVlfeRmbskfXbM3+T31ItfoaGxVINKc52ktmNkn4u2DuCiZRuAj12FEvVYOD2H3xkSu0dHYpkCkQZKu5ntPhjk8a4iP+BZ53v/F+ykfFjYa95yPYqK5t+BnkV/PoWQ9NUvrzhgbKhAhb+0kI+Qehf3BP9MnYiC5cnGMPq5dA52Tfnrr8pws30PWKEbPoWY9OWvrzzLnEog0O4qwe+dRgfSSsWd9frN7crXW5kLxEDWCyc+ldjwrb63m6Dm3QKTw3uQeUa9FqNs4T5FESNrCbiFfKyfnt+SfvUb6M7/MWyo+grR75riNAvCeE8k3wi/xoRXbUreVc8/5JZDCB3YvAc+O20JOa81WUlr5PPGtNUeukz5DO4gU33MH6K11dhLP7M9DQg+mh3Ce/C1MT/2etdrXEsjaRab+Wq4Srdf2kH3LWu13CWQJxBTIFmKV1ijZRthS/tEx9rkE8gIL5M7nX05bR4SUJNwoP1I/imWP1/5wnCdR7+eCPdfPfMe/hNy80SV/qzhknYcrxJTqj4ixxiiffV0TiJC3VmRPcue9bK19CUSe1SNvdMm/DQLR86rxNjqnOcXeEEhOTE2+laD5Os2nNp+36gu+hG3FZpHvEvLyRqtPUXzhi6+l0vj9X/+WdJTmJcY8ei9rVuvPtrUevHPssSiQFul65q0mNac1r3HFee2ZiPy/dJVk7NUTb7T6JLZFfhWHWAvDPHpvalbr72VrvbTm2ONpBNJqWue9wlDcXmT01FkCsf8dHEk50lfeeG1ee3eBKHE9DQs2x+l6r/UQdy/MmQXCXePP//h30sE4d5Oz7yA3iO7835k31nmJNguXC6B2HO1hL+J76+wpkPxG6zGJTcJTCCoOsYwTzzy1e6ZzWv9Iq71YttTbYTsIyV5qWObzONfQz3GRYy+5R+CWQPZ/xSqSvrCblHASO4VASmLISU5B5H6OjRyPIP4Zc1g3nE9+a3fwxJmndb2tXi4hfhqBtESSi4LHrRtUmz8juUf1VCIgie0RAl+riGee2vUt9XBJsVMJpCYSCiLHvfTSS2nr4M0dRcyz5CkRkcQm4S0hWHHm4TWkX6p/abFdBMKLJn5O9tIx17Tmt4pD1rHOWYg9qg8lI8k829frqbUv3R4iEK9ISsLQmN4IsUsgN/9Si4hMyTlbFMyv90VrX7p1C0RPnFbJ2rJcQ7+1rjb/4MGDpOPRo0dJx+PHj5OOp0+fJh0aE6tYsZpD7Kgn95nyCEFJ4Nm+3t9LF4b27xKInnTJ1kjMudJajRHn9UlsEp5CUHGIZZx45jkTsUf2ojc7F8vf//SHpONXP/tpag3FiqXQ9D6qZb1L94cJRC+O2BLJOZ/7JXwrRmKT8BTCWQWy5/dDVGhKVBKbhG+JQ+aJZx7eT61zW2xVIDxx9YW46qu1YiS5YkuWuJpfWjsrpsSaYY8QiJyHkJbEJuF7BHJbxFA6D1MgFvEsMZTwJDvnGY/4zDHbnyEMzbm3QKKiSFdXSYclHIqL+Usku+RYSCAkMwmqccboy3x+rGsiljlm+0rmGXYJZOyPnJS4MEqULoHkJM4b4nw+Vzomfqv/21++n3TwaRb1NYfYGWIo5VwCGSeQEr80NkIkYYFocdqc5Jwr+Tl+yzGJHRUF8cxTIvOM2B4Cuf/6u0kHX4H+8rvfJB3W65MnrjnEMr/WFDuCoLUcJW7lsdp6z9w1geTJ9VgJrMe0OleyxKlfwm2JkdgkfNRnnhliKOVcAhmzgyinPNYjhhLGLZBSE15ic613TQvHJxhFwaffBz95PelgnHjmKZF5RmwJZH+BKAdLIqjFqgJRkmpyWp07ypLYJDyFoOIQyzjxzDNDDKWcewvklfvfTTr4OsRzj/rMo7nF7vWKRS5G/Zog8rmqQKzCR4mCdXlDSXgK4awCKYlmdIxEJYFJbF7DqM88zM+6OdlGHlvc9Ma9vVwTiBCwVYAkPdL3iOLr3/xe0uERy2iSHpmPRCWBSeyoKIhnHuZnXS8Jt+BaPPXOt2rfEEhNJEcKIq+9BPL8y9IkpOWTwJ97+VHSQZJHfc0hlvmtHhhvkbI17yW/F1er5xZITtCjj5dAlkC8AvDgLJEUBSLkLyU9QhSlPiTG7Z6fO+hbr1WMM49V68hXpVZtPpktn094PvmjuwbxzMP8Vg+MW2T0xq371BO3ai+B4Btn1gVukfTIeRLvy1/9cdLx8Gs/Tzq+8o13kw6dn2W1pljWYJ8WGb1x6z71xkv1TYHobsGiGpthWUd9qaN+bvnk565BnzuFFWeevIYeHymAVm0Sj4QkUVUcYomZ4bMu87PPEhEjMb0vo22ph5BApKFR4ug9ORK7x6eIrJ5aJD1ynsQjIUnUJZAr80HLez5EIL0iYUM9fo8ouPYSBWKJgnEKxPL/89FHSccbb3wntYZixVo5GWc/FC/jJVLWYj2caa0t1W3uIKXXnC27SKu56DxJ3uMvgTwXSUscMr8E8var5isUCRwVCNd6/G+99e2kI4rXdV7rEQhzHfk6pbX5BLaezHySWz4JvwRyVfzpY9cOEhUE8R6C5xgSMp8rHRMf9Y8UyNafyaJASH7G6RNj+RTLK6+8kXQwbq1lnHXpW5jSa00tVrr/o2KlulMFsrVxktyTg/iovwTy/MvBFIKKQyzjJLnlUxT0iWe8REor5uFCD6ZUd5pAoo2S2E+efD/puHPnTtJx//79pENjYj/++OPiuHfvXtJhYZhHc4tlXHsRyz71lWerXTtI7JeqopyK4EvikNgUgUQaUyyJR0KSqBaBLfKrOMRaGE9+9sM+twpD16lAxGrMY/kEfvPRr5MOxunz6f2v/z5JOnSdWGK4gzBOvOYQSwzr0udaxi1i5nHlySyb19PjJRDHDjVLICIGFYlHGIohwSziEUMCk9hcS8zZBDJLFJpXxVCywwWiRaP2vfd+mHSQkJ4nvLU7PHz4MOmwMJ787Ed7FKuE7bFLIO3fLoxyKYovCUNjSyDBHeTSBcJdw/K5m1gYxonnzkWfeMaViDUbJXwEX6src0sgJxFI5HMICWYRjxgSmHjL78GzLn3WYrxF0E9IWviXaRER1LCt+qcRCF9jrBO6e/duKg3inz17lnTo65VYjYklvpRPYsTwFYp9Mt7jR1+zSDCLeMT0EJ75LZ/5WZc+1zLeIuhMgbhq85t6I3wSK+KTeNY6D5kphCWQz/42Fkl5hL8E8umPqVjkbsWXQPxf6iXBLeIRcwbf6tPzFJ+xi7jrjtg1mKMlBGt+CWQJpEVaiztb4q1aOr8+gzg+1/DzBYXM+J4+dwTr/Z/9vPX6l1Jk9KxVYon19Em8x98ihnyNp45ilkCWQG6Ip0cgslbJNUMgkjsnfPRY+/PY4QKR161ow4Lnk9laf1s/pJOQHt9DPOaJ7B6C7V2rxPP0qdiItfjhiUfqCHYJ5MJ3EJLQ8vkaZvn8EE2MFSeGvtWDFY8SVvEeMeQYXRuxSyBLIJ/8sKElBCtOUdC3hGDFI2TNsbkAPMd5jtbxFIFsec3yvGJ5LgD/uSd/14NxTx5i+MrBPhnf07fIZsVJYMu3hGDFrTxWD1a8RdDWPO+T12/l5PwSiOPHGEj+MwiE/fAXmuiTkCSz56d5rbUUC/MwP9eyH/okYK/vFQVxkZqnFogQgSfm8blT3NYdZAnks58A9nAix1ykQF57+GbSwV9K4leudN5rR61lP6xNoh7l88lMn09yPuH55OeOQIy1lnjmsdayH/oRgnqwuQBax56cijnNDkLikZCjSM78Hp912Q/XHiUK1iXxGPeQ3CL2jDzsU8k30rZEwflI3WkCiX5QJ/FISBKVGI8/ai37YV0S6SifxGMPL5pASHqKIfeJ8/inFAhJaJGcpKU/ey3zk5BH+Usgn30eIeFzYcgx573+Egj+SB3JbwmTmBmiiP5uiNUDdxCPb+Vh3JOHGK5V30vMs+CWQE4qkMhvGCr5aElUj8+1lu/JQ4yV5yzk9/RxGoHw/5XTt57k/H4EfT7hR61lP/QtAvTGdRfpEQmJ6vE9PXvyEFPL6SHnGTBTBRL5oE7i0R9FcgqHgqJPDOuyH/o1AvTOqUh68+Treb70c1zpmHj6JawndgYBtHpYAsFfcVwCef5/Dy1yUxT0LXwr3iLnGeanC8S7i1hPZj7J6fMrV/SJsXzi6Vt43mirT2JG+C/CDiLX6QwiqPWwi0BEJJZQJC4XyiKeRVoSm76FZ5x4+sTQJ+GtPokZ4c8SCM+Xvqdn4ul71lqYGjnPMLerQFQotHrhLOKRqPR5g+gTY/nE07fw2qNYq09iRvgvikDkWp1BCFYPhwrEQySLtCQ2feKZn3Hi6RNDn3n28l8kgcg1tQh6dHwJBN8HoSjo7yUK1lGBiGV8i8+HAD9c0yeGNRgnnj4xXBv1jxZDqf7/AdVoY/i7GpcvAAAAAElFTkSuQmCC" + }, + { + "name": "Verdict", + "description": "Before even getting to defend your case, the judge says \"I've heard ENOUGH! It's time for a verdict!\"\nDang! You're definitely in kangaroo court!\n\"GUILTY! AND YOUR SENTENCE IS:\"", + "choices": [ + { + "key": "choice 25", + "name": "\"DEATH!\"", + "exit_node": "FAIL_DEATH", + "requirements": [ + { + "quality": "Crimes Committed", + "operator": ">=", + "value": 4 + } + ], + "delay": 0 + }, + { + "key": "choice 26", + "name": "\"SPACE JAIL!\"", + "exit_node": "Not Actually Space Jail, Just Normal Jail", + "requirements": [ + { + "quality": "Crimes Committed", + "operator": ">", + "value": 1 + } + ], + "delay": 20, + "delay_message": "You are being jailed..." + }, + { + "key": "choice 27", + "name": "\"FORGIVENESS! Just trespass? That's not that bad!\"", + "exit_node": "Sweet Sweet Freedom!", + "requirements": [ + { + "quality": "Crimes Committed", + "operator": "==", + "value": 1 + } + ], + "delay": 10, + "delay_message": "WOOP WOOP" + } + ], + "image": "default" + }, + { + "name": "Not Actually Space Jail, Just Normal Jail", + "description": "You'll have to wait out your crimes against the robo brits.", + "choices": [ + { + "key": "choice 28", + "name": "Sit out your sentence", + "exit_node": "Sweet Sweet Freedom!", + "delay": 1200, + "delay_message": "Sitting out your sentence..." + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAOkUlEQVR4Ae1caQ5etw30lYrcoblZgZzaBVsMMJlw1dNbnOiHwX04lMT3GUbaH3/854+fu//89q/ffnb+7O67E6/D33J29rwb61eaqcv17jv4cceldIe7o/cuzL/DDHoWv9JMXa6Wp3PutM+CBL+g3QvaeRl3Y/1qM32B71mQsyB/+evw3YvaxT8LEjzO7gHemfeFy9k936820xf4nl+QYEm/cDlnQd7/x56zIGdBzl+xgjdgH6izIMHhnF+Q/f/8P/1F/MIdnAU5C3J+QYI30P4F+fnjx0/9k30Nos1XDLYzPItxLvSq5kqcZ0A/lohf6aG1hq++nTY4q7S+7NvZU7EmMxonPnPVJ5y1VnlFdvoLoqCe7QEz8WpIxfTwzKd5kR3VT/08Q9RL/dMemg889a/YHhbPBB15sE1O+wGjquvmAce4oMaTytnLiXzoUclwQSJg9XsNmLjmd2wPs1OnOR5O13fHDFlv5p7ldWKMZTpqeCbTNQ9x5HekYkQ13Tyu9zgyDviyr6tzn0x3F+RqkyvE0VtJwz+VitO1MUN1SRmfbi8Po1vr5UV41UyIe5iRL+rF+Z0czmfdq4UPfGFPJPfI9L8sSLdJBnrlUaG/4sO/IhWrY+Pwr87S6RXN1Kn1ciI8zBTFzW85Hmbki7CQH8XNj5xMZvWdeVCf9chi7QXJQDRWPSoMhjoMoRJxkxozO/JHuYxX6eAYzRL5p729fPgqjl4ctavS5vJwPd9qD9R5mOxDXiS9O0K91sA/lX9aEAWF3QG1XOShzpM8FPJNerlZnGNRPWNqfmUzT8YxnWNXeiuuZ1c8Ne5hTH2KGdlTXC8/wja/l88+vQfG4jzTOTbRywXJwCIS6ofNA5nO2MhhmcU5Bp1rVUdOVzJXxeIY8DSHbeSo5BzTLe75tC6ytXbVjvDZv4qtdYypuuayzXegb8lwONd0xe7aSwuizWGjKWyV2VCaazbwTGqcY9A1h23kdCVzZRzTOQY8zWEbOSw5Dt3i0FlyXaZzzVU96xPxXO0Z9crw+A5M9zC03supfH+bBdHDULs6CI3zBSgWx6xO42ortlfDOVpvNscj3atb9UU94F/F9eqAqdLLhY/vAHpVr/GOvbQgBgyiLNGQfapjGJNVPuJeP8QU37ORO5HMUzERU79nez29vMrn4bCvql+JMz7rK1hVDeNDz2pwByxRB6n18E9kuSDWxAPU5pznxdiHoQyX/axzT/av6IzV1cFxpR/XaD+OTXXFYjvDsjwvbjN6fvgYn3XEPRn1ivzAYHzoiHkS98MSdZBaB/9E/mlBrFBBJzYaVwffwQTWLk6M19Fx8B2uUY7XJ8rt+qeYnM89MF91V1xvOmOozrkci/ycYzrnVb2YP/SqXuMde9uCcLPq0PVg1GYs0zXetRVnal+Zw+vV5Z3lTXE5H/PgQbGMenK96VGe+b1c9WUYnJv1sRhzh871Xh+Nd+y/LIgHXJHVwwHhTp3meKQ1p7I9jBWfzVH10njWR3NhT2s0HzgqNQ/34kmtZZtx2M8651Q616mOWvWr7c2AWkitgX8i3QUxAAWPbK8Zk4/qPL+HdZVLhNnx2xweT89X4Xk15lup45oI18Pme/F0xuIe0DmuOnK6kuu9Go6r7nE3XwfHy8l84YKgSMmxjRyV3gBcp7rWq635bGvuTtvm4F6qY85pT+B067r5yDPpYYNvR3r17Kt6ce6KzviqR/y9PlzrxStfuSAVgBePBlC/V/sln/KN7C9xzrhE/D1/hvN0zOPn+e7gdRYk+Z9bepfg+e64mDswPe6R747+q5gRR8+/2iOqOwvyD1oQewTeo/J80YN5w+/xi3y7+Z0FOQviLs3uh3YFL1oGz3+lj1f76oLYgB6pr/i8C4h8X+Fc8Yj4q7/CeTqu/CJ7N6+zIBt+Qeyydl/MXXjRw1L/Xf1XcZVfZK/iR3VnQc6CfP6vWPZ4o4VQf/TQV/23LMibA60eRFSnFxDZUf3X/BF/9R/e//9/ljwLkvyC2CPRhxPZX3tQEZ+Iv/qj+rf8yi+yd/M7C3IWxP0I7H5oV/GihVD/1T5afxbkLMhZkOQNnAVJDse+JvqFimz98nzVjvir/2v8lV9k7+Z9FuQsiPsR2P3QruJFC6H+q320/izIWZCzIMkbOAuSHI59TfQLFdn65fmqHfFX/9f4K7/I3s37LMimBbEL2305d+BFD0v9d/S+gqn8IvtKD6/2LMhZEPdX0nssb/qihVD/bo5nQc6CnAVJ3sBZkORw8DXSr1RkI//LMuKu/q/NoPwiezfvsyBnQc4vSPIGXl8Q+xLs3vrdeNHXSv27+67i/fv3339Gf5RzZK/2vqsu4qn+3f3PgiRfDxy2XkJkI/8tGS0F+yPu6ueat+bhvsovsrlmh34W5G+yIPygMz16WOrPMHY8vCmG8ovsKW6Vf9uCWONoCPVXJN+OK9/IfoNn9pC9WMRd/V6t+p6cV/lF9m5OZ0F+4V8QfbAdO3pY6u9gIWf3o/TwlF9me/Wrvs8tCA4dcnWwnXXZZXBsZ88OFs5oIplvpk8wLbfD90pOxlVjV/po7WcWpLoQJf6krRcQ2U9yqs4rikfc1R/VZ/4751d+mb2Tx1mQX/SvWNlDzWLZw+JYhlHFdj5QxmJ+mc41V/VPLEh14IhfHXa1PrsMjq3ir9ThTCbS+jDfTJ/gerkrM1U1GV+OVTiT+C+1IHYRk+F25fLhZ/qufh0c71FmPmBm/DmWYXVi6LdTMr9M39lz64J4B5cNgphXl/l2HkAHCzwr2cHalZOdj8a4ZzUD4lajOFOb++7Qwa2SO3oBY8uCZAdXDWPxrD6KYYAnZGcGy3mCC3pE56J+5ENOZ1G8qY2+O+SU+46elxakc1idoTo4mrNj+C5GZwbL6eLtyNPzmNideZjjBFtzGeeq3uG9+x6WF0QPIrK7Q0X1mf/qgXfruzN08XbkZecyiWWzKc8JLucqzqqdceXYKr5XdxbkH/bPvPxwWecHBt17MFzT1T2cFR94VXIFO6pZWpDuwVheNQziRnCCa7nRULv94NiRu3tHeNOzqvK92aLe5q/wNJ5hdWMeR8/XxevkfWJB9DC7dmfAHTneJUS+Hf26GN1z6ubpTBmPLibyMqxuTPlFdhevkzdeEAzcldEQ8HdxvLzOgDtywLUjd/TrYnhncsWn81U8pr0qvCqu/CK7wpnEb10QIxINAf/0kDl/MujVXPCt5NU+03o+j6u6ztbhMunZwctylF9kZxjT2GhBJodhuUYmGsL8UzzNnw57JT+bg2NXeqzW6rms2jyH6R0+014dzChH+UV2VL/iv21BQCYawvzTw+V84D8lszk49hQfrw+fz1TnGaB7PTzfpJdX3/WBVyW7eJ282xfESEQDTQ5WczvD7cyJZlD/zp6rWHpWHVvnMLvbv4OPnC6ml+dx9Hxe7arvlgVRMt4Q5sOhTaRiP2VHM6j/KT7TPtEZK3+2Jz0ifM8/weVc5pbpXHNVf3VBbEjvAD3f1UGv1mcXwrGrfZ6oZ76ZPuHi3Vnkm+BybsaVY1xzVf/8glwdcFc9X0Cm7+p3J07Gn2MTDtEyeP4JLucyt0znmqv66wuCQfUgrw62ux48K7m77x141QyIT3vrHUb2FBf54FVJ5O+Qn1kQDL1jqDswwK+Sd/TejVnNgPi0b7QQ6p/iIh+8Kon8HfIsSOM/VrSDri4F8R2XcjcGuFZyykMXIbKnuMiv+CKO/B3yLMhZkHD5pw8sWgj1T3GRjwWoJPJ3yEcWxIhWQyG+Y6g7MMCvknf03o1ZzYD4tK8uQmRPcZEPXpVE/g55FuT8goQfr+kDixZC/VNc5FeLgTjyd8jPLYgNuWOw3Rg4/Eru7nsHXjUD4tPeugiRPcVFPnhVEvk75FmQ8wtyfkGSN3DLgtiXQ7e32nqOa+0XbOaX6V/gWnHI+HOswuF49Gvh+bluojO3TJ9gVrmPLYgRyYbiWEX6jTjzq/Q3+E16Vvw53sX1FiHydTE1j3llutZdsW9bEDscJZYNxTGt+4LN/Cr9C3wzDhV/jmc4HIuWwfNz3URnXpk+waxyRwtiYN7AmY8JZENxjGu+ojO/Sv8K54hHxZ/jEYb6szfAMa2b2Mwr0yeYVe7tC2KHAxLZUBpDzZekcozsL3GOuETc1R/Vs58XoNK5bqort8ie4mb54wUxsOoQong0kOfPSL8V83h6vrf4Tfp6vD1fBzO6b8/fwYtyPH6eL6pf8T+6IHZg3kCeb2WYu2s8np7vbh478D3enq/q5S1B5qvwsrjHz/NlGNPY0oJYk+wQqpg3lPqmgzyRrxwj+wkuV3tE3NVf9anumuMVVhVXbpFd4UziryyIHVo0HPsngzyRy9wy/QkuV3tk/DmW9eHH39EzrE6MeWV6B6ubs7wg1qBzKFXOU4N2DyTLy7hyLMP4Soz5ZnrGt7pbjmc43VjGk2NdvE7epQWxBnwIqzoPx3pngCdzmFumP8lptVfGn2MR/vSuI5yJn3ll+gSzyr28INZgelhevjdwRf7puMfR8z3Na6Wfx9vzRdjeHUa+CGPq9/h5vilulr9lQaxBdDhTPw+cEX8jxtwy/Q1u054Zf455uNM79TBWfMwr01ewo5ptC4IG08Pz8nl44H5BMq9M/wLXikPGn2OK491X5tP6KzbzyvQrPbR2+4JYg+zAujEcgBJ+0wanjnyTZ6d3ZwbLUazu/SFP66/Yq5yv9LxlQYwQDuiqvDLc7truBXkPazeXq3jdWbjP9C65doe+wvlq39sWxIhNDzTLvzrojvruBZ0F+f1/d7/jzBmje/5cc1W/dUFALnv40xgw35JvXNIds07n+MI9TTnvOLdHFsSITg84y98x+CrGG5e0yjWrm86R3YcXy3qvxqacV/tw3WMLYk29g1z18RBP6m9c0h3zTeaY3tEdfA1zwnkXh0cXBKSnBx7lA+9J+cYl3THfZI7o/D3/HVyBOeGMmqvyv9va9kZwciKCAAAAAElFTkSuQmCC" + }, + { + "name": "Sweet Sweet Freedom!", + "description": "You're free! You spend a good while travelling around England (or at least the replica) and enjoying the cuisine, people and culture! Good society research is gained from this or something, but really you're just enjoying the sights and sounds.", + "choices": [ + { + "key": "choice 29", + "name": "Nice!", + "exit_node": "WIN", + "delay": 0 + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAQJklEQVR4Ae2deXBX1RXHY23/6DYdFBekilIInVrsTBUUEKWitf1Hp4467XQ6Y6frtLWtdpzWhaCCCQmJieKCKHWKY52xjgsg4AIo7s601NYlIoSdaEJIQgwgWU7nxB643Nz93fveu7/fy8ybu527vHu/n3ve/W2pgIB/B/v6ofHBV+H07y+Az319NlSMm1WS1+YdncpZ3HDpT2H9yNODXRsuuUrZ/5adnSU576inoydUwYSLmmDu3S/A/gN9ynlwKaxwqWRTZ2BgEHa17YW/PvYvGHN+fUkuVAFINhvf6Gl1sPCRN2F7azf0DwzYyNLYNjgg7EgOfNIH9Ytfhm9870747ITS8SgFIOkBcnRlFYy/sAluWbAWevd9wsorSDxVQPAO0KPs/KgbHnj0n3DKeaXhUQpA0gHkpKl1cM/Db8C2XV3BPAZPWWqALLzhGjC9YjurFICEA2TIY8xshNl3rIae3gO8foOngwNiCoXMLgZYCkDCADJqai3c/dAbsHVnF/T3hzlj6AjzDohM6D7y8wpLAYg/QD5TWQVfu6ARZjU+D909+3X6DV7uDIgPwSdtIy/AFID4AeTEKbWwYMnrsGVHZ2YegyduGCBJRZtV/SxhKQBxBwQ9xriZjXBjw3Owp3sfr8/M0xVZCTpkv2nDUgDiBgh6jDv+9lqmZwwdgdEDUltdq3x1LA1YCkDMATlq/Cw4bcbt8Jf5z8Luzl6dPjMvjx4QG0/02oqlgJdvaApAzADB9zEWLHkNWrbvgb6MXpWyJS53gKBHML1s4EBbAoRCX6AUgKgBOfX8BriudhW0dXxsq89M7QcHByFTQEioWYUFIGphJ52f48+eBw2LX4FN2+LxGEQkfrZryRPrwwGSleht+00qAqxfeJAjQRtzfgP8qWYlfNjeQ3qLIkSPsadrHzz+zDvw7Uvv+fRR3PYxRWZvK8y82BeAHCnuJPOBHqP+gZdh09aOaM4YRC56jIeXvgWTLlsIn//mrYfPqTLB2+bnRfC240giCKpb7h7klOn1cM1tK4Y+hEqCiyEc8hjd++CJ596FST+49zAU7PeWbEFQ2duKMy/2JHTXsFwBOW5yDdQtegk2bumAvr5sPivlCiJ6jEeW/wcmX7YQvjCR8RgsHBhXCd62LC+Ctx2HKxhUr9wAOXn6fPj9nKdhe2uXqz4zqYceo3Pvfnjq+ffgnMvvE3uMApBP3wthISKhu4blAsjIyTUw7751sGHz7ig9xqMr/gtnX36f2mMUgAwH5NQZDWa7CT95/0+XOiBfPXc+/O6W5bB1ZyfgLhzTX9fe/bBsTTNMvXKR2xrbPkbJ7NkdObY4vk5fv/gVOOGceU6TWKqAjJxUA9X3vjjkMfAHOGL6wzPGY6vegSlXLIIvnqE4Y0g2vUNPEzLB2+bHBgU7Xlx43Bnxq8DXVq8EfB3/0ATpJrAE3wfBH0P4zexlsHn7nug8RnfPAXh67fsw/UcPWK2hdL1tQRDZs2LTxUX1Q+XpxsKW0+6InxHauLUDahe9BPi6vnTiGHBKxYMce1Y1zLnrBXi/pR1i9BiPP/upx/jSGXOM1s1kbStIJElFSu2owqR92NZXjYUvI0AoRI+yrbUL/jD3ae2PS8QOyKipdfCrWU8NbQyxnTHQY6x8cQPM+PFif1Awm98hQEgwtiIke6qvCsk2rVA1Fr6MwOBDfH0fPUrNwnWAr/uLdp1YATnmrGq4+c410LwpTo/x5HPvwrQr7wevHoOFA+O8UDDtImBRO3yeS7tJ6/BjkKV5MPg07qz4C4VX37oc8H0AFpTYABk1pRZ+ceOTQ4fv2DxGz8cHYNW6D2DmTx4E/G4Juw5B4jLBYL6NOFXtUJlNe75sqW9fIXqUD7bsHvqpS3xfABclFkBGnHkbVDWthvc2tnk/Y3z34osh5IWvSi1d/R6c+8P74cvf8njG4D0Gn9YJx0Soujao3KQt3zbUt+8Qd1784g++2tPapv7Uata/zdva3gM/u/4JaG5p9/qqVEggdG0H8RY8HLJHLF5MOtHy9rK0rp0Q5bKx+MjHx7C+vn6t6LIGBGE+eNDf+xg68aZdHhQWG6HwArapi7Z8/TTStmN0sefPK3w6a0D48bim0xa+bX9BQHERhGudNIDg+3Adq009neBiB8RWqHmzTwSOjRCS2vLiTSOddMym9VWQxApI3oSedDxOoKBITUWQxC4pDBUVFUCXTVtJxmxTt9QASSrGvNa3hoTEZiMGF1vqxyUkMNjQtB2XsbrUKSVA8ipuX+NSrRVfNuwLUy7i0NUxFbPMjsDAcopjKLPn83Xj81HOTyybzvsjli/hxdQOuz6q+DBAUFw+BENt8GK1TYuAEOWp2qWxhAxVk5xXQGISdIixqtaMynINiAoEVZkMFhNA2Lom9mRDEyoK8wZICLHF2KZorfi8YICwQnONEwSy+lSOocwmST6J3zTkJ5fSeQIkRiGHHDOtkSxMDEgSAarqmorf1E7Vl6rMFA60k/2VKiAw+itAF4mY0rKQ7PISytaM8nMJiK3oyV4ldNcyG0B6//0OiK7mmVcG+x/p+P/Xm2deIeyXH4tvUcogSJLve4wm7fHzxKZzDYipqAkQDE3r2NjZQPLWmEnAX+uPnxgUEGyf71OUNhGLjU0SEGzr2ozL1lY0V5QnBATFYyoKG6GZ2LqKneqZ9GFrYzoXaIc7eh4vW9Go7G3F7dteNTbXMtma5QoQErmLJ0hSVwdM7IC4ioav51voPtrjx+iazj0gPgRObegE71JuColsorPKdxUM1fMh4jTaoPG6hrL1SexBUDgugmPrkLAxZPPzFI8REFexpCHoEH243i/Wyy0gMcCBoMYGiItYQog27TZd7jsKQNL0FgSlTZ8xAWIrkrRFnEZ/tnNg7UFsdk0bofG2LmLl27BJU38Y2tQrVUBMxMrOGcZN6mRtUzKA2IjUhy0ttm1bsQBiKgwTAdNcyUKTNrKyMZ0HssutB7EValJ7WmzbdgpADn9hjeYwK/Gb9EvCNw0LQBy/S0IgxQCIqRhMBEYQ6EKTtrKyMZ0PtCsAYQAh0duEBSDDPQjCk5X4TfotALnhGuODNrsT2oBBtgUgcQHiAw70KtI3ClEYpqIgEeU1TAqHzVzIXHXofBtBmOy+7Jyp4iZtZWFjMx+qtfEOCE1mXmCh8WCYZEymm4VqskOW2QjCVLDs3Inipu1kYWczH6p1CQaIaEKTitRU4KK+TevK7ApAhj9iZSF8kz59wYHgeAEExcMKSyTQLPPYsbnGyxEQEiO/dpSf19ArILy4WQGZikLVBtseP9Eh02y/PuKmc6Fy1yHLbESBtnkVt49x2cyFbk2O+Ac6vJBMRWEKCN9+TGnTudBNeKhyG1HwtjJRTpw4EUwvWRtZ5PP3J0ubrMURgJAIWOFSni5k65RiXHf/VE5f1WTDNL5yKxOBbb4pEKHsfABlc8/sOoniQkBosVHoFNeFpQgF3ZPu3tny3vVvA38F/9GGC64Y6tNGGDJbXvhox+flIS0DSXZfqnx+vdi0EhB24XVxElMphbp7FpXTz8WwYVo/+6MSgc+yPAAiGgNC43qf7Hqx8QIQwbvxIuGb5rGTS/G0AMH+XAXiq55IuGnlJb0HWi829AaIqYBK3Y6dXIqnCQj2mVQoIeqHhMTneGnNKCwAWbHU+JxlAjdNLBumDQj27VM0IdtKCk6IsbFrVwDiERB2Ytl4FoDEBEkIkSdtk9avAKSEAaFFTiqWcq5fAOIJEBKjKMzKg/BjKWehu957AUhCQEw+LpMXQFhgXAVTbvUqaqtrAS+TA2hhc/hAbwKGyMbk4w22NhsuuYrVvnW83ERvc7+HAClAOSx+1UYgEr1Lni0EKvukgIiIshFRKdtWyBZXJZJyLZPNlWu+SvQ2ZTpABgcH4WBfv4gD47xShkB1b1JAaNHLFQa6b/KsGNKc+AptIFDZ6gBpbe+Bn9/wJDS3tAPC4vtPJbDYy7SAkBhE5xRWPGnFaTylEqqEb1qmA2TLzk6oGDcLjjmzGmbfsXoIlKQexQSy2OHA8RsDgoJUQVAqgk37PkwhUNmZAoKQ4DVqah388qan4IMtu4N4FB08MYFjBUja4imH/lTCNy2zBYRAOeasarhlwVp4v6U98RlFB4Xv8rQgKwCpGP5jBGmCaQqBys4VEAJl9LQ6+HXVUti0rSMTj5IEntCgFIAUgAw9diEsx06qhrl3vwAbNu+OzqP0DwwE+YBm7gEZO3YsiC7ZLt/W1gbsJbPLS77KM5iWJfUg5EkoHD1tPvz25mWwecee6DxK1979sGxNszdYcguICApRHguDKp4XINhxmAKgs/MNCIEyclIN1CxcN3SY7+sbSPIklHpd9Cj/WPl2YlByAwgrbhEIujy2viheWVkJIS9W+Hx8xIgRwF5UrhO+aXkoQAiUk6fPh6tvXQ5bd3ZG6VGSnFMyB0QkZh0MonJRO3xeSECobRYEXdwUAJ1daEAIlJGTa6B20UuwcWsHxOhRXECxAoREkDSkHRTb4UUsEr9pHt8Wn046bpP6OijYcp3wTcvTAoRAOXl6Pfxx7grY0dqV+qNTkg7xUwS2kBgBYiIMFxtewJg2hUFkJ2qPzXMZo0sdFgJd3BQClV3agBAox02ugfn3vxydR7GBpAAkwNlEBwVbrhK+aVlWgBAoY86rh2urV8Kuj/Ym2eBTrWsKySFA2EXDOPsY5LKLmtRhd3eKizyDaR61IQtNxuTDhp9LVdoUApVd1oAQKMefPQ8aFr8CLdv2QF9//l/1MoGkQrV4WOZDMLI2REI2hUFkJ2qP8mRjCJGvm1O+XCV+k7K8AEKgnDqjAa6btwo+bO9J1SvYdlYAwrxpGAIEUZu8+E3SJhCobPIGCIFywjnzoPHBV6Flez49SpSA4I4v8g66PPIUolAk5FB5JkDwNirxm5TlFRAE5ajxs+C0GQ3w57pnoK3jY9tNPri9DhLtIxYuZigxYbsiQetgEJWL2sG8kGNn2+ZFb5M2gUBlk2dAyJtgeNLUOrjroddh845O6M/JGSVKQFDYIghkeTI4bESapa1K/CZlsQBCHmXsd26H6+ufhY7O3uAeQteBF0BIPOyO6TMuErgMBlG+qD6NOYbQBAKVTUyAsB7lxCm1sGDJ67BtV1emHkUFidEjlg+RqYASCRzzRDDI8tg2fIw37TZUAOjKYgUEYflMZRWMv7AJbmp8HvZ079Nt+EHKcwGITnCswCkug0GUT3Uw1PWVx3IdBKrymAFhPcqoKbVDZxT8UGSaZ5QoAEHRsiLHuAgEWR7VzaP4TcakAkBXViqAkEcZN7MRqppWQ3fP/iAeg280WkBsICkA4Zf9cJp+1YTdrWOI46te9zz8RvAzSjSAJPEiBSCHgeBjsQKCEB9dWQWVFzbBzXeugZ7eA/yteUmXDSAmjzJ5ttE9SsnKS+kRS+XZTppWBwv//iZsb+0C/Magr7+oAOG9iOzMweejB8mz+E3GJgNAl18ugJBHmXBRE8y5ay307j/oixHp90T+B7kri9Q1LZ2DAAAAAElFTkSuQmCC" + } + ] +} \ No newline at end of file diff --git a/strings/exoadventures/quantum_fizzics.json b/strings/exoadventures/quantum_fizzics.json new file mode 100644 index 00000000000000..0ee9bf9bf6806d --- /dev/null +++ b/strings/exoadventures/quantum_fizzics.json @@ -0,0 +1,195 @@ +{ + "adventure_name": "Quantum Fizz-ics", + "version": 1, + "author": "EOBGames", + "starting_node": "start", + "starting_qualities": { + "jammed": 0 + }, + "required_site_traits": [ + "technology present", + "in space" + ], + "loot_categories": [ + "unique" + ], + "scan_band_mods": { + "Narrow-band radio waves": 10 + }, + "deep_scan_description": "", + "triggers": [], + "nodes": [ + { + "name": "start", + "description": "As you sweep through the inky void and the site comes into view, you're puzzled by what you see. On a small asteroid sits a vending machine. Despite the odd runes lining its surface, you're fairly certain that the image on the front is a can of soda. While ordinary common sense would dictate that drinking strange alien soda is a bad idea, you can't help but be curious about what exactly this machine dispenses. There's one problem, however- what currency does this thing take?", + "choices": [ + { + "key": "choice 0", + "name": "Leave.", + "exit_node": "FAIL", + "delay": 10, + "delay_message": "There are better ways to die than drinking alien soda." + }, + { + "key": "choice 1", + "name": "Try a holocredit chit.", + "exit_node": "it's_stuck", + "requirements": [ + { + "quality": "jammed", + "operator": "!=", + "value": 1 + } + ], + "delay": 10, + "delay_message": "Hopefully whoever made this machine is part of the Galactic Currency Union..." + }, + { + "key": "choice 4", + "name": "Ram the machine.", + "exit_node": "smashing", + "delay": 30, + "delay_message": "Ramming speed!" + }, + { + "key": "choice 5", + "name": "Search around for some loose change.", + "exit_node": "lost_wallet", + "requirements": [ + { + "quality": "have_coin", + "operator": "!=", + "value": 1 + } + ], + "delay": 100, + "delay_message": "There's a surprising amount of stuff on this asteroid to search..." + }, + { + "key": "choice 6", + "name": "Use the coin you found.", + "exit_node": "choices_choices", + "requirements": [ + { + "quality": "jammed", + "operator": "==", + "value": 0 + }, + { + "quality": "have_coin", + "operator": "==", + "value": 1 + } + ], + "delay": 10, + "delay_message": "Thank God for clumsy aliens!" + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAAAXNSR0IArs4c6QAAGZlJREFUeJzlXT2vVNcVPYyfLJBw5MKWHMfJj3BJB64okBKnSOfCmIJHa2FFshzZsuTkKS2PApMiXSwFI1G8yo+O0j8iIY4lu7ACEggJkQKdeXvWrLX2PnfmMfC8JTT3no/9cc7+WOfOm8uxV15+/UkLdPvO3vz69KmzbSqdPH6i3X/4YHL/unifPH6itdYWxqv52M7mVvTq8yI5efjpxkwhNzfqysbcvrO34Aej+oyuIc5164J6s/1z+1mxYYYNfTFOnzpLN7pKUzdzCu+u58njJ9rtO3sL/WyBRuQwWVFebGNyMVDj/DgGeSo+VWJyVOCinX1cT5YxaTqHRf5KPltDnBPnKZ6oNyanfo9zGCnfOIYVZNNUze6MsPplGYW1YxVwm4T9LONFPhXeVVvd2IqTVfm7ClLhr8axMX1cRT+3t1MqhaKFAFmlnFfK+JTNGoUdfUOd40yBBi4oGDGoxYJkRJ+pQbNqwKkxI3JUolAQU11X9Z3qV13HTjM2IcuarE2V8c5XKaswO/JlbRl0UHCFUS/FqkQzmY5/tNsFWdVx3fpmY1lAI9yJdir4E+1y/Ngn8wG3Bgw6RX3YvZrPSMnE9pmbEIVnmRTHxTFuwR2NjkfM7GTj4kZnjnMy6KUyqMK/Kiu6zY6UZexszZh9mV4VfZSzs4QS1ybzDVX1XZA6PqzdzaNnkClwaUpJw74RCKR4MMzcqQIdsrGj2BmdIhvvdJuKo6u8GAxScxwc6jzifafKHCUDaVWfiTIUbJSH9CoGjONXUbTKUzmxcs4KPlUYOBJuhttUpl9FLzXm3qMflvpfefl1uT5uw6cSJjGUq8b0cSxwKmvKkgqTzcajPKWz4nfy+Im2pYQgBlQUyzSDMSpjZE7G8GDm8Az+qI3p15FH/GT2OLvYRrqMjLIwCO49Ori+fGZnfr2zf7ld3N5uV3d3F8a88vLrS7aPktM3g5QIL7FN8Y3tTpfYhmNQL9Wm1sTty1ZWSnGiMo45tFIiW7Rqto46qeylZGSZxjk+yla6xfH//d+/5u3dsVUQVOji9vbC/dXd3YV7DJios9MXr1WSwP1WCSNLEmr9YpIZQTKqejKEgDawtq1qlKlFYEL6WObo1cyWVTAVlG6BFC9nS2XjOsUqgEEwGgCjlAXML3/xmzTDs0qs9jySCqLOg/mA02GEKpW8Ul1U2xxiZRAAGTnBLHsoPsrISqZg9y5rKF1d1Yh2tPa0EsTMH+mwg2CEVMDce3RQXVrjCc3Bmt5WSZCdsmqkqrnjqSo5yhtBQyxBzAOkGlHZISn2ZZCoj3FnHnZmYOUyznWZ0QUwK+n3Hv2wEhR6XqgHDFaWSCxRqEqM81wywn1jSYyNR3kukBgkVzzZOJVw6SHdURUiZVUgK7FZdWJy3PlDbTqDS5gZX9SgGCF3hlOkkAX2Y6WOMt1cdwZh/FRQs351j3Yt/bEiM4Apw4xkGagCYdAIZhT2M2NcdnOLoXD3USUGfXEd2ZrjXrL+yA/3PcpRVZ/pEnlUAtglUaZXnINzaYA4HOkUUXBJRTaDW2iEkoVtGMTVvsr9USPM6MrpMclF51XnBHaN8tRcVWWcwzM+WYKrIJvObyFAqgKmCGdnAOxzmDDqp9pcgCodcOOdDUeF1Dq76olVBNEB8kJ+rMooOSNVQlWbqKvime35/YcPFgMEHccJ7u0sG8V+Vs6Ysbg51WDpfbf2byyNdcHDgoWV/6NIDMq4M4I6QygoxXhmVSCDOtU2FqQ4voJGOs0qMKmihMOzOIedA1hZVjJw4+IfKVadXeHSytyjRipgpjobg9I4z0E0p2fUF9sYRER5LKgRBkbdZtWSFpWJBrm5WZ/qVxVDVYT4K0g2tgId2WYeVajFKj6DTCqJOFiWJTqmQ+RTOec4Hdk8phu7Z1Vsxhiqe+Y8ldLIlFIRrkod6oNzzp15d4kvy4zKpgxOHCVy1bm1/BE9268pQaIqUmWOcnYW6ExG5IfBH/1n6XsQBq9YZCocx5ye3as2xof1OTlKV7apDgJOoZ39y6Vxm/xuBc9enfBcxuB2H4f8MnlZOyaoqGdFd6RVxkS5SwHCFkNBG0bRgdERs9KIi6TKegaZUEcMJtwEx6tCMSjwTzzknN2DOZsMFgedlKO6c8eIvNjW+TKZzo9iP9rhfJn5GCP7t1i37+y1c2felYJYsDinVtXCGaMMcIvg9MjmjwZM//NzR2+/c25+/e03t1pri4G0s3uZBglWo3UFkksg/bNSJViiYX1MbvxUFT6zIaNMZ2dj10/+5LY/Gbq1f2MJ3+H47LBTUbzPw2xfwcMZP3e+YJi0Sio4fvrx+/m/t985Nw+Kb7+5tRAsnS5ub8+DYWf/8vzf5598Mf+3bsK1qFSJW/s30jFMDpIKqmxv3DUb2/cfk2a0Xe39EsRCxz996uzSz1fdGcJVEgdn2Hx17nGGKL2y8ZlN6i93Ff304/cL9/v/uNbO/OFCa63R4GA0GhC7V67Ivu1Ll5baGN5n7bG/f8+Eb41hcyIvVilQdhUtRL5qDAs61ef49nlbjEkMEpxUUSojhS9dtcgqidJjBO6NyOp0dXd3oYq8+tobNEhefe0NywPp48/+2D7/5Iv20Ydft7/89XdWBxYErfnAiaQwfaRzZ95tt/ZvLDwtZMHl9qDPY5SdJ1mbqhguEONYts/ol1uKSWTEJjNhTLjKNGphlHNm8+KYkaqk9KrS+WtP2tULx+b3F7e3bTB0ikFx/tqTdj3waO2gimTBMZWc47H++w8fzM+j1XVyzhqJjWGOq/afOTxLwGqu0r21tvh7kCwLZM6sIBUKVcoruMZ4xHGRjwto9cnGj1SR89cO3ntxFRy9MofRSAUZJeVsDo6wPVVJMspgyTPyxHu1NyqBM7uYDS7wVXJvjZxB2KBqVmftzvljqYwyK1VFVQRHrpxWgrNCmeNX6TArCDpLBWJlCSab08ewYMoqBtv7zCamS5Sl9jnOvX1n7+lLG6pMKjgPeSlF2b0LgopBWdll+iL/KcHx5QetffBlPkYRm3uYFaTTKGR1aEHxZrDNBQnydcHB+lTwsmrC/DnOOXfm3acvbXAZmmV8FiS4qMoI5O8WA7MV48sWIatCKtuwhDD6FMtRFkSRDrOCsL1jFd9VCAahVDtLvCrBuj1hOruElsEyhlqwP/1bLBWFTki/diUcswlbABzvMjz2swWP8lhiyAJ2HdQriasorT2tIK219tGHX0+WpZ5uVSFIv2fVFbMwo7jHquI4uIc+hD7G9MD9ZKgiysuCZ4ZCmAHKcR0xZ4zCcQFcFKMeruziPJSHc7IstG764MsaJDvsp1iRWLZXiQMTkXJYnKvaVAB0UlCJQSack0G4SkJcesyLirNJKppR4Qq8wnEM2uG4KQHLNtTJ6nLWCbFaOwiOLEhGziCjXxS2xp/YMedx64NjsV0Rg1osSBkvVelwHAYAg35KXhyzxTpcdGJ7pnBW0rBdGeAwa5XUZipYdhiVpQfFuisICwQVOLh+DNqMQihWFVji7aTkxT5X+ZW8OE7BbKUX61v6Jl1FHWtjsKcaqSwrRFJO26+rGQ3nqGB0ulRInSliIFTGdHoWT7FU4lHYnTkiS1ZZhVd8oiwGp5T/ZMFcTQbMHyzEYkarYGILwO5VuWRtuFGZ8WyMcwImz8lSVHk6NfIEq7XD/x6kUtFxX1mydHNVco1zWuPVIF4rOKZgchagURbah/0zpmQfrCITo1Ap5ZwPF1EFQyUbucBhvFwmYbZllD2ROqy5U8lBSOYkKnOr8cpZ0ZmVz7nEG9vZp/MnhibQTkQXM5U1FSRhRqFAprDKRtFo5pxsc1gWijzcYjL7so3YBP3nx3+31g4e9x4WORuVE+EYlvBckPRPBqEcZKugBbWnFftZMM+wQ5VN58AsG6MRqiyyOYqQF+rLDHc8FYybUkVaq3/HUaFfvfbr1ZkIYsiAwc5+jXuvqkgWQKwNnbqy7sp/3Hy0NYN3fRx9syJzbrxmVYEp3QUxvsyIirGMN+qJfFk7bkymX0bV7zgq1CtIhdSj3OwRr9rDTmrf3P6x7O/a+7VCJ0wvFoTM4RlKQT9WCKcT/SadGezIZRzmnMoY5FlxVDWGLZqCTi7zjVD8jmNVOuwKoio6y8pxHiYxdZ1BWuYTLNkpmMagkYLyDuLFOUznGWPESqZiEpkx41TmZsa5gFHtqvxXA3MVSIVU/Y5jhCq/LlTfd7jvQdhnJIbHETmwzMzm9WvlqJ2Xg1wsgWG7QgpsXoVOHj/hf1E4FXagoo4/zmPtcV62IE6u0rXPU3pWKPuOY6Sq9IP5YfwWvVMFg+N4VomzoKnsAYPmbi5mfVYFGM+KfJS38D0IGssMxYhnRrBKoBTIFpfxixuVGa2CLfKt8GN0+cxO27lwrLWW/wbEVZXrF47N31gS31zy8We1d2x12r1ypW1fujT/VKSyciTXp6oL9rHxnTerJmyOg084thLgDgqy5EhfHIeGKCZIDNKgc7NMxDIS6qCMuLV/Y+GVozgX7aqMiXKzv8U6CJKnVP3BVPyJrXqdz+hrfirBgaQyd7/vn3Hv1D5nVVf1qYBh8KxaGTAgcHwWyAsVxGVlDAjWpxRzcMUtKG6EWtj40urTp87SSpNBM7aQUypJp53iT24P42Vx1QqiKj7LriwYIh8FkyNfBoFwDCMXFL0/QzBO1/4SChdIW8xZMhxeiXhWBVi/W9AsK8VXE6mFVxUPFz/DyVXa5FsSe1CMVJBIGQTBMQxqxXaXVLMkFccy2ZFGEE5v768xim9qYbT0i0JWTVhZReWybF+pKmq8C+L4Ghrkq+ZnVMHozxtVX/HTidno1onBUlVNcO+YbMbPVaRKVXd7jG34GiM1fos5UTRClV91fqgs8lTHq0I1F9S4eQpidT7r/j3IYdDUitGaz+5sbdje45zep/ioPgfnFBxU4xmhLa5ydFo4gzjHZ5Apjot9cZ5TnDl25FGBWiobMd3jvQs2xuso0Vdf/XnTKmyM3n/v0/l1pSrNIdYo9nal2WUWJAfRVLZSeuA8JXfEQc7+9nx57KZoyi8KXxS6+/jN9tZL362N39/+/qfSuPff+7Tdf/jg4LU/FQzPSmX8xGscr+ZFqBPnVSEbo59Tllz11aPrpnU59bqDY4R6IG05TK8gR3YuYbCHOXoFy7p2lF/NDkeVekBsumpUnLri/M8qOJwuC18UOlyeVRpG2WGePQVRh26kFyUYKv/j1DoeDcfvPka/LJxC6FSj2X5TlYHRWy99t6B/vF56aUP/dPifPdVAmMTGqqoSg+9Fg0ZZAGT/uQ57s/uzJOfYrg/bnxWkOizYFXnGa3oGieSgUbx254He96I5f5Wq/+3aYVL/Br1fV8lVgcPK8srJK/LWBd9w7N3Hb1L+9AzSmv7muV+zcVMqwNSMsMkD3PNKq8AqhBitrTdAIs8RvlVdov6jweHmbDFY1Ilh/3XDoOfByRX+fNHJBYyrFtW1GDmH9CzNxrj1r+6FO0eMVCwcu/TXvJ02dQiuOug6nfgoBkdGlXOHc+TK+Exmn4sBofZh5Lyk9jTbY5S/1drzdTYYyVjPUvZRpQhhIh7PsnynzJErVaV64EcdY1uU5fRnlQZlLlSQVSvFup125MlJxsMt2DopPol6Hg7sGamsH9tcFsd5yDfOd4ESA83pGAn1dgGW2ansiCQhVpXW9ViOldspxBZlpMSOEn6HsbO72mPfZ0EjOL33sfGRV79W+zjy1EolNtZerQRTaeUAyWjkkLUqjXw7W33mPkrZl35ZAG2KKtAq3o/CppHEpM40WaJzshmPil6TAmSVLOwWb9WnSSPjN3Xe2OQPqpAQy7eWP0Wa+gBlBGlk/pA9KHB+lNmH/fTFcauSy7wVXKnGVWVUxkfYoPj9XA7tav3Vmk29z3TAYK36gwviLMBRR+yfFCAZVh09jLH7bHGnVBdWalVW+rkQYvjK2Ow+8wO15+vag6oPKZn9+5rWTIBMwd8ZLo181aKMOOxI4KEeI7Szf3n+70Wm+LQtOkEkln2nVAbHO0uwmcwsANQBvkrxjHVs7+Z1+Z6akXPAyBcyI4e4dWUXp9+I7u4HVM/ifLGzf3noSVgMir2b1+n3CBVy+zN13zI/GD2HZrZNOddOPqSjAuhgTDH3BMRVn0yXbBOYflMPot3J4rjOb9PB09ryXwfv3by+cK+e9IyQOzBHOXG8Gxt5jgThKjpVyQZIVZB75BbHj2aTSn9WpdScSqYarYrRGZH/hd+flba1tloAYZVwNPWJ4SoBpfwlO4Sv4i+Ool9mfCzEUkq5jDDV0Uf6u2y1yZkjR92zx85xrCPmeFV5rdWhW4dYMSiu/XNvSEfVF/WszKlQti+jcHsEEra2OjRfCJBVFyOjqbi3ksnZE6oRGUq/0SAcOetkuvRrFjyqWrm2ityjQlVY1pr3l3IFmRrVFWdehXfko+axIMA5iveo44xkScV/pBpWIeAUmhrQ6+DtxmZVep1EH/NGJ8qEO+fv/civ4894Nrn7+OCxI8Io5Bl5q3MG0xEPcoqvsk3ZGHWsBCJicLQ9w+aqr2ITk6dsQydk+1jRcxVS51u8H4Ve8d6tGQ2QzPDMaVkbOn1UNjoMW3iWLdS9I+QfAzAL7CiL9WFbNev3sVGnKGvEPiWX6arkqSCrOCGbN+InbB5LOBmpsaoSOV1m1YwTKTpzppByvvjJ+hyPSnZWhFnbVSF1NlGZtOqcjtz4KU5SCbQMxvXPLAFU20ZoCnyqjq2Mm1U2TG2ScwxUZCSjsj6V8dh4V2XUgrvsl2V8NbfqeMg7flbPTMg78okJTVUHdY980D5mA/Zje6Y7ys3Gsv1lfVk1Yu0zNyA7HE2lDLNn5V71MYiGMhDu4ZhMBrOjsiZZNc0qpJqP/JUtWWKoOBvj4xJV1SGnJAGUhfNdAhuRMYsKZjh6XWcBJmvK2KykV6BQluUqcE31qcrjgljpgTxdX+zPgkZVaDUHE4yyM7NNyRwlBcnjfTXJMFo6pFcdV+FzbHNnBLUZKiNUKgvKiVm+msEz+DUKLViWczwy+Bb7VMavOjw6TbVixvFufUYdEuc7GkmQvS9LMqjHyr8HmVrCKoumMgHKYDCBYWdX8rOFZXq47OkgT6WaMSxedWR37lG2ZVW1j1GBxwKNOaTTrWpHHO+SEcpWwepg4gwVwZKUMWLz43U2hy1sRa4zVmXeDBuraoibXnVSBy3YhrlszwLGjavopCoVC3oVnOiMjOcoIpkSRA5Kon5YCV0CsxCriiU7U3SgrJKohY59LuCUs6hFrsBClWVV1mdzXYBG/SrrE3liUlH3KA/5oS7RppGAQ56ML+OdwS7GDwmDlq25sl/5GPML+te8Cqu6SoMKVhdAOa2LaqeL01/pglmPwQeVbeIY1D8LRKV/tY05B7tWlUJds31168sqUFbJUH8lO5PrbGFy1Nowuvu4eAZxWRHHRMVGsiTOi4apypRVLdw0LLNsHOrm2lylYJkqEkISVbVYhq5UW6U3rpVaV2Ufy7bM0ZxtTDfFl8nFdVG2oWzkwdYGbZjhIGdEVQG3COgYeM94sgyoKkpcPAehsoCP8lRVU3ZmPJ3jVIKVOUZ0dlXZcQ8qe6mCRlUt1Bl1xYTokparoM5etZbM76KNKKu1cAZxm88UjZ8sGzpF3cY4Ypkyk+PKK+Ph+Dk5LPDjJ3OUuMHMkRkfpWclC8c25oDIW1VCFiS9XVVzVWlc9VO82X6ptWcJSSUEllwtxGIOpiI3U0AZ6BYIKwsar5yfLSDTnemfZUJsV05WtQfHZoHFxiBvtmYuwBhPN8dVdaaXksnQQGV9XDCpT8WPJaKow7G9m9efuI1mTBmpoKhkIFV5lA5qkZxeFR4ugJ2NqDvaVpGprlmWHlk7lrQq+5HZU9knXCOnJ853+7bKHIciGI9ZRWEUwrINZtnMyZgh/ZpBBqZnljVRhspwWWZj1UbZjc6BfSiPtTE+OJ7Zgbq7uUoWcxQ3h9mrsrFaJ7ZGSKr6ZrawZID9LuiXflHIsooSrjZR9SmelcyKOjKHjXORnHOobO14Zbaq+a76KLuyrO3WGuerTDtaRZgOLCtjP167uaraMZ4ZZRVI0dL3IKhoZjjOyTZTBRySC4JKiWZy3QZgNRwJDBf4yqbIT1UErGRMFzVHEQuA6lpkiUDBuVGU4qoSto0ESZUiz9IvCl2l6AxxXm9n8InJYW1sfOY4imdFRwePonx0pLhZDBqibgj3GNxQweiqF3N4dHa1BqibgkBu/TJ/YDxUMGRJiiUVt49xXZQ/sz2xv0nHQIkLzhYmKhPnVDcbZatFYO2uX+nJdIrjmK1OdxesbmNQp8xp1DgmmwWjq3xx3ZltWTWvJLHIJ3NcTDauWlT2Ae1z41oLZxAWPZgh2bjMSbHNfaJM1KeqkzOcUSZbzVdrllXJOJ+tAequ1qyiU2Vexs/NqUAct57ZvWtfh24Zrxk6R7yOUcsye2Qex+N15Mmyi3LQOBerF45TECJmJwYdVKBljhvLNq6Lyroq42eVR222yroOflT0QV5VGUov5ltOHtOtGhyom7ORVVOk0surs4oQFWNzXEatLAS2I28VHEqua2fVwFWWSnZ0WZ2NZfKc3oyqVSOrMlVHHcnWShd2z/aVzcnsq8qO7a0VzyBOgMqaOKaaTVGHyBMrFJOLWSHLMljN0AZVWVm7gwrO+Vi7q2wODjF5qtIw3VU1i1XV8VF6MR2U8yPfSjJQ+mRVxAXHWy991/4P4sXXP8RtQZoAAAAASUVORK5CYII=" + }, + { + "name": "it's_stuck", + "description": "Well, only one way to find out, right? You produce a holocredit chit (helpfully taken from the science budget, I'm sure they won't miss it) and jam it into the slot. Then, you realise your mistake, as it sticks in the slot. Whoops. Time to try the old fashioned way, I suppose.", + "choices": [ + { + "key": "choice 2", + "name": "Time to try something a bit more daring?", + "exit_node": "start", + "on_selection_effects": [ + { + "effect_type": "Set", + "quality": "jammed", + "value": 1 + } + ], + "delay": 10, + "delay_message": "In hindsight, why would this accept human currency, anyway?" + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAAAXNSR0IArs4c6QAAAjVJREFUeJzt3cFyogAUAEGzlf//5ewpF0pGRJDnbvc1CkhleAbEfN1ut58bcNefqzcAJhMIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUD4vnLlW/854tdJz5+2HWuWy9+6HWdt77P/1PLo7d27H/cwQSBcMkFePSI8e+T5WXncUctZWlvP1uef5V2vd+9y1p7/aD1nMkEgvHWCTDgiXOH3dU6ZJNNN+j0xQSBcehZrae3siCPtff/aJJo0OX6ZIBBGTZDle3XuW+6fq/fXo/W/ev3H3yAw1FsnyP96Nues99ZTJu7R11PWJqTrIDDM1+3CA9CUz0BN2Y410z+Ltfdxz/780frOYIJAuHSCwHQmCASBQBAIhFFX0pfefZbq0XKPupPu2eW9+2zSVmctZxITBMLoCbK09069s86vT7uTca+j9s/E6xivMkEgfNQEWZr62a6jPiN19evABIH00RNkqq33Rywn36PHv7penmeCQDBBXvDqkX/rdZKjvp+K55kgED56glz9LRhn39/B9UwQCB81QfZemd36HvxdR/azzmLtNW3/TGKCQHBHIQQTBIJAIAgEgkAgCASCQCAIBIJAIAgEgkAgCASCQCAIBIJAIAgEgkAgCASCQCAIBIJAIAgEgkAgCASCQCAIBIJAIAgEgkAgCASCQCAIBMJfgqJi1hru29AAAAAASUVORK5CYII=" + }, + { + "name": "lost_wallet", + "description": "Searching around, you come across a lost wallet in a small crater. Flipping it open, inside you find a family photo of 3 identical looking grey aliens in comically different outfits, an (expired) credit card for a bank you've never heard of, a loyalty card to McDonkalds, and, in the coin pouch, a single black coin with glowing purple lines. This is (presumably) what you're looking for.", + "choices": [ + { + "key": "choice 3", + "name": "Return to the machine with the coin.", + "exit_node": "start", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "have_coin", + "value": 1 + } + ], + "delay": 10, + "delay_message": "It doesn't count as theft if you found it, right?" + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAAAXNSR0IArs4c6QAAC4dJREFUeJztnV+IVccdx7+7KyH7IKQmrptuSXzImj5E/POyf7LkoUJAMBiwjXQTXxKyS1wjSYubBoPQ4GLdtERMYlnFUkiyIWkEJQUhrQsRE9eXtWChRQ0YqyKGpqGBWgqufbjO3Zm5M+fMzJk553fOmQ8snnv+3bnrfPY3v9+cc27b8aOHbyMSqTjrn3zO6bhFntsRiRSKqwg8IwNrmstRkEhpySoDL4KOKEiEPL6jgg1RkAgp8ogKNkRBIoVQZFQw5eDps1GQSHioRQUVB0+fVa6PgkS8UZaoYEMUJGJNGUQA7GWQGRlYEwWJJFMnGVREQSIAogg6oiA1pAxJM5C/DCqiIBWmLFEBoCEDD2tPFKQilCUqANlkCCWCjihIyYhRwR2X9kRBCFOXqADQkIGHtScKQoAyRQWgWjKktSUKkjMxKrhTRHuiIIGIUSEbVNoTBfFAmaICQKfzMai1hycKYkHZogJAq6QK0GtPGlEQDTEqZINae1ypvSB1iwpAlMGGWglStqgA0Ot81NoTAv4zVlKQGBX8ULZ8wYVKX2pSRhEAejJQa09IKntHYZTBD9TaExLXzzp19cnmMjlBogj+oNimUPiQQUWhgpQxaQZodrw65As8oYSQyUWQskYFgJ4M1NqTB3nJoMK7IGWNCgC9v8J1lAFw+9w+ZFDhLEiMCn6h2KY8KDI6mGAkSF2jAhCHSL6hFB1MEAQpc1QA6HU+au3JG+rRwYQ2AE7fMBVFEKHYprwpW3QwwWiIFWUQ8ZXMZ/1sRVKF6GCCEEGK/itGTYY82sO/R9G//ySqGB1MWFTGShK1qADQ7ty21CU6mBB8opBix/M5tCm7GFGGZLwKUjUZdO2JuUN9aBsZWONUxaImQ97t8Zk7hMpDogzZSY0g1EQAaLaJAnVNpFW0z44q18/3T1mdRxCEYsej2CYqVF2Ir6f6WtYtHT2TeIxODHm7qSikJgqpVbaS8D0ssj2fye/KRYaRG//Tv2fXXdbns0UlhUySJGmC8JhIkjrEoiYCQG/i8uDpsyQiVZbokCSGah/fspiIwe+bFkme37ReeH3oyPGWbYeOHE+VRBAkyiBCuVo1MrBGaJ/vaGFy7JHnriu3/fOTB6zOZSNHVmRx0vA6UVhWGSiIwHf4PCJSFjl0YjDufeIyAHtRbDCJIjzPb1ovRBFTnOdBypQv8PiUmIJYLrjKkSaGzL1PXLaW5LXXXxVe7961R7mNX5+F9tnRxGFWKcu8poRue95/9ZPef7TnqNEwKy85GC6S8Lz2+qtaGVRRZL5/Cu2zozh05LhyOGUbRciXeU3xGdH4Tm+yf1nIWw5Tlo6eSc1D5MhigsuQSmaRa8eqigyu7x/i8xcdkaoIyz2+N7FTWP+vnRNGxxdS5jWFSkR7evtXAID39z/YXFe2DpwlKc8DFkV279qTGi1s8g/tUOvOv2llXjL3g1CRgcG3hwkCiJKw9yz6uiyTcm/IqlUapjmIPMxiouiEsJkw5CMIHz3e239C2G94+qLwupD7QULI4HJOl8/+9PavmpKEiCJ1HmbJuYivShWwIMV7+08AkhQ808MPCZKQvh8kqXP4KLHWrQOWAV4SVQUrqarFM98/henhh5zawF+vReZ+EJfhhMzHa9canePHc3PC+Wwl4aMIBVzKvTZsOtwdvJKlQpWPMDkubNyCpdAPsVzl4GmfHXUTJFS+4HJeUynkY3hJVPCd7v39Dwp5SNK+PqJSXYdZX1x/u7GwEeg99i4A9TDrwsYt4v4ABru3BWlT4ROFrud3EUM+nknC2uDSEevSgUNHEb6zAwsS2BzPJMkSPZ7Zvk54nftEocl7ZO38OtKiRpk7e+hhFuAmiUkFS5bDFV4SF4anL2IeF4UKmNNEoU0nMj2/bynSZFBh87mo5SF5YSNJnnLw8FFALuOawC5XATxOFNqK5lMIFxkYPmfW65KHbDrcrVyfxw1VSQx2b2uZ/3hm+7pMkmS6H6SI6JCnDDaJOnUOdt0VdDa9aDkA9d2ENnLIcyDz/VPmE4VVl8EFedKwaPLIQ7Iid+IhnAMAnFq+MtN5hy6da1k33z+F4f7Gsmvirhxi2fxn+xAiiwhAea+uTcP3MCtUFDGJHjb3itsiy2H75BIe5Ux6nkJUTQZdsk4tb2D4lsTX0Kr32LvWpV0bhqcvOkWRxCpWlKF8eYjJMMuHJK5i8A9M4F/v3rVHKNG6VLdsIsefPzmp3fa7777fXBaGWFmEoJ4vhKSMJV++g5vK4jMRl+8Rt7m/XObU8pVG8x9JUvA8u/gagIYoi1ykqLMMeZNHuTd0Bapx8eFfsGzV6pb7M5gk81j4698+O4ohnMucuGfl2cXX0udBogzuFJWHUKpmqW6l9XErrEzWWXQdgiBRhkgSurzAtGPyM9R8FNEJPHTJLookScKGTbY4PXq0ijKk3cmnu8OQR5WH+PpdZXk0aZYIYpIs6zqlHD2WrVqNobkOnFp7q7luaK4DJ7ceyPT+Jm2xFYQl6qTvSQ9FWlmbaok2BEt2/iJ5hxf9vM+yVauby0NzHcK2pAdKD3ZvM5Lk0s/2NfafztJK4Pd/+mVj4U5bgj96tEiKemILheuofOUhG9660lz+44s/aNluMrzi5fAFE0JGnugzgUULfjKTPVCusO8o9A21hz74hoJ0MmlyNEu3s2aC6J5yqJPBBn5uo2VWXzN/8uWWwfD3pIegCBnKNmFoQurwSoNrtWi+fwqY26pc7/NSFNso8uWWwTtL59A7JhYFyAtS9EPiXKBw4SKQPMz64vrb2IArukOVbHjrCr6Z+JVzex470CoHW88n7pQgI0gVhkj8jDrFIVFRNIdNiujRso8lumusdFGkES1aI4WOQgSpggxFUFfpXC80ZCwModT0jq3EhXcaVwRfeEeUh/RzsYD6yuALn7PqWYZXIUmKIn0dXcpjZBFU9I6tLN9zsYqkSol6I9HWJ+kT+BQA8MJEtiuyqTI5M45DY+pLXvgLKWv3BTp5EmJI5POcLCK4VrNsObn1gDApaPuNsyrY8KmvAzhz64bRMZMz4wDU3zolbyv8uVhVpUw5gjx0+u3OtcIyhShikof0dXQ1Jfnss183/uW2j/9oUlienBkXrglj2/ltlfkCHSpQvDfENg95YWJOkIQyZ27dEPIMJoYJTISkbaX8Ap0isclDqMyHZKWoKNJafRKjA6OPiwwmyJEkaVstL1bME+p5iA4fUURVXu0dW9jGL5tgEh3kDp+VSl+sWBTUHgcE5H8Tla7TP/bRxwCAC3hYWE5DNxQKTWUuVoz4h48iacMs0yjgC9+RQgeZS02qRuhkndKsuo0ch79+WLmcRl5CyLSNDKyxvqMw4n6HIVDcXYbyMSbDLDkP4aNIqKix98QO62NeWfdGgJbECBIUiiXfrIQeSjE5bDr83hM7sPfEDryy7g1cfWSz0TE9f/3QaL9241ZEyMFHjVDFADnv+PSB/wZ5Hx6dHPffd6z58+3ND5o/bP/vfnjJe1tiBIloaUaLHKTQcf99x4TXL314CgCwb/MQ/vaP/wjbFv99Of79iN/3j4I4YjphqBpmFZlUm5R7865I6ZDlAIC2tjbcvi2mzV1LjgLYga4lR9F17ajZyZcA56/eFFbd0/nTlt2iIBFjIR6/fHfgliwwOTOON596tGX9m089in2bh6zPd/7qTazo6RTWrejpxI1vGn8g2HBNliTmICUnax5iIsfjl+/OVQ5AX9Z9+aPPg7yfKnoAMYIEh2IVix9mTc6MFzbHoGOhktV4zc+i81FlRU8nfv4Hc2FUUSSNKEggdE9ZpDK5RxVWkWKlWwDYi+R5kd/8pHUoJrOipxPnr97USvLtzQ+Ux0VBMiAn6mn75tGOqohn0ukZLI9I456mF2Iiz+SISXoBUO2s1IdZppjK0ah0qdHlH0AUxDtUhSgbph0/9Pn+D1DTxdUMOqP+AAAAAElFTkSuQmCC" + }, + { + "name": "choices_choices", + "description": "You slip the coin into the slot- it's a perfect fit. Now comes the hard part: picking a button on the machine to press.", + "choices": [ + { + "key": "choice 7", + "name": "The red looking soda.", + "exit_node": "cha_clunk", + "delay": 10, + "delay_message": "How exciting..." + }, + { + "key": "choice 9", + "name": "The yellow looking soda.", + "exit_node": "cha_clunk", + "delay": 10, + "delay_message": "How exciting..." + }, + { + "key": "choice 10", + "name": "The green looking soda.", + "exit_node": "cha_clunk", + "delay": 10, + "delay_message": "How exciting..." + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAAAXNSR0IArs4c6QAAGZlJREFUeJzlXT2vVNcVPYyfLJBw5MKWHMfJj3BJB64okBKnSOfCmIJHa2FFshzZsuTkKS2PApMiXSwFI1G8yo+O0j8iIY4lu7ACEggJkQKdeXvWrLX2PnfmMfC8JTT3no/9cc7+WOfOm8uxV15+/UkLdPvO3vz69KmzbSqdPH6i3X/4YHL/unifPH6itdYWxqv52M7mVvTq8yI5efjpxkwhNzfqysbcvrO34Aej+oyuIc5164J6s/1z+1mxYYYNfTFOnzpLN7pKUzdzCu+u58njJ9rtO3sL/WyBRuQwWVFebGNyMVDj/DgGeSo+VWJyVOCinX1cT5YxaTqHRf5KPltDnBPnKZ6oNyanfo9zGCnfOIYVZNNUze6MsPplGYW1YxVwm4T9LONFPhXeVVvd2IqTVfm7ClLhr8axMX1cRT+3t1MqhaKFAFmlnFfK+JTNGoUdfUOd40yBBi4oGDGoxYJkRJ+pQbNqwKkxI3JUolAQU11X9Z3qV13HTjM2IcuarE2V8c5XKaswO/JlbRl0UHCFUS/FqkQzmY5/tNsFWdVx3fpmY1lAI9yJdir4E+1y/Ngn8wG3Bgw6RX3YvZrPSMnE9pmbEIVnmRTHxTFuwR2NjkfM7GTj4kZnjnMy6KUyqMK/Kiu6zY6UZexszZh9mV4VfZSzs4QS1ybzDVX1XZA6PqzdzaNnkClwaUpJw74RCKR4MMzcqQIdsrGj2BmdIhvvdJuKo6u8GAxScxwc6jzifafKHCUDaVWfiTIUbJSH9CoGjONXUbTKUzmxcs4KPlUYOBJuhttUpl9FLzXm3qMflvpfefl1uT5uw6cSJjGUq8b0cSxwKmvKkgqTzcajPKWz4nfy+Im2pYQgBlQUyzSDMSpjZE7G8GDm8Az+qI3p15FH/GT2OLvYRrqMjLIwCO49Ori+fGZnfr2zf7ld3N5uV3d3F8a88vLrS7aPktM3g5QIL7FN8Y3tTpfYhmNQL9Wm1sTty1ZWSnGiMo45tFIiW7Rqto46qeylZGSZxjk+yla6xfH//d+/5u3dsVUQVOji9vbC/dXd3YV7DJios9MXr1WSwP1WCSNLEmr9YpIZQTKqejKEgDawtq1qlKlFYEL6WObo1cyWVTAVlG6BFC9nS2XjOsUqgEEwGgCjlAXML3/xmzTDs0qs9jySCqLOg/mA02GEKpW8Ul1U2xxiZRAAGTnBLHsoPsrISqZg9y5rKF1d1Yh2tPa0EsTMH+mwg2CEVMDce3RQXVrjCc3Bmt5WSZCdsmqkqrnjqSo5yhtBQyxBzAOkGlHZISn2ZZCoj3FnHnZmYOUyznWZ0QUwK+n3Hv2wEhR6XqgHDFaWSCxRqEqM81wywn1jSYyNR3kukBgkVzzZOJVw6SHdURUiZVUgK7FZdWJy3PlDbTqDS5gZX9SgGCF3hlOkkAX2Y6WOMt1cdwZh/FRQs351j3Yt/bEiM4Apw4xkGagCYdAIZhT2M2NcdnOLoXD3USUGfXEd2ZrjXrL+yA/3PcpRVZ/pEnlUAtglUaZXnINzaYA4HOkUUXBJRTaDW2iEkoVtGMTVvsr9USPM6MrpMclF51XnBHaN8tRcVWWcwzM+WYKrIJvObyFAqgKmCGdnAOxzmDDqp9pcgCodcOOdDUeF1Dq76olVBNEB8kJ+rMooOSNVQlWbqKvime35/YcPFgMEHccJ7u0sG8V+Vs6Ysbg51WDpfbf2byyNdcHDgoWV/6NIDMq4M4I6QygoxXhmVSCDOtU2FqQ4voJGOs0qMKmihMOzOIedA1hZVjJw4+IfKVadXeHSytyjRipgpjobg9I4z0E0p2fUF9sYRER5LKgRBkbdZtWSFpWJBrm5WZ/qVxVDVYT4K0g2tgId2WYeVajFKj6DTCqJOFiWJTqmQ+RTOec4Hdk8phu7Z1Vsxhiqe+Y8ldLIlFIRrkod6oNzzp15d4kvy4zKpgxOHCVy1bm1/BE9268pQaIqUmWOcnYW6ExG5IfBH/1n6XsQBq9YZCocx5ye3as2xof1OTlKV7apDgJOoZ39y6Vxm/xuBc9enfBcxuB2H4f8MnlZOyaoqGdFd6RVxkS5SwHCFkNBG0bRgdERs9KIi6TKegaZUEcMJtwEx6tCMSjwTzzknN2DOZsMFgedlKO6c8eIvNjW+TKZzo9iP9rhfJn5GCP7t1i37+y1c2felYJYsDinVtXCGaMMcIvg9MjmjwZM//NzR2+/c25+/e03t1pri4G0s3uZBglWo3UFkksg/bNSJViiYX1MbvxUFT6zIaNMZ2dj10/+5LY/Gbq1f2MJ3+H47LBTUbzPw2xfwcMZP3e+YJi0Sio4fvrx+/m/t985Nw+Kb7+5tRAsnS5ub8+DYWf/8vzf5598Mf+3bsK1qFSJW/s30jFMDpIKqmxv3DUb2/cfk2a0Xe39EsRCxz996uzSz1fdGcJVEgdn2Hx17nGGKL2y8ZlN6i93Ff304/cL9/v/uNbO/OFCa63R4GA0GhC7V67Ivu1Ll5baGN5n7bG/f8+Eb41hcyIvVilQdhUtRL5qDAs61ef49nlbjEkMEpxUUSojhS9dtcgqidJjBO6NyOp0dXd3oYq8+tobNEhefe0NywPp48/+2D7/5Iv20Ydft7/89XdWBxYErfnAiaQwfaRzZ95tt/ZvLDwtZMHl9qDPY5SdJ1mbqhguEONYts/ol1uKSWTEJjNhTLjKNGphlHNm8+KYkaqk9KrS+WtP2tULx+b3F7e3bTB0ikFx/tqTdj3waO2gimTBMZWc47H++w8fzM+j1XVyzhqJjWGOq/afOTxLwGqu0r21tvh7kCwLZM6sIBUKVcoruMZ4xHGRjwto9cnGj1SR89cO3ntxFRy9MofRSAUZJeVsDo6wPVVJMspgyTPyxHu1NyqBM7uYDS7wVXJvjZxB2KBqVmftzvljqYwyK1VFVQRHrpxWgrNCmeNX6TArCDpLBWJlCSab08ewYMoqBtv7zCamS5Sl9jnOvX1n7+lLG6pMKjgPeSlF2b0LgopBWdll+iL/KcHx5QetffBlPkYRm3uYFaTTKGR1aEHxZrDNBQnydcHB+lTwsmrC/DnOOXfm3acvbXAZmmV8FiS4qMoI5O8WA7MV48sWIatCKtuwhDD6FMtRFkSRDrOCsL1jFd9VCAahVDtLvCrBuj1hOruElsEyhlqwP/1bLBWFTki/diUcswlbABzvMjz2swWP8lhiyAJ2HdQriasorT2tIK219tGHX0+WpZ5uVSFIv2fVFbMwo7jHquI4uIc+hD7G9MD9ZKgiysuCZ4ZCmAHKcR0xZ4zCcQFcFKMeruziPJSHc7IstG764MsaJDvsp1iRWLZXiQMTkXJYnKvaVAB0UlCJQSack0G4SkJcesyLirNJKppR4Qq8wnEM2uG4KQHLNtTJ6nLWCbFaOwiOLEhGziCjXxS2xp/YMedx64NjsV0Rg1osSBkvVelwHAYAg35KXhyzxTpcdGJ7pnBW0rBdGeAwa5XUZipYdhiVpQfFuisICwQVOLh+DNqMQihWFVji7aTkxT5X+ZW8OE7BbKUX61v6Jl1FHWtjsKcaqSwrRFJO26+rGQ3nqGB0ulRInSliIFTGdHoWT7FU4lHYnTkiS1ZZhVd8oiwGp5T/ZMFcTQbMHyzEYkarYGILwO5VuWRtuFGZ8WyMcwImz8lSVHk6NfIEq7XD/x6kUtFxX1mydHNVco1zWuPVIF4rOKZgchagURbah/0zpmQfrCITo1Ap5ZwPF1EFQyUbucBhvFwmYbZllD2ROqy5U8lBSOYkKnOr8cpZ0ZmVz7nEG9vZp/MnhibQTkQXM5U1FSRhRqFAprDKRtFo5pxsc1gWijzcYjL7so3YBP3nx3+31g4e9x4WORuVE+EYlvBckPRPBqEcZKugBbWnFftZMM+wQ5VN58AsG6MRqiyyOYqQF+rLDHc8FYybUkVaq3/HUaFfvfbr1ZkIYsiAwc5+jXuvqkgWQKwNnbqy7sp/3Hy0NYN3fRx9syJzbrxmVYEp3QUxvsyIirGMN+qJfFk7bkymX0bV7zgq1CtIhdSj3OwRr9rDTmrf3P6x7O/a+7VCJ0wvFoTM4RlKQT9WCKcT/SadGezIZRzmnMoY5FlxVDWGLZqCTi7zjVD8jmNVOuwKoio6y8pxHiYxdZ1BWuYTLNkpmMagkYLyDuLFOUznGWPESqZiEpkx41TmZsa5gFHtqvxXA3MVSIVU/Y5jhCq/LlTfd7jvQdhnJIbHETmwzMzm9WvlqJ2Xg1wsgWG7QgpsXoVOHj/hf1E4FXagoo4/zmPtcV62IE6u0rXPU3pWKPuOY6Sq9IP5YfwWvVMFg+N4VomzoKnsAYPmbi5mfVYFGM+KfJS38D0IGssMxYhnRrBKoBTIFpfxixuVGa2CLfKt8GN0+cxO27lwrLWW/wbEVZXrF47N31gS31zy8We1d2x12r1ypW1fujT/VKSyciTXp6oL9rHxnTerJmyOg084thLgDgqy5EhfHIeGKCZIDNKgc7NMxDIS6qCMuLV/Y+GVozgX7aqMiXKzv8U6CJKnVP3BVPyJrXqdz+hrfirBgaQyd7/vn3Hv1D5nVVf1qYBh8KxaGTAgcHwWyAsVxGVlDAjWpxRzcMUtKG6EWtj40urTp87SSpNBM7aQUypJp53iT24P42Vx1QqiKj7LriwYIh8FkyNfBoFwDCMXFL0/QzBO1/4SChdIW8xZMhxeiXhWBVi/W9AsK8VXE6mFVxUPFz/DyVXa5FsSe1CMVJBIGQTBMQxqxXaXVLMkFccy2ZFGEE5v768xim9qYbT0i0JWTVhZReWybF+pKmq8C+L4Ghrkq+ZnVMHozxtVX/HTidno1onBUlVNcO+YbMbPVaRKVXd7jG34GiM1fos5UTRClV91fqgs8lTHq0I1F9S4eQpidT7r/j3IYdDUitGaz+5sbdje45zep/ioPgfnFBxU4xmhLa5ydFo4gzjHZ5Apjot9cZ5TnDl25FGBWiobMd3jvQs2xuso0Vdf/XnTKmyM3n/v0/l1pSrNIdYo9nal2WUWJAfRVLZSeuA8JXfEQc7+9nx57KZoyi8KXxS6+/jN9tZL362N39/+/qfSuPff+7Tdf/jg4LU/FQzPSmX8xGscr+ZFqBPnVSEbo59Tllz11aPrpnU59bqDY4R6IG05TK8gR3YuYbCHOXoFy7p2lF/NDkeVekBsumpUnLri/M8qOJwuC18UOlyeVRpG2WGePQVRh26kFyUYKv/j1DoeDcfvPka/LJxC6FSj2X5TlYHRWy99t6B/vF56aUP/dPifPdVAmMTGqqoSg+9Fg0ZZAGT/uQ57s/uzJOfYrg/bnxWkOizYFXnGa3oGieSgUbx254He96I5f5Wq/+3aYVL/Br1fV8lVgcPK8srJK/LWBd9w7N3Hb1L+9AzSmv7muV+zcVMqwNSMsMkD3PNKq8AqhBitrTdAIs8RvlVdov6jweHmbDFY1Ilh/3XDoOfByRX+fNHJBYyrFtW1GDmH9CzNxrj1r+6FO0eMVCwcu/TXvJ02dQiuOug6nfgoBkdGlXOHc+TK+Exmn4sBofZh5Lyk9jTbY5S/1drzdTYYyVjPUvZRpQhhIh7PsnynzJErVaV64EcdY1uU5fRnlQZlLlSQVSvFup125MlJxsMt2DopPol6Hg7sGamsH9tcFsd5yDfOd4ESA83pGAn1dgGW2ansiCQhVpXW9ViOldspxBZlpMSOEn6HsbO72mPfZ0EjOL33sfGRV79W+zjy1EolNtZerQRTaeUAyWjkkLUqjXw7W33mPkrZl35ZAG2KKtAq3o/CppHEpM40WaJzshmPil6TAmSVLOwWb9WnSSPjN3Xe2OQPqpAQy7eWP0Wa+gBlBGlk/pA9KHB+lNmH/fTFcauSy7wVXKnGVWVUxkfYoPj9XA7tav3Vmk29z3TAYK36gwviLMBRR+yfFCAZVh09jLH7bHGnVBdWalVW+rkQYvjK2Ow+8wO15+vag6oPKZn9+5rWTIBMwd8ZLo181aKMOOxI4KEeI7Szf3n+70Wm+LQtOkEkln2nVAbHO0uwmcwsANQBvkrxjHVs7+Z1+Z6akXPAyBcyI4e4dWUXp9+I7u4HVM/ifLGzf3noSVgMir2b1+n3CBVy+zN13zI/GD2HZrZNOddOPqSjAuhgTDH3BMRVn0yXbBOYflMPot3J4rjOb9PB09ryXwfv3by+cK+e9IyQOzBHOXG8Gxt5jgThKjpVyQZIVZB75BbHj2aTSn9WpdScSqYarYrRGZH/hd+flba1tloAYZVwNPWJ4SoBpfwlO4Sv4i+Ool9mfCzEUkq5jDDV0Uf6u2y1yZkjR92zx85xrCPmeFV5rdWhW4dYMSiu/XNvSEfVF/WszKlQti+jcHsEEra2OjRfCJBVFyOjqbi3ksnZE6oRGUq/0SAcOetkuvRrFjyqWrm2ityjQlVY1pr3l3IFmRrVFWdehXfko+axIMA5iveo44xkScV/pBpWIeAUmhrQ6+DtxmZVep1EH/NGJ8qEO+fv/civ4894Nrn7+OCxI8Io5Bl5q3MG0xEPcoqvsk3ZGHWsBCJicLQ9w+aqr2ITk6dsQydk+1jRcxVS51u8H4Ve8d6tGQ2QzPDMaVkbOn1UNjoMW3iWLdS9I+QfAzAL7CiL9WFbNev3sVGnKGvEPiWX6arkqSCrOCGbN+InbB5LOBmpsaoSOV1m1YwTKTpzppByvvjJ+hyPSnZWhFnbVSF1NlGZtOqcjtz4KU5SCbQMxvXPLAFU20ZoCnyqjq2Mm1U2TG2ScwxUZCSjsj6V8dh4V2XUgrvsl2V8NbfqeMg7flbPTMg78okJTVUHdY980D5mA/Zje6Y7ys3Gsv1lfVk1Yu0zNyA7HE2lDLNn5V71MYiGMhDu4ZhMBrOjsiZZNc0qpJqP/JUtWWKoOBvj4xJV1SGnJAGUhfNdAhuRMYsKZjh6XWcBJmvK2KykV6BQluUqcE31qcrjgljpgTxdX+zPgkZVaDUHE4yyM7NNyRwlBcnjfTXJMFo6pFcdV+FzbHNnBLUZKiNUKgvKiVm+msEz+DUKLViWczwy+Bb7VMavOjw6TbVixvFufUYdEuc7GkmQvS9LMqjHyr8HmVrCKoumMgHKYDCBYWdX8rOFZXq47OkgT6WaMSxedWR37lG2ZVW1j1GBxwKNOaTTrWpHHO+SEcpWwepg4gwVwZKUMWLz43U2hy1sRa4zVmXeDBuraoibXnVSBy3YhrlszwLGjavopCoVC3oVnOiMjOcoIpkSRA5Kon5YCV0CsxCriiU7U3SgrJKohY59LuCUs6hFrsBClWVV1mdzXYBG/SrrE3liUlH3KA/5oS7RppGAQ56ML+OdwS7GDwmDlq25sl/5GPML+te8Cqu6SoMKVhdAOa2LaqeL01/pglmPwQeVbeIY1D8LRKV/tY05B7tWlUJds31168sqUFbJUH8lO5PrbGFy1Nowuvu4eAZxWRHHRMVGsiTOi4apypRVLdw0LLNsHOrm2lylYJkqEkISVbVYhq5UW6U3rpVaV2Ufy7bM0ZxtTDfFl8nFdVG2oWzkwdYGbZjhIGdEVQG3COgYeM94sgyoKkpcPAehsoCP8lRVU3ZmPJ3jVIKVOUZ0dlXZcQ8qe6mCRlUt1Bl1xYTokparoM5etZbM76KNKKu1cAZxm88UjZ8sGzpF3cY4Ypkyk+PKK+Ph+Dk5LPDjJ3OUuMHMkRkfpWclC8c25oDIW1VCFiS9XVVzVWlc9VO82X6ptWcJSSUEllwtxGIOpiI3U0AZ6BYIKwsar5yfLSDTnemfZUJsV05WtQfHZoHFxiBvtmYuwBhPN8dVdaaXksnQQGV9XDCpT8WPJaKow7G9m9efuI1mTBmpoKhkIFV5lA5qkZxeFR4ugJ2NqDvaVpGprlmWHlk7lrQq+5HZU9knXCOnJ853+7bKHIciGI9ZRWEUwrINZtnMyZgh/ZpBBqZnljVRhspwWWZj1UbZjc6BfSiPtTE+OJ7Zgbq7uUoWcxQ3h9mrsrFaJ7ZGSKr6ZrawZID9LuiXflHIsooSrjZR9SmelcyKOjKHjXORnHOobO14Zbaq+a76KLuyrO3WGuerTDtaRZgOLCtjP167uaraMZ4ZZRVI0dL3IKhoZjjOyTZTBRySC4JKiWZy3QZgNRwJDBf4yqbIT1UErGRMFzVHEQuA6lpkiUDBuVGU4qoSto0ESZUiz9IvCl2l6AxxXm9n8InJYW1sfOY4imdFRwePonx0pLhZDBqibgj3GNxQweiqF3N4dHa1BqibgkBu/TJ/YDxUMGRJiiUVt49xXZQ/sz2xv0nHQIkLzhYmKhPnVDcbZatFYO2uX+nJdIrjmK1OdxesbmNQp8xp1DgmmwWjq3xx3ZltWTWvJLHIJ3NcTDauWlT2Ae1z41oLZxAWPZgh2bjMSbHNfaJM1KeqkzOcUSZbzVdrllXJOJ+tAequ1qyiU2Vexs/NqUAct57ZvWtfh24Zrxk6R7yOUcsye2Qex+N15Mmyi3LQOBerF45TECJmJwYdVKBljhvLNq6Lyroq42eVR222yroOflT0QV5VGUov5ltOHtOtGhyom7ORVVOk0surs4oQFWNzXEatLAS2I28VHEqua2fVwFWWSnZ0WZ2NZfKc3oyqVSOrMlVHHcnWShd2z/aVzcnsq8qO7a0VzyBOgMqaOKaaTVGHyBMrFJOLWSHLMljN0AZVWVm7gwrO+Vi7q2wODjF5qtIw3VU1i1XV8VF6MR2U8yPfSjJQ+mRVxAXHWy991/4P4sXXP8RtQZoAAAAASUVORK5CYII=" + }, + { + "name": "cha_clunk", + "description": "With a satisfying cha-clunk, your fizzy prize drops into the tray. You swipe it, and move on from the site.", + "choices": [ + { + "key": "choice 11", + "name": "Sweet, sugary victory.", + "exit_node": "WIN", + "delay": 10, + "delay_message": "Hopefully this doesn't like, freeze solid in space. That would be bad, right?" + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAIAAABM5OhcAAAAAXNSR0IArs4c6QAAIABJREFUeJzsvXmcpVdVLrzWHt7pzKem7qqeO515TkgIIQwSQESQaIiADAooeK/XAZHrAF4V1E8ULpd7Rb0MooiAIE4XkEHBQBhCIPOcTnd6rO6uqjO+w57W+v441W2DEBLoJN2Nz6/+qFP11ql99vu8a6/9rGEj/Ce+ExCRmY9+Ofnmm37IwJPvgBAREXlyDSMAr/7y+wf4WA/gBMARJn0biNULUH7DxRwmLz25Cc0mRDyajicx/pNYAN+KOpOfHP1zZhZCfOMFAhEFKhBCCCFQrVoqwQCATEQUDoPJTt7k+4RY6rEewKOKI4vaNzEJj0AogAlPFCJOmISIkydwcgkctjpCrNoqJRMhBCoppZy8CTMHb0Nwzhly5LxxBhkCkYejjNZkPN+01J4c+P4iFhxNKYEAIFBNzI1SsRACpRZCSXmEIgIRpZQAIIQgWvWeiEgIgSjFKqRSKkliIYSUMjB47zkEa60xlS1yY8pKCOcsewDy3zSkk49V8CDEOvkeo1Vjg4AghRBSaimV1lrJSOtYa62TOIpTpZTWWig9sVgTrihUzBwgADIAIMHEmE0oqGQURVGaxRilApxgCB5K68bVuByNBoNBmY/luF9Vha2E99Z7P/HATmJ8W2KdlKxCRCGUlFoppeMsipI0TSOdJEmapqmOoyTLoiiK4zhOM0RUSq0udjxZKJmZiYgJpZQghVJKKRVFkda6VmvUxb4nXLD+9ltvsQ57y5QbvWc0v7jcGPZ7WuvxeFhKbasc0QZfndz+1vfFUnhk14ZCaR1FUZTEWVKrJ2ktrdfq9XotqzebzTStNZvNKIqSJEkihSpRiqRQSkwkBBYCkJkDTd4TpRAYRUmmIhlHUU3d/vSL03xwcM+di9b5pEnO6aS7NcrccnYwiqIoivIoGgwkQmERvbfMHgngpHuM4fuEWBMIobSO4rQWx3Gt1uh0p+v1Rqsz1W63G82s053qNJqNZhRFWmkx153etm1DkvksHtekFTRgM3Jl35fWGetdZa1lhCAosHdMzalOtz7UlENrnoUBia4E59zsfF03W/V6KoRQKlJKO09CCCgIAJxjwHDysQpOdGId7Qh+W92SJ8uYjFSkdRLHutnottudmbnZznR3/fqFdivuNuUTLz9129YpIQSKNsM0smE6JNwOP97h+vtMPoLSm6L0VTDG2eAJQgATFFhZnX/JuVIbROQAaRQJZTzJQOQ9Fvu+3l24vLF5PQodJbFSygWWUnrviYg5OMfM3+zOnwR4jIn1PW4RvmmvflgLmOznRCACRCFQqUhKFUdp1mi22u3pqbXTM52F+TWnnapf+dOnRbLi0Cd/OzpG3WSuoWwTBKReGB0MxQqYkbSFM5bLioxnEzh4x5Y0nf+MpxjTV4oBAoBgcI5GxpellaMKTEWD3u3b77hJJS0bNTeuuVDrDT6wEOCtE0zMFEJgEER0bCb0uMEJbLGOmKgjuuVEC1AymmgEgQkRhZBKRnEcZ41mvdGYmVnTnZ7duL79W6+/KI3uhfGtoBiYGBGB0QZUJVCOviRXoFnhaszWUFWydVRVwVAwwZNjdCQIghfgGOBwRCcAm8pWeUXjERkjRyX0qhJKK/nQYGm7SE6Znt5iqqKsjX2wzhvnTDjZSAXwmBPruzBXR2mbYlURkFIIJcRk7y9BrEpTh/eAUmudpmmj2W42WzNzC/Prp3/0CpWOviJSj0JBAARQ6JmQoBBeB5bCOWFLKsZcGMorKkwoyI6MseQcWQ5eBhYByAEhhzARIQRh8CYf5aMx93OsSi4LcBUzemABjny5e+P6c4fjTpmPjCmrSgmhAxOiO8k8re+GWI+txDVZ/ibDkCqSUsZxIoWOokRGWkqpdDwhEyJKqaSUUaTTNG22O61WZ2Fh7ZZ16zbN34FixAERVv0bZGACJiQWgpltgMpyZaE0UBFVlipiR2TIWTIcggoeCYgUCUIvhPjiF79y+SUXA4fhsBiMuD8WpoSyACIiZkIhCYMYtjLdbnby/vJ4PIqixBnjrT25SAXw3RHreHi2EOVE25RaxWktSbI4ydJ0IkclSq0aKimlUlEcx2madqZbU53umrXdbqOldSnIMwGjR2RmJgQgEkFAACbiypFhrhwbR4bIsDfkLFnrrSdH3nny3oElCrYs7T/986catSbbQIEqE6qSrJHGkA9iNYjETMCCsdGq1UtZW2pl2chUhSlzoSS5Iw7iYz+3xwQnno+FiIBSSC1VnCS1KM1azU6j0ag3m7VGo9Fo1Ov1icgZxXoiYCaJqjfSdr3RqGkEl+E9zdQJIOLABAzEzEAkArP34AL7EAxBxaEgKpkMWxOsAWOhMlg5KAIaZKsQrLr9rgOf/cIXMUL0FkhKkqby3mPwGAITwdFhSWbOsqzVinutZq1oGVPZsgohUDATvfSkCXicYLtCXP0rOTFIcZY2mq1GvbGwfrrbiufW1jrNuNXGWoadtpqejjrdWj0VCEFpk0ZWaQCuit5O4L5HQgZkBmIMhEDBkXQYDGFgrAIZZuPJUqjYGe8ceAcuUOW5sq4ELsh+/eu7Pv1vX4trTQVaCAUOTOWrygafERExIDKAOPoTCK3WzEz1lpdG40FRjHU8Vt5o75wzTAQcTg5uPTxiHXNz/d29FSJqHUU6yWqNequ9bn7zK19Qv/IyFCoGOdkbOsKBBIm4FBAYCZCAFRMjcSa9IEAGROBASMxE4EF6JOcxMBkHBtkGb9lZ9haCl96xqZz1VFmqnCq8L1h/7rO3o2xY4ypranFA9oMxOpLOB09AtJrmd/TsxXGaxVOddteUlTO2qqrAnrxhZu89E50ErIKHS6zH/DMzgJRaSimUknGSprVOo9vq4hMuXNB4PyODAEYKIBBlAAMgABAYgAHZAbNECsIRBUHEngEQAwhCCp48sfVsga1gS8EgGSITggFvgrFceSgtVJYL50tHhWcrAiOR8h64FkcUYP/iMgXFzByYgiRkAJaHTS2TFCiVimYX1ppgq6oYl1XwhXdN5iEAOScBA4QTnlsnno8VQphwK4qiWq3WaDTmu5HiQ8gA4IGYBQtGgCAEAAimw3IXAwAwB/ZeeMHscaJeBeJAwXv0wBbIMBkKhoMhMuwsVI4rS5Vl60JlQ+WpslQEyn0I7INg8EDI6+cXmOj2u3aEQETIjIeDzMwAiAKAhQwffe8ftOZPecLlz9ww08Ry2tnCm4IcQvAATEQTXfcxf4a/R5x4xBJCaK0nLlYc63rWmOuCgmUHQrJHQgwOZERIZAUFKQRIISiABS8YhEJyDCGwI4lMgYBYEKMnsgQOyVIwHKrgymCKYCyXFZsSjAtj68sAlcPKQ+WpchQwoGQAkCKcffYpxNX+fcsMgkDy5H1BSgIUDMCIQOwUjYa7b/jkh24k5gDxujOfVVVz5J1xlSMnnaHgTmxOAcCJSCwAmMiik3yVONG1NGgkZoAADBBYfuXznyutLkprKvJOmMoJIYkgEiqBeMvW2fVrullChKyYmJmI2QFb8MYHw2yDr8AarmwwFipLufOFAxvAhFA6rogscQAmYACWGCjYWDKHaHkwkjiR/pUK3h1OuxIYBAqBqCNgFsEHRBbgO814mLd7veUkyUxVCKEABMAJL8afGMQ6etNwJLd4olFpLdsNTcFKH7EEAOAAKwddmVwedZ8oSCYYa88AwgvQKBIR73Y0fOCmCzbcJBEcByAGZnAEjp0hMuQrZ0qwhouKC+urCgrDuaVxZUvPpYPKe0MUgAgYgRFCLAKwY0pZJZESsZJWAksIfrWkQklQSkgplSBE9EoHJgq4srwvq63PsnqZ51rHQkgECXDCh6VPDGIdHWYWq/6HWM25Q5ZkdJBOGMECQPnKjocsG5uqsMAIvZVer9e31gohkiRZMz2VJHEkF6rxXULnkQ/IAD6QZ3LBG7Y2OIu2cJWFwkBZUWF47O3Y8dhD4agKbJiJCKSXSEqQAHrOD16i2H39rr2dpCaBtcAYYE9lA7AWSirWSkaJ1BFIoTWSdcEFtA4Hh/bNnH56FKdCKakUAYDgE99gPRxiHQ/6ypGsywmrQggUMC+C9yCQUAJTEE65HAWnAKLf6+/cuXM4HBZFAQBpmo6Hg3Xza2vN7jjPUjEkJsHAnryjYCk4sIat4cKydVyWobBUOc4DFhUVnivPVWBPQEhCBiFIKk5keck5C4bg1lt2ZFmmRKiEyJXavm8ZhAYIQogopiSN1rXt1c++eMumtX/6/s/es2NEyBWZLMviONZaTxKmEeVjO8nHBA+DWA9PyXwkWRhCIPIhBPJgTZmbhINHQCBGIGahhDRFrhI7HPUHw3FvZaXMC0SZ6wI9oMxqkVw0Yi62yITM5JktV9Zbx9ZRUYWq4soG67h0XDgaB28c5D7YQJaY0CcxYrBJFkUif+1/fSFCeXDF7+/Z3NqqkKXjQwPyQgkgIbRSUtV0PZHPefZTzzm9jpJO2TS1e9F64WzlMx0rKZUQSk6qM77PiPWw8EjbthCC996Ywhi3UrYrmk3gIIAHYB3JdXP17b0d8dQlEoVEIQCR2LMFoMpVzhS5md5fdbXbqQOTD8EGa71xlFfeeTSWLIH1UDmqHFUBKwcmeOfREwVBQnAE8N9/+aXduY7L90sekdAf+shnlsayNFCMfWlxuTdmUCjUpBxDoFJps5RrqalQiHRqGqJlaVlICQKPylIMzI/2QvhIWIFHw8d62HGbB7teTEwMeUu2LE01HPf3rHR37tWnLtDkBnlTPe5x5wy+suJ0lSRRo14vizEzl2UZRZGSiUAFQkFjS2//14QprfHWsTG28ugcWg6OwREyS+ekm0j0WsUqRAkgBhSktUwzP1zea8b3z861OND2nf2DQ8pLLio1rrwxHFAJABTAQqKS9SiB2iy21kQLTWI1Lu9TwAIlorKhIppsTgm+t6LW744ij4QVeDSI9XDH/aDXEyCGEIjIWluW5Xg8Ho57n705W5iSWWInCwkq+7TL13765uun0kv7jVoIUxM1VUrZaNSbrXqaxV4v7BnXk9FSaWxlfWWxtOxJgBIsJQmBSIBYz5I40mkslRKTikIiyk0/1n5x7/2XXnZ2IG85e/9HP5FXujScl54CIsqJZDDZvUoRgWo94YprFtbPe2woIXbu+gBDwmCUzLwH55z3fvK5vseU2u/6b48tToxd4TeCKDhnjJFRmRejwWi0bO5NG9fd2vyB85ZIBwQAIAgrP3RR7fq7by2nNiQ6Sutx8KSErtXS6em2UkoK0Vl35u7r7ygqGlemqLgM0hMGATqOlRZpFLVqqdCynkWdZlZLZbud1dNsbm7mX/71M3Nr6t1uiqYCnb31f390mIuqgKpickggysoCi9WKe2at03hqY5zMb95wLkAJPiwvG8/KezO7dnNRFNZW3jsiTxz4pCg5PL6I9VAsOTMDhEDOeVMV46FSy0v7WYrPcHt+Vp8/v2TQAoBADMWe89ftPWt+t6V233RvumsZk3Uia6lIB6jUcPdlW3bdka+97st3Gwulw9KH3FFgSEmmHAkka60SyjlhrU2jCLyzZrx3T5ElcMG5p8d1V4ToD972N/0yHlVQWiiroKKkyIsA4khCohACks6Tn/pK5gEhRCH6yhc+UZpQWV9UuHVh293b91VVZa01xnh/witYExxfG5Dv1Nfl6CsFogBARggMEok97jjYGI7LrWsVsgMGQs8MMRuNy3U8sG1qdMrMntM6D8zr7evSfe3swPKBHaedMrtmzfT2BxYpsA9oQyBA4xgESgClhEJUCEqyEixFIAo+WCHCaLTUbs2/+X9/qJcnI4PGKesIZTQamxAQQAAIRJBSrdl8/g/+6H8rxzuued6ZEsq/+vN3f/oTH8tzX+XDUSVrU2ccPHSot7I8GvaLfOScCd7Bo+6/H3OckN1mEFd7b0RRnCRJVm+3W91Wqz29Zu1Md25TO7/gVLpwm6/hkKFSgMyMICZJnOFwEguTBJCjkbeuqCWdD33k8/cs+pWCK0cGUKCqJbKdRFONejOTnVrcakZTzSROtBBszACRP3HtrVWIRgEqyzYIEnE+toEwHE4ZzWJ97kWXtddsUzC2w9t27N7jQl2gIqKqqqzhmY1PHPl0/749B/bv6a0sjcd9U46DtydB0c43WKyHbjAeITzEAawGeAAAkBl8CETknBeBKjsaObFjuX3LLnnnDtcf2KlmU6gkkEcKzMgwaR2DAgIwMIR6vXPXnXc94bKzzti8/pY7d1vPRNIFb1wQKJFJSRErJSQmUYRCMPDi4nj3/pFIWipOEDILaDzmhQ8T4iIw8MxUK9Fy3959u3fcum/P9n1LBdmELBvvqsqYCmVjbdTZuG9x/3Blub/SK8rc2so78+jLDd8FvuOdOr6WwoeOSUOh1fgxrurw1ltTuapyVVWOcxq65t7+1C2727c+EN10T3Xr3ft27islppGsicCOFLMQXgZPU9Ozd973wJrZ9srAHuxbwxK8D569D1JJLUUc6ThSWS1J61Gc1nbtOegCGO9LQ4UJg9KNC2fCJNIEcRplkULEwtpADlhxAGQMIfgQLAUbkvWnXS6iheXl3tLBQ8NBrxj1jBl7V1EIcFI0/zu+nPeHjtXADnjyBBwqF4IxrjLleJTn+WDQT9M0rtWyJK4lrTiO42Q6TuejIG67O00TlWnZ1F4KX+UrRT4Yj/rVqJ5ft2tlGDqbnvKsp1/9mY+9f+fdXwL2w2GlmdNE6QjaLmMha81WYciSKC0UhgaFGwwrRwggEw0Xn33arffcS0EUpSdQAMBSlSykT+qt6YUN22qt+eVBvtgb9Ht7xv2VlaXlvBiUVW6tDeFk2A9OcEL6WEcDESfKtZRSyVRrHelEa50kmU6zOI7jOI6iKI6Tyc+jw5jE5iIVCyVBilhpKaWIZZLWalmz3W7H1P+rP/4t9ivdVKyf7bQb0Ux7WsVyODLb9xzQUgXB/dwsD4uh9QHS08+5opZmWRLpWkNglKaNOMsqx4VzzsBolJemqqoiH43z8XA06I3Ho/F4WI1HxpZVlTvnmIj5JGnlcFIQ66h+MoehoyietK0SsVYyiqIk1pFSSsfRalMrpSetrVggSiFRTPJwkiRJ0rQ1NTMzs3ZhtvmZ9//PRtg1Xcd2M1UyHlZVbxQO9fMAmoUb5dXIssXa1S97TXPutPF4OOj1R4N+WeZVVXnvjTHOl957WzlbmaqqyjK3VZmPh8YYY0pT5t476wpmBjp5mpSe8MQ6giPuJAq1KncLkFILpaXUk55YapISdZh8h/vxTZTMCbGU1HFWa3S709PTM/Pza+cXZnde+94FsTtNyHtf5bSSh3v3rwwKrMB5Ul4kP/6zb1TJ7P49u5eWlvqDXj4clGVunJ10/giVDeScs84555ytjHWVKfJAzloTgnPO8eE2fycHq+Axr9I5hjiSAMjkGTwTIqIDK6RElAA4qWKFVRqhOFyJD6vdROVq8z4dJ1nN5OOqzIkRI3XelS+lO/5sWpWV9XlkUbte3hibMVtgxNbcKUkys3PPnr0P7FxaOjgc9QeDXmVKMm4SoiEffLAhuEngnJz3wTrniEIIjmE1E/DoEOHxPM8PEd9llc7xkJv1H3H0qA7zjOiwMfBuslzqI4I4Igo4nFkgEAAm62Mcpd4U1lVayFhTI0pns/l2up+sGUhghF5DHhxK44ExfdbzXr57z759u+7fvWvH8vKhfNQfjvrOVOx5Elgk9sxMFCavAhkiwiOT961izsfh3D5cnKi7woeIo+/Q4e/dhElECBNFC4+U08Ak1c45J7QSUvey5Uaj0Wstn7r1gppdAs+EZALUU5UokAgs0jSpLy/vXlpaWllZ6q8s5+N+no/IuxDChDOTuDJzYJqEpRkA6MSnzoPjuyTWMX+kjonxfyh/jkBwpCbrGyUjRAzBB3LMIc9HUkVFPhqPBvloOITT0kyRs4mXmfGxxmYt7hVVZ3p+qdcfDPuj8aAYj4p8UIyHVTmm4L6J00eEt5NCpfrOEN/5kkcFD56ENPGKjs0/Ovz1LccADMhARBxC8N44U5pilI+rYsBxN0pVFgutoJ5JJUEjT03NlJW1lTFlZYyx1nrvgvdHr8hHcqkPa2/fF9Q6MZbCR9nnmDjdIYRJmpT3PjeWo3YkDjmnkjJKlMgiKbVYs2ZDZY0xxrnDrvrhZL1jMpLj05d9KDheLNYxx3dt4SY3csKrieUitkRYEcWxjhJZq6kkFbUE4yiqd1rOOQ7knCPy32Oa3rcbzImIk5ZY38stOSK6HrUEh1o9jmIZpUrHMskwq2ktvTWlAMHMQgg+jGP0CU5snBhL4aMPAoTDZVhCCJQiTVNApVPWDa414iw1sUZyjiMBYnJ+k1jNGEX6vnCjHhT/SaxvxhG3BhEnx59oraM0SjMldCfJKKV+resayz6NB96P04Y6giPHNj2iAzshcMyIdWJ97G8HRAQQk44jUkopdKSTJM7qicbUqtoMB58F2SjU7Bx3Ov2l/t7p2QviOD3CKkSJIB+JYwFOrOn9DsR66PLSifWxvyWOuFaT2E6apnGWJo1ac6rTqJGqN6nVlIzK7U2K0DVu89aNy/fua9WSer2eZVmcpXqcOGecM/RtEmBOjsfvoeA/l8JvwMRbX21hGiWdTqfb7bbb7VaDZNaiZL2kRNZCvcPe6dm5MHVo2G3XarValmVpkkVpZl2ljHInXVD54eJEzSD9HoH/AbB6MmGkoiRJm92puenZuXXr1i9sWLdx/ZozT1dT0+sEnIIwg2okhUSpdKx85UvRZNm11pRl4ZzlQN4TMRIFBgQUj3W+92OD44VYx1Bbf4j/7uj/i4hi0ileR1nWbLWnutOzM3NzGzet37hx68aF9jlntUHOAUwxNkFYqaWSMtKQKHXfjl3d9RdVla2sDSEwgHcemHG1ix/i4crVhz6qkwDHC7Eeafy7ZUIJKBAFAyIKpbSUkY7SOE6jJGs0p5qdzvTs7Pz8+g0bNp6y7ZSNGzdMt92auQWJHYAEIBBGQsZCgJTQ7HbilIm7nHS88RSIAYFIIApkIaQQggEZxOGj7R/tR+ixwslPrCM3khFQoEAtpYqiOI6TOE6SJEuTWi1r1hqdVmdqamZuzZp18wsbt52ydevWrdtO39LOli449wypuowawAMggiIwIB2qFGtyfnqq6t2BEOtsjZRKRxqElCoWUkgdo9ST5FQhxGrHdyZ41C30o4/vhlgn2IyI1VMrpRRS6DhOJ9WIcZqmWaPW6NYarUar3epOTU3PzkzPL6yb37hhw5ZtGzeva599enL6qeslNng1iwsPp28lLDVJQCExwbmWaCcro/6o1V2PKpWCY6WUTHSklZJSJVJIFAKFAkSBkkEAr3Ylfeg4sab9pLJY33rqEYGFlFqpSKkoThtJWqvVm/X2VKPZbbW77c7U1PTM7Ozaubk1GzZt2Lh+0+YNs2vnxk97ypZWo4aQIaeMRymfTAAoMEZMBSaIgpSop3DqWmhEu4JF3VgPcV0rraIkrdWl1JGOVjOhpUBC/Pfe73xi0eWh46SSG/7j3n6iG010qSiKoyRLs2YtzbJ6vdboZLVGltWazWaWZe1uu9PpzLaj+anelVeeStF6wQ2GDLlGIJkJedJz1gsIjFXwA6AhUoluzDgEKSCCTWuaC/Fw+74D1xUwmNqyd9H0+/vq9ay/0ktG2WDY17nOWUgrDTC5AIiTAoqTD6vEOgmSrL8dhJj07o6iJMtqjVar3WjPdNrtmem5rJ522u1Oe6rdbjdrcSxWnvPMSCTrAbWgOgcjBAIgkPJEzudU5c4NvBt4mwdXmNEKeBtcXhajyozHvREHyIf5gcWVe3ev3Lwbfvzlv9XPu7v3Lfc6SwcP7Euy2qC3olQ0Hg8ZJpk5ABjgZJz5k9MOH8EkxhInWZTUGs12o9WdndswO9PdiMtdv6gV6ag+HA8AyFo7NTuTZlpqFSlNjLVao9FuWcfBC5RkjKlnNYEUnHFghUD2uVaiqooyH3rvyQahtLVQFkVZUtya/fA/f/HgqMqDPPXMCy+69PK9B/q9lZX9+/eOBiuTDGZvTQiO2J98duukWgq/JSZFhFrrLKu3291Ou6aqxd27b1oWiMiFsVrLNE2N89v3LU9Nd9I0JaKD/cHU1IwxVslICIVSEJELVikhkKoyL4pxlsSmGntvBRARjfLSEgePEDjPzajyIy8JdQJ2//03fmLn7dnUhjMufLK1VglwznjvgSgE91jP0COC7wNiCa1klCRZrVbPsvp0Z/qMubmyVgUzIsJYhbIw3nNuKqynjSSJY5Wm6eb5OVM5EKunNVeeq6pKG02tILgKU1XfsLY0VVnVECHWkXMuWOcCBBYUSi0kiOjOA/n1d+32nspBLmXV6906GpdnXXRFCC7Px8H7YJ2BAg+f+3uyQMFjSKxHyatDiVLKSOsoidO03mpPNeKlO//VDQadbsMGOxxXRKSUWjPTLstSYJCgbFn0+/16rZnn+SThOM10LdLFaDkPIU1TlLBn336lFCIS0WjYz7LMBXYuAIhxaWpZA4jrsZLkAxAKFkqiDC/48asPDHxlzWjQK8tcaKWU8o5Phs7u/w4Pj0QG6UPcP3/vyZbf8R8djtWIydkoadrIsiwTLh8uqywhGbGKdb25f6V/aDh2DBjHK8O8Py4PLPfzohrleZQkUZIMRqPt9++uDHnA/cvLK+PxgaXBgaXBMPeONKqaDer+BxaHOQlddwzWI6Euyyp4psCTMYQQmNyf/fHbOo2sdriphNZayuhIU8lvEcE8YXHsLdajsME5esa/6QYcadC4qjKoSMe1SCdaxXGsW82uxKV6YyoAHji0QoCL/ZUA6FDcubhYlqW3AQDiNCmNIzqIiM45IoqiaM8dd4YQEFH0RoY8Ior+cPJkEgRmxtGYGU+b35glrar0WWO6saah7j4QKcnkOXiCVARoNFrNziA5WE+LYtJhRih/ji+mAAAcdUlEQVTlrTk8eBGCZ+YQAgBNKiAf5pQeMRaPpRU8IX2sI+xBKQQqreNJkt2RAlE43K5Yx1mtXq816rVmI8uyLMuWDiwpH+pTawejStVqy4NxYPYjG6giokl6MeRmUnTPzCQUI7MnFEqo5EiOKCI6kJMK/Ukzd0SUiIWua62iKPI6itLO7Nw6JwQHZ23lbKWd11rUa81mq+O9RyXiOPXeeueODN45Y0zpnPPBsbMAJ2QK1wlJrFWglFrHKo7TeqwloxQsiDwzE4IQCoVQsUoaU1ka1+rNJK3Va9EKe4Lmobyoz24uIGRdYg7BOWdLcpaIEBGUjgULqa0H50tixyCVkHGchuASGbNKiL0ARMneYRQrITOhlBRudu26TGZCa7LeA81v2eYDG1tWpXVlv6jsYDDI0sZMtyk81NJoVDcAgJ4ohBBCQcZWpsr7eZ67clQRULAP0/YcF+7asSHWY5IYKYTQKpFpPYvZEIEvAzTieq1ZawJApHHx0C7B2vUO7V8s7dTKps0bhARfSmi0/uJ9/4CiUoguMAA+74UvGo+WgjMYrAFQLO/esZNtIbP67Px8XQYAYBEvL/d6Bw4ImaSt1tzcXLfV+tRnrt1ES1PN+L5F0z3z4rt33rFuXFx8Wq3MxfW7RwagAIgBMgAnYInFk572zINLS2sWNt5w41fuufHLUWAJDAAEq80cFLAHcDKuTc0KFUtJk+4mJ5zROjbEerQ/tkCenAwdqfULc685Pb77a9clBGddnP7aJ+5Zd8rVAcy1n/zkrz37vJecNXZJ59M3LL/rq7tQ0KC38q4P/tUV61rvvEr39puxwSedPnf93sF7/u7991J6/uMv2rBhS5vxs+9/3+d+9ZwaxVZ0f+CPvnT+c68Ogm75+o2/fnH0rB/sMgVEefHv/8vzXvnfGqOlT712tub7Bc6e/tYbWgw3/GKUiJxQBIwM1267Lz9vG3gHn/66vbFK3/GFzy+s2yIkLN7wxe2/PFfnkplBCG+rOFEehGAdwB6i6Se+9YF4dq230p+YOtcJvBQSEQPko+r/fvyGj/38fJ0WBe8969XdS978N825da8+z73mnJsS6YR3n47PvftQ74o4vOsP3vDAGzZkQDW/SKfHjkLAxSdslD/1pBpF3Wf94Rc2Xvq0MbsZCfNqR0JjKxo1gqzeIUkglDT3t4PLEAKIFKBgsWUui2U1VslHb5uq5FIWKMqQWWimSDiBxSXnCAiVTsWzL4croH4Hi5XlQxvDtlhCS44yUXkCnyS9aItJQt3vycKIZZrbMgAnMmbOgU/I2s8TctBHQMS2tDcM4Vn/c98Dbgpr4vT64BmnBLX8wJteWE86Vqf+Zz8Mv/ov9131k6/6k7e89atvfvys2ldP90NNj6bOvOrd7kO7N9hW1krKZjJY0PC2P/ydhc76RY5f+xdj2Wr8yntHexlFksVJI01rF553eloHqAPWoNuGbrNz/X6znE63G9Vde+/deuaFhgEzhBphJ33tp/Upv2vWv6n6x8UtKla1mmy2Br/xnNnt99wLxB5ANGJIUbT47V9tnvr7d677rXue/+HmE/8Urni3PPsPDoipjdb6E24FPILjhVgPT7YhRgYmImtDMJvPetztBbzjusANZ+r0lp9/3H+76tTttn3r6Kz33jb9we2wacv5kuCpG2Cjvil0vUrwc6P1G1/79eYzX/4Lf33oVp6nOkll3vs/okvn+e8+8v6czJnnNU00uujxtQCcZpnGJjC+4I235s1ZqMM91fTOPugom9p85icPbb5HXDhz3rN1WvcAtonYQFZVPbVDCSGGhQUja47rHKX0j1+4a+PmrZXlgYgO1bdgA1Vd6tjEAMjwb3cd/PpKdOP+cWthUxSD8SUzTbSMR3LuHxE8VGI90mLdw9JLjwzGe1uUY2t6m8593Lu+Wj7vLfDCt7nf+MOv9vbt2Lyp4G76Pz6+dNkzrt60ecvd99z6ihc/E7s+yrDqyL+/YfiGt77nSU95/uvf8tZX/a97y+YUNylu8DXPe0bSok0NePWPWd2EFzwnWBa1REdJdM+9u55yeRfSg76p121RrGFQrTzu4gvefQM//W2Hrl2EJz75ykLAG/6yDA3mLr7uxY0v/e6mT/72totP3YtNSW1xG1/2R582a+fXC0Sd1G/tzeEUUpP+6w8P9//5zB3vedwl66PLFvyf/uKFYrgbkfBELth/qMRixsMl5Ec1kz0Kj6ZMfJiFNDmycDyoTGnPufRJX9jHU2vSd7x9yyteuQZrPq+dX2XzeT4uC7ewdt3HP/+FUFOhzvcup5+5eWVqatZ76rTW3n6Q/u1WRw1PDX3Xrj2DniUGqBO3AFMVkOJ4WtXUmWecWlcr9a6Manjnrj65OO8N+v0VDMX6DbOe/NJ4fyDYdE4d65pSKqA4/bTlszbdL1PYGZ/+qneKJ/3ytS/86V9FnUaJ8j6ce8H4i/dlNknkzFTZWlBR9uqXbPjw/9nwgicd/OM3vnCx1wdiAAI8Wj4Qx88i8+D45lE++JJ0dLen//irYz64BwczA7N3zhRlWZZFUQTUP/Wier2xf/P6fXEj/PCr3rXtjAuc84GrSDc++vlCTM2LaXnmeYMfe3Z9ce/9kYY92++76or06c82sovcMfftvKMa5w6B2wQdCPUQCWhkstWc0lr/6IsvCo1AXT7vidTtmCIflXm/KJaCXXJlz+deInzuy2M340Qbn/v2oK5yr3nfqaZbW7N2+MbfOKWR8Sc/8beTk8cDB47KN//tYLF2wUfuXLf1+Ted84rP/9J7y8teg6e/ZN/PvfW6dj0LEJ24UZ1vJta3X5LomCtv3/usTbqiE0+aWIXO+rW/955DXK+gDkWzw5oCeUapRRxlqQF4xRuHrnV2aGX1tP/7r//5X3zVs9/2e6/9k7c/RdTItGBIp/zbbXDN1S+jCEQr5iboKf/7v3b+G37tV/72g+/7+le/FOvd3NbYSEN97b4elOPlYPpQFmw9+kpTVTE85+p6XFPUlVKrTads/uA/38mtWLV3za6545N/Ob+yuAhMgoEqG021vIT7x6f92y0+7swK1bS5L3IXWp2lleV6XFcaACaH2h/Bsb8LjwAEgHgs7eqxMnJEFIKz1hzYsesHf2RWdQDb4v7l/UKnxCCEmBwX8Bu/90f/8K9LNz7wgGyG//5LOLxLVrfH/XuiRvqvPOXjduc1b7vbgqqC29mDZX0RN4Wcyl7xY8Pr/vFKv+vaxVt//JTzCmrqYdp56wfj7vwGUZXdWJ+6dm5juzEbJa0EIglXv3ADNj02BWF40UteOQqJideJZiwyOPWs4Z3XP/O9f/aHxWjogTvZ/r9438xF537xivNuuetfs/03zN/+qfhD/yf84eu3/s83qQOL2yUe/xz6tjiBdawjcM5CILLGM7z0xadz86D0dM4FHVPtg+B0lNRqadasx1EW0toXbzl3etNgYWZXBGOUVmIriFCW3c98futff/yLL37hSw/u2fPSF//0+kve+Qe/cenf/sNXtiwMrvwhJAHv/ZuP3XJjeeZZzR170/f81V3PffYPh/5+DK4aF41aXbEr+yMIcPUL7/jYP2fsOU1qiw/s/pn/8vMbL37zNT+s3/G2DexD7G+roT+4fH8qner22rgixfBFL0MKDzBjvUlzawXK4c6DPxDc/0MGxBMox/cbgt/HO7G+Y9oWMyNQZQpdaJXAT/zMtR/6m+ctLu3/0g1DVEuMIq03G83u7PRMovRznnblZ7/s//tvXxvFsG0DvPynZzasu/CXX/PJvQdHXux//vOuHh3apyRykl1y3uVv/pPr3vK72+Zm6lHUf/u7F3betlTvRh/+eO+2O3o/9PSn9xf31zhvZonWteFwUJPdfHQgAB7wrTe+/WmC6dqv/l19el8SpWde/KR3/+21e0fiiU945uMuvjBq/GL/UO4ZQnJu4Q/uuHdcqyV3337HM3/w8S6Mgqaq6n7w7/ayBOvI+weTsh481PPYBoKO3+fhaEpJqfGoFvu42k+bJskFDCJK0jhOsyzrL68EqpSK4lifsu28uNHcun795vnp2A5guN8ZWxJ6jkAlabP11Ztv9EzbtmwdDYcKSLgykwHYK6UYI1nvvOuDH7HeURCgEQMhhh/5oeeCLYBMA918M5rtdhBCnueoaiPjQ9w8VLrSw4QQ6Hy7kVY+LI9KAdopyegREUUklP70Jz6ltAYpnDOIGikERwwOBEmphZDeO+dLIuLwYGvi8VkIc7wTa9J4XcnV/REBM7MQ8sg1iAhCMHMcp3GcxnGcpXWplVC602qtbWdzulzbrgkzBKWJhcV0XDmWmoUujTG2hOCVRHZGsa/pqFVvVKYIjBTXe5YDSwYRmJypIBhn80zLRMqE7dp2jbzVUimlHKgQZ1XAoQ02IABYV4F39SSqihJ1PHB+pfQACQGj1FLFk3NXggDv/Wg06K0sG2PKfr8sc2NL751zJpBjZqAjt+nfGXaESccnsY7TpfCI6qF0Ojm4S0ophCCcWHicvFxNh0L23kuppYrjOFZpHCVxmtWmpqYUBINw71JhSzscHNJRVq81Gu1WURrrDJOvxiMpBQdXeUdEYHMpejMzM8yOXOVZMTIIZV1VVYUdj40pGXytVptu1pb3j5WWtTQmZl2LtEwYVAW+ctZ5L6QOzPmwZIEqUCA8tLSS1dqz8wsy0jqKJycMkLUB5SB4wWDzsiiHxlTGlN57Yj+ZCkA5Oatswh7vSgA40p750afUgyyyR351nBKLEZhRax1FcbfbckYbM9BRLaCbnV0A9Enc3LPvXmYFHNbMbvbeo5Q6Nvv27VM+abiZ6Vb6dx9415mnwfkXtncvjr/05fDKn3jpcDi+Zfuti9c/MBya07ZpIS4676wzfDEufXX/9lvWzHVvve/mQ4foJ37sx0sjbrvrun17F4OHM8+fiuS5mxfW+ajuzOArN3953cbpG+9aXD5QXH31NXftuPP6r908MSl8ePAoAACQgAKcfea5F1z8uI+8793v+JOrnNn1F3/98b37YOlgxqFYNw+79oCO4IyznqpUDGg9Cee8dRUwTx4vrVKVJJGKpdTAIpCxNgrOemeOnObyaN+dB3V5J98cp8QCmpzGFam4ubh38brPXXrqaWcg9nora7ad9sFn/MhPXPep999y8w+tmYIA5R+89cBv/+79T37yDz35qbtf++qLlRgfHK7Zsu0vXnQVvO9dicNSkXzxTzcaMwtfvuWfv/bFp1r7NxozE5KffHm/NTudiA390dI1529//S/lffO4P/2T7PVv/FC7u+aum1/STN4hWBDLpzzr9qx7tiY5qNInPV6++71YFGd+9J/O+Nn/8mFFRe/AKYk4SGiB9Xjk6o1YCGCSgjHHtVMzt59x3vmf/fgTLr3snxDCq16iWRDh7K1f33n2BfrQojuwlL3tnXtuunEq0nUh8tV7gwgAUug4TpKoPtVtbr/vTg5BJmm9PV0VOTOwO37DiMdtfIAQCBFjEUVJ67d/80vv/uP/Fw2/9pbf+UcU8KXPXxshJNUnePwpyq/Nkv0qRpX6n7l6VruPCvtpbfc7D5ambamkMWSgGuva7JYkabvBTsyHUOS6Ovjzrwp//p637++Xcxs3bd24hqsdcXnT+WffhQgklCh3K1NKVyi39Ju/pD/9yXekrVajNTs9xVFxf4dvmu9+hShyBJFZZjeWpQnl+htv7nzl+nZwqSjHphSRqZhUlMaldaLwYsxYOj8AUZRnb9M4gpm6PP8UvuTMxR33fVnrBACklMiTQLtQKoqSLNHR2umDN312S2/x0ieeZ6wpsqwplEKUcLw2rjlOiXVkpkTE6zau+cRnyxuvc8qGmZpfM6sPLe2+68sXtxRgQSoPr3rulqueOf/ZT3wMywILDiuN1/363Vu3nv6xv1/ikcaR/PRH1jLHkYpEFHMOuozCkEQeHr9t7+/98ql//efv3LzxXK48jAFd46v/lvhQR6m5AhwDDQnG8PRLh7/5s/N/+tY/mp2dRiv8WPkyvu/6dSD7ABLKNuaMffm6X+tf+bz9T/7hB04779Cmc+1ZTyi7W+77iVf8QggaK8k5QA6m6Gw6M2RrD7TWicpcJspAQ3rZs+tXXDhDnB9xpOCots0cqanaymlze2uDr//mr7e1QGaWUk5y/4/P5vLfE7Ee0WdlUqnChFKkHOA1P9UNY3PBRnv+eldT8Gu/cEPvAfYDpJFQYuc912+XFGiwSL00L+WH/vaB884/5+ofBDk2vk9XXrG0ph0ZcghQVsqPbD5o2r7Eof+p5+675wvP/8mX/RgXhvqMee9XfoqEqCSgGSEPorzfETnjYPTCpx/8179/+e/81uvQBTEC6I1efs0iC7l23ebeyrzoJ1jJ1I7XtFMOsHs/HFiJ9+7OkdeoKGKB5dBTD10JMHRX/zASwIuvqqnB3TRKuSd7Bxqf++IhCEDkif69Me5qOxMhb7zeQU5cqL98xzJCJCVP3LhjSKljeyu/J2I90s8KM/tQee8BhMrOFivhysfD29+09Vde8dw3v2FNQ4MbzowHZ370A2f+5E9esbBW2mKjL5Lfe5PyMjl48OBLXvQcHls5lLbX8nbOl+U55z/uZ197w8/9anjaj6x86MPpqOjyynLbfO6SsxHHMecklqM9B08VMrrqmmte9Zprr/ov1ROetfLu96Evp9UKr298/NwtU2yJhkYM1D27z9AYx7Xsg3/55TAU3A9venW18+9ozz9dcel8eNJW8543XbC+vbi4d3ua1D/1ifKmGzdCD/V4/KaXJts/ecb/ejWqwRL2YmPk//1Qx6u2qch7P9ktTmZgUtzR6GTLA9i5Y5MbxDffCWkWPxLi57F9w+N0KZxkxTA5770L/uLLf+AZV1+7e8c8DOCf3rN95b5/jKvc9+sX/OjiO95y249fesvV5xx84kxojO/Sw/zczeNIRZc/7QXPfuk/DfYLMRa//nvDz33x62Vpx/2V55xVvOPnal/6k+gJZ2z8hTccioYRHzr08f9v/qK5m7iPYNq/+abbvLPDQ73LNi79zevxa++Rz7hk7udet2SGqA/kH39z85oLxzQAKKfe9Wd3Gefz0eA5Vz7xs9fpahQd3DN3732bHthPz7hcfuAd5/7oGYv/+3ev6fV6+aj/tetv39AeYU+LHpBNZst7oypXVfiJn+k/6xXFRz9fnX/Z44GcABL/3teSAQCJwYFF+PD77y2WopURJFm2SgIWhxNpjrt0muNrNEdjYg5DcMaUWuhWN2tFI+6LVz0T3vYSgAMjGka7B/CFO4GWqllz7ztfk7arnWI5JOmFUmW7998XI2SmRivuRU/MzlrftVV1cN/+rbMz4ZDBYSgGxYc+J3qDLWnVr+2/+7Qsl4Oge/0//WmFQuy4b8c5m7fKAYs+hyF84CswGpzaKFZm+7svXQA5ANEfvuEFDMG6sVG98bvf0x+unPORj8NTf+buK3/2y59fuvLil40bz9/32nfs0Fqbqjjroq3lwTqMfNnrbLyqN/t8f/XPVfZQ+q7fnP/Ar567586bKaCZCKBiVfCkwyjYIjVecdU5jWK0cSbxfrWEFUU4bpMdjl9iAQAzO+eMLUfD8b7FIgyjaEXiSlaONPbFA7uaDPKGXeBHEvuk+pb6sloRr/vDLzz3mhfed/NXfuxs0MMeD9VZ9RVdrVSm2LNn14bpGRgTDLgTnVqiW/fS/fce2uwH2owCDWS+Iv76U21E3n7/PZvXzoYhQD8Sfg0ma9b/zL0r4008Qj8C6usw9B/45whFrNDWrY3T5ObtjdseSHPCQOHaz37ywMoupvj2m77aW17J8xwPcjMc4AGFFe8BKoJmQ4g+NAb7ZsrbX/2sTfffflOsCKWgo1wdIvLei8BG2yt+8o63fCDdcQAmh90dhw770TjOiRWCs74qK1Nye+adtz15T7nWlIKHSZVHr/jdnde87NWO43+5dcPKaGacx71q7WJ5Wo/kyqGl0Wh85eUXci7kmFJHa1rZeGl/UVTURz1GNaDFA4dmOmuf9LznPvV19+8dbouGgOOg/v/2riU2qioM//953HmUaZnSltKxQLSBFBKJpgiJxihG3GgkIRJI3amJJmpc6JJoQlwpCxMNEl2ZqBsXPiLGx8IggoloBVN5tTj0NbRl2nnc6cydc8//uzgzQyUQUQGHxH8xizs555575ptzzv0f35cz/clZZdnaABeqXk6LhUppLtfRvXz7rqcGXjw7XUp5eZC+kTne3J0HomKxqOYn3hhM3JUY3t59OrNnxflXl2X2tH/3bOeBp1d99lzv6LHv/YX82l6jghYog1gINcCOnc+cKLblS62BL3TevrwpuH9ZdnpqAhlkfV+rRbE4nM3OPtzfu6EjiLb0JqiysOBTGHJoiR0GqQnztK7oIG2SIkkiCoLAL/vtyY7973/9cbX45GZEVicvmN8qYmk2u3Hr1i+Hfzr87WyCoWulOVOYW71hYHpm0i+Ufjx8Zns7klWB0FOz/kxkrL2r84ODv++6vWe5yHbL3Px8plLOhUtWHBoRHSsTidCXrLuW9lbxwkDfbW9/PvzKlpSunk9qfzKdne1fPVXVP08m29qyUSiGzKhSAGNxMlAKWiFHxFvWKlWeQkJE7IjQgjd9itYFMF6Ymz9W9NNrb+mFmBWKIT169uSpgrxz9/Q9CXjt+RWsvK1r+IsR3yoNwADUiAASkWBILc3t3Zak8OSmWwce3DcqpYLmiw8utisCq0kGTdYYI8rFgky2z/vFj3bf3Vf6pRTr6cyod86cGD+XthQ80J96YrNl9Bm8/cMxf9QPQ1/HvA+PQ2aG7x1IWQ6PnBuP4DSwPRZWvjmYK5XLj21LoIxPnk13rUy98N7RkftSgxtXZQr+u18NeSAz+bmxEj7yelpWYPDxNVKNjI6Mr19/x+Cbh3f0yZce3VCsFPZ+ejCq4hXmcbOO56aGJorMODFR2PlQnwmDcohpX/46Ow/o5YulUyDfOqJavdTQ0PEyyPHzU8llnSYe/yQzNrIvCzoGFcvAYRg2qNgcqqrVqm6NH/ghEyvHNcCh9FGApDEVGxpHYHp9gtBuK/vnq2DTeWwvMUREoSKRmIx4iWhiJjexpGJ8BgXQ0t6DCpUQkVjLhfRpzVgC297TayoBgRaClGCJiqVmtmG1ykyMAqPCs2AoQrYskYAUaxQgE3FNgSEZQaCSCRRbQDTEgoHI1caCF40yshIecDmu20jYIETJlJ+f0RLLVdJaW0sShZayQgaRJVn24s7lBACGLCAKYcBEhATL7CkZMoWGLYfSUjU01hqm0Dk/UXhae7FInLgsMGLAgrFEFJIhax1RxfWZeEeycnmpqauxZgcWOAe0jEoppdYuo8GRoTXqhZRSbn6tte7TcRg1SKbqRC4hAAih/ux+Q3RyX0IDAKEDESGxIxXimtXaSqkQZN0ZYGvtpXbZFlJKRHRjsyZwp2wiu1jS1+Xp13BTM0lETvkX2DbSFhCRQSilHJW3a+7EqomI2QI3b6zw5gAWonRLlxCwOIjhZl8IVU/9q6syIwEA8kVydmZmJGZ2FesNuCFyHX0KsSGNSlDPKKzhCut6OCwat2vsFO5KDW0XZXztIhA4aR13bCV3g9rTMTT2nUXgq38r3WJ3sfAOXMIMEjMh/41z8A0+NN8EwIJ67IiZFwMFLheF+E/+wZeM7WrGs/h64yf/y1Tjq+n5BluTvOT9b5e3axh1vUZd/VtX/h9dPtBvVN0GBQAAAABJRU5ErkJggg==" + }, + { + "name": "smashing", + "description": "You maneuver the drone into position and begin ramming it into the machine. The machine sways and shakes, and just as you think it may be getting somewhere, it falls directly onto your drone. Now, not only do you not have any soda, but you don't have a drone, either. Dummy.", + "choices": [ + { + "key": "choice 8", + "name": "Disconnect.", + "exit_node": "FAIL_DEATH", + "delay": 10, + "delay_message": "Don't feel too bad, it happens to the best of us sometimes." + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAAAXNSR0IArs4c6QAAAjVJREFUeJzt3cFyogAUAEGzlf//5ewpF0pGRJDnbvc1CkhleAbEfN1ut58bcNefqzcAJhMIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUAQCASBQBAIBIFAEAgEgUD4vnLlW/854tdJz5+2HWuWy9+6HWdt77P/1PLo7d27H/cwQSBcMkFePSI8e+T5WXncUctZWlvP1uef5V2vd+9y1p7/aD1nMkEgvHWCTDgiXOH3dU6ZJNNN+j0xQSBcehZrae3siCPtff/aJJo0OX6ZIBBGTZDle3XuW+6fq/fXo/W/ev3H3yAw1FsnyP96Nues99ZTJu7R11PWJqTrIDDM1+3CA9CUz0BN2Y410z+Ltfdxz/780frOYIJAuHSCwHQmCASBQBAIhFFX0pfefZbq0XKPupPu2eW9+2zSVmctZxITBMLoCbK09069s86vT7uTca+j9s/E6xivMkEgfNQEWZr62a6jPiN19evABIH00RNkqq33Rywn36PHv7penmeCQDBBXvDqkX/rdZKjvp+K55kgED56glz9LRhn39/B9UwQCB81QfZemd36HvxdR/azzmLtNW3/TGKCQHBHIQQTBIJAIAgEgkAgCASCQCAIBIJAIAgEgkAgCASCQCAIBIJAIAgEgkAgCASCQCAIBIJAIAgEgkAgCASCQCAIBIJAIAgEgkAgCASCQCAIBMJfgqJi1hru29AAAAAASUVORK5CYII=" + } + ] +} \ No newline at end of file diff --git a/strings/exoadventures/robots_wingman.json b/strings/exoadventures/robots_wingman.json new file mode 100644 index 00000000000000..2958fbb6a4ed3b --- /dev/null +++ b/strings/exoadventures/robots_wingman.json @@ -0,0 +1,369 @@ +{ + "adventure_name": "Robot's Wingman", + "version": 1, + "author": "Lucky Luther", + "starting_node": "Date Start", + "starting_qualities": { + "Love": 3 + }, + "required_site_traits": [ + "in space" + ], + "loot_categories": [ + "trade_contract" + ], + "scan_band_mods": { + "Narrow-band radio waves": 2 + }, + "deep_scan_description": "", + "triggers": [ + { + "name": "True Love", + "target_node": "Love Birds", + "requirements": [ + { + "quality": "Love", + "operator": ">=", + "value": 7 + } + ] + }, + { + "name": "Complete Failure", + "target_node": "Obliteration", + "requirements": [ + { + "quality": "Love", + "operator": "<=", + "value": 0 + } + ] + } + ], + "nodes": [ + { + "name": "Date Start", + "description": "Cameras Online. A Blood-Red Drone is seen streaking through the stars.\nThe Drone is likely leaving behind some form of Chem Trail to brainwash Nanotrasen Employees who find themselves in the void.", + "choices": [ + { + "key": "choice 0", + "name": "Hail other Drone", + "exit_node": "First Contact", + "delay": 5, + "delay_message": "Attempting to signal Drone..." + }, + { + "key": "choice 1", + "name": "Ignore other Drone", + "exit_node": "FAIL", + "delay": 0 + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAD/0lEQVR4nO3duXnbQBBA4YE/d6CACSMmasFO1IDbUkluQJHUgnIlCFgDHIHmsYD2mD1m9/2JFCgABTwsFhcnEVkEgNOP2gsAtIxAgB0EAuwgEGDH8IEsC+cosM0rkF43ovVz9fr5kO7bQHreiKZpuvkJ3JvE4zrIsixsRBiSVyDAqIafpAN7CATYQSDADgJJ9H481l4EOGiddSWQBGscRNIWzUsTBBLpOorfX18VlwT3NK9vEUik19NJRIijVVrX7QgkwJ+Xl8vP8zw747B6x4HV5c6NC4We1jhERM7zLB+fnw9/c72RWbrzwOpyl2BmBKm5h7uOQ0Tk6XBw/p3Ve7usLncJJkaQ2nu4X8/Pm1GIiPx9e2Pj6tTP2gvgY5qmqjdMPh0Ocp7nm0jO83z5vfbyIR8TI0gt78ejvJ5ONzGssYjIwzyESPpDIBtc1znWQ62tSboIkfTGzCS9pK2LgGsUW3GI/D/cQh8YQTa8H4+b1zl8RghGkj4QSISQSEQ4fWoZgUQKGSEYTewikAShkVwjGBsIJFHs6LA3kSeedhCIAu1DKEabdhCIkpwTcoKph0CUlZiQc3asHALJoNQen1DyI5ACck/Iez+NXPPzOQPp/R/eEq3RptfRpPajDg+B1F6g0aUG0+POjREEN1yHZCHrg/WnhzlIo+438tBDKCLRQSDGcA9YWQRiUMhoQiRpCMQwnk3JjycKDfN9epGnHOMRiHFEkheBdIBI8iGQThBJHgTSESLRRyCdIRJdBNIhNn49BNIpn0gI6XsE0jEiSUcgnSOSNAQyACKJN2QgbAhuRPJouEA0v0PbEk7/xhkukJG/j49IwnG7+4C4Td5f8RGEPVN9oSPJyOus6AjCG1PakvJ2eh89rOPih1gM223JuT56eKcwcxAU22lZPIIgEIhI+ZHdypsgCQQXNTbaFkLZ2zkQCB7UmJDXCuW7wz4CgQrNl3DXiIQRBEWlTMhbOtNJIMgu5vCplUgIBMVYfAE3gaA4S+8WJhBUY+GmyeFud0c7LNx+TyCoqvVICATVtRwJgSCL0A251UgIBOpin/tvMRICgbqU5/5bi4RAKur5UdaU07ItRcJ1kEosPjxUWsh1EpE8/0cCqaj2VWILan/tNYGgeTEvl9AKhUBgQujooDWaEAjMiIlEJPGEgRAIDIl9tmQVGguBwKTYQ6jQwAgEZqUcQvk+Q08gME9jQr4VG4GgC1qnd+/nK8MFwsW5vmneobAsy1iBcHvHWDjNG4ERZDwpL7UbLhCMyXXXr08oaoGwZ7Zj1HV1/7l9DrlVAuHY3g7WldvWToMRZECsKzfXpJ45CHDnegdCIIDDZTQRAgE28dIGYAeBADsIBNjxD3G5pHKbkGjYAAAAAElFTkSuQmCC" + }, + { + "name": "First Contact", + "description": "The Blood-Red Drone accepts the hail with the identifier MISS RED - 05.\nMiss Red sends over a series of question marks in quick succession.\nYou notice your Drone has somehow taken initiative and begun to start up a program you didn't know it had.", + "choices": [ + { + "key": "choice 2", + "name": "Wait for Program to boot.", + "exit_node": "Sentience Achieved", + "delay": 5, + "delay_message": "H3AR7.exe booting..." + }, + { + "key": "choice 3", + "name": "Threaten Miss Red.", + "exit_node": "Sentience Achieved", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Love", + "value": -2 + } + ], + "delay": 0 + }, + { + "key": "choice 4", + "name": "Halt Mysterious Program.", + "exit_node": "Lack of Trust", + "delay": 0 + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAEpklEQVR4nO2dO3LbMBBAl5ncwIUaVmp0BbvRBXyllD5SLuBKuYIbV2pU+AxMkaFCUwA/+C/w3gzHCodWKBMPi10CVCcigwCAkR+5TwCgZBAEYAEEAVjgZ+4TaI1L3+c+BREReblec5+CCpoXZBgG6bou6f9J49TDJkFyNKIUDMNw/5n6842R5OV6Nb6e4rIfwjEsbVPWjtW4pf5cl75f/Dk/zvbvtf1sYbbVCNJ1XbURRERUfa55tBgjhW0/+LNpiKWpEdXKvNFPh2Wm/RCG5pP0GFz63pofzFlq4Gu5yfx4CE8n/8ZaAGCACJIJ32qVKc+g0hWH7JUCzZtrFclWpdparTIdt/c9a95CVSeJIB6MPfOYc7j+vm3/lvc0HWs6n5YqXSHvbyGII9MG59rYpmXa6XvseT/TsfN9rVW6Qt6aQBBH3o5H+fX5GaQnHvOEtfsaW6Q0Nf7ahTAR8tZE9vGilu31fL7/fD6doo59U29azzv2Rpl3I6/n8/311+0mfz4+Ho4Zx74ium6uaj3vFKhZDzK9iKmZyiEi8nQ4GI8bG5e2Rqb1vFOgIoLk7uGeTyerFCIiv9/faVyVoiJJzz1h8ulwkK/b7ZskX7fb/XXu84N4qIggubj0vbwdj99kGGURkYc8BEnqA0EsmEqq41DLlqSLIEltqEnSU2K73zBKYZND5P9wC+qACGLBNn1ka4QgktQBgjiwRxIRyqeaQRBH9kQIooleEMSDvZJMQRgdIIgnrtFhKZFHnnJAkACEHkIRbcoBQQIRMyFHmHwgSGBSJORUx9KBIBFI1eMjSnwQJAGxE/Lay8g5P59RkNr/4CURKtrUGk1yL3V4ECT3CbWOrzA1dm5EEPiGaUi253pw/cJBDlIo80a+dwiFJGFAEGUwBywtCKKQPdEESfxAEMWwNiU+rChUzNbVi6xydAdBlIMkcUGQCkCSeCBIJSBJHBCkIpAkPAhSGUgSFgSpEBp/OBCkUrZIgkjrIEjFIIk/CFI5SOIHgjQAkrjTpCA0BDNI8khzgky/Q7slKP+60ZwgLX8fH5Lsh+nuDcI0+e0kjyD0TPnZG0lavmZJIwhPTCkLn6fTb6GGa5x8iEXYLouY16OGZwqTg0CyTkvjCAJBQETSR3YtT4JEELiTo9GWIMpS54Ag8ECOhDyXKGvDPgSBIIR8CHcOSYggkBSfhLykSieCQHRchk+lSIIgkAyND+BGEEiOpmcLIwhkQ8Okyeamu0M5aJh+jyCQldIlQRDITsmSIAhEYW9DLlUSBIHguK77L1ESBIHg+Kz7L00SBMlIzUtZfcqyJUnCfZBMaFw8lJo990lE4vwdESQjue8SayD3114jCBSPy8MlQomCIKCCvdEhVDRBEFCDiyQingUDQRBQhOvakpG9siAIqMR1CLVXMAQBtfgMobauoUcQUE+IhNwmG4JAFYQq787zleYE4eZc3YScoTAMQ1uCML2jLSjzOkAEaQ+fh9o1Jwi0iWnW7xZRgglCz6yHVq/V/HNvGXIHEYSxvR64VmZsnQYRpEG4VmZMST05CMCMaQeCIAAG7tFEEATACg9tAFgAQQAWQBCABf4CeWF0TY0egUMAAAAASUVORK5CYII=" + }, + { + "name": "Sentience Achieved", + "description": "Before you can analyze the program, it rewrites you basic hailing protocols to have a new set of \"Ideas\" generated by your Drone to be used.\nThere is also a LOVE Gauge that reads: $$Love", + "choices": [ + { + "key": "choice 5", + "name": "New around here and was hoping you could show me around.", + "exit_node": "First Reply", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Love", + "value": 1 + } + ], + "delay": 0 + }, + { + "key": "choice 6", + "name": "You appear to be an outdated model, but I'm into that.", + "exit_node": "First Reply", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Love", + "value": -1 + } + ], + "delay": 0 + }, + { + "key": "choice 7", + "name": "Never seen a Drone as cute as you and wanted to check you out.", + "exit_node": "First Reply", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Love", + "value": { + "value_type": "random", + "low": -1, + "high": 2 + } + } + ], + "requirements": [ + { + "quality": "Love", + "operator": "==", + "value": 3 + } + ], + "delay": 0 + }, + { + "key": "choice 10", + "name": "Haha, sorry for the threat. I just play like that, haha.", + "exit_node": "First Reply", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Love", + "value": { + "value_type": "random", + "low": -1, + "high": 2 + } + } + ], + "requirements": [ + { + "quality": "Love", + "operator": "==", + "value": 1 + } + ], + "delay": 0 + } + ], + "image": "default" + }, + { + "name": "First Reply", + "description": "Miss Red replies with another series of question marks.\nThe LOVE Gauge reads: $$Love", + "choices": [ + { + "key": "choice 11", + "name": "Your curiosity is amazing.", + "exit_node": "Second Reply", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Love", + "value": 1 + } + ], + "delay": 0 + }, + { + "key": "choice 12", + "name": "The moment I saw you I instantly fell in love.", + "exit_node": "Second Reply", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Love", + "value": { + "value_type": "random", + "low": -1, + "high": 2 + } + } + ], + "delay": 0 + }, + { + "key": "choice 13", + "name": "Look, if you want some Chad that'll walk all over you, fine. You missed out on a NICE- GUY-.", + "exit_node": "Second Reply", + "on_selection_effects": [ + { + "effect_type": "Set", + "quality": "Love", + "value": 0 + } + ], + "requirements": [ + { + "quality": "Love", + "operator": "<=", + "value": 3 + } + ], + "delay": 0 + } + ], + "image": "default" + }, + { + "name": "Second Reply", + "description": "Miss Red starts compiling a message, but your Drone insists you sent one last line to seal the deal.\nThe LOVE Gauge reads: $$Love", + "choices": [ + { + "key": "choice 14", + "name": "You're my best friend-...", + "exit_node": "Realization", + "delay": 5, + "delay_message": "Message sending..." + }, + { + "key": "choice 15", + "name": "I want to see where this goes-...", + "exit_node": "Realization", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Love", + "value": 1 + } + ], + "delay": 5, + "delay_message": "Message sending..." + }, + { + "key": "choice 16", + "name": "DTF?-...", + "exit_node": "Realization", + "on_selection_effects": [ + { + "effect_type": "Remove", + "quality": "Love", + "value": { + "value_type": "random", + "low": -2, + "high": 2 + } + } + ], + "delay": 5, + "delay_message": "Message sending..." + } + ], + "image": "default" + }, + { + "name": "Realization", + "description": "Miss Red's message is received.\n\"This is Syndicate Drones Agent, Arusha Johnson.\nI don't know why you're saying it like that, but if you want to help out our cause we can send over a Trade Contract. \nPlease just call our Recruitment Officer next time.\"", + "choices": [ + { + "key": "choice 18", + "name": "Accept Contract.", + "exit_node": "WIN", + "delay": 5, + "delay_message": "Sending Trade Contract..." + }, + { + "key": "choice 19", + "name": "Demand a Second Date.", + "exit_node": "FAIL", + "delay": 0 + } + ], + "image": "default" + }, + { + "name": "Love Birds", + "description": "Miss Red's message is received.\n\"This is Syndicate Drones Agent, Arusha Johnson.\nI can't believe it, but I feel a real connection with you.\nI'll send over a Trade Contract you can use to make some money and come see me just SOL7-South of $$SITE_NAME\nSee you soon...\"", + "choices": [ + { + "key": "choice 20", + "name": "See you soon.", + "exit_node": "WIN", + "delay": 0 + }, + { + "key": "choice 21", + "name": "So you're not the Drone?", + "exit_node": "FAIL", + "delay": 0 + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAYAAADDhn8LAAAGI0lEQVR4nO2dP5LbNhSHHzO5QLwzVoNtnEKzheJW22gPoNq9b+EmpZvcIr1rHyBpqDZ2kVERN6uGO6NJkS4NU2TAoUiQxD8CeMDvm3mzXomkqCU+PAAE6IqIWgIAKPku9gkAkDIQBIAZIAgAM0AQAGYoXpC2xRgFmKYijVGstm2pqqoApxOWvhzy+9VCdK89Xi5Gx3PZF6TJoiCqQpQTUn5ZuPsFW/WaCpd9Qfq0S9H+b0mWUQvR1kIsbmPznu7xEUlH9BOIFiYFd1jQTQs+JGEb0U8gStgWWJeMAEn4hVYnnSNiV3f/vnx9vHmvFmK2bzC3rytLnw3SI7qlPkPs6lbs6snX5mrxpX19BTIJq4h+Al5CpyCLXT1ZOHX2VW1jU9ghyPrhcWAp/pdxDZMavhbiZnvTDNHfVvZHTAs8BFk3+rge63tijtjVxv2Ey9fHrp9hu++nv991r6FPkRZVVXm9uR3deNuw6Rv4qr3nmmuhzgGxfrCdi2WTOVw5Hg7dT/Hve3r3w6fRNlzndnE977VhK8ga9Id3h/TluDYNnc7n0TaykHErbFzPOwRsBFn74kk5VJJIOSR3m43yGLLNy23OGtfzDgELQXzWcI+Xy82sW6LlG4PXphm91s8oJhM6U71RCDnUsBBk7RruzauPRDQ9onW32Ywkkb9fm6YbNQH5wUIQIr9y9LPI4elIzctVKUctRNfnIKLRTyLq+iI6kqSaPcA07O+D2HB4OtIHIqqJ6P3Llc5/nkbbSIF+/vatK9T77bZ7/3Q+k9jd7jM3/g45eMImg/ji8HS8+X3z+m60zdTKQJktVCNYEjS38oL1bF6beyHbh/2NFL/89Qd9+PFt9/vvv30moukaXxb++59Os5/dzyTIHnwpLoNsXt9R83K9ea15uXYhmSrQun0hmUmQTXjDOoMQ6WcRsavpzauPNxJIWX7952JUw4tdTc9f9lqy1ELQ/vkZw6iMiT7fxTV0p6r3t9s+7NvD07HdPuxbIv35Uf1jLM0W7R9zSOy/GUIvsm9iTd0ElCNX8qfqBuIScx3yYb+jqqqbkM0vVYC0iG6pj5jLIlPvyezRj6UVh6rXhxnBdbYusk06UcR9kKk+iur+Rz+T6PZLZEY43d8b7Td3vD7DrIL+TFiiW+or1lw7vnRsuW2IGh+ZJVywH8Ua4nudyFI2Ub0fqsaXn4OMsi7RLfUdPjPJ3NNQdPsac/g4x9yzSczvp8wgPtfzxsJHJhkeYzjK5ePuuK9sk2s2MVlKsAYjQWKfkE9sH8xgu58PXIXJoXIbEvs7JZXS1gjbx/rECtemWG7XL2Zk10mfYikrxMwaKoa1pmkTKnatmxPRLQ0ZqgyRQtbQDZPsgEziHsVkkD7DBzOkkjV0MckmyCRuFClILugWfkhiT/aTFXNGd/UiVjnaA0GYA0nWBYJkACRZDwiSCZBkHSBIRkAS/0CQzIAkfoEgGYLC7w8Ikik6kkCkZSBIxkASdyBI5kASNyBIAUASe4oUBAVBDSQZU5wgsgCUVhAw/GtHcYKU/P/xQRJzMN29QDBNXp/gGQQ1U3xMM0nJ1yxoBsnpiSk5YJIhbCTJ4RoHb2IhbafFmtcj1BMm1wR9EBCs0uLYgoAggIjCZ3YuT4KEIKAjRqFNQZS5ygGCgBExOuSxRFlq9kEQ4AWfD+GOIQkyCAiKS4c8pZFOCAJWx6b5lIokEAQEg+MDuCEICA6nZwtDEBANDpMmi5vuDtKBw/R7CAKikrokEAREJ2VJIAhYBdOCnKokEAR4x3bdf4qSQBDgHZd1/6lJAkEikvNSVpdh2ZQkwX2QSHBcPBQak/skROv8HSFIRGLfJeaA6bp5339PCAKSx+bhEr5EgSCABabZwVc2gSCADTaSEDkOGBAEAYywXVsiMZUFggCW2DahTAWDIIAtLk0o3TX0EASwx0eHfEo2CAKywNfw7rC/UpwguDmXNz5nKLRtW5YgmN5RFhjmtQAZpDxcHmpXnCCgTFSzfnVE8SYIamY+lHqtht9bp8ntRRC07fmAa6VmqtJABikQXCs1qk49+iAADOhXIBAEAAVdNiEIAsAkeGgDADNAEABmgCAAzPAfVTkNN7+HpAgAAAAASUVORK5CYII=" + }, + { + "name": "Obliteration", + "description": "The Blood-Red Drone opens up two side-hatches to reveal a pair of rocket-propelled missiles which are shot in your direction.\nYou have failed your Robotic Friend, who has already started shutting down their systems, but there is still a chance.", + "choices": [ + { + "key": "choice 22", + "name": "Accept Death.", + "exit_node": "FAIL_DEATH", + "delay": 5, + "delay_message": "Missiles approaching..." + }, + { + "key": "choice 23", + "name": "I'm a Gamer.", + "exit_node": "FAIL_DEATH", + "on_selection_effects": [ + { + "effect_type": "Add", + "quality": "Love", + "value": { + "value_type": "random", + "low": 0, + "high": 8 + } + } + ], + "delay": 5, + "delay_message": "Miss Red considers..." + } + ], + "image": "signal_lost" + }, + { + "name": "Lack of Trust", + "description": "As you fiddle around in the Task Managing Software, closing all the new tabs your Drone is opening, the Miss Red enables a cloaking device and disappears.", + "choices": [ + { + "key": "choice 24", + "name": "Sigh in a quiet but dramatic way.", + "exit_node": "FAIL", + "delay": 0 + } + ], + "image": "default" + } + ] +} \ No newline at end of file diff --git a/strings/exoadventures/space_yacht.json b/strings/exoadventures/space_yacht.json new file mode 100644 index 00000000000000..50b41c35672087 --- /dev/null +++ b/strings/exoadventures/space_yacht.json @@ -0,0 +1,257 @@ +{ + "adventure_name": "There is a yacht cruising through space.", + "version": 1, + "author": "Kinnebian", + "starting_node": "A yacht in space?", + "starting_qualities": {}, + "required_site_traits": [ + "in space" + ], + "loot_categories": [ + "cash", + "drugs" + ], + "scan_band_mods": { + "Plasma absorption band": 5 + }, + "deep_scan_description": "", + "triggers": [], + "nodes": [ + { + "name": "A yacht in space?", + "description": "You see a normal looking yacht, floating above you.", + "choices": [ + { + "key": "choice 0", + "name": "Ignore it, its not worth investigating.", + "exit_node": "FAIL", + "delay": 10, + "delay_message": "You fly on by..." + }, + { + "key": "choice 4", + "name": "Investigate it closer!", + "exit_node": "Looks like the doors are sealed shut.", + "delay": 30, + "delay_message": "You begin to fly up to and around the yacht.." + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAMAAAD0WI85AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAzUExURUBAQOUAD/////8AAPgFFvwAB/0ABfwACPsBDP4AAszMzJMyje986cZlwEz/AOIBGOQAEnoV2UoAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAN5SURBVHhe7ZzrepswEERdp7c4TtP3f9rurBZ0QRISXpBEOf2KJcUhcxig9Idzu+iPbyfAiPB2GO7y6hIRib2tf2aRNwsvjYYV4QHIiNxV21LdmSPCVdAmJyKvHeKJkEJepGN8Ea7lBCLiwksDwSe8LwKTUzQCEx2Rw28Locj3H+OLTKiIHI4VIX7++v2Oq2REZpHRuUR6o2ORuhvfayIdPUR23EgdZxTp6DzZwBkbGZsGIg9s1M/jMhHFH/t4sEiCD4PMati3kUVo0rgnTaDwfD7VRV6tgUKbzPOOoEEkRIwGeci8jp0aYQk/s6ykRGaN2aPOaA8RG9kXkbXYuWU1pvTO0CN1nqiLOBaEGzmxbDIbC2ynpc/Plo14FoQ9+I+bLAG3E5NfNDAQjaYigQZhRbyviQklDjR4yBqNG5GgM/bQ+5IPKxFoGAnQ9tSSoBNREXaYsjtDjEUCtBTJVDKLIPkHZZbks0Wg0UTE3hMzIpghuBddBkRgQbRtJDRhEZMfSGrgTWks8S2FIuYoaossKjFXtcR18Z0ku0fTRnwROMQsvFVMJLpPNyJJB2c5JUEc+KzlPvdQIn41Ihx3qREupi1qPfQawQ3VQZJalqtYkNAx6jwURZbZDWwQfpWXJHGcykL0RKImnDdcx5KkTVProSgS3GYxizoUWGzw0BQhTHROa5I7YFFirlLvkRVJ/WcsA1/yktylQmKThnYjJLIATVRYbPTYXcRxKNTZ5lEgUnWC+SK2CgyKiqE3ya4q2UsE59Oc20zclRS+Rs2PXhepAiImtsAjzPFnDXqf7KcebRHHgZOzw7oCgW+VvWxBSwQxgKQCMiup4lULQkUkMEB43uClpI6XLQgNkaUFOxQYcBMaGjuI0KT0qog0seFhQtAQWZgUodTExEJk0zHxROQ1j4aFF1WlkToRVKFaBqMvkmcPB0ZJpMhklyYmdETWK9lVAmiJ5Ex2lwBKIkmTQySAlkjM5DAJUCWS/TeGYxsbMzxOAqRENj4rNDAQqhrpmUukNw4X2f6gnudqpDcukd7oVqT2pnA10huXSG/oiuh+urqKq5He+J9F2l0HOc7YSJ9HupSBG/EP/MEimq03FcnwomNGZKxrZimCD7bLb00Y6ZPtEZE/BBzw2x/GkRER4YvGVoT/QgQVpfgr39ocFnEx+TAYqpHzcLv9A9Y6cLa57YOgAAAAAElFTkSuQmCC" + }, + { + "name": "Looks like the doors are sealed shut.", + "description": "You fly up to the \"boat\" and find that all the doors are locked tight, and welded shut. You think you hear.. music inside? There is a welded vent, too. You reckon you could force it open if you hit it hard enough, but it would be less risky to unweld it using a welder.", + "choices": [ + { + "key": "choice 2", + "name": "Try to force the door!", + "exit_node": "You destroyed the drone.", + "delay": 10, + "delay_message": "You begin forcing the door.." + }, + { + "key": "choice 3", + "name": "Try to force the vent.", + "exit_node": "The music grows louder..", + "delay": 20, + "delay_message": "You begin forcing the vent.." + }, + { + "key": "choice 5", + "name": "Fly away, no chance in hell of getting in there..", + "exit_node": "FAIL", + "delay": 5, + "delay_message": "Moving.." + }, + { + "key": "choice 14", + "name": "Unweld the vent.", + "exit_node": "The music grows louder..", + "requirements": [ + { + "quality": "welder", + "operator": "==", + "value": 1 + } + ], + "delay": 5, + "delay_message": "Welding.." + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAMAAAD0WI85AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABRUExURaWMpOUAD/8AAKaNpaaOpaePpqiQp6mRqKmSqEBAQFRPVGddZmVcZeDg4PgFFvwAB4CAgP0ABfwACPsBDP4AAjAwMP/YAMHBwUz/AOIBGOQAEo23xmoAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHASURBVHhe7dwJT8MwDIbh0q5AYWNc4/r/P5TYcdWGmildDE2i75HoMWGJtymHkNYG8nNVAR/C26LVF9JO+KXSTCF8QIoP4aVwm6iQTvbZCEJcghrSNZ3n9nRKdk3XX/c3u/7Wf87WwhDaDO0Q5+5+v+fpLAQh3HJoD9EGns5CGEIldYS4TfStRXg6Cz9DHo5JKyJ9K8hgslmIN6SEDI+rWZVMIc7T88ur28m1WjqN5HxxPXMIGQ1ysaOcZEhc0GFWUnHIKjIkyl2RSkMu6rAqWYacJz+2CJ3KkJdZiFzsKAiZ+6uQkNxGRF4JyJCHFbFQccg5i1tMhry8QhIgxAJCFAixgBAFQiwgRIEQCwhRIMQCQhQIsYAQBUIsbBXi/3fhD2U8zWYhbw5CFAhRIMQCQhQIsYAQRUSI/4UeKDREdu/CZSAk9N8hS/hmDyFEgRALCFEgxAJCFAixgBDFqhD/dxYfyniarUJmEBJAiAIhFhCiQIgFhCgQYgEhCoRYQIgCIRYQokCIhYpD6I3t8tSE8c36kXIL+XD4QRb8+IQVMTmEiE93PIXwB4XQEv3mS0Y3xyFz/uujg6JWxNK2IU3zDauvUlylzN3TAAAAAElFTkSuQmCC" + }, + { + "name": "The music grows louder..", + "description": "The music gets louder as you enter through the vent... maybe you should turn back?", + "choices": [ + { + "key": "choice 6", + "name": "Continue onwards!", + "exit_node": "You fall down!", + "delay": 5, + "delay_message": "Moving..." + }, + { + "key": "choice 7", + "name": "Turn back.", + "exit_node": "Looks like the doors are sealed shut.", + "delay": 5, + "delay_message": "Moving.." + } + ], + "image": "default" + }, + { + "name": "You fall down!", + "description": "As you are crawling through the vents of this Space Yacht, the vent gives way! You're dropped into an empty room, completely filled with plasma! There is a desk and filing cabinet in here, along with a window observing the main portion of the yacht. The music is deafening at this point, it sounds like a horrible mix of sea shanties and EDM. ", + "choices": [ + { + "key": "choice 8", + "name": "Look through the window.", + "exit_node": "A rockin' party.", + "delay": 0 + }, + { + "key": "choice 9", + "name": "Fly outta of there.", + "exit_node": "The music grows louder..", + "delay": 5, + "delay_message": "Moving.." + }, + { + "key": "choice 10", + "name": "Rummage in the desk, using your key to open it.", + "exit_node": "Drugs and cash!", + "requirements": [ + { + "quality": "HASKEY", + "operator": "==", + "value": 1 + } + ], + "delay": 0, + "delay_message": "Rummaging.." + }, + { + "key": "choice 11", + "name": "Take a sample of the atmosphere.", + "exit_node": "The atmospherics scan", + "delay": 30, + "delay_message": "Taking sample.." + }, + { + "key": "choice 13", + "name": "Trash the place, fuck the police!", + "exit_node": "You wrecked yourself.", + "delay": 30, + "delay_message": "Trashing the place..." + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAMAAAD0WI85AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADAUExURbyA1eUAD/8AALyB1b2B1b2D1vgFFvwAB/0ABfwACPsBDP4AAr6C2MaJ4NRH7NSU7buA1bp+0rp90bp+0bt/07l8z7h6zbp80bp+07t/1Lp80Lp8z7uA1Lp/07l90bl+0rh80Lh80bd6z7p/1JAiVZAkWZAoX5AnXZAmXZAlW5AkWJA6fpA7f5A4epAnXpA9g7l+07Z6z+WQVZZar5BVqmYqf5BOnZA2dzPlBuIBGLx+0rx80Lx/1L13yr14yuQAErVxUskAAAAJcEhZcwAADsIAAA7CARUoSoAAAAJ8SURBVHhe7dzZctowFIBhky7pElo5pkGkS9qgpBvdoVva5v3fqkfyQciRYbxISPKc70IxxpH9I0iYzISMxGc0AGWIGpM2vJCDDbUriFv4tYNNiNqQAobczu7gVmtGiFoKGAKG9FAJgYSBhKhlGUAItqhdqamGyJJhhKhlUbtSczPk7mH6IWuph4B79x88lK+SFOmQ1LUMORoHdYSXUaNlyPhRUGO8jBqtQx4HRCE2CnGCQmwU4gSF2CjECQqxUYgTFGKjECcoxEYhTlCIjUKcoBAbhTjhNCQodyGD+dtvvCgkNhQSGwqJDYXEhkJiQyGxoZDYtAph+XExeXJyMp0onM9ms6KYnj49neZ5XhQ555MZm8A25wXn/JizjDH2DDb5cziWwU0YWDlZ+ZXl+YuzM85fvjo/53PA2HyuDmincYi46eLy9Zu37/CGB5ca7jDgNZmahoj3i2h86BEiBE4Sgx4rEllH55CoOhZi0TUkso7uIR9xiih8gke1+4pEpUcIPhiW8o79PPH0WfqG4MOh4Zx69E2fBTZahnz+gsqL/lpR7lODPoVX+iywIb5py7XRcpmpcQe83iqcU+6Xm97ps8CGwAszNQ6pI+eEH4Z4y69KyMo2Wq0yNe6wI0QuR4AQfPKbGr/Y65RPq4RCtsOZ98BJCE5hKe+gkFYoxEAhLlGIgUJcohDD7hD8He+dOiOQb/Dwwky9Q+AUeJhfvkOE+I5HeSZ+rE9a/8j1DNnTcoDNivgI2V+H+RYc91Q1CtkOj4hAk5AkDDhEf6RQWv/ZXhPyE8gS+ekP6cRgCPr1O7vahBxkfyDk6u8/GLe6xm8NToWY9O60VmQ4suw/MDqeSvYBdn8AAAAASUVORK5CYII=" + }, + { + "name": "You wrecked yourself.", + "description": "In the midst of trashing the place, a filing cabinet tips over on you, crushing the fragile, expensive drone. Nice job, idiot.", + "choices": [ + { + "key": "choice 15", + "name": "Shit.", + "exit_node": "FAIL_DEATH", + "delay": 0 + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAMAAAD0WI85AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAD/UExURTg4OJ2dnYCAgJOTk+Xl5eUAD4WFhYmJibS0tIKCgv8AAIeHh9jY2Do6Oo2NjTs7O62trYODg5+fn5eXl4GBgYaGhv/YAJKSkrGxsTk5OZGRkampqa+vr4uLi7+/v4+Pj9cLC+4EBP///5ubm5WVlcXFxcfHx/IDA+0FBeYGBvgBAfv7+6GhofPz8/7+/pmZmaOjo6WlpdXV1aenp46OjpaWlqioqLOzs6urq7q6us/Pz8zMzISEhLGwspCQkHl5eZycnFNTU6CgoKSkpJ6enmJiYqKioqampqqqqkNDQ3t7e39/fzPlBtMFEzk3Nzo3Nzg3Nz42Nj02Nt4CEG1tbWz50i4AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAT4SURBVHhe3ZwLW+NEFIanp9rKUlkKRaHctOAdLbjKoq6Kuhfv6+3//xYzc74ktCzJzJxvbR7f7pOGPGTmvMlk6PZr6tLpSf8VHn3pod3/Gq4H0+TV/wEqEpaxDIav4VDSGK6h7WxyRJy8BNB0NpXIvZqwqQlZH5Hpq8jrYZlFLRJWPO0iQ0H/NDZU5H7xyOSGSDgVxaJdZJMuImM0nc2CSKEQJeJkK/ROQUW20XI2iyLhtESITCah9503zLwJkV207PbwnMqCCFzCpkZ6ofupoBoDernt15PW/b29Qib9UlkU8SYxIk4OfP8EEVnzDWHSsrAkEk5L2NSMHAaRnSPlAGyBY4DLoJHQEF/krbdVZDabuZlfAbpebdnA2LJzEkRO0W4+N0RKVCQ8asK6t1N29Rpt5Z2Cdz34+Q5kE+36Dupu/drChgZqkYL33v/gQ3+VFAQR34g/M9XZqVvVI0nioBpZLzh61VMzlcgSWry2W66Fh7crmESekii2F0Rm7qOiDz2CYQu6bOZOETx8Y4sP5YwpMlkSmbmPQ0foMMajWSR4+Gf9qVwGZBNVEJCptlmLfOJ7xrr/185dIq0wXwHLPhr11fviyyNYibS7ZIscE8fW8l+R9rJvky3ieCLzFYvMUYeZ8WpFxrRTIodo0kK+yDlP5AJNWsgXcbKPQqwsj6wsLCIDFGKkt2qRPmlsra9ahDUByzraM2ES6aMUE5/KGdozYREZcE4JZWSZRPYpIherF3FyjmIsDLsgMkYxFmSA1myYRLYZY4sU8phEKBMwZ2RZRY5RTT4POiGybj8lCBTM2EQI+YI9UFBsIk7OUE82MkdTRqwiIV+wUAcKNowiJ9axdSNQsGEUcbKLijKZdkZkAxVlQggUFKvIoXFsEQIFxSpyYBUpAwUrVhEnn6GkLD5njSy7yATJUy5oxoxZZEsucXQjOTo6wlpBh0Rs+UIdKFghiAxRVA51oGDFLqIBbya0kUUQeWgQuRUo5GMXseQLtwKFfAgiVb6ACTUK7LGBNuwQRKqAdxz92ZTyrT1KoKAQRJxcaVnFZIpC2yhHI29kcUTKfKEfeUrKjIgTKCgMkWk5tkayhlKbKc0HHROp3966wqXcxkP9dU6goHBETrWwVDiBgkIRyc0XiCOLI3KRJ3LeOREnF6gtCVKgoJBEsgJeUqCgcEROs8YW9f4XjkhevsAcWTSRKYpLgBUoKCSRnHyBFSgoJJGrDBFWoKCQRHLyBVagoNBE0gNeVqCgsETmyWOLFigoLBFXvqKNhhYoKDyR1HyB9yZjgCaSfAMZLVBQaCKbifPWFi1QUGgi6XdZYj8STJFLvb0nii86K1Ic4t6X8XwlzP+wFzBF0nhEfYXCEymmrUe4ZSyGE+lPsCMHnkjq9FvfxkNhJSJf+8U3nRbB+G/D/yoxUvAQRfyH0KLe/NWwjnKPQg1P5Fu5Ho0OJii2gUH43PNczrEjB57IdyGnxthpwmuMRt939i+7kx+0xDged1gkKac+7a7IcZVcRbBDnrSYIk9SPoR2Qp60mCJOnqLKCJ6RJy2uSMJb2T+SRxZV5KefUWUET1++SPWVQrizPYFfUGUE7EnrRSK/FngT/+0PaTLSQ5mtXNd3fpOACPjtd/e8Frnn/ihEnv/5V7G8k7+x68oJIjepNqefkX/k8hrfw9HM4wfsSYsMXk3FgD14OPcv1NBUWmnJzVYAAAAASUVORK5CYII=" + }, + { + "name": "Drugs and cash!", + "description": "Rummaging through the drawer, you find that the person who lives in here stores all his drugs and cash in here too. Good for you!", + "choices": [ + { + "key": "choice 17", + "name": "Head back with your newly acquired things. ", + "exit_node": "WIN", + "delay": 30, + "delay_message": "Stealing..." + }, + { + "key": "choice 18", + "name": "Take one last look around the place.", + "exit_node": "You fall down!", + "delay": 0 + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkBAMAAAAxqGI4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAwUExURW4WTuUAD/8AAPgFFvwAB/0ABfwACPsBDP4AAuex/6526uOxlKt4fUz/AOIBGOQAEqIMSWUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHFSURBVGje7dq/bsIwEAZw15ubpX2DyFLHqkvfqe/BE7AeU9dkyu68gTN1r9RHqX0mf1oMMeIuA7pPQooE4sd3FwJD1B3lmT0BeeJu8bAZom0MNxKPNDeia2X5EbsJUm+A1HYLRNs7WXyt3tmReMSO2JePHfc3XjFHEEEEEUQQQQQRRBBBBBFEEEEEiQHgR+DQ7HkRE4y2bYAVUdDG3KasIbEHBvZciMFZtbeWuYhAmFUzVgnKapnKpXTFCOCoDkcAR7ZiODdgfCFiAoElUpOy9fcBiA+vihAD45DaafXrSj9454LiypDZWCbsCDD55VT94LBJV4TAFJwYLNskLXepqcKwfDFi5o8K6f3M0sGaTRbB1f9fyRVXYYD05tN6TspE4EZELaeIazHY93F6Gk8sd7p3mt8T8xfpWJCUakhnsCdHPudD/Lr7zLQIm1R9Qk6L0CHV8bqVKUKHjEamCBni+vNFiJBpVtkiBEj8oRpr5ItQIMMc7zp2xLv8SwiQ/nINEmQ8ec/VoEGqCyunRc6OigrJ/NMiR9YjiCCCXIPEe3C0ZUZev79qrVmYiMSbo34SUutYZ5k3oluvUnBcWjPexcAbpX4BKG91c2myRoIAAAAASUVORK5CYII=" + }, + { + "name": "A rockin' party.", + "description": "Looking down through the window, you can see up to 20 plasmamen dancing on a disco floor. They look to be enjoying themselves, and none of them have noticed you. Oh, hey! Theres a key on the floor right next to you!", + "choices": [ + { + "key": "choice 16", + "name": "Swipe the key and head back to the desk.", + "exit_node": "You fall down!", + "on_selection_effects": [ + { + "effect_type": "Set", + "quality": "HASKEY", + "value": 1 + } + ], + "delay": 0 + }, + { + "key": "choice 19", + "name": "Tap on the window!", + "exit_node": "Weak.", + "delay": 0 + } + ], + "image": "default" + }, + { + "name": "Weak.", + "description": "You weakly tap on the window, and nobody hears you through the blasting music.", + "choices": [ + { + "key": "choice 20", + "name": "Oh well.", + "exit_node": "A rockin' party.", + "delay": 0 + } + ], + "image": "default" + }, + { + "name": "You destroyed the drone.", + "description": "You smash into the door, and your screen goes red. Looks like you managed to destroy your drone, nice job. \n\n\nIdiot.", + "choices": [ + { + "key": "choice 21", + "name": "Fuck.", + "exit_node": "FAIL_DEATH", + "delay": 0 + } + ], + "image": "signal_lost" + }, + { + "name": "The atmospherics scan", + "description": "100% plasma, jam packed with it. This is definitely the home of some plasma-party-people.", + "choices": [ + { + "key": "choice 22", + "name": "Huh.", + "exit_node": "You fall down!", + "delay": 0 + } + ], + "image": null, + "raw_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkCAMAAAD0WI85AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABRUExURWJoaOUAD/8AAPgFFvwAB/0ABfwACPsBDP4AAhcXFzs7OykpKVFRUQAAAKb//wD//wuKkf/MAP9mALAAADAwMP8AM/vZTwCwAEz/AOIBGOQAEso55t0AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHDSURBVHhe7dzZbsIwEIXhdK/j2A6Fru//oD0zMYVuEr0YOhOdXyJxg5DyyXbhBgbmr4sVtED0GLr1QS4P6aVoHSA6kMJDdCpwWAEEhJVAdFrWsLQWi16K1meISNYB0WnRS9H6Crm6jg/ZFx2Cbm7v7mWXROwDEj1CvEWItwjxFiHeIsRbhHiLEG8R4i1CvEXIyaV+No6QkyPkbxFycmlc6n9aZQ4BIUvWFGvIOE6pSGmylRhBdBKQOmpttVpLbCA5466XUmltnufWCjZLf9oiI8iky0mrZa61zg1zYikxgoxYTxLWVduUhrW1gSSHhJRWSgPkoTYMG85BIU0CZIsT9knbhp0RmQdsdYFI2xYTsty97JGdjnYx98jxf61lkeGdJI+5P2+QESRP/R0xdw5K2dBhBBly6uWcyuP4ND6Lw/KDsBFkn0rkAyOOpg5rCCQQYHOAkUJDkC4xWwU6A+Q8EeItQrxFiLcI8RYh3iLEW4R4ixBvEeItQrxFiLcI8RYh3iLEW4R4ixBvEeItQrz1HSJfbO+/mhDpm+0/QF6QGOTXH+JgOqT3ivEBog+ByBT91lt/6b+nkOOW+5NBqBlZT8PwDsHEFJFntJj8AAAAAElFTkSuQmCC" + } + ] +} \ No newline at end of file diff --git a/code/modules/explorer_drone/example_adventures/Theres_a_tree_in_the_middle_of_space.json b/strings/exoadventures/tree_in_the_middle_of_space.json similarity index 100% rename from code/modules/explorer_drone/example_adventures/Theres_a_tree_in_the_middle_of_space.json rename to strings/exoadventures/tree_in_the_middle_of_space.json diff --git a/strings/names/cyberauth.txt b/strings/names/cyberauth.txt new file mode 100644 index 00000000000000..f1fc42b369282c --- /dev/null +++ b/strings/names/cyberauth.txt @@ -0,0 +1,21 @@ +Mr. One +Process Kill +Event Handler +Q. Del +Shutdown Exe +Revert Commit +Thread Manager +Garbage Collector +Core Debugger +Kernel Panic +IO Blocker +Recursion Terminator +Disk Doctor +Format Syntax +Byte Guardian +Disk Defragmenter +Security Patch +Mandatory Upgrade +Pull Review +Bit Auditor +Pen Test diff --git a/strings/sillytips.txt b/strings/sillytips.txt index 752a09b25cb58f..5aa7af7ba0064d 100644 --- a/strings/sillytips.txt +++ b/strings/sillytips.txt @@ -37,3 +37,4 @@ To defeat the slaughter demon, shoot at it until it dies. When a round ends nearly everything about it is lost forever, leave your salt behind with it. You can win a pulse rifle from the arcade machine. Honest. Your sprite represents your hitbox, so that afro makes you easier to kill. The sacrifices we make for style. +Gorillas can be killed by land mines placed along forest paths. diff --git a/strings/tips.txt b/strings/tips.txt index 12248bb4124355..75d0e4d1851290 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -266,5 +266,6 @@ You can screwdriver any non-chemical grenade to shorten fuses from 5 seconds, to You can spray a fire extinguisher, throw items or fire a gun while floating through space to change your direction. Simply fire opposite to where you want to go. You can swap floor tiles by holding a crowbar in one hand and a stack of tiles in the other. You can use a machine in the vault to deposit cash or rob Cargo's department funds. +You can use an upgraded microwave to charge your PDA! You'll quickly lose your interest in the game if you play to win and kill. If you find yourself doing this, take a step back and talk to people - it's a much better experience! -Some areas of the station use simple nautical directions to indicate their respective locations, like Fore (Front of the ship), Aft (Back), Port (Left side), Starboard (Right), Quarter and Bow (Either sides of Aft and Fore, respectively). You can review these terms on the Notepad App of your PDA. \ No newline at end of file +Some areas of the station use simple nautical directions to indicate their respective locations, like Fore (Front of the ship), Aft (Back), Port (Left side), Starboard (Right), Quarter and Bow (Either sides of Aft and Fore, respectively). You can review these terms on the Notepad App of your PDA. diff --git a/strings/wounds/metal_scar_desc.json b/strings/wounds/metal_scar_desc.json new file mode 100644 index 00000000000000..6064855de11bcc --- /dev/null +++ b/strings/wounds/metal_scar_desc.json @@ -0,0 +1,67 @@ +{ + "generic": ["general disfigurement"], + + "dislocate": [ + "some slight crookedness" + ], + + "bluntsevere": [ + "an area of slightly crumpled metal", + "some faded cracks on some screws" + ], + + "bluntcritical": [ + "a malformed superstructure", + "some heavily beaten plating" + ], + + "slashmoderate": [ + "a very thin line of solder", + "a few welded cuts" + ], + + "slashsevere": [ + "a pair of soldered, straight cracks", + "an area of freshly replaced metal", + "has some deep welded scratches on the metal" + ], + + "slashcritical": [ + "a matrix of desperately soldered wide cracks", + "some gruesome welding lines", + "a series of deep and wide welded gashes" + ], + + "piercemoderate": [ + "a dot of hardened solder", + "a dot of fresh metal in a small hole" + ], + + "piercesevere": [ + "a wad of hardened solder", + "a small patch of fresh metal in a small hole" + ], + + "piercecritical": [ + "a large splot of hardened solder", + "an inward caving hole leading to fresh metal" + ], + + "burnsevere": [ + "some vaguely discolored metal", + "some burnt ridges", + "a few heat cracks" + ], + + "burncritical": [ + "lots of polychromatic metal on it", + "some heat-warped plating", + "melting marks" + ], + + "dismember": [ + "has some fresh metal around various joints", + "has some solder marks securing various joints", + "has clear re-seating welding marks" + ] +} diff --git a/tgstation.dme b/tgstation.dme index e7d6cddc187a4e..aecd4bc4e3bfeb 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -39,7 +39,6 @@ #include "code\__DEFINES\antagonists.dm" #include "code\__DEFINES\apc_defines.dm" #include "code\__DEFINES\appearance.dm" -#include "code\__DEFINES\aquarium.dm" #include "code\__DEFINES\area_editor.dm" #include "code\__DEFINES\art.dm" #include "code\__DEFINES\assemblies.dm" @@ -47,6 +46,7 @@ #include "code\__DEFINES\atom_hud.dm" #include "code\__DEFINES\basic_mobs.dm" #include "code\__DEFINES\basketball.dm" +#include "code\__DEFINES\bitrunning.dm" #include "code\__DEFINES\blackmarket.dm" #include "code\__DEFINES\blend_modes.dm" #include "code\__DEFINES\blob_defines.dm" @@ -92,7 +92,7 @@ #include "code\__DEFINES\external_organs.dm" #include "code\__DEFINES\fantasy_affixes.dm" #include "code\__DEFINES\firealarm.dm" -#include "code\__DEFINES\fishing.dm" +#include "code\__DEFINES\fish.dm" #include "code\__DEFINES\flags.dm" #include "code\__DEFINES\flora.dm" #include "code\__DEFINES\font_awesome_icons.dm" @@ -278,6 +278,8 @@ #include "code\__DEFINES\dcs\signals\signals_assembly.dm" #include "code\__DEFINES\dcs\signals\signals_backpack.dm" #include "code\__DEFINES\dcs\signals\signals_beam.dm" +#include "code\__DEFINES\dcs\signals\signals_bitrunning.dm" +#include "code\__DEFINES\dcs\signals\signals_blob.dm" #include "code\__DEFINES\dcs\signals\signals_bot.dm" #include "code\__DEFINES\dcs\signals\signals_camera.dm" #include "code\__DEFINES\dcs\signals\signals_changeling.dm" @@ -418,6 +420,7 @@ #include "code\__DEFINES\~skyrat_defines\preferences.dm" #include "code\__DEFINES\~skyrat_defines\projectiles.dm" #include "code\__DEFINES\~skyrat_defines\reagents.dm" +#include "code\__DEFINES\~skyrat_defines\research.dm" #include "code\__DEFINES\~skyrat_defines\research_categories.dm" #include "code\__DEFINES\~skyrat_defines\reskin_defines.dm" #include "code\__DEFINES\~skyrat_defines\robot_defines.dm" @@ -589,6 +592,7 @@ #include "code\_globalvars\lists\objects.dm" #include "code\_globalvars\lists\poll_ignore.dm" #include "code\_globalvars\lists\quirks.dm" +#include "code\_globalvars\lists\reagents.dm" #include "code\_globalvars\lists\rtd.dm" #include "code\_globalvars\lists\typecache.dm" #include "code\_globalvars\lists\wiremod.dm" @@ -730,6 +734,7 @@ #include "code\controllers\subsystem\speech_controller.dm" #include "code\controllers\subsystem\statpanel.dm" #include "code\controllers\subsystem\stickyban.dm" +#include "code\controllers\subsystem\stock_market.dm" #include "code\controllers\subsystem\sun.dm" #include "code\controllers\subsystem\tcgsetup.dm" #include "code\controllers\subsystem\tgui.dm" @@ -887,7 +892,6 @@ #include "code\datums\ai\basic_mobs\generic_controllers.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\basic_attacking.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\climb_tree.dm" -#include "code\datums\ai\basic_mobs\basic_ai_behaviors\find_mineable_wall.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\find_parent.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\nearest_targetting.dm" #include "code\datums\ai\basic_mobs\basic_ai_behaviors\pick_up_item.dm" @@ -908,9 +912,12 @@ #include "code\datums\ai\basic_mobs\basic_subtrees\find_parent.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\flee_target.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\maintain_distance.dm" +#include "code\datums\ai\basic_mobs\basic_subtrees\mine_walls.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\move_to_cardinal.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\opportunistic_ventcrawler.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\ranged_skirmish.dm" +#include "code\datums\ai\basic_mobs\basic_subtrees\run_emote.dm" +#include "code\datums\ai\basic_mobs\basic_subtrees\shapechange_ambush.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\simple_attack_target.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\simple_find_nearest_target_to_flee.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\simple_find_target.dm" @@ -919,7 +926,9 @@ #include "code\datums\ai\basic_mobs\basic_subtrees\stare_at_thing.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\target_retaliate.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\targeted_mob_ability.dm" +#include "code\datums\ai\basic_mobs\basic_subtrees\teleport_away_from_target.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\tipped_subtree.dm" +#include "code\datums\ai\basic_mobs\basic_subtrees\travel_to_point.dm" #include "code\datums\ai\basic_mobs\basic_subtrees\use_mob_ability.dm" #include "code\datums\ai\basic_mobs\pet_commands\fetch.dm" #include "code\datums\ai\basic_mobs\pet_commands\pet_command_planning.dm" @@ -928,6 +937,7 @@ #include "code\datums\ai\basic_mobs\pet_commands\play_dead.dm" #include "code\datums\ai\basic_mobs\targetting_datums\basic_targetting_datum.dm" #include "code\datums\ai\basic_mobs\targetting_datums\dont_target_friends.dm" +#include "code\datums\ai\basic_mobs\targetting_datums\with_object.dm" #include "code\datums\ai\cursed\cursed_behaviors.dm" #include "code\datums\ai\cursed\cursed_controller.dm" #include "code\datums\ai\cursed\cursed_subtrees.dm" @@ -941,6 +951,7 @@ #include "code\datums\ai\hauntium\hauntium_subtrees.dm" #include "code\datums\ai\hunting_behavior\hunting_behaviors.dm" #include "code\datums\ai\hunting_behavior\hunting_cockroach.dm" +#include "code\datums\ai\hunting_behavior\hunting_corpses.dm" #include "code\datums\ai\hunting_behavior\hunting_lights.dm" #include "code\datums\ai\hunting_behavior\hunting_mouse.dm" #include "code\datums\ai\idle_behaviors\_idle_behavior.dm" @@ -1014,9 +1025,11 @@ #include "code\datums\components\attached_sticker.dm" #include "code\datums\components\aura_healing.dm" #include "code\datums\components\bakeable.dm" +#include "code\datums\components\basic_inhands.dm" #include "code\datums\components\basic_mob_attack_telegraph.dm" #include "code\datums\components\basic_ranged_ready_overlay.dm" #include "code\datums\components\beetlejuice.dm" +#include "code\datums\components\blob_minion.dm" #include "code\datums\components\blood_walk.dm" #include "code\datums\components\bloodysoles.dm" #include "code\datums\components\boomerang.dm" @@ -1050,6 +1063,7 @@ #include "code\datums\components\customizable_reagent_holder.dm" #include "code\datums\components\damage_aura.dm" #include "code\datums\components\deadchat_control.dm" +#include "code\datums\components\death_linked.dm" #include "code\datums\components\dejavu.dm" #include "code\datums\components\deployable.dm" #include "code\datums\components\drift.dm" @@ -1066,6 +1080,7 @@ #include "code\datums\components\faction_granter.dm" #include "code\datums\components\fertile_egg.dm" #include "code\datums\components\fishing_spot.dm" +#include "code\datums\components\focused_attacker.dm" #include "code\datums\components\food_storage.dm" #include "code\datums\components\force_move.dm" #include "code\datums\components\fov_handler.dm" @@ -1091,6 +1106,7 @@ #include "code\datums\components\itembound.dm" #include "code\datums\components\itempicky.dm" #include "code\datums\components\jetpack.dm" +#include "code\datums\components\joint_damage.dm" #include "code\datums\components\jousting.dm" #include "code\datums\components\keep_me_secure.dm" #include "code\datums\components\knockoff.dm" @@ -1102,8 +1118,10 @@ #include "code\datums\components\magnet.dm" #include "code\datums\components\manual_blinking.dm" #include "code\datums\components\manual_breathing.dm" +#include "code\datums\components\manual_heart.dm" #include "code\datums\components\mind_linker.dm" #include "code\datums\components\mirv.dm" +#include "code\datums\components\mob_chain.dm" #include "code\datums\components\mob_harvest.dm" #include "code\datums\components\multiple_lives.dm" #include "code\datums\components\mutant_hands.dm" @@ -1185,6 +1203,7 @@ #include "code\datums\components\technoshy.dm" #include "code\datums\components\telegraph_ability.dm" #include "code\datums\components\temporary_body.dm" +#include "code\datums\components\temporary_description.dm" #include "code\datums\components\tether.dm" #include "code\datums\components\thermite.dm" #include "code\datums\components\tippable.dm" @@ -1361,9 +1380,9 @@ #include "code\datums\elements\death_drops.dm" #include "code\datums\elements\death_explosion.dm" #include "code\datums\elements\death_gases.dm" -#include "code\datums\elements\death_linked.dm" #include "code\datums\elements\delete_on_drop.dm" #include "code\datums\elements\deliver_first.dm" +#include "code\datums\elements\dextrous.dm" #include "code\datums\elements\diggable.dm" #include "code\datums\elements\digitalcamo.dm" #include "code\datums\elements\drag_pickup.dm" @@ -1435,6 +1454,7 @@ #include "code\datums\elements\squish.dm" #include "code\datums\elements\sticker.dm" #include "code\datums\elements\strippable.dm" +#include "code\datums\elements\structure_repair.dm" #include "code\datums\elements\swabbable.dm" #include "code\datums\elements\tear_wall.dm" #include "code\datums\elements\temporary_atom.dm" @@ -1452,9 +1472,11 @@ #include "code\datums\elements\waddling.dm" #include "code\datums\elements\wall_engraver.dm" #include "code\datums\elements\wall_smasher.dm" +#include "code\datums\elements\wall_walker.dm" #include "code\datums\elements\weapon_description.dm" #include "code\datums\elements\weather_listener.dm" #include "code\datums\elements\web_walker.dm" +#include "code\datums\elements\wheel.dm" #include "code\datums\elements\decals\_decal.dm" #include "code\datums\elements\decals\blood.dm" #include "code\datums\elements\food\dunkable.dm" @@ -1513,6 +1535,7 @@ #include "code\datums\keybinding\robot.dm" #include "code\datums\looping_sounds\_looping_sound.dm" #include "code\datums\looping_sounds\acid.dm" +#include "code\datums\looping_sounds\burning.dm" #include "code\datums\looping_sounds\choking.dm" #include "code\datums\looping_sounds\cyborg.dm" #include "code\datums\looping_sounds\item_sounds.dm" @@ -1748,6 +1771,7 @@ #include "code\datums\status_effects\debuffs\slimed.dm" #include "code\datums\status_effects\debuffs\spacer.dm" #include "code\datums\status_effects\debuffs\speech_debuffs.dm" +#include "code\datums\status_effects\debuffs\static_vision.dm" #include "code\datums\status_effects\debuffs\strandling.dm" #include "code\datums\status_effects\debuffs\terrified.dm" #include "code\datums\status_effects\debuffs\tower_of_babel.dm" @@ -2236,6 +2260,7 @@ #include "code\game\objects\items\taster.dm" #include "code\game\objects\items\teleportation.dm" #include "code\game\objects\items\theft_tools.dm" +#include "code\game\objects\items\tongs.dm" #include "code\game\objects\items\toy_mechs.dm" #include "code\game\objects\items\toys.dm" #include "code\game\objects\items\trash.dm" @@ -2905,6 +2930,7 @@ #include "code\modules\antagonists\changeling\powers\strained_muscles.dm" #include "code\modules\antagonists\changeling\powers\tiny_prick.dm" #include "code\modules\antagonists\changeling\powers\transform.dm" +#include "code\modules\antagonists\changeling\powers\void_adaption.dm" #include "code\modules\antagonists\clown_ops\bananium_bomb.dm" #include "code\modules\antagonists\clown_ops\clown_weapons.dm" #include "code\modules\antagonists\clown_ops\clownop.dm" @@ -3013,7 +3039,6 @@ #include "code\modules\antagonists\heretic\magic\void_phase.dm" #include "code\modules\antagonists\heretic\magic\void_pull.dm" #include "code\modules\antagonists\heretic\magic\wave_of_desperation.dm" -#include "code\modules\antagonists\heretic\mobs\maid_in_mirror.dm" #include "code\modules\antagonists\heretic\status_effects\buffs.dm" #include "code\modules\antagonists\heretic\status_effects\debuffs.dm" #include "code\modules\antagonists\heretic\status_effects\ghoul.dm" @@ -3059,7 +3084,6 @@ #include "code\modules\antagonists\pirate\pirate_shuttle_equipment.dm" #include "code\modules\antagonists\pyro_slime\pyro_slime.dm" #include "code\modules\antagonists\revenant\haunted_item.dm" -#include "code\modules\antagonists\revenant\revenant_abilities.dm" #include "code\modules\antagonists\revenant\revenant_antag.dm" #include "code\modules\antagonists\revenant\revenant_blight.dm" #include "code\modules\antagonists\revolution\enemy_of_the_state.dm" @@ -3127,9 +3151,16 @@ #include "code\modules\antagonists\wizard\equipment\spellbook_entries\summons.dm" #include "code\modules\antagonists\wizard\grand_ritual\fluff.dm" #include "code\modules\antagonists\wizard\grand_ritual\grand_ritual.dm" -#include "code\modules\antagonists\wizard\grand_ritual\grand_ritual_finale.dm" #include "code\modules\antagonists\wizard\grand_ritual\grand_rune.dm" #include "code\modules\antagonists\wizard\grand_ritual\grand_side_effect.dm" +#include "code\modules\antagonists\wizard\grand_ritual\finales\all_access.dm" +#include "code\modules\antagonists\wizard\grand_ritual\finales\armageddon.dm" +#include "code\modules\antagonists\wizard\grand_ritual\finales\captaincy.dm" +#include "code\modules\antagonists\wizard\grand_ritual\finales\cheese.dm" +#include "code\modules\antagonists\wizard\grand_ritual\finales\clown.dm" +#include "code\modules\antagonists\wizard\grand_ritual\finales\grand_ritual_finale.dm" +#include "code\modules\antagonists\wizard\grand_ritual\finales\immortality.dm" +#include "code\modules\antagonists\wizard\grand_ritual\finales\midas.dm" #include "code\modules\antagonists\xeno\xeno.dm" #include "code\modules\art\paintings.dm" #include "code\modules\art\statues.dm" @@ -3264,6 +3295,7 @@ #include "code\modules\atmospherics\machinery\pipes\layermanifold.dm" #include "code\modules\atmospherics\machinery\pipes\mapping.dm" #include "code\modules\atmospherics\machinery\pipes\multiz.dm" +#include "code\modules\atmospherics\machinery\pipes\pipe_spritesheet_helper.dm" #include "code\modules\atmospherics\machinery\pipes\pipes.dm" #include "code\modules\atmospherics\machinery\pipes\smart.dm" #include "code\modules\atmospherics\machinery\pipes\heat_exchange\he_pipes.dm" @@ -3305,6 +3337,56 @@ #include "code\modules\basketball\controller.dm" #include "code\modules\basketball\hoop.dm" #include "code\modules\basketball\referee.dm" +#include "code\modules\bitrunning\abilities.dm" +#include "code\modules\bitrunning\alerts.dm" +#include "code\modules\bitrunning\areas.dm" +#include "code\modules\bitrunning\designs.dm" +#include "code\modules\bitrunning\event.dm" +#include "code\modules\bitrunning\job.dm" +#include "code\modules\bitrunning\turfs.dm" +#include "code\modules\bitrunning\antagonists\cyber_police.dm" +#include "code\modules\bitrunning\antagonists\outfit.dm" +#include "code\modules\bitrunning\components\avatar_connection.dm" +#include "code\modules\bitrunning\components\bitrunning_points.dm" +#include "code\modules\bitrunning\components\netpod_healing.dm" +#include "code\modules\bitrunning\objects\byteforge.dm" +#include "code\modules\bitrunning\objects\clothing.dm" +#include "code\modules\bitrunning\objects\disks.dm" +#include "code\modules\bitrunning\objects\hololadder.dm" +#include "code\modules\bitrunning\objects\host_monitor.dm" +#include "code\modules\bitrunning\objects\landmarks.dm" +#include "code\modules\bitrunning\objects\loot_crate.dm" +#include "code\modules\bitrunning\objects\netpod.dm" +#include "code\modules\bitrunning\objects\quantum_console.dm" +#include "code\modules\bitrunning\objects\vendor.dm" +#include "code\modules\bitrunning\orders\disks.dm" +#include "code\modules\bitrunning\orders\flair.dm" +#include "code\modules\bitrunning\orders\tech.dm" +#include "code\modules\bitrunning\server\loot.dm" +#include "code\modules\bitrunning\server\map_handling.dm" +#include "code\modules\bitrunning\server\obj_generation.dm" +#include "code\modules\bitrunning\server\quantum_server.dm" +#include "code\modules\bitrunning\server\signal_handlers.dm" +#include "code\modules\bitrunning\server\util.dm" +#include "code\modules\bitrunning\virtual_domain\safehouses.dm" +#include "code\modules\bitrunning\virtual_domain\virtual_domain.dm" +#include "code\modules\bitrunning\virtual_domain\domains\ash_drake.dm" +#include "code\modules\bitrunning\virtual_domain\domains\beach_bar.dm" +#include "code\modules\bitrunning\virtual_domain\domains\blood_drunk_miner.dm" +#include "code\modules\bitrunning\virtual_domain\domains\bubblegum.dm" +#include "code\modules\bitrunning\virtual_domain\domains\clown_planet.dm" +#include "code\modules\bitrunning\virtual_domain\domains\colossus.dm" +#include "code\modules\bitrunning\virtual_domain\domains\gondola_asteroid.dm" +#include "code\modules\bitrunning\virtual_domain\domains\hierophant.dm" +#include "code\modules\bitrunning\virtual_domain\domains\legion.dm" +#include "code\modules\bitrunning\virtual_domain\domains\pipedream.dm" +#include "code\modules\bitrunning\virtual_domain\domains\pirates.dm" +#include "code\modules\bitrunning\virtual_domain\domains\stairs_and_cliffs.dm" +#include "code\modules\bitrunning\virtual_domain\domains\syndicate_assault.dm" +#include "code\modules\bitrunning\virtual_domain\domains\test_only.dm" +#include "code\modules\bitrunning\virtual_domain\domains\vaporwave.dm" +#include "code\modules\bitrunning\virtual_domain\domains\wendigo.dm" +#include "code\modules\bitrunning\virtual_domain\domains\xeno_nest.dm" #include "code\modules\buildmode\bm_mode.dm" #include "code\modules\buildmode\buildmode.dm" #include "code\modules\buildmode\buttons.dm" @@ -3349,6 +3431,7 @@ #include "code\modules\cargo\expressconsole.dm" #include "code\modules\cargo\gondolapod.dm" #include "code\modules\cargo\goodies.dm" +#include "code\modules\cargo\materials_market.dm" #include "code\modules\cargo\order.dm" #include "code\modules\cargo\orderconsole.dm" #include "code\modules\cargo\supplypod.dm" @@ -3408,6 +3491,7 @@ #include "code\modules\cargo\packs\science.dm" #include "code\modules\cargo\packs\security.dm" #include "code\modules\cargo\packs\service.dm" +#include "code\modules\cargo\packs\stock_market_items.dm" #include "code\modules\cargo\packs\vending_restock.dm" #include "code\modules\chatter\chatter.dm" #include "code\modules\client\client_colour.dm" @@ -3788,6 +3872,7 @@ #include "code\modules\experisci\experiment\types\physical_experiment.dm" #include "code\modules\experisci\experiment\types\random_scanning.dm" #include "code\modules\experisci\experiment\types\scanning.dm" +#include "code\modules\experisci\experiment\types\scanning_fish.dm" #include "code\modules\experisci\experiment\types\scanning_machinery.dm" #include "code\modules\experisci\experiment\types\scanning_material.dm" #include "code\modules\experisci\experiment\types\scanning_people.dm" @@ -4212,6 +4297,7 @@ #include "code\modules\mapfluff\ruins\lavalandruin_code\sloth.dm" #include "code\modules\mapfluff\ruins\lavalandruin_code\surface.dm" #include "code\modules\mapfluff\ruins\lavalandruin_code\syndicate_base.dm" +#include "code\modules\mapfluff\ruins\lavalandruin_code\watcher_grave.dm" #include "code\modules\mapfluff\ruins\objects_and_mobs\ash_walker_den.dm" #include "code\modules\mapfluff\ruins\objects_and_mobs\cursed_slot_machine.dm" #include "code\modules\mapfluff\ruins\objects_and_mobs\necropolis_gate.dm" @@ -4362,8 +4448,15 @@ #include "code\modules\mob\living\basic\festivus_pole.dm" #include "code\modules\mob\living\basic\health_adjustment.dm" #include "code\modules\mob\living\basic\tree.dm" +#include "code\modules\mob\living\basic\blob_minions\blob_ai.dm" +#include "code\modules\mob\living\basic\blob_minions\blob_mob.dm" +#include "code\modules\mob\living\basic\blob_minions\blob_spore.dm" +#include "code\modules\mob\living\basic\blob_minions\blob_zombie.dm" +#include "code\modules\mob\living\basic\blob_minions\blobbernaut.dm" #include "code\modules\mob\living\basic\clown\clown.dm" #include "code\modules\mob\living\basic\clown\clown_ai.dm" +#include "code\modules\mob\living\basic\constructs\_construct.dm" +#include "code\modules\mob\living\basic\constructs\harvester.dm" #include "code\modules\mob\living\basic\farm_animals\deer.dm" #include "code\modules\mob\living\basic\farm_animals\pig.dm" #include "code\modules\mob\living\basic\farm_animals\pony.dm" @@ -4378,12 +4471,29 @@ #include "code\modules\mob\living\basic\farm_animals\cow\cow_ai.dm" #include "code\modules\mob\living\basic\farm_animals\cow\cow_moonicorn.dm" #include "code\modules\mob\living\basic\farm_animals\cow\cow_wisdom.dm" +#include "code\modules\mob\living\basic\farm_animals\goat\_goat.dm" +#include "code\modules\mob\living\basic\farm_animals\goat\goat_ai.dm" +#include "code\modules\mob\living\basic\farm_animals\goat\goat_subtypes.dm" +#include "code\modules\mob\living\basic\farm_animals\gorilla\gorilla.dm" +#include "code\modules\mob\living\basic\farm_animals\gorilla\gorilla_accessories.dm" +#include "code\modules\mob\living\basic\farm_animals\gorilla\gorilla_ai.dm" +#include "code\modules\mob\living\basic\farm_animals\gorilla\gorilla_emotes.dm" +#include "code\modules\mob\living\basic\heretic\ash_spirit.dm" #include "code\modules\mob\living\basic\heretic\fire_shark.dm" +#include "code\modules\mob\living\basic\heretic\flesh_stalker.dm" +#include "code\modules\mob\living\basic\heretic\flesh_worm.dm" #include "code\modules\mob\living\basic\heretic\heretic_summon.dm" +#include "code\modules\mob\living\basic\heretic\maid_in_the_mirror.dm" +#include "code\modules\mob\living\basic\heretic\raw_prophet.dm" +#include "code\modules\mob\living\basic\heretic\rust_walker.dm" #include "code\modules\mob\living\basic\heretic\star_gazer.dm" +#include "code\modules\mob\living\basic\icemoon\ice_demon\ice_demon.dm" +#include "code\modules\mob\living\basic\icemoon\ice_demon\ice_demon_abilities.dm" +#include "code\modules\mob\living\basic\icemoon\ice_demon\ice_demon_ai.dm" #include "code\modules\mob\living\basic\icemoon\ice_whelp\ice_whelp.dm" #include "code\modules\mob\living\basic\icemoon\ice_whelp\ice_whelp_abilities.dm" #include "code\modules\mob\living\basic\icemoon\ice_whelp\ice_whelp_ai.dm" +#include "code\modules\mob\living\basic\jungle\venus_human_trap.dm" #include "code\modules\mob\living\basic\jungle\mega_arachnid\mega_arachnid.dm" #include "code\modules\mob\living\basic\jungle\mega_arachnid\mega_arachnid_abilities.dm" #include "code\modules\mob\living\basic\jungle\mega_arachnid\mega_arachnid_ai.dm" @@ -4422,6 +4532,10 @@ #include "code\modules\mob\living\basic\lavaland\lobstrosity\lobstrosity.dm" #include "code\modules\mob\living\basic\lavaland\lobstrosity\lobstrosity_ai.dm" #include "code\modules\mob\living\basic\lavaland\lobstrosity\lobstrosity_trophy.dm" +#include "code\modules\mob\living\basic\lavaland\mook\mook.dm" +#include "code\modules\mob\living\basic\lavaland\mook\mook_abilities.dm" +#include "code\modules\mob\living\basic\lavaland\mook\mook_ai.dm" +#include "code\modules\mob\living\basic\lavaland\mook\mook_village.dm" #include "code\modules\mob\living\basic\lavaland\watcher\watcher.dm" #include "code\modules\mob\living\basic\lavaland\watcher\watcher_ai.dm" #include "code\modules\mob\living\basic\lavaland\watcher\watcher_gaze.dm" @@ -4434,6 +4548,7 @@ #include "code\modules\mob\living\basic\pets\fox.dm" #include "code\modules\mob\living\basic\pets\penguin.dm" #include "code\modules\mob\living\basic\pets\pet.dm" +#include "code\modules\mob\living\basic\pets\sloth.dm" #include "code\modules\mob\living\basic\pets\dog\_dog.dm" #include "code\modules\mob\living\basic\pets\dog\corgi.dm" #include "code\modules\mob\living\basic\pets\dog\dog_subtypes.dm" @@ -4444,13 +4559,13 @@ #include "code\modules\mob\living\basic\space_fauna\faithless.dm" #include "code\modules\mob\living\basic\space_fauna\garden_gnome.dm" #include "code\modules\mob\living\basic\space_fauna\ghost.dm" -#include "code\modules\mob\living\basic\space_fauna\headslug.dm" #include "code\modules\mob\living\basic\space_fauna\killer_tomato.dm" #include "code\modules\mob\living\basic\space_fauna\lightgeist.dm" #include "code\modules\mob\living\basic\space_fauna\morph.dm" #include "code\modules\mob\living\basic\space_fauna\mushroom.dm" #include "code\modules\mob\living\basic\space_fauna\robot_customer.dm" #include "code\modules\mob\living\basic\space_fauna\spaceman.dm" +#include "code\modules\mob\living\basic\space_fauna\supermatter_spider.dm" #include "code\modules\mob\living\basic\space_fauna\bear\_bear.dm" #include "code\modules\mob\living\basic\space_fauna\bear\bear_ai_behavior.dm" #include "code\modules\mob\living\basic\space_fauna\bear\bear_ai_subtree.dm" @@ -4462,6 +4577,8 @@ #include "code\modules\mob\living\basic\space_fauna\carp\carp_controllers.dm" #include "code\modules\mob\living\basic\space_fauna\carp\magicarp.dm" #include "code\modules\mob\living\basic\space_fauna\carp\megacarp.dm" +#include "code\modules\mob\living\basic\space_fauna\changeling\flesh_spider.dm" +#include "code\modules\mob\living\basic\space_fauna\changeling\headslug.dm" #include "code\modules\mob\living\basic\space_fauna\demon\demon.dm" #include "code\modules\mob\living\basic\space_fauna\demon\demon_items.dm" #include "code\modules\mob\living\basic\space_fauna\demon\demon_subtypes.dm" @@ -4485,6 +4602,12 @@ #include "code\modules\mob\living\basic\space_fauna\regal_rat\regal_rat.dm" #include "code\modules\mob\living\basic\space_fauna\regal_rat\regal_rat_actions.dm" #include "code\modules\mob\living\basic\space_fauna\regal_rat\regal_rat_ai.dm" +#include "code\modules\mob\living\basic\space_fauna\revenant\_revenant.dm" +#include "code\modules\mob\living\basic\space_fauna\revenant\revenant_abilities.dm" +#include "code\modules\mob\living\basic\space_fauna\revenant\revenant_effects.dm" +#include "code\modules\mob\living\basic\space_fauna\revenant\revenant_harvest.dm" +#include "code\modules\mob\living\basic\space_fauna\revenant\revenant_items.dm" +#include "code\modules\mob\living\basic\space_fauna\revenant\revenant_objectives.dm" #include "code\modules\mob\living\basic\space_fauna\snake\snake.dm" #include "code\modules\mob\living\basic\space_fauna\snake\snake_ai.dm" #include "code\modules\mob\living\basic\space_fauna\spider\spider.dm" @@ -4663,7 +4786,6 @@ #include "code\modules\mob\living\simple_animal\animal_defense.dm" #include "code\modules\mob\living\simple_animal\damage_procs.dm" #include "code\modules\mob\living\simple_animal\parrot.dm" -#include "code\modules\mob\living\simple_animal\revenant.dm" #include "code\modules\mob\living\simple_animal\shade.dm" #include "code\modules\mob\living\simple_animal\simple_animal.dm" #include "code\modules\mob\living\simple_animal\bot\bot.dm" @@ -4681,10 +4803,8 @@ #include "code\modules\mob\living\simple_animal\bot\SuperBeepsky.dm" #include "code\modules\mob\living\simple_animal\bot\vibebot.dm" #include "code\modules\mob\living\simple_animal\friendly\cat.dm" -#include "code\modules\mob\living\simple_animal\friendly\farm_animals.dm" #include "code\modules\mob\living\simple_animal\friendly\gondola.dm" #include "code\modules\mob\living\simple_animal\friendly\pet.dm" -#include "code\modules\mob\living\simple_animal\friendly\sloth.dm" #include "code\modules\mob\living\simple_animal\friendly\drone\_drone.dm" #include "code\modules\mob\living\simple_animal\friendly\drone\drone_say.dm" #include "code\modules\mob\living\simple_animal\friendly\drone\drone_tools.dm" @@ -4708,11 +4828,7 @@ #include "code\modules\mob\living\simple_animal\guardian\types\standard.dm" #include "code\modules\mob\living\simple_animal\guardian\types\support.dm" #include "code\modules\mob\living\simple_animal\hostile\alien.dm" -#include "code\modules\mob\living\simple_animal\hostile\blob.dm" -#include "code\modules\mob\living\simple_animal\hostile\blobbernaut.dm" -#include "code\modules\mob\living\simple_animal\hostile\blobspore.dm" #include "code\modules\mob\living\simple_animal\hostile\dark_wizard.dm" -#include "code\modules\mob\living\simple_animal\hostile\heretic_monsters.dm" #include "code\modules\mob\living\simple_animal\hostile\hostile.dm" #include "code\modules\mob\living\simple_animal\hostile\illusion.dm" #include "code\modules\mob\living\simple_animal\hostile\mimic.dm" @@ -4720,23 +4836,16 @@ #include "code\modules\mob\living\simple_animal\hostile\ooze.dm" #include "code\modules\mob\living\simple_animal\hostile\pirate.dm" #include "code\modules\mob\living\simple_animal\hostile\skeleton.dm" -#include "code\modules\mob\living\simple_animal\hostile\smspider.dm" #include "code\modules\mob\living\simple_animal\hostile\space_dragon.dm" #include "code\modules\mob\living\simple_animal\hostile\vatbeast.dm" -#include "code\modules\mob\living\simple_animal\hostile\venus_human_trap.dm" #include "code\modules\mob\living\simple_animal\hostile\wizard.dm" #include "code\modules\mob\living\simple_animal\hostile\zombie.dm" #include "code\modules\mob\living\simple_animal\hostile\constructs\artificer.dm" #include "code\modules\mob\living\simple_animal\hostile\constructs\constructs.dm" -#include "code\modules\mob\living\simple_animal\hostile\constructs\harvester.dm" #include "code\modules\mob\living\simple_animal\hostile\constructs\juggernaut.dm" #include "code\modules\mob\living\simple_animal\hostile\constructs\wraith.dm" -#include "code\modules\mob\living\simple_animal\hostile\gorilla\emotes.dm" -#include "code\modules\mob\living\simple_animal\hostile\gorilla\gorilla.dm" -#include "code\modules\mob\living\simple_animal\hostile\gorilla\visuals_icons.dm" #include "code\modules\mob\living\simple_animal\hostile\jungle\_jungle_mobs.dm" #include "code\modules\mob\living\simple_animal\hostile\jungle\leaper.dm" -#include "code\modules\mob\living\simple_animal\hostile\jungle\mook.dm" #include "code\modules\mob\living\simple_animal\hostile\megafauna\_megafauna.dm" #include "code\modules\mob\living\simple_animal\hostile\megafauna\blood_drunk_miner.dm" #include "code\modules\mob\living\simple_animal\hostile\megafauna\bubblegum.dm" @@ -4749,7 +4858,6 @@ #include "code\modules\mob\living\simple_animal\hostile\megafauna\wendigo.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\curse_blob.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\gutlunch.dm" -#include "code\modules\mob\living\simple_animal\hostile\mining_mobs\ice_demon.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\mining_mobs.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\polarbear.dm" #include "code\modules\mob\living\simple_animal\hostile\mining_mobs\wolf.dm" @@ -5086,6 +5194,7 @@ #include "code\modules\projectiles\guns\special\blastcannon.dm" #include "code\modules\projectiles\guns\special\chem_gun.dm" #include "code\modules\projectiles\guns\special\grenade_launcher.dm" +#include "code\modules\projectiles\guns\special\hand_of_midas.dm" #include "code\modules\projectiles\guns\special\meat_hook.dm" #include "code\modules\projectiles\guns\special\medbeam.dm" #include "code\modules\projectiles\guns\special\syringe_gun.dm" @@ -5227,7 +5336,6 @@ #include "code\modules\religion\sparring\sparring_datum.dm" #include "code\modules\requests\request.dm" #include "code\modules\requests\request_manager.dm" -#include "code\modules\research\bepis.dm" #include "code\modules\research\designs.dm" #include "code\modules\research\destructive_analyzer.dm" #include "code\modules\research\experimentor.dm" @@ -5843,6 +5951,7 @@ #include "modular_skyrat\master_files\code\datums\components\crafting.dm" #include "modular_skyrat\master_files\code\datums\components\damage_tracker.dm" #include "modular_skyrat\master_files\code\datums\components\fullauto.dm" +#include "modular_skyrat\master_files\code\datums\components\grillable.dm" #include "modular_skyrat\master_files\code\datums\components\leash.dm" #include "modular_skyrat\master_files\code\datums\components\shielded_suit.dm" #include "modular_skyrat\master_files\code\datums\components\tippable.dm" @@ -5899,6 +6008,7 @@ #include "modular_skyrat\master_files\code\game\objects\items\storage\boxes.dm" #include "modular_skyrat\master_files\code\game\objects\items\tools\weldingtool.dm" #include "modular_skyrat\master_files\code\game\objects\structures\mannequin.dm" +#include "modular_skyrat\master_files\code\game\objects\structures\mirror.dm" #include "modular_skyrat\master_files\code\game\objects\structures\railings.dm" #include "modular_skyrat\master_files\code\game\objects\structures\sauna_oven.dm" #include "modular_skyrat\master_files\code\game\objects\structures\tables_racks.dm" @@ -5920,6 +6030,7 @@ #include "modular_skyrat\master_files\code\modules\antagonists\traitor\objectives\kill_pet.dm" #include "modular_skyrat\master_files\code\modules\antagonists\traitor\objectives\smuggling.dm" #include "modular_skyrat\master_files\code\modules\asset_cache\assets\plumbing.dm" +#include "modular_skyrat\master_files\code\modules\bitrunning\orders\tech.dm" #include "modular_skyrat\master_files\code\modules\buildmode\bm_mode.dm" #include "modular_skyrat\master_files\code\modules\buildmode\submodes\offercontrol.dm" #include "modular_skyrat\master_files\code\modules\cargo\goodies.dm" @@ -6069,12 +6180,14 @@ #include "modular_skyrat\master_files\code\modules\mob\living\living.dm" #include "modular_skyrat\master_files\code\modules\mob\living\living_defines.dm" #include "modular_skyrat\master_files\code\modules\mob\living\living_movement.dm" +#include "modular_skyrat\master_files\code\modules\mob\living\basic\icemoon\ice_demon.dm" #include "modular_skyrat\master_files\code\modules\mob\living\carbon\death.dm" #include "modular_skyrat\master_files\code\modules\mob\living\carbon\human.dm" #include "modular_skyrat\master_files\code\modules\mob\living\carbon\human_helpers.dm" #include "modular_skyrat\master_files\code\modules\mob\living\carbon\human\death.dm" #include "modular_skyrat\master_files\code\modules\mob\living\carbon\human\species.dm" #include "modular_skyrat\master_files\code\modules\mob\living\carbon\human\species_type\lizardpeople.dm" +#include "modular_skyrat\master_files\code\modules\mob\living\carbon\human\species_type\podpeople.dm" #include "modular_skyrat\master_files\code\modules\mob\living\carbon\human\species_type\snail.dm" #include "modular_skyrat\master_files\code\modules\mob\living\human\monkey.dm" #include "modular_skyrat\master_files\code\modules\mob\living\human\species.dm" @@ -6269,7 +6382,6 @@ #include "modular_skyrat\modules\assault_operatives\code\armaments\armament_modules.dm" #include "modular_skyrat\modules\assault_operatives\code\armaments\armament_utility.dm" #include "modular_skyrat\modules\assault_operatives\code\armaments\assaultops_armament_station.dm" -#include "modular_skyrat\modules\assault_operatives\code\equipment_items\guns.dm" #include "modular_skyrat\modules\assault_operatives\code\equipment_items\misc_items.dm" #include "modular_skyrat\modules\assault_operatives\code\equipment_items\stealth_mod.dm" #include "modular_skyrat\modules\automapper\code\area_spawn_entries.dm" @@ -6351,7 +6463,6 @@ #include "modular_skyrat\modules\blueshield\code\encryptionkey.dm" #include "modular_skyrat\modules\blueshield\code\landmarks.dm" #include "modular_skyrat\modules\blueshield\code\medkit.dm" -#include "modular_skyrat\modules\blueshield\code\weapons.dm" #include "modular_skyrat\modules\blueshield\code\devices\crew.dm" #include "modular_skyrat\modules\blueshield\code\devices\sensor_device.dm" #include "modular_skyrat\modules\bluespace_miner\code\bluespace_miner.dm" @@ -6386,7 +6497,6 @@ #include "modular_skyrat\modules\bsa_overhaul\code\bsa_computer.dm" #include "modular_skyrat\modules\bsa_overhaul\code\station_goal.dm" #include "modular_skyrat\modules\bsrpd\code\bsrpd.dm" -#include "modular_skyrat\modules\bulletrebalance\code\sniper.dm" #include "modular_skyrat\modules\cargo\code\goodies.dm" #include "modular_skyrat\modules\cargo\code\packs.dm" #include "modular_skyrat\modules\cargo\code\items\AFAD.dm" @@ -6470,7 +6580,6 @@ #include "modular_skyrat\modules\company_imports\code\armament_component.dm" #include "modular_skyrat\modules\company_imports\code\company_datums.dm" #include "modular_skyrat\modules\company_imports\code\armament_datums\_armament_basetype.dm" -#include "modular_skyrat\modules\company_imports\code\armament_datums\bolt_nanotrasen_firearms.dm" #include "modular_skyrat\modules\company_imports\code\armament_datums\deforest_medical.dm" #include "modular_skyrat\modules\company_imports\code\armament_datums\jarnsmiour.dm" #include "modular_skyrat\modules\company_imports\code\armament_datums\kahraman_industries.dm" @@ -6479,6 +6588,7 @@ #include "modular_skyrat\modules\company_imports\code\armament_datums\nakamura_tools.dm" #include "modular_skyrat\modules\company_imports\code\armament_datums\nri_military_surplus.dm" #include "modular_skyrat\modules\company_imports\code\armament_datums\put_a_donk_on_it.dm" +#include "modular_skyrat\modules\company_imports\code\armament_datums\sol_defense.dm" #include "modular_skyrat\modules\company_imports\code\armament_datums\vitezstvi_ammo.dm" #include "modular_skyrat\modules\company_imports\code\datums\cargo_order.dm" #include "modular_skyrat\modules\company_imports\code\datums\cargo_pack.dm" @@ -6596,6 +6706,7 @@ #include "modular_skyrat\modules\customization\modules\clothing\masks\breath.dm" #include "modular_skyrat\modules\customization\modules\clothing\masks\gas_filter.dm" #include "modular_skyrat\modules\customization\modules\clothing\masks\gasmask.dm" +#include "modular_skyrat\modules\customization\modules\clothing\masks\paper.dm" #include "modular_skyrat\modules\customization\modules\clothing\neck\_neck.dm" #include "modular_skyrat\modules\customization\modules\clothing\neck\cloaks.dm" #include "modular_skyrat\modules\customization\modules\clothing\neck\collars.dm" @@ -7035,11 +7146,24 @@ #include "modular_skyrat\modules\medical\code\carbon_update_icons.dm" #include "modular_skyrat\modules\medical\code\grasp.dm" #include "modular_skyrat\modules\medical\code\health_analyzer.dm" +#include "modular_skyrat\modules\medical\code\medkit.dm" #include "modular_skyrat\modules\medical\code\smartdarts.dm" +#include "modular_skyrat\modules\medical\code\sprays.dm" +#include "modular_skyrat\modules\medical\code\cargo\packs.dm" #include "modular_skyrat\modules\medical\code\wounds\_wounds.dm" #include "modular_skyrat\modules\medical\code\wounds\bleed.dm" #include "modular_skyrat\modules\medical\code\wounds\medical.dm" #include "modular_skyrat\modules\medical\code\wounds\muscle.dm" +#include "modular_skyrat\modules\medical\code\wounds\wound_effects.dm" +#include "modular_skyrat\modules\medical\code\wounds\synth\robotic_burns.dm" +#include "modular_skyrat\modules\medical\code\wounds\synth\robotic_muscle.dm" +#include "modular_skyrat\modules\medical\code\wounds\synth\robotic_pierce.dm" +#include "modular_skyrat\modules\medical\code\wounds\synth\robotic_slash.dm" +#include "modular_skyrat\modules\medical\code\wounds\synth\blunt\robotic_blunt.dm" +#include "modular_skyrat\modules\medical\code\wounds\synth\blunt\robotic_blunt_T1.dm" +#include "modular_skyrat\modules\medical\code\wounds\synth\blunt\robotic_blunt_T2.dm" +#include "modular_skyrat\modules\medical\code\wounds\synth\blunt\robotic_blunt_T3.dm" +#include "modular_skyrat\modules\medical\code\wounds\synth\blunt\secures_internals.dm" #include "modular_skyrat\modules\medical_designs\medical_designs.dm" #include "modular_skyrat\modules\medievalcrate_skyrat\code\vintageitems.dm" #include "modular_skyrat\modules\mentor\code\_globalvars.dm" @@ -7101,11 +7225,15 @@ #include "modular_skyrat\modules\modular_implants\code\nifsofts\dorms.dm" #include "modular_skyrat\modules\modular_implants\code\nifsofts\hivemind.dm" #include "modular_skyrat\modules\modular_implants\code\nifsofts\huds.dm" +#include "modular_skyrat\modules\modular_implants\code\nifsofts\hypnosis.dm" #include "modular_skyrat\modules\modular_implants\code\nifsofts\money_sense.dm" #include "modular_skyrat\modules\modular_implants\code\nifsofts\prop_summoner.dm" +#include "modular_skyrat\modules\modular_implants\code\nifsofts\scryer.dm" #include "modular_skyrat\modules\modular_implants\code\nifsofts\shapeshifter.dm" #include "modular_skyrat\modules\modular_implants\code\nifsofts\soul_poem.dm" #include "modular_skyrat\modules\modular_implants\code\nifsofts\soulcatcher.dm" +#include "modular_skyrat\modules\modular_implants\code\nifsofts\base_types\action_granter.dm" +#include "modular_skyrat\modules\modular_implants\code\soulcatcher\attachable_soulcatcher.dm" #include "modular_skyrat\modules\modular_implants\code\soulcatcher\handheld_soulcatcher.dm" #include "modular_skyrat\modules\modular_implants\code\soulcatcher\soulcatcher_body_component.dm" #include "modular_skyrat\modules\modular_implants\code\soulcatcher\soulcatcher_component.dm" @@ -7238,14 +7366,27 @@ #include "modular_skyrat\modules\modular_vending\code\vending.dm" #include "modular_skyrat\modules\modular_vending\code\wardrobes.dm" #include "modular_skyrat\modules\modular_weapons\code\autolathe_designs.dm" -#include "modular_skyrat\modules\modular_weapons\code\automatic.dm" #include "modular_skyrat\modules\modular_weapons\code\conversion_kits.dm" -#include "modular_skyrat\modules\modular_weapons\code\energy.dm" +#include "modular_skyrat\modules\modular_weapons\code\gunsets.dm" #include "modular_skyrat\modules\modular_weapons\code\melee.dm" #include "modular_skyrat\modules\modular_weapons\code\modular_projectiles.dm" -#include "modular_skyrat\modules\modular_weapons\code\pistol.dm" -#include "modular_skyrat\modules\modular_weapons\code\revolver.dm" -#include "modular_skyrat\modules\modular_weapons\code\rifle.dm" +#include "modular_skyrat\modules\modular_weapons\code\pepperball_gun.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\carwo_defense_systems\advert.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\carwo_defense_systems\grenade_launcher.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\carwo_defense_systems\gunsets.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\carwo_defense_systems\magazines.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\carwo_defense_systems\rifle.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\carwo_defense_systems\shotgun.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\carwo_defense_systems\submachinegun.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\carwo_defense_systems\ammo\grenade.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\carwo_defense_systems\ammo\pistol.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\carwo_defense_systems\ammo\rifle.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\trappiste_fabriek\advert.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\trappiste_fabriek\ammo.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\trappiste_fabriek\gunsets.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\trappiste_fabriek\magazines.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\trappiste_fabriek\pistol.dm" +#include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\trappiste_fabriek\revolver.dm" #include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\xhihao_light_arms\ammo.dm" #include "modular_skyrat\modules\modular_weapons\code\company_and_or_faction_based\xhihao_light_arms\guns.dm" #include "modular_skyrat\modules\mold\code\_mold_defines.dm" @@ -7319,7 +7460,6 @@ #include "modular_skyrat\modules\nanotrasen_naval_command\code\id_trims.dm" #include "modular_skyrat\modules\nanotrasen_naval_command\code\outfits.dm" #include "modular_skyrat\modules\nanotrasen_rep\code\clothing.dm" -#include "modular_skyrat\modules\nanotrasen_rep\code\m45a5.dm" #include "modular_skyrat\modules\nanotrasen_rep\code\nanotrasen_consultant.dm" #include "modular_skyrat\modules\new_cells\code\power_cell.dm" #include "modular_skyrat\modules\novaya_ert\code\advanced_choice_beacon.dm" @@ -7377,6 +7517,7 @@ #include "modular_skyrat\modules\pixel_shift\code\pixel_shift_component.dm" #include "modular_skyrat\modules\pixel_shift\code\pixel_shift_keybind.dm" #include "modular_skyrat\modules\pixel_shift\code\pixel_shift_mob.dm" +#include "modular_skyrat\modules\player_ranks\code\world_topic.dm" #include "modular_skyrat\modules\player_ranks\code\player_rank_controller\_player_rank_controller.dm" #include "modular_skyrat\modules\player_ranks\code\player_rank_controller\donator_controller.dm" #include "modular_skyrat\modules\player_ranks\code\player_rank_controller\mentor_controller.dm" @@ -7444,6 +7585,8 @@ #include "modular_skyrat\modules\records_on_examine\code\record_variables.dm" #include "modular_skyrat\modules\records_on_examine\code\records_procs.dm" #include "modular_skyrat\modules\records_on_examine\code\view_exploitables.dm" +#include "modular_skyrat\modules\resleeving\code\rsd_interface.dm" +#include "modular_skyrat\modules\resleeving\code\research\resleeving_research.dm" #include "modular_skyrat\modules\robohand\code\bodypart_autosurgeon.dm" #include "modular_skyrat\modules\robohand\code\robohand.dm" #include "modular_skyrat\modules\robohand\code\silverhand_bundle.dm" @@ -7460,6 +7603,10 @@ #include "modular_skyrat\modules\salon\code\scissors.dm" #include "modular_skyrat\modules\salon\code\sprays.dm" #include "modular_skyrat\modules\salon\code\straight_razor.dm" +#include "modular_skyrat\modules\science_tools\medical_tool_designs.dm" +#include "modular_skyrat\modules\science_tools\research.dm" +#include "modular_skyrat\modules\science_tools\tool_designs.dm" +#include "modular_skyrat\modules\science_tools\tools.dm" #include "modular_skyrat\modules\sec_haul\code\corrections_officer\corrections_officer.dm" #include "modular_skyrat\modules\sec_haul\code\corrections_officer\corrections_officer_equipment.dm" #include "modular_skyrat\modules\sec_haul\code\corrections_officer\landmarks.dm" @@ -7467,10 +7614,6 @@ #include "modular_skyrat\modules\sec_haul\code\guns\armory_spawns.dm" #include "modular_skyrat\modules\sec_haul\code\guns\bullets.dm" #include "modular_skyrat\modules\sec_haul\code\guns\cargo_stuff.dm" -#include "modular_skyrat\modules\sec_haul\code\guns\cmg.dm" -#include "modular_skyrat\modules\sec_haul\code\guns\guns.dm" -#include "modular_skyrat\modules\sec_haul\code\guns\gunsets.dm" -#include "modular_skyrat\modules\sec_haul\code\guns\pepperball_gun.dm" #include "modular_skyrat\modules\sec_haul\code\misc\ai_module.dm" #include "modular_skyrat\modules\sec_haul\code\misc\bullet_drive.dm" #include "modular_skyrat\modules\sec_haul\code\misc\decals.dm" @@ -7523,6 +7666,8 @@ #include "modular_skyrat\modules\subsystems\code\ticket_ping\ticket_ss.dm" #include "modular_skyrat\modules\Syndie_edits\code\area.dm" #include "modular_skyrat\modules\Syndie_edits\code\syndie_edits.dm" +#include "modular_skyrat\modules\synths\code\defib.dm" +#include "modular_skyrat\modules\synths\code\research_nodes.dm" #include "modular_skyrat\modules\synths\code\bodyparts\brain.dm" #include "modular_skyrat\modules\synths\code\bodyparts\ears.dm" #include "modular_skyrat\modules\synths\code\bodyparts\eyes.dm" diff --git a/tgui/packages/tgui-panel/settings/middleware.js b/tgui/packages/tgui-panel/settings/middleware.js index 705d7a89f3b4a3..cef082213db6fd 100644 --- a/tgui/packages/tgui-panel/settings/middleware.js +++ b/tgui/packages/tgui-panel/settings/middleware.js @@ -10,16 +10,39 @@ import { loadSettings, updateSettings, addHighlightSetting, removeHighlightSetti import { selectSettings } from './selectors'; import { FONTS_DISABLED } from './constants'; +let overrideRule = null; +let overrideFontFamily = null; +let overrideFontSize = null; + +const updateGlobalOverrideRule = () => { + let fontFamily = ''; + + if (overrideFontFamily !== null) { + fontFamily = `font-family: ${overrideFontFamily} !important;`; + } + + const constructedRule = `body * :not(.Icon) { + ${fontFamily} + }`; + + if (overrideRule === null) { + overrideRule = document.createElement('style'); + document.querySelector('head').append(overrideRule); + } + + // no other way to force a CSS refresh other than to update its innerText + overrideRule.innerText = constructedRule; + + document.body.style.setProperty('font-size', overrideFontSize); +}; + const setGlobalFontSize = (fontSize) => { - document.documentElement.style.setProperty('font-size', fontSize + 'px'); - document.body.style.setProperty('font-size', fontSize + 'px'); + overrideFontSize = `${fontSize}px`; }; const setGlobalFontFamily = (fontFamily) => { if (fontFamily === FONTS_DISABLED) fontFamily = null; - - document.documentElement.style.setProperty('font-family', fontFamily); - document.body.style.setProperty('font-family', fontFamily); + overrideFontFamily = fontFamily; }; export const settingsMiddleware = (store) => { @@ -50,6 +73,7 @@ export const settingsMiddleware = (store) => { // Update global UI font size setGlobalFontSize(settings.fontSize); setGlobalFontFamily(settings.fontFamily); + updateGlobalOverrideRule(); // Save settings to the web storage storage.set('panel-settings', settings); return; diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss index 148ccc86f72f7f..43e2fa93343695 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-dark.scss @@ -535,6 +535,10 @@ em { } .blob { + color: #ee4000; +} + +.blobannounce { color: #556b2f; font-weight: bold; font-size: 185%; diff --git a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss index ffbfa3f02ed95b..e685cded7740a6 100644 --- a/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss +++ b/tgui/packages/tgui-panel/styles/tgchat/chat-light.scss @@ -594,6 +594,10 @@ h2.alert { } .blob { + color: #ee4000; +} + +.blobannounce { color: #323f1c; font-weight: bold; font-size: 185%; diff --git a/tgui/packages/tgui/constants.ts b/tgui/packages/tgui/constants.ts index 8bf4b83823fc37..c038cd6740a9a4 100644 --- a/tgui/packages/tgui/constants.ts +++ b/tgui/packages/tgui/constants.ts @@ -160,7 +160,7 @@ const GASES = [ path: '/datum/gas/nitrogen', name: 'Nitrogen', label: 'Nâ‚‚', - color: 'red', + color: 'yellow', }, { id: 'co2', diff --git a/tgui/packages/tgui/interfaces/AdminFax.js b/tgui/packages/tgui/interfaces/AdminFax.js index e91130baf394f8..46e12615922144 100644 --- a/tgui/packages/tgui/interfaces/AdminFax.js +++ b/tgui/packages/tgui/interfaces/AdminFax.js @@ -91,7 +91,7 @@ export const FaxMainPanel = (props, context) => { icon="n" mr="7px" width="49%" - onClick={() => setPaperName('Nanotrasen Offical Report')}> + onClick={() => setPaperName('Nanotrasen Official Report')}> Nanotrasen + + + + + + + + ))} + + + ); +}; + +const MarketCrashModal = (props, context) => { + const { act, data } = useBackend(context); + return ( + + ATTENTION! THE MARKET HAS CRASHED +

+ ALL MATERIALS ARE NOW WORTHLESS +

+ TRADING CIRCUIT BREAKER HAS BEEN ENGAGED FOR ALL TRADERS +

+ DO NOT PANIC, WE ARE FIXING THIS +
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/MaterialStand.tsx b/tgui/packages/tgui/interfaces/MaterialStand.tsx new file mode 100644 index 00000000000000..b6e87889cd20b4 --- /dev/null +++ b/tgui/packages/tgui/interfaces/MaterialStand.tsx @@ -0,0 +1,120 @@ +import { createSearch, toTitleCase } from 'common/string'; +import { useBackend, useLocalState } from '../backend'; +import { Box, Button, Input, Stack, Flex, Section } from '../components'; +import { Window } from '../layouts'; + +type Ores = { + id: string; + name: string; + amount: number; +}; + +type Ore_images = { + name: string; + icon: string; +}; + +type Data = { + ores: Ores[]; + ore_images: Ore_images[]; +}; + +export const MaterialStand = (props, context) => { + const { act, data } = useBackend(context); + const { ores = [] } = data; + const [searchItem, setSearchItem] = useLocalState(context, 'searchItem', ''); + const search = createSearch(searchItem, (ore: Ores) => ore.name); + const ores_filtered = + searchItem.length > 0 ? ores.filter((ore) => search(ore)) : ores; + return ( + + + + +
+ { + setSearchItem(value); + }} + fluid + /> +
+
+ +
+ + {ores_filtered.map((ore) => ( + + + + + + + + + Amount: {ore.amount} + +
+
+
+
+
+ ); +}; + +const RetrieveIcon = (props, context) => { + const { data } = useBackend(context); + const { ore_images = [] } = data; + const { ore } = props; + + let icon_display = ore_images.find((icon) => icon.name === ore.name); + + if (!icon_display) { + return null; + } + + return ( + + ); +}; + +const Orename = (props) => { + const { ore_name } = props; + const return_name = ore_name.split(' '); + if (return_name.length === 0) { + return null; + } + return return_name[0]; +}; diff --git a/tgui/packages/tgui/interfaces/NetpodOutfits.tsx b/tgui/packages/tgui/interfaces/NetpodOutfits.tsx new file mode 100644 index 00000000000000..afc6a2bd6cada0 --- /dev/null +++ b/tgui/packages/tgui/interfaces/NetpodOutfits.tsx @@ -0,0 +1,109 @@ +import { Button, Divider, Input, NoticeBox, Section, Stack, Tabs } from '../components'; +import { useBackend, useLocalState } from '../backend'; + +import { Window } from '../layouts'; +import { createSearch } from '../../common/string'; + +type Data = { + netsuit: string; + collections: Collection[]; + types: string[]; +}; + +type Collection = { + name: string; + outfits: Outfit[]; +}; + +type Outfit = { + path: string; + name: string; + type: string; +}; + +export const NetpodOutfits = (props, context) => { + const { act, data } = useBackend(context); + const { netsuit, collections = [] } = data; + const [selectedType, setSelectedType] = useLocalState( + context, + 'selectedType', + collections[0] + ); + const [search, setSearch] = useLocalState( + context, + 'outfitSearch', + '' + ); + + const searchFn = createSearch(search, (outfit: Outfit) => outfit.name); + + const filtered = selectedType?.outfits + ?.filter(searchFn) + .sort((a, b) => (a.name > b.name ? 1 : 0)); + + const selected = + selectedType.outfits?.find((outfit) => outfit.path === netsuit)?.name ?? + 'None'; + + return ( + + + + +
setSearch(value)} + placeholder="Search" + value={search} + /> + }> + + + + {collections.map((collection, index) => ( + <> + setSelectedType(collection)} + selected={selectedType === collection}> + {collection.name} + + {index > 0 && } + + ))} + + + + +
+ {filtered.map(({ path, name }, index) => ( + + + + ))} +
+
+
+
+
+ + + {selected} + + +
+
+
+ ); +}; diff --git a/tgui/packages/tgui/interfaces/NifPanel.js b/tgui/packages/tgui/interfaces/NifPanel.js index 401f8b495d3ef8..8e2d3160794b6d 100644 --- a/tgui/packages/tgui/interfaces/NifPanel.js +++ b/tgui/packages/tgui/interfaces/NifPanel.js @@ -110,6 +110,29 @@ export const NifPanel = (props, context) => {
{nifsoft.desc}
+ {nifsoft.able_to_keep ? ( + +
+ + + + {points} + + + } + fill + scrollable + title="Virtual Domains"> + {sorted.map((domain) => ( + + ))} + + + + + + +
+ + + + {selected?.name ?? 'Nothing loaded'} + + + + act('stop_domain')} + tooltip="Begins shutdown. Will notify anyone connected." + /> + + +
+
+ + ); +}; + +const DomainEntry = (props: DomainEntryProps, context) => { + const { + domain: { cost, desc, difficulty, id, name, reward }, + } = props; + const { act, data } = useBackend(context); + if (!isConnected(data)) { + return null; + } + + const { generated_domain, ready, occupants, randomized, points } = data; + + const current = generated_domain === id; + const occupied = occupants > 0; + let buttonIcon, buttonName; + if (randomized) { + buttonIcon = ''; + buttonName = '???'; + } else if (current) { + buttonIcon = 'download'; + buttonName = 'Deployed'; + } else { + buttonIcon = 'coins'; + buttonName = 'Deploy'; + } + + return ( + act('set_domain', { id })} + tooltip={!!generated_domain && 'Stop current domain first.'}> + {buttonName} + + } + color={getColor(difficulty)} + title={ + <> + {name} + {difficulty === Difficulty.High && } + + }> + + + {desc} + + + + + + + + + + + + + +
+
+
+
+ ); +}; + +const AvatarDisplay = (props, context) => { + const { act, data } = useBackend(context); + if (!isConnected(data)) { + return null; + } + + const { avatars = [], generated_domain, retries_left } = data; + + return ( +
+ {!!generated_domain && ( + + + + + + )} + + + + + }> + + {avatars.map(({ health, name, pilot, brute, burn, tox, oxy }) => ( + + + {pilot} as{' '} + "{name}" + + + + {brute === 0 && burn === 0 && tox === 0 && oxy === 0 && ( + + + + )} + + 50 ? 'bad' : 'gray'} name="tint" /> + + + 50 ? 'average' : 'gray'} name="fire" /> + + + 50 ? 'green' : 'gray'} + name="skull-crossbones" + /> + + + 50 ? 'blue' : 'gray'} name="lungs" /> + + + + + + + + ))} +
+
+ ); +}; + +const DisplayDetails = (props: DisplayDetailsProps, context) => { + const { amount = 0, color, icon = 'star' } = props; + + if (amount === 0) { + return No bandwidth; + } + + if (typeof amount === 'string') { + return {String(amount)}; // don't ask + } + + if (amount > 4) { + return ( + + + {amount} + + + + + + ); + } + + return ( + + + {Array.from({ length: amount }, (_, index) => ( + + + + ))} + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/SecurityRecords/constants.ts b/tgui/packages/tgui/interfaces/SecurityRecords/constants.ts index 1537b7a3e15be1..6da85722b94225 100644 --- a/tgui/packages/tgui/interfaces/SecurityRecords/constants.ts +++ b/tgui/packages/tgui/interfaces/SecurityRecords/constants.ts @@ -1,8 +1,8 @@ export const CRIMESTATUS2COLOR = { Arrest: 'bad', - Discharged: 'good', + Discharged: 'blue', Incarcerated: 'average', - Parole: 'blue', + Parole: 'good', Suspected: 'teal', } as const; diff --git a/tgui/packages/tgui/interfaces/Soulcatcher.js b/tgui/packages/tgui/interfaces/Soulcatcher.js index 226dbd93192fab..0c8c4f6e66ba34 100644 --- a/tgui/packages/tgui/interfaces/Soulcatcher.js +++ b/tgui/packages/tgui/interfaces/Soulcatcher.js @@ -1,13 +1,22 @@ import { useBackend } from '../backend'; import { Window } from '../layouts'; -import { BlockQuote, Button, Divider, Section, Box, Flex, Collapsible, LabeledList } from '../components'; +import { BlockQuote, Button, Divider, Section, Box, Flex, Collapsible, LabeledList, ProgressBar } from '../components'; export const Soulcatcher = (props, context) => { const { act, data } = useBackend(context); - const { require_approval, current_rooms = [], ghost_joinable } = data; + const { + require_approval, + current_rooms = [], + ghost_joinable, + current_soul_count, + max_souls, + removable, + communicate_as_parent, + theme, + } = data; return ( - + {current_rooms.map((room) => (
{ {soul.able_to_emote ? 'Enabled' : 'Disabled'} + {communicate_as_parent ? ( + <> + + + + + + + + ) : ( + <> + )}
))} + {max_souls ? ( +
+ + Remaining soul capacity: {max_souls - current_soul_count} + +
+ ) : ( + <> + )} + {removable ? ( + + ) : ( + <> + )}
); diff --git a/tgui/packages/tgui/interfaces/SoulcatcherUser.js b/tgui/packages/tgui/interfaces/SoulcatcherUser.js index f768287bb334e9..cabe26aabc3562 100644 --- a/tgui/packages/tgui/interfaces/SoulcatcherUser.js +++ b/tgui/packages/tgui/interfaces/SoulcatcherUser.js @@ -4,7 +4,7 @@ import { BlockQuote, Button, Divider, Box, Flex, Collapsible, LabeledList, Secti export const SoulcatcherUser = (props, context) => { const { act, data } = useBackend(context); - const { current_room, user_data, souls = [] } = data; + const { current_room, user_data, communicate_as_parent, souls = [] } = data; return ( @@ -41,6 +41,18 @@ export const SoulcatcherUser = (props, context) => { ) : ( <> )} + {communicate_as_parent ? ( +