diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 403526d30b..a553cef999 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -210,6 +210,8 @@ This prevents nesting levels from getting deeper then they need to be. * Do not divide when you can easily convert it to a multiplication. (ie `4/2` should be done as `4*0.5`) +* Do not use the shorthand sql insert format (where no column names are specified) because it unnecessarily breaks all queries on minor column changes and prevents using these tables for tracking outside related info such as in a connected site/forum. + #### Enforced not enforced The following different coding styles are not only not enforced, but it is generally frowned upon to change them over from one to the other for little reason: diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt index c34c6b694b..d0546da131 100644 --- a/SQL/database_changelog.txt +++ b/SQL/database_changelog.txt @@ -1,3 +1,13 @@ +21 April 2017, by Jordie0608 + +Modified table 'player', adding the column 'accountjoindate', removing the column 'id' and making the column 'ckey' the primary key. + +ALTER TABLE `feedback`.`player` DROP COLUMN `id`, ADD COLUMN `accountjoindate` DATE NULL AFTER `lastadminrank`, DROP PRIMARY KEY, ADD PRIMARY KEY (`ckey`), DROP INDEX `ckey`; + +Remember to add a prefix to the table name if you use them. + +---------------------------------------------------- + 10 March 2017, by Jordie0608 Modified table 'death', adding the columns 'toxloss', 'cloneloss', and 'staminaloss' and table 'legacy_population', adding the columns 'server_ip' and 'server_port'. diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index 77e9b9429e..0d0817bf1f 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -261,15 +261,14 @@ DROP TABLE IF EXISTS `player`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `player` ( - `id` int(11) NOT NULL AUTO_INCREMENT, `ckey` varchar(32) NOT NULL, `firstseen` datetime NOT NULL, `lastseen` datetime NOT NULL, `ip` int(10) unsigned NOT NULL, `computerid` varchar(32) NOT NULL, `lastadminrank` varchar(32) NOT NULL DEFAULT 'Player', - PRIMARY KEY (`id`), - UNIQUE KEY `ckey` (`ckey`), + `accountjoindate` DATE DEFAULT NULL, + PRIMARY KEY (`ckey`), KEY `idx_player_cid_ckey` (`computerid`,`ckey`), KEY `idx_player_ip_ckey` (`ip`,`ckey`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index be27384ea5..4d74b9deaa 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -261,15 +261,14 @@ DROP TABLE IF EXISTS `SS13_player`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `SS13_player` ( - `id` int(11) NOT NULL AUTO_INCREMENT, `ckey` varchar(32) NOT NULL, `firstseen` datetime NOT NULL, `lastseen` datetime NOT NULL, `ip` int(10) unsigned NOT NULL, `computerid` varchar(32) NOT NULL, `lastadminrank` varchar(32) NOT NULL DEFAULT 'Player', - PRIMARY KEY (`id`), - UNIQUE KEY `ckey` (`ckey`), + `accountjoindate` DATE DEFAULT NULL, + PRIMARY KEY (`ckey`), KEY `idx_player_cid_ckey` (`computerid`,`ckey`), KEY `idx_player_ip_ckey` (`ip`,`ckey`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; diff --git a/Test.txt b/Test.txt deleted file mode 100644 index 68db24f630..0000000000 --- a/Test.txt +++ /dev/null @@ -1 +0,0 @@ -~~ \ No newline at end of file diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm index 167aa9ef1b..1c47260f2c 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm @@ -148,10 +148,8 @@ /area/ruin/powered/golem_ship) "u" = ( /obj/structure/table/wood, -/obj/item/weapon/bedsheet/rd{ - desc = "Majestic."; +/obj/item/weapon/bedsheet/rd/royal_cape{ layer = 3; - name = "Royal Cape of the Liberator"; pixel_x = 5; pixel_y = 9 }, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm index 711ee674ee..930fea83aa 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm @@ -84,6 +84,7 @@ /area/ruin/powered) "p" = ( /obj/structure/rack, +/obj/item/weapon/storage/bag/plants/portaseeder, /obj/item/weapon/storage/bag/ore, /obj/item/weapon/storage/firstaid/regular, /turf/open/floor/plating/asteroid/basalt, diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm index 65d7aac80f..64c1a7cb26 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm @@ -9,19 +9,89 @@ /turf/closed/wall/r_wall, /area/ruin/powered) "d" = ( -/obj/structure/shuttle/engine/propulsion{ - icon_state = "propulsion"; - dir = 8 +/obj/structure/table/wood, +/obj/item/weapon/lighter, +/obj/item/weapon/lighter, +/obj/item/weapon/storage/fancy/rollingpapers, +/obj/item/weapon/storage/fancy/rollingpapers, +/obj/item/weapon/storage/fancy/rollingpapers, +/obj/item/weapon/storage/fancy/rollingpapers, +/turf/open/floor/plasteel/freezer{ + baseturf = /turf/open/floor/plating/lava/smooth }, -/turf/closed/mineral/volcanic/lava_land_surface, -/area/lavaland/surface/outdoors) +/area/ruin/powered) "e" = ( -/obj/machinery/smartfridge, +/obj/structure/table/wood, +/obj/item/weapon/storage/box/disks_plantgene, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) "f" = ( +/obj/machinery/plantgenes/seedvault, +/turf/open/floor/plasteel/freezer{ + baseturf = /turf/open/floor/plating/lava/smooth + }, +/area/ruin/powered) +"g" = ( +/obj/structure/table/wood, +/turf/open/floor/plasteel/freezer{ + baseturf = /turf/open/floor/plating/lava/smooth + }, +/area/ruin/powered) +"h" = ( +/turf/open/floor/plasteel/freezer{ + baseturf = /turf/open/floor/plating/lava/smooth + }, +/area/ruin/powered) +"i" = ( +/obj/structure/closet/crate/hydroponics, +/obj/structure/beebox, +/obj/item/weapon/melee/flyswatter, +/obj/item/honey_frame, +/obj/item/honey_frame, +/obj/item/honey_frame, +/obj/item/queen_bee/bought, +/obj/item/clothing/head/beekeeper_head, +/obj/item/clothing/suit/beekeeper_suit, +/turf/open/floor/plasteel/freezer{ + baseturf = /turf/open/floor/plating/lava/smooth + }, +/area/ruin/powered) +"j" = ( +/obj/structure/shuttle/engine/propulsion{ + icon_state = "propulsion"; + dir = 8 + }, +/turf/open/floor/plating/asteroid/basalt/lava_land_surface, +/area/lavaland/surface/outdoors) +"k" = ( +/obj/structure/closet/crate, +/obj/effect/spawner/lootdrop/seed_vault, +/turf/open/floor/plasteel/freezer{ + baseturf = /turf/open/floor/plating/lava/smooth + }, +/area/ruin/powered) +"l" = ( +/obj/machinery/door/airlock, +/turf/open/floor/plasteel/freezer{ + baseturf = /turf/open/floor/plating/lava/smooth + }, +/area/ruin/powered) +"m" = ( +/obj/structure/shuttle/engine/propulsion{ + icon_state = "propulsion"; + dir = 8 + }, +/turf/open/space/basic, +/area/lavaland/surface/outdoors) +"n" = ( +/obj/machinery/smartfridge, +/turf/open/floor/plasteel/freezer{ + baseturf = /turf/open/floor/plating/lava/smooth + }, +/area/ruin/powered) +"o" = ( /obj/structure/closet/crate/hydroponics, /obj/item/weapon/cultivator, /obj/item/weapon/cultivator, @@ -39,34 +109,22 @@ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"g" = ( +"p" = ( /obj/machinery/hydroponics/constructable, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"h" = ( -/obj/structure/closet/crate, -/obj/effect/spawner/lootdrop/seed_vault, -/turf/open/floor/plasteel/freezer{ - baseturf = /turf/open/floor/plating/lava/smooth - }, -/area/ruin/powered) -"i" = ( -/obj/machinery/plantgenes/seedvault, -/turf/open/floor/plasteel/freezer{ - baseturf = /turf/open/floor/plating/lava/smooth - }, -/area/ruin/powered) -"j" = ( +"q" = ( /obj/item/weapon/hatchet, /obj/item/weapon/storage/bag/plants, /obj/item/weapon/reagent_containers/glass/bucket, +/obj/structure/table/wood, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"k" = ( +"r" = ( /obj/structure/table/wood, /obj/item/weapon/storage/bag/plants, /obj/item/weapon/storage/bag/plants, @@ -76,7 +134,7 @@ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"l" = ( +"s" = ( /obj/structure/table/wood, /obj/item/weapon/gun/energy/floragun, /obj/item/weapon/gun/energy/floragun, @@ -87,25 +145,13 @@ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"m" = ( -/turf/open/floor/plasteel/freezer{ - baseturf = /turf/open/floor/plating/lava/smooth - }, -/area/ruin/powered) -"n" = ( -/obj/structure/shuttle/engine/propulsion{ - icon_state = "propulsion"; - dir = 8 - }, -/turf/open/floor/plating/asteroid/basalt/lava_land_surface, -/area/lavaland/surface/outdoors) -"o" = ( +"t" = ( /obj/effect/mob_spawn/human/seed_vault, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"p" = ( +"u" = ( /obj/structure/sink{ icon_state = "sink"; dir = 8; @@ -116,19 +162,19 @@ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"q" = ( +"v" = ( /obj/machinery/vending/hydronutrients, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"r" = ( +"w" = ( /obj/machinery/vending/hydroseeds, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"s" = ( +"x" = ( /obj/machinery/reagentgrinder{ pixel_y = 5 }, @@ -141,7 +187,7 @@ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"t" = ( +"y" = ( /obj/structure/sink{ dir = 4; icon_state = "sink"; @@ -152,57 +198,51 @@ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"u" = ( -/obj/machinery/door/airlock, -/turf/open/floor/plasteel/freezer{ - baseturf = /turf/open/floor/plating/lava/smooth - }, -/area/ruin/powered) -"v" = ( +"z" = ( /obj/machinery/door/airlock/external, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"w" = ( +"A" = ( /obj/machinery/door/airlock/external, /obj/structure/fans/tiny, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"x" = ( +"B" = ( /obj/structure/disposalpipe/trunk, /obj/machinery/disposal/bin, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"y" = ( +"C" = ( /obj/machinery/seed_extractor, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"z" = ( +"D" = ( /obj/machinery/biogenerator, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"A" = ( -/obj/machinery/chem_dispenser/mutagen, +"E" = ( +/obj/machinery/chem_dispenser/mutagensaltpeter, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"B" = ( +"F" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"C" = ( +"G" = ( /obj/structure/closet/crate/hydroponics, /obj/item/clothing/under/rank/hydroponics, /obj/item/clothing/under/rank/hydroponics, @@ -212,13 +252,13 @@ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"D" = ( +"H" = ( /obj/machinery/chem_master/condimaster, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"E" = ( +"I" = ( /obj/structure/table/wood, /obj/item/weapon/reagent_containers/glass/bucket, /obj/item/weapon/reagent_containers/glass/bucket, @@ -228,25 +268,25 @@ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"F" = ( +"J" = ( /obj/item/weapon/storage/toolbox/syndicate, /obj/structure/table/wood, /turf/open/floor/plasteel/freezer{ baseturf = /turf/open/floor/plating/lava/smooth }, /area/ruin/powered) -"G" = ( +"K" = ( /obj/structure/disposalpipe/segment, /turf/closed/wall/r_wall, /area/ruin/powered) -"H" = ( +"L" = ( /obj/structure/disposalpipe/segment{ dir = 1; icon_state = "pipe-c" }, /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /area/lavaland/surface/outdoors) -"I" = ( +"M" = ( /obj/structure/disposalpipe/trunk{ dir = 8 }, @@ -284,10 +324,10 @@ a a a c -o -o -o -o +t +t +t +t c a a @@ -299,17 +339,17 @@ b "} (3,1,1) = {" b -b +a a a a a c c -m -m -m -m +h +h +h +h c c a @@ -321,16 +361,16 @@ b "} (4,1,1) = {" b -b -a a a c c c c -u -u +c +c +l +l c c c @@ -344,18 +384,18 @@ a (5,1,1) = {" a a -a -a -a c -e -m -p -m -m -p -m -p +c +k +c +n +h +u +h +h +u +h +u c a a @@ -366,18 +406,18 @@ a (6,1,1) = {" a a -a -a -a c -f -m -m -m -m -m -m -C +d +h +c +o +h +h +h +h +h +h +G c a a @@ -388,18 +428,18 @@ a (7,1,1) = {" a a -a -a -a c -g -m -g -m -m -g -m -g +e +h +c +p +h +p +h +h +p +h +p c a a @@ -408,44 +448,44 @@ a a "} (8,1,1) = {" -a -a -a -a +b a c +e +h +l +h +h +v +h h -m -q -m -m -x B -B -G -H +F +F +K +L a a a a "} (9,1,1) = {" -a -a -a -a +b a c -i -m -e -m -m -y -m -m +f +h c -I +p +h +n +h +h +C +h +k +c +M a a a @@ -454,18 +494,18 @@ a (10,1,1) = {" a a -a -a -a c g -m -r -m -m -z -m -g +h +c +p +h +w +h +h +D +h +p c b a @@ -476,18 +516,18 @@ a (11,1,1) = {" a a -a -a -a c -j -m -s -m -m -A -m -D +h +h +c +q +h +x +h +h +E +h +H c a a @@ -496,20 +536,20 @@ a a "} (12,1,1) = {" -a -a -a -a +b a c -g -m -m -m -m -m -m -g +h +h +c +p +h +h +h +h +h +h +p c a a @@ -520,18 +560,18 @@ a (13,1,1) = {" a a -a -a -a c -k -m -m -g -g -m -m -E +i +h +c +r +h +h +p +p +h +h +I c a a @@ -542,18 +582,18 @@ a (14,1,1) = {" a a -a -a -a c -l -m -t -m -m -t -m -F +c +i +c +s +h +y +h +h +y +h +J c a a @@ -564,15 +604,15 @@ a (15,1,1) = {" a a -a -a -a +b c c c c -v -v +c +c +z +z c c c @@ -584,21 +624,21 @@ a a "} (16,1,1) = {" -a -a b a -a -d +b +j c -n +j c -m -m +j c -n +h +h c -n +j +c +j a a a @@ -611,12 +651,12 @@ a a a a -b a -b +a +a c -w -w +A +A c b b diff --git a/_maps/map_files/Cerestation/cerestation.dmm b/_maps/map_files/Cerestation/cerestation.dmm index f10211f5b1..1edf7431b1 100644 --- a/_maps/map_files/Cerestation/cerestation.dmm +++ b/_maps/map_files/Cerestation/cerestation.dmm @@ -1922,9 +1922,6 @@ /obj/structure/window/reinforced{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /turf/open/floor/plasteel/vault{ baseturf = /turf/open/floor/plating/asteroid/airless; dir = 8 @@ -1948,14 +1945,12 @@ /obj/structure/window/reinforced{ dir = 1 }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 10 - }, /obj/structure/cable/orange{ d1 = 1; d2 = 2; icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/vault{ baseturf = /turf/open/floor/plating/asteroid/airless; dir = 8 @@ -3744,11 +3739,15 @@ }, /area/ai_monitored/security/armory) "ahq" = ( -/obj/machinery/light/small{ - dir = 1 +/obj/machinery/atmospherics/components/unary/vent_pump{ + dir = 8; + layer = 2.4; + on = 1 }, -/turf/open/floor/plating/asteroid, -/area/security/transfer) +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) "ahr" = ( /obj/structure/cable/orange{ d1 = 1; @@ -4531,20 +4530,13 @@ }, /area/security/transfer) "aiQ" = ( -/obj/machinery/power/apc{ - dir = 1; - name = "Security Transfer Range APC"; - pixel_x = 0; - pixel_y = 24 +/obj/structure/chair{ + dir = 4 }, -/obj/structure/cable/orange{ - d2 = 8; - icon_state = "0-8" - }, -/turf/open/floor/plating/astplate{ +/turf/open/floor/plasteel/black{ baseturf = /turf/open/floor/plating/asteroid/airless }, -/area/security/transfer) +/area/security/prison) "aiR" = ( /obj/structure/rack, /obj/item/weapon/pickaxe/mini, @@ -4952,10 +4944,13 @@ }, /area/security/transfer) "ajJ" = ( -/turf/open/floor/plating/astplate{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel/black{ baseturf = /turf/open/floor/plating/asteroid/airless }, -/area/security/transfer) +/area/security/prison) "ajK" = ( /obj/structure/rack, /obj/item/weapon/shovel, @@ -5360,20 +5355,35 @@ d2 = 2; icon_state = "1-2" }, -/obj/machinery/light/small{ - dir = 8 +/obj/machinery/door/airlock/security{ + name = "Interrogation Room"; + req_access_txt = "0"; + req_one_access_txt = "38;2" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plating{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"akC" = ( +/obj/machinery/light/small, +/obj/structure/cable/orange{ + d1 = 1; + d2 = 8; + icon_state = "1-8" }, /turf/open/floor/plating/astplate{ baseturf = /turf/open/floor/plating/asteroid/airless }, /area/security/transfer) -"akC" = ( -/obj/machinery/light/small, -/turf/open/floor/plating/asteroid, -/area/security/transfer) "akD" = ( /obj/effect/decal/cleanable/blood/old, -/turf/open/floor/plating/asteroid, +/turf/open/floor/plating{ + baseturf = /turf/open/floor/plating/asteroid/airless; + icon_plating = "asteroid_dug"; + icon_state = "asteroid_dug"; + name = "ditch" + }, /area/security/transfer) "akE" = ( /obj/structure/disposalpipe/segment, @@ -5719,15 +5729,35 @@ d2 = 2; icon_state = "1-2" }, -/turf/open/floor/plating{ +/obj/structure/cable/orange{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel{ baseturf = /turf/open/floor/plating/asteroid/airless }, -/area/security/transfer) +/area/security/prison) "alm" = ( -/turf/closed/wall/r_wall{ +/obj/structure/extinguisher_cabinet{ + pixel_y = 32 + }, +/obj/machinery/camera{ + c_tag = "Brig Cells North 2" + }, +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 8 + }, +/turf/open/floor/plasteel{ baseturf = /turf/open/floor/plating/asteroid/airless }, -/area/security/transfer) +/area/security/prison) "aln" = ( /obj/structure/mineral_door/iron{ name = "Transfer Center" @@ -5928,30 +5958,40 @@ d2 = 2; icon_state = "1-2" }, -/obj/machinery/door/airlock/security{ - name = "Inmate Transfer Facility"; - req_access_txt = "2" - }, -/turf/open/floor/plating{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel{ baseturf = /turf/open/floor/plating/asteroid/airless }, -/area/security/transfer) +/area/security/prison) "alL" = ( /obj/machinery/light/small{ dir = 8 }, /obj/item/weapon/ore/glass, -/turf/open/floor/plating/asteroid, +/turf/open/floor/plating{ + baseturf = /turf/open/floor/plating/asteroid/airless; + icon_plating = "asteroid_dug"; + icon_state = "asteroid_dug"; + name = "ditch" + }, /area/security/transfer) "alM" = ( /obj/item/weapon/shovel, -/turf/open/floor/plating/astplate{ - baseturf = /turf/open/floor/plating/asteroid/airless +/turf/open/floor/plating{ + baseturf = /turf/open/floor/plating/asteroid/airless; + icon_plating = "asteroid_dug"; + icon_state = "asteroid_dug"; + name = "ditch" }, /area/security/transfer) "alN" = ( /obj/item/weapon/ore/glass, -/turf/open/floor/plating/asteroid, +/turf/open/floor/plating{ + baseturf = /turf/open/floor/plating/asteroid/airless; + icon_plating = "asteroid_dug"; + icon_state = "asteroid_dug"; + name = "ditch" + }, /area/security/transfer) "alO" = ( /obj/structure/closet/emcloset, @@ -6391,9 +6431,6 @@ }, /area/security/prison) "amA" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 10 - }, /obj/structure/cable/orange{ d1 = 1; d2 = 4; @@ -6404,6 +6441,7 @@ d2 = 8; icon_state = "4-8" }, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden, /turf/open/floor/plasteel{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -6414,20 +6452,15 @@ d2 = 4; icon_state = "2-4" }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 6 - }, /obj/structure/cable/orange{ d1 = 2; d2 = 8; icon_state = "2-8" }, -/obj/machinery/camera{ - c_tag = "Brig Cells North 2" - }, -/obj/structure/extinguisher_cabinet{ - pixel_y = 32 +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -7034,8 +7067,8 @@ "anI" = ( /obj/docking_port/stationary/random{ dir = 1; - id = "pod_asteroid1"; - name = "asteroid" + id = "pod_lavaland1"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -8103,7 +8136,7 @@ /obj/machinery/computer/shuttle/pod{ pixel_x = -32; pixel_y = 0; - possible_destinations = "pod_asteroid1"; + possible_destinations = "pod_lavaland1"; shuttleId = "pod1" }, /obj/machinery/light/small{ @@ -9004,32 +9037,34 @@ }, /obj/structure/grille, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) "ary" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) "arz" = ( /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Command-Service Bridge" + }) "arA" = ( -/obj/structure/window/reinforced{ - dir = 4; - pixel_x = 0 +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"arB" = ( +/obj/machinery/camera{ + c_tag = "Core-Command-Cargo Bridge 4"; + dir = 8; + network = list("SS13") }, /turf/open/floor/engine, -/area/space) -"arB" = ( -/obj/structure/lattice/catwalk, -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/structure/grille, -/turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) "arC" = ( /turf/closed/wall{ baseturf = /turf/open/floor/plating/asteroid/airless @@ -15851,6 +15886,10 @@ req_one_access_txt = "19;41" }, /obj/structure/disposalpipe/segment, +/obj/machinery/door/poddoor/preopen{ + id = "bridge"; + name = "Emergency Blast Door" + }, /turf/open/floor/plasteel/black{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -15881,6 +15920,10 @@ req_one_access_txt = "19;41" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/poddoor/preopen{ + id = "bridge"; + name = "Emergency Blast Door" + }, /turf/open/floor/plasteel/black{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -17888,7 +17931,6 @@ pixel_x = 5; pixel_y = 3 }, -/obj/item/weapon/stamp, /obj/item/device/radio/intercom{ broadcasting = 0; name = "Station Intercom (General)"; @@ -17896,6 +17938,7 @@ }, /obj/item/stack/packageWrap, /obj/item/device/destTagger, +/obj/item/weapon/stamp, /turf/open/floor/plasteel{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -22499,8 +22542,13 @@ icon_state = "1-4" }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) "aPn" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced, @@ -22514,8 +22562,13 @@ pixel_x = 0 }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) "aPo" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced, @@ -22533,7 +22586,9 @@ }, /obj/structure/grille, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) "aPp" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced, @@ -22545,25 +22600,31 @@ }, /obj/structure/grille, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) "aPq" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"aPr" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/structure/grille, -/turf/open/space, -/area/space) -"aPr" = ( -/obj/structure/lattice/catwalk, -/obj/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 +/obj/structure/window/reinforced{ + dir = 1 }, -/obj/structure/grille, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) "aPs" = ( /obj/structure/grille, /obj/machinery/door/firedoor, @@ -23762,11 +23823,10 @@ }, /area/hallway/primary/fore) "aQS" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) "aQT" = ( /obj/structure/window/reinforced{ dir = 1 @@ -23788,15 +23848,22 @@ /turf/open/floor/engine, /area/space) "aQV" = ( -/obj/machinery/door/airlock/glass, -/turf/open/floor/plasteel/neutral/corner{ - tag = "icon-neutralcorner (NORTH)"; - icon_state = "neutralcorner"; - dir = 1; - baseturf = /turf/open/floor/plating/asteroid/airless +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" }, -/area/hallway/primary/fore) +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) "aQW" = ( +/obj/machinery/door/airlock/glass, +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, /turf/open/floor/plasteel/neutral/corner{ tag = "icon-neutralcorner (NORTH)"; icon_state = "neutralcorner"; @@ -23805,13 +23872,10 @@ }, /area/hallway/primary/fore) "aQX" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 5 - }, /obj/structure/cable/orange{ - d1 = 1; - d2 = 4; - icon_state = "1-4" + d1 = 4; + d2 = 8; + icon_state = "4-8" }, /turf/open/floor/plasteel/neutral/corner{ tag = "icon-neutralcorner (NORTH)"; @@ -24994,9 +25058,10 @@ }, /area/hallway/primary/fore) "aSQ" = ( -/obj/structure/window/reinforced, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) "aSR" = ( /obj/machinery/door/airlock/glass, /turf/open/floor/plasteel/neutral/corner{ @@ -25440,8 +25505,11 @@ dir = 6 }, /obj/structure/grille, +/obj/structure/window/reinforced, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) "aTD" = ( /obj/structure/window/reinforced{ dir = 1 @@ -25451,8 +25519,11 @@ dir = 4 }, /obj/structure/grille, +/obj/structure/window/reinforced, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) "aTE" = ( /obj/structure/window/reinforced{ dir = 1 @@ -25463,7 +25534,9 @@ }, /obj/structure/grille, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) "aTF" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/machinery/door/airlock/atmos{ @@ -27380,6 +27453,9 @@ dir = 1 }, /obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/neutral/corner{ tag = "icon-neutralcorner (NORTH)"; icon_state = "neutralcorner"; @@ -27850,16 +27926,27 @@ }, /obj/structure/girder, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Command-Service Bridge" + }) "aXD" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced{ dir = 8 }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Command-Service Bridge" + }) "aXE" = ( /obj/structure/grille, /obj/structure/window/reinforced/fulltile, @@ -27910,8 +27997,13 @@ dir = 10 }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) "aXJ" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced{ @@ -27926,8 +28018,14 @@ dir = 6 }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) "aXK" = ( /obj/structure/lattice/catwalk, /obj/structure/cable{ @@ -28036,8 +28134,13 @@ }, /obj/structure/girder, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Command-Service Bridge" + }) "aXT" = ( /obj/structure/cable{ d1 = 1; @@ -28076,8 +28179,13 @@ }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) "aXY" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced{ @@ -28091,8 +28199,14 @@ }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) "aXZ" = ( /obj/machinery/power/solar_control{ id = "foresolar"; @@ -28416,8 +28530,13 @@ dir = 10 }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) "aYy" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced{ @@ -28425,8 +28544,13 @@ }, /obj/structure/girder, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) "aYz" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced{ @@ -28440,8 +28564,13 @@ icon_state = "1-2" }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) "aYA" = ( /obj/structure/lattice/catwalk, /obj/structure/cable{ @@ -28652,17 +28781,14 @@ name = "Civilian Asteroid" }) "aYU" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, -/obj/machinery/camera{ - c_tag = "Medbay-Cargo Bridge"; - dir = 4; - icon_state = "camera" - }, /obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) "aYV" = ( /obj/machinery/conveyor/auto{ tag = "icon-conveyor0 (EAST)"; @@ -29061,8 +29187,13 @@ }, /obj/structure/girder, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Command-Service Bridge" + }) "aZN" = ( /obj/structure/grille, /obj/structure/window/reinforced/fulltile, @@ -29137,8 +29268,13 @@ dir = 9 }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) "aZU" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced{ @@ -29153,8 +29289,14 @@ dir = 5 }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) "aZV" = ( /obj/structure/lattice/catwalk, /obj/structure/cable{ @@ -29212,6 +29354,9 @@ /area/hallway/primary/port) "bac" = ( /obj/machinery/door/airlock/glass, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -29363,8 +29508,13 @@ icon_state = "1-8" }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) "bat" = ( /obj/structure/disposalpipe/trunk{ dir = 1 @@ -29410,6 +29560,12 @@ }, /area/hallway/primary/port) "bay" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -29746,6 +29902,9 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -29942,6 +30101,9 @@ pixel_x = -32 }, /obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/neutral/corner{ tag = "icon-neutralcorner (NORTH)"; icon_state = "neutralcorner"; @@ -30496,6 +30658,12 @@ pixel_x = 29; pixel_y = 0 }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, /turf/open/floor/plasteel/neutral/corner{ tag = "icon-neutralcorner (EAST)"; icon_state = "neutralcorner"; @@ -30571,6 +30739,9 @@ pixel_x = -24 }, /obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/neutral/corner{ tag = "icon-neutralcorner (NORTH)"; icon_state = "neutralcorner"; @@ -31180,6 +31351,11 @@ d2 = 8; icon_state = "2-8" }, +/obj/structure/cable{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, /turf/open/floor/plasteel/neutral{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -32150,6 +32326,9 @@ dir = 1 }, /obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/neutral/corner{ tag = "icon-neutralcorner (NORTH)"; icon_state = "neutralcorner"; @@ -33966,6 +34145,9 @@ dir = 8; icon_state = "pipe-c" }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/neutral/corner{ tag = "icon-neutralcorner (NORTH)"; icon_state = "neutralcorner"; @@ -34487,6 +34669,12 @@ d2 = 8; icon_state = "1-8" }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_y = 0 + }, /turf/open/floor/plasteel/neutral{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -34496,6 +34684,12 @@ dir = 1; on = 1 }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_y = 0 + }, /turf/open/floor/plasteel/neutral{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -37957,6 +38151,12 @@ icon_state = "camera"; network = list("SS13") }, +/obj/machinery/button/door{ + id = "cmooffice"; + name = "Office Emergency Lockdown"; + pixel_x = 0; + pixel_y = -24 + }, /mob/living/simple_animal/pet/cat/Runtime, /turf/open/floor/plasteel/barber{ baseturf = /turf/open/floor/plating/asteroid/airless @@ -38438,8 +38638,13 @@ dir = 5 }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) "bpN" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced, @@ -38453,8 +38658,13 @@ dir = 4 }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) "bpO" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced, @@ -38467,8 +38677,13 @@ dir = 9 }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) "bpP" = ( /obj/machinery/light{ dir = 4 @@ -38551,8 +38766,13 @@ icon_state = "pipe-c" }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) "bpW" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced, @@ -38569,8 +38789,13 @@ dir = 4 }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) "bpX" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced, @@ -38587,8 +38812,13 @@ icon_state = "pipe-c" }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) "bpY" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 @@ -38635,6 +38865,9 @@ /obj/structure/window/reinforced/fulltile, /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "cmooffice" + }, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -40738,7 +40971,7 @@ /obj/machinery/computer/shuttle/pod{ pixel_x = 0; pixel_y = 32; - possible_destinations = "pod_asteroid3"; + possible_destinations = "pod_lavaland3"; shuttleId = "pod3" }, /obj/item/device/radio/intercom{ @@ -40760,8 +40993,8 @@ "btw" = ( /obj/docking_port/stationary/random{ dir = 4; - id = "pod_asteroid3"; - name = "asteroid" + id = "pod_lavaland3"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -41048,15 +41281,24 @@ /turf/open/floor/engine, /area/space) "btW" = ( -/obj/structure/window/reinforced, -/obj/machinery/camera{ - c_tag = "Service-Engineering Bridge 2"; - dir = 1 +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) "btX" = ( /obj/machinery/door/airlock/glass, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ icon_state = "neutralcorner"; dir = 8; @@ -41069,6 +41311,12 @@ pixel_x = 0; pixel_y = -29 }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ icon_state = "neutralcorner"; dir = 8; @@ -41077,6 +41325,12 @@ /area/hallway/primary/central) "btZ" = ( /obj/machinery/light, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ icon_state = "neutralcorner"; dir = 8; @@ -41087,6 +41341,12 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ icon_state = "neutralcorner"; dir = 8; @@ -41104,6 +41364,12 @@ /obj/effect/turf_decal/stripes/line{ dir = 8 }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ icon_state = "neutralcorner"; dir = 8; @@ -41112,6 +41378,12 @@ /area/hallway/primary/central) "buc" = ( /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ icon_state = "neutralcorner"; dir = 8; @@ -41122,6 +41394,12 @@ /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 4 }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -41136,6 +41414,11 @@ /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ dir = 8 }, +/obj/structure/cable{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, /turf/open/floor/plasteel/neutral{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -41309,12 +41592,24 @@ dir = 2; icon_state = "pipe-c" }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, /area/hallway/primary/central) "bur" = ( /obj/machinery/light, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -41325,24 +41620,39 @@ pixel_x = 0; pixel_y = -29 }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, /area/hallway/primary/central) "but" = ( /obj/machinery/door/airlock/glass, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, /area/hallway/primary/central) "buu" = ( -/obj/structure/window/reinforced, -/obj/machinery/camera{ - c_tag = "Medbay-Engineering Bridge"; - dir = 1 +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) "buv" = ( /obj/machinery/door/airlock/glass, /turf/open/floor/plasteel/neutral/corner{ @@ -41849,19 +42159,19 @@ dir = 6 }, /obj/structure/grille, +/obj/structure/window/reinforced, /turf/open/floor/plating/asteroid/airless, -/area/space) +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) "bvv" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, -/obj/structure/lattice/catwalk, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/structure/grille, -/turf/open/space, -/area/space) +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) "bvw" = ( /obj/structure/window/reinforced{ dir = 1 @@ -41871,8 +42181,11 @@ dir = 10 }, /obj/structure/grille, +/obj/structure/window/reinforced, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) "bvx" = ( /obj/machinery/door/airlock/maintenance{ name = "External Airlock Access"; @@ -42199,8 +42512,11 @@ icon_state = "pipe-c" }, /obj/structure/grille, +/obj/structure/window/reinforced, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) "bvW" = ( /obj/structure/window/reinforced{ dir = 1 @@ -42213,8 +42529,11 @@ dir = 4 }, /obj/structure/grille, +/obj/structure/window/reinforced, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) "bvX" = ( /obj/structure/window/reinforced{ dir = 1 @@ -42228,8 +42547,11 @@ icon_state = "pipe-c" }, /obj/structure/grille, +/obj/structure/window/reinforced, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) "bvY" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /obj/structure/cable{ @@ -53296,6 +53618,9 @@ icon_state = "0-4" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "ceoffice" + }, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -53313,6 +53638,9 @@ icon_state = "4-8"; pixel_x = 0 }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "ceoffice" + }, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -53338,6 +53666,9 @@ icon_state = "4-8"; pixel_x = 0 }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "ceoffice" + }, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -53359,6 +53690,9 @@ icon_state = "0-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "ceoffice" + }, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -54299,6 +54633,13 @@ pixel_y = 8; req_access_txt = "10;11" }, +/obj/machinery/button/door{ + id = "ceoffice"; + name = "Office Emergency Lockdown"; + pixel_x = -24; + pixel_y = -8; + req_access_txt = "10;11" + }, /turf/open/floor/plasteel/neutral{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -55644,6 +55985,7 @@ /area/atmos) "bSJ" = ( /obj/machinery/computer/apc_control, +/obj/machinery/light, /turf/open/floor/plasteel/neutral{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -55665,6 +56007,11 @@ /area/crew_quarters/chief) "bSL" = ( /obj/machinery/suit_storage_unit/ce, +/obj/machinery/airalarm{ + dir = 1; + icon_state = "alarm0"; + pixel_y = -22 + }, /turf/open/floor/plasteel/neutral{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -58987,8 +59334,13 @@ icon_state = "pipe-c" }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) "bYM" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced{ @@ -59004,8 +59356,13 @@ }, /obj/structure/girder, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) "bYN" = ( /obj/structure/lattice/catwalk, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ @@ -59290,8 +59647,13 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/disposalpipe/segment, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) "bZo" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced{ @@ -59305,8 +59667,13 @@ }, /obj/structure/girder, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) "bZp" = ( /obj/machinery/light{ dir = 8 @@ -61264,17 +61631,10 @@ name = "Central Asteroid Maintenance" }) "cdj" = ( -/obj/structure/window/reinforced{ - dir = 4; - pixel_x = 0 - }, -/obj/machinery/camera{ - c_tag = "Docking-Medbay Bridge"; - dir = 8; - network = list("SS13") - }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) "cdk" = ( /obj/structure/disposalpipe/junction{ icon_state = "pipe-j2"; @@ -61528,6 +61888,12 @@ d2 = 4; icon_state = "1-4" }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -62223,6 +62589,12 @@ dir = 4; pixel_x = 24 }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -62678,21 +63050,24 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 10 }, -/turf/open/floor/plating/airless/astplate{ - baseturf = /turf/open/floor/plating/asteroid/airless - }, -/area/mine/unexplored{ - name = "Civilian Asteroid" - }) -"cfO" = ( +/obj/structure/grille, /obj/structure/window/reinforced{ dir = 8 }, +/turf/open/floor/plating/airless/astplate{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/construction/hallway{ + name = "Service-Science Bridge" + }) +"cfO" = ( /turf/open/floor/engine{ baseturf = /turf/open/floor/plating/asteroid/airless; name = "reinforced floor" }, -/area/hallway/primary/port) +/area/construction/hallway{ + name = "Service-Science Bridge" + }) "cfP" = ( /turf/open/floor/engine{ baseturf = /turf/open/floor/plating/asteroid/airless; @@ -62700,16 +63075,20 @@ }, /area/hallway/primary/port) "cfQ" = ( -/obj/structure/window/reinforced{ - dir = 4; - pixel_x = 0 - }, /obj/structure/disposalpipe/segment, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, /turf/open/floor/engine{ baseturf = /turf/open/floor/plating/asteroid/airless; name = "reinforced floor" }, -/area/hallway/primary/port) +/area/construction/hallway{ + name = "Service-Science Bridge" + }) "cfR" = ( /obj/structure/window/reinforced{ dir = 8 @@ -62722,11 +63101,15 @@ d2 = 4; icon_state = "2-4" }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4 + }, /turf/open/floor/plating/airless/astplate{ baseturf = /turf/open/floor/plating/asteroid/airless }, -/area/mine/unexplored{ - name = "Civilian Asteroid" +/area/construction/hallway{ + name = "Service-Science Bridge" }) "cfS" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -62768,8 +63151,13 @@ icon_state = "pipe-c" }, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) "cfV" = ( /obj/structure/lattice/catwalk, /obj/structure/window/reinforced{ @@ -62785,8 +63173,13 @@ }, /obj/structure/girder, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) "cfW" = ( /obj/structure/table, /obj/item/toy/figure/clown, @@ -62837,11 +63230,15 @@ pixel_x = 0 }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/floor/plating/airless/astplate{ baseturf = /turf/open/floor/plating/asteroid/airless }, -/area/mine/unexplored{ - name = "Civilian Asteroid" +/area/construction/hallway{ + name = "Service-Science Bridge" }) "cgb" = ( /obj/structure/window/reinforced{ @@ -62853,11 +63250,15 @@ d2 = 2; icon_state = "1-2" }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4 + }, /turf/open/floor/plating/airless/astplate{ baseturf = /turf/open/floor/plating/asteroid/airless }, -/area/mine/unexplored{ - name = "Civilian Asteroid" +/area/construction/hallway{ + name = "Service-Science Bridge" }) "cgc" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -62972,9 +63373,6 @@ name = "Port Asteroid Maintenance" }) "cgp" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, /obj/machinery/light{ dir = 8 }, @@ -62982,7 +63380,9 @@ baseturf = /turf/open/floor/plating/asteroid/airless; name = "reinforced floor" }, -/area/hallway/primary/port) +/area/construction/hallway{ + name = "Service-Science Bridge" + }) "cgq" = ( /obj/effect/turf_decal/stripes/line{ dir = 9 @@ -63083,6 +63483,9 @@ icon_state = "tube1"; dir = 4 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -63167,6 +63570,9 @@ pixel_x = 28; pixel_y = 0 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -63224,26 +63630,24 @@ name = "Research Asteroid" }) "cgT" = ( -/obj/structure/window/reinforced{ - dir = 4; - pixel_x = 0 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/open/floor/plating/airless/astplate{ +/turf/closed/wall/r_wall{ baseturf = /turf/open/floor/plating/asteroid/airless }, -/area/mine/unexplored{ - name = "Research Asteroid" +/area/construction/hallway{ + name = "Service-Science Bridge" }) "cgU" = ( -/obj/structure/window/reinforced{ +/obj/machinery/light/small{ dir = 8 }, /turf/open/floor/engine{ baseturf = /turf/open/floor/plating/asteroid/airless; name = "reinforced floor" }, -/area/hallway/primary/aft) +/area/construction/hallway{ + name = "Service-Science Bridge" + }) "cgV" = ( /turf/open/floor/engine{ baseturf = /turf/open/floor/plating/asteroid/airless; @@ -63251,36 +63655,31 @@ }, /area/hallway/primary/aft) "cgW" = ( -/obj/structure/window/reinforced{ - dir = 4; - pixel_x = 0 - }, +/obj/structure/disposalpipe/segment, /obj/machinery/camera{ c_tag = "Service-Research Bridge"; dir = 9; icon_state = "camera" }, -/obj/structure/disposalpipe/segment, /turf/open/floor/engine{ baseturf = /turf/open/floor/plating/asteroid/airless; name = "reinforced floor" }, -/area/hallway/primary/aft) +/area/construction/hallway{ + name = "Service-Science Bridge" + }) "cgX" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/structure/cable{ d1 = 1; d2 = 2; icon_state = "1-2" }, -/turf/open/floor/plating/airless/astplate{ +/turf/closed/wall/r_wall{ baseturf = /turf/open/floor/plating/asteroid/airless }, -/area/mine/unexplored{ - name = "Research Asteroid" +/area/construction/hallway{ + name = "Service-Science Bridge" }) "cgY" = ( /obj/machinery/atmospherics/components/unary/portables_connector/visible{ @@ -63324,16 +63723,14 @@ name = "Aft Asteroid Maintenance" }) "chd" = ( -/obj/structure/window/reinforced{ - dir = 4; - pixel_x = 0 - }, /obj/structure/disposalpipe/segment, /turf/open/floor/engine{ baseturf = /turf/open/floor/plating/asteroid/airless; name = "reinforced floor" }, -/area/hallway/primary/aft) +/area/construction/hallway{ + name = "Service-Science Bridge" + }) "che" = ( /obj/machinery/power/solar{ id = "portsolar"; @@ -63507,6 +63904,11 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, +/obj/structure/cable{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -64193,11 +64595,15 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 9 }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, /turf/open/floor/plating/airless/astplate{ baseturf = /turf/open/floor/plating/asteroid/airless }, -/area/mine/unexplored{ - name = "Research Asteroid" +/area/construction/hallway{ + name = "Service-Science Bridge" }) "ciE" = ( /obj/structure/window/reinforced{ @@ -64211,11 +64617,15 @@ d2 = 4; icon_state = "1-4" }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4 + }, /turf/open/floor/plating/airless/astplate{ baseturf = /turf/open/floor/plating/asteroid/airless }, -/area/mine/unexplored{ - name = "Research Asteroid" +/area/construction/hallway{ + name = "Service-Science Bridge" }) "ciF" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -68698,8 +69108,13 @@ /obj/structure/lattice/catwalk, /obj/structure/window/reinforced, /obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) "cqD" = ( /turf/closed/wall{ baseturf = /turf/open/floor/plating/asteroid/airless @@ -68963,8 +69378,8 @@ "crd" = ( /obj/docking_port/stationary/random{ dir = 8; - id = "pod_asteroid2"; - name = "asteroid" + id = "pod_lavaland2"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -68979,7 +69394,7 @@ /obj/machinery/computer/shuttle/pod{ pixel_x = 0; pixel_y = -32; - possible_destinations = "pod_asteroid2"; + possible_destinations = "pod_lavaland2"; shuttleId = "pod2" }, /obj/structure/chair{ @@ -69557,6 +69972,11 @@ d2 = 8; icon_state = "1-8" }, +/obj/structure/cable{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, /turf/open/floor/plasteel/neutral/side{ baseturf = /turf/open/floor/plating/asteroid/airless; dir = 1; @@ -70509,6 +70929,12 @@ dir = 1; pixel_y = -24 }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ icon_state = "neutralcorner"; dir = 8; @@ -70521,6 +70947,12 @@ dir = 4; icon_state = "pipe-c" }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ icon_state = "neutralcorner"; dir = 8; @@ -70532,6 +70964,12 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/plasteel/neutral/corner{ icon_state = "neutralcorner"; dir = 8; @@ -70539,44 +70977,50 @@ }, /area/hallway/primary/aft) "ctA" = ( -/obj/structure/window/reinforced, +/obj/structure/disposalpipe/segment{ + dir = 4 + }, /obj/machinery/camera{ c_tag = "Research-Docking Bridge 1"; dir = 1; icon_state = "camera"; network = list("SS13") }, -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) "ctB" = ( -/obj/structure/window/reinforced, -/obj/machinery/camera{ - c_tag = "Research-Docking Bridge 2"; - dir = 1; - icon_state = "camera"; - network = list("SS13") - }, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/machinery/power/apc{ + dir = 2; + name = "Science-Docking Bridge APC"; + pixel_y = -24 + }, +/obj/structure/cable{ + d2 = 8; + icon_state = "0-8" + }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) "ctC" = ( -/obj/structure/window/reinforced, -/obj/machinery/camera{ - c_tag = "Research-Docking Bridge 3"; - dir = 1; - icon_state = "camera"; - network = list("SS13") - }, /obj/structure/disposalpipe/segment{ dir = 4 }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) "ctD" = ( /obj/machinery/door/airlock/glass, /obj/structure/disposalpipe/segment{ @@ -70978,8 +71422,11 @@ /obj/structure/lattice/catwalk, /obj/structure/girder, /obj/structure/grille, +/obj/structure/window/reinforced, /turf/open/space, -/area/space) +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) "cul" = ( /obj/machinery/status_display{ density = 0; @@ -75746,6 +76193,9 @@ /obj/structure/grille, /obj/structure/window/reinforced/fulltile, /obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "rdoffice" + }, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -75755,6 +76205,9 @@ /obj/structure/window/reinforced/fulltile, /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "rdoffice" + }, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -75773,6 +76226,9 @@ /obj/structure/window/reinforced/fulltile, /obj/machinery/door/firedoor, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "rdoffice" + }, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -76682,6 +77138,7 @@ icon_state = "camera"; network = list("SS13") }, +/obj/item/clothing/neck/stethoscope, /turf/open/floor/plasteel/whitepurple/side{ tag = "icon-whitepurple (SOUTHWEST)"; icon_state = "whitepurple"; @@ -76730,6 +77187,7 @@ /obj/machinery/newscaster/security_unit{ pixel_x = -28 }, +/obj/machinery/recharger, /turf/open/floor/plasteel/red/side{ icon_state = "red"; dir = 8; @@ -83054,7 +83512,9 @@ "cPD" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) "cPE" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/engine, @@ -83142,12 +83602,11 @@ /turf/open/floor/engine, /area/space) "cPT" = ( -/obj/structure/window/reinforced{ - dir = 8 - }, /obj/structure/disposalpipe/segment, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) "cPU" = ( /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/airless @@ -83339,6 +83798,12 @@ /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, /turf/open/floor/plasteel/neutral/corner{ tag = "icon-neutralcorner (EAST)"; icon_state = "neutralcorner"; @@ -83358,6 +83823,9 @@ "cQC" = ( /obj/machinery/door/airlock/glass, /obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/neutral/corner{ tag = "icon-neutralcorner (NORTH)"; icon_state = "neutralcorner"; @@ -83414,6 +83882,9 @@ /area/hallway/primary/central) "cQJ" = ( /obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/neutral/corner{ tag = "icon-neutralcorner (NORTH)"; icon_state = "neutralcorner"; @@ -83846,14 +84317,13 @@ }, /area/hallway/primary/starboard) "cRM" = ( -/obj/structure/window/reinforced{ - dir = 1 - }, /obj/structure/disposalpipe/segment{ dir = 4 }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) "cRN" = ( /obj/structure/window/reinforced{ dir = 1 @@ -84231,7 +84701,9 @@ dir = 4 }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) "cSD" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -84805,6 +85277,12 @@ dir = 4; icon_state = "pipe-c" }, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -84821,6 +85299,12 @@ "cTX" = ( /obj/machinery/door/airlock/glass, /obj/structure/disposalpipe/segment, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, /turf/open/floor/plasteel/neutral/corner{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -85064,12 +85548,19 @@ }, /area/teleporter) "cUy" = ( -/obj/structure/window/reinforced, /obj/structure/disposalpipe/segment{ dir = 4 }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) "cUz" = ( /obj/structure/window/reinforced, /obj/structure/disposalpipe/segment{ @@ -87179,6 +87670,10 @@ req_one_access = null; req_one_access_txt = "0" }, +/obj/machinery/door/poddoor/preopen{ + id = "bridge"; + name = "Emergency Blast Door" + }, /turf/open/floor/plasteel/black{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -87192,6 +87687,10 @@ req_one_access = null; req_one_access_txt = "0" }, +/obj/machinery/door/poddoor/preopen{ + id = "bridge"; + name = "Emergency Blast Door" + }, /turf/open/floor/plasteel/black{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -87277,6 +87776,9 @@ /obj/structure/window/reinforced/fulltile, /obj/structure/grille, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "qmoffice" + }, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -87294,6 +87796,9 @@ "cZQ" = ( /obj/structure/window/reinforced/fulltile, /obj/structure/grille, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "qmoffice" + }, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -87530,6 +88035,11 @@ /area/quartermaster/qm) "dap" = ( /obj/structure/closet/secure_closet/quartermaster, +/obj/machinery/button/door{ + id = "qmoffice"; + name = "Office Emergency Lockdown"; + pixel_x = -24 + }, /turf/open/floor/plasteel/brown{ tag = "icon-brown (WEST)"; icon_state = "brown"; @@ -88359,6 +88869,9 @@ icon_state = "alarm0"; pixel_x = -22 }, +/obj/structure/cable{ + icon_state = "1-2" + }, /turf/open/floor/plasteel/neutral/corner{ tag = "icon-neutralcorner (NORTH)"; icon_state = "neutralcorner"; @@ -90292,6 +90805,9 @@ /obj/structure/grille, /obj/structure/window/reinforced/fulltile, /obj/machinery/door/firedoor, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "cmooffice" + }, /turf/open/floor/plating{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -91711,7 +92227,6 @@ }, /obj/item/weapon/stamp/ce, /obj/item/weapon/pen, -/obj/machinery/light, /turf/open/floor/plasteel/neutral{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -91722,10 +92237,8 @@ d2 = 4; icon_state = "1-4" }, -/obj/machinery/airalarm{ - dir = 1; - icon_state = "alarm0"; - pixel_y = -22 +/obj/structure/cable{ + icon_state = "1-2" }, /turf/open/floor/plasteel/neutral{ baseturf = /turf/open/floor/plating/asteroid/airless @@ -92435,17 +92948,13 @@ name = "Central Asteroid Maintenance" }) "djU" = ( -/obj/structure/window/reinforced{ - dir = 4; - pixel_x = 0 - }, -/obj/machinery/camera{ - c_tag = "Docking-Medbay Bridge 2"; - dir = 8; - network = list("SS13") +/obj/structure/cable{ + icon_state = "1-2" }, /turf/open/floor/engine, -/area/space) +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) "djV" = ( /obj/structure/closet/crate, /obj/effect/spawner/lootdrop/maintenance, @@ -93766,6 +94275,12 @@ scrub_N2O = 0; scrub_Toxins = 0 }, +/obj/machinery/button/door{ + id = "rdoffice"; + name = "Office Emergency Lockdown"; + pixel_x = -24; + pixel_y = -8 + }, /turf/open/floor/plasteel/cafeteria{ baseturf = /turf/open/floor/plating/asteroid/airless }, @@ -94369,10 +94884,10 @@ /obj/structure/disposaloutlet{ dir = 8 }, -/obj/structure/disposalpipe/trunk{ - dir = 8 - }, /obj/structure/lattice/catwalk, +/obj/structure/disposalpipe/trunk{ + dir = 4 + }, /turf/open/space, /area/space) "dnB" = ( @@ -96655,6 +97170,4503 @@ }, /turf/closed/wall/r_wall, /area/maintenance/incinerator) +"dsd" = ( +/obj/machinery/power/apc{ + dir = 1; + name = "Armory APC"; + pixel_x = 0; + pixel_y = 24 + }, +/obj/structure/cable/orange{ + d2 = 4; + icon_state = "0-4" + }, +/obj/structure/rack, +/obj/item/weapon/storage/box/chemimp{ + pixel_x = 4; + pixel_y = 3 + }, +/obj/item/weapon/reagent_containers/glass/bottle/morphine, +/turf/open/floor/plasteel/darkred/side{ + icon_state = "darkred"; + dir = 1; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/ai_monitored/security/armory) +"dse" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/structure/rack, +/obj/item/weapon/storage/lockbox/loyalty, +/obj/item/weapon/storage/box/trackimp, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/darkred/side{ + icon_state = "darkred"; + dir = 1; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/ai_monitored/security/armory) +"dsf" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/structure/cable/orange{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/ai_monitored/security/armory) +"dsg" = ( +/obj/structure/closet/secure_closet{ + name = "contraband locker"; + req_access_txt = "3" + }, +/obj/effect/spawner/lootdrop/armory_contraband{ + loot = list(/obj/item/weapon/gun/ballistic/automatic/pistol = 5, /obj/item/weapon/gun/ballistic/shotgun/automatic/combat = 5, /obj/item/weapon/gun/ballistic/revolver/mateba, /obj/item/weapon/gun/ballistic/automatic/pistol/deagle, /obj/item/weapon/storage/box/syndie_kit/throwing_weapons = 3) + }, +/turf/open/floor/plasteel{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/ai_monitored/security/armory) +"dsh" = ( +/obj/machinery/atmospherics/components/unary/vent_scrubber{ + on = 1; + scrub_N2O = 0; + scrub_Toxins = 0 + }, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsi" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsj" = ( +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsk" = ( +/obj/machinery/airalarm{ + frequency = 1439; + locked = 0; + pixel_y = 23 + }, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsl" = ( +/obj/machinery/camera{ + c_tag = "Security Interrogation"; + dir = 9; + icon_state = "camera"; + network = list("SS13"); + tag = "null" + }, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsm" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsn" = ( +/obj/structure/chair{ + dir = 4 + }, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dso" = ( +/obj/structure/table/wood, +/obj/item/device/flashlight/lamp, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsp" = ( +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsq" = ( +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsr" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 6 + }, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dss" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dst" = ( +/obj/structure/table/wood, +/obj/item/device/taperecorder, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsu" = ( +/obj/structure/chair{ + dir = 8 + }, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsv" = ( +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsw" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsx" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsy" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsz" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/machinery/light/small, +/turf/open/floor/plasteel/black{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsA" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsB" = ( +/obj/structure/cable/orange{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door_timer{ + id = "Cell 8"; + name = "Cell 8"; + pixel_x = 32; + pixel_y = 0 + }, +/turf/open/floor/plasteel{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsC" = ( +/obj/machinery/power/apc{ + dir = 1; + name = "Security Transfer Range APC"; + pixel_x = 0; + pixel_y = 24 + }, +/obj/structure/cable/orange{ + d2 = 4; + icon_state = "0-4" + }, +/turf/open/floor/plating/astplate{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/transfer) +"dsD" = ( +/obj/structure/cable/orange{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/turf/open/floor/plating/astplate{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/transfer) +"dsE" = ( +/obj/structure/cable/orange{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/cable/orange{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsF" = ( +/obj/structure/mineral_door/iron{ + name = "Transfer Center" + }, +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/plating/astplate{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/transfer) +"dsG" = ( +/obj/structure/cable/orange{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door_timer{ + id = "Cell 7"; + name = "Cell 7"; + pixel_x = 32; + pixel_y = 0 + }, +/turf/open/floor/plasteel{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsH" = ( +/obj/structure/cable/orange{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/obj/structure/cable/orange{ + d1 = 2; + d2 = 4; + icon_state = "2-4" + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/prison) +"dsI" = ( +/obj/machinery/door/airlock/security{ + name = "Inmate Transfer Facility"; + req_access_txt = "2" + }, +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/plating{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/transfer) +"dsJ" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/plating{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/transfer) +"dsK" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/plating{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/transfer) +"dsL" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/plating/astplate{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/transfer) +"dsM" = ( +/obj/structure/cable/orange{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/turf/open/floor/plating/astplate{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/security/transfer) +"dsN" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/window/reinforced/fulltile, +/obj/machinery/door/firedoor, +/obj/structure/grille, +/obj/structure/cable{ + icon_state = "0-4" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "ceoffice" + }, +/turf/open/floor/plating{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/crew_quarters/chief) +"dsO" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/machinery/door/airlock/glass_engineering{ + name = "Chief Engineer's Office"; + req_access_txt = "56" + }, +/obj/structure/cable{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/obj/structure/cable{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/turf/open/floor/plasteel/neutral{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/crew_quarters/chief) +"dsP" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/window/reinforced/fulltile, +/obj/machinery/door/firedoor, +/obj/structure/grille, +/obj/structure/cable{ + d2 = 8; + icon_state = "0-8" + }, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "ceoffice" + }, +/turf/open/floor/plating{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/crew_quarters/chief) +"dsQ" = ( +/obj/machinery/camera{ + c_tag = "Core-Command-Cargo Bridge 4"; + dir = 8; + network = list("SS13") + }, +/turf/open/space, +/area/space) +"dsR" = ( +/obj/machinery/camera{ + c_tag = "Core-Command-Cargo Bridge 1"; + dir = 8; + network = list("SS13") + }, +/turf/open/space, +/area/space) +"dsS" = ( +/obj/machinery/camera{ + c_tag = "Core-Command-Cargo Bridge 2"; + network = list("SS13") + }, +/turf/open/space, +/area/space) +"dsT" = ( +/obj/machinery/camera{ + c_tag = "Core-Command-Cargo Bridge 3"; + network = list("SS13") + }, +/turf/open/space, +/area/space) +"dsU" = ( +/obj/machinery/camera{ + c_tag = "Core-Command-Cargo Bridge Ceneter"; + dir = 1 + }, +/turf/open/space, +/area/space) +"dsV" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dsW" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dsX" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dsY" = ( +/obj/machinery/light{ + icon_state = "tube1"; + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dsZ" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dta" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dtb" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dtc" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtd" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dte" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtf" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtg" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dth" = ( +/obj/machinery/camera{ + c_tag = "Command-Service Bridge"; + dir = 4; + icon_state = "camera" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dti" = ( +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dtj" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dtk" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dtl" = ( +/obj/machinery/camera{ + c_tag = "Command-Engineering Bridge"; + dir = 8; + network = list("SS13") + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dtm" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dtn" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dto" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtp" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtq" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtr" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dts" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/power/apc{ + dir = 8; + name = "Medical-Cargo Bridge APC"; + pixel_x = -25 + }, +/obj/structure/cable{ + icon_state = "0-2"; + d2 = 2 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtt" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtu" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtv" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtw" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dtx" = ( +/obj/machinery/power/apc{ + dir = 8; + name = "Command-Service Bridge APC"; + pixel_x = -25 + }, +/obj/structure/cable{ + icon_state = "0-4"; + d2 = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dty" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dtz" = ( +/obj/structure/cable{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dtA" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dtB" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dtC" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dtD" = ( +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtE" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtF" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtG" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dtH" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtI" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtJ" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dtK" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtL" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtM" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dtN" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtO" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtP" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dtQ" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/light{ + icon_state = "tube1"; + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dtR" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dtS" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dtT" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dtU" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtV" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/camera{ + c_tag = "Medbay-Cargo Bridge"; + dir = 4; + icon_state = "camera" + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtW" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtX" = ( +/obj/machinery/light{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtY" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dtZ" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dua" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dub" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"duc" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dud" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"due" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"duf" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dug" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"duh" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dui" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"duj" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"duk" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/neutral/corner{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/port) +"dul" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/turf/open/floor/plasteel/neutral{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/starboard) +"dum" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dun" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duo" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dup" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duq" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dur" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dus" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"dut" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"duu" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"duv" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duw" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dux" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duy" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duz" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duA" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duB" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"duC" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"duD" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"duE" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duF" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duG" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duH" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duI" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duJ" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duK" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duL" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duM" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duN" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duO" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duP" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duQ" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duR" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duS" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duT" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duU" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duV" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duW" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duX" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duY" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"duZ" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dva" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvb" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvc" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvd" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dve" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvf" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvg" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvh" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvi" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvj" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvk" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvl" = ( +/obj/machinery/camera{ + c_tag = "Service-Engineering Bridge 1"; + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvm" = ( +/obj/machinery/power/apc{ + dir = 2; + name = "Service-Engineering Bridge APC"; + pixel_y = -24 + }, +/obj/structure/cable{ + icon_state = "0-4" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvn" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvo" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvp" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvq" = ( +/obj/machinery/camera{ + c_tag = "Service-Engineering Bridge 2"; + dir = 1 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvr" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/plasteel/neutral/corner{ + icon_state = "neutralcorner"; + dir = 8; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/central) +"dvs" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/plasteel/neutral/corner{ + icon_state = "neutralcorner"; + dir = 8; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/central) +"dvt" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/plasteel/neutral/corner{ + icon_state = "neutralcorner"; + dir = 8; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/central) +"dvu" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/plasteel/neutral/corner{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/central) +"dvv" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/plasteel/neutral/corner{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/central) +"dvw" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/plasteel/neutral/corner{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/central) +"dvx" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"dvy" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"dvz" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"dvA" = ( +/obj/machinery/camera{ + c_tag = "Medbay-Engineering Bridge"; + dir = 1 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"dvB" = ( +/obj/machinery/power/apc{ + dir = 2; + name = "Engineering-Medical Bridge APC"; + pixel_y = -24 + }, +/obj/structure/cable{ + d2 = 8; + icon_state = "0-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"dvC" = ( +/obj/machinery/camera{ + c_tag = "Medbay-Engineering Bridge 2"; + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"dvD" = ( +/turf/closed/wall{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvE" = ( +/turf/closed/wall{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvF" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvG" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvH" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvI" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvJ" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvK" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvL" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvM" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvN" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvO" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvP" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvQ" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvR" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvS" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvT" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvU" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvV" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvW" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvX" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvY" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dvZ" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Service-Engineering Bridge" + }) +"dwa" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"dwb" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"dwc" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Engineering-Medical Bridge" + }) +"dwd" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwe" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwf" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwg" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwh" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwi" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwj" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwk" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwl" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwm" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwn" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwo" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwp" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwq" = ( +/obj/machinery/light{ + icon_state = "tube1"; + dir = 8 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwr" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dws" = ( +/obj/machinery/camera{ + c_tag = "Docking-Medbay Bridge"; + dir = 8; + network = list("SS13") + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwt" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwu" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwv" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dww" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwx" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwy" = ( +/obj/machinery/power/apc{ + dir = 4; + name = "Docking-Medical Bridge APC"; + pixel_x = 24; + pixel_y = 0 + }, +/obj/structure/cable{ + icon_state = "0-2"; + d2 = 2 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwz" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwA" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwB" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwC" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwD" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwE" = ( +/obj/machinery/light{ + icon_state = "tube1"; + dir = 8 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwF" = ( +/obj/machinery/camera{ + c_tag = "Docking-Medbay Bridge 2"; + dir = 8; + network = list("SS13") + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwG" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dwH" = ( +/obj/machinery/door/airlock/glass, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/neutral/corner{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/starboard) +"dwI" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/neutral/corner{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/starboard) +"dwJ" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/neutral/corner{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/starboard) +"dwK" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/neutral/corner{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/starboard) +"dwL" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/neutral/corner{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/starboard) +"dwM" = ( +/obj/machinery/door/firedoor, +/obj/effect/turf_decal/stripes/line, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/neutral/corner{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/starboard) +"dwN" = ( +/obj/structure/extinguisher_cabinet{ + pixel_x = 24 + }, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/neutral/corner{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/starboard) +"dwO" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dwP" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dwQ" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dwR" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dwS" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dwT" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dwU" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dwV" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dwW" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dwX" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dwY" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dwZ" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxa" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxb" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxc" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxd" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxe" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxf" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxg" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxh" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxi" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxj" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxk" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxl" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxm" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxn" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxo" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxp" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxq" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxr" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxs" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxt" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxu" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxv" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxw" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxx" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxy" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxz" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxA" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxB" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxC" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxD" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxE" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxF" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxG" = ( +/obj/machinery/light/small{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxH" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxI" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxJ" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxK" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxL" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxM" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxN" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxO" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxP" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxQ" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxR" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxS" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxT" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxU" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxV" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxW" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxX" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxY" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dxZ" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dya" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyb" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyc" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyd" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dye" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyf" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyg" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyh" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyi" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyj" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyk" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyl" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dym" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyn" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyo" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyp" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyq" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyr" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dys" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyt" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyu" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyv" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyw" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyx" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyy" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyz" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyA" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyB" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyC" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyD" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyE" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyF" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyG" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyH" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyI" = ( +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyJ" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/turf/open/floor/plasteel/neutral/corner{ + icon_state = "neutralcorner"; + dir = 8; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/aft) +"dyK" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/plasteel/neutral/corner{ + icon_state = "neutralcorner"; + dir = 8; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/aft) +"dyL" = ( +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/plasteel/neutral/corner{ + icon_state = "neutralcorner"; + dir = 8; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/aft) +"dyM" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Research-Docking Bridge 5"; + dir = 1; + icon_state = "camera"; + network = list("SS13") + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyN" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Research-Docking Bridge 2"; + dir = 1; + icon_state = "camera"; + network = list("SS13") + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_x = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyO" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyP" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyQ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyR" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyS" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyT" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyU" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyV" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Research-Docking Bridge 3"; + dir = 1; + icon_state = "camera"; + network = list("SS13") + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyW" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyX" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyY" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dyZ" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dza" = ( +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/machinery/camera{ + c_tag = "Research-Docking Bridge 4"; + dir = 1; + icon_state = "camera"; + network = list("SS13") + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dzb" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dzc" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dzd" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dze" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dzf" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dzg" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dzh" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dzi" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dzj" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dzk" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/space) +"dzl" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/space) +"dzm" = ( +/obj/structure/lattice, +/turf/open/space/basic, +/area/space) +"dzn" = ( +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/space, +/area/space) +"dzo" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/structure/grille, +/obj/structure/cable{ + d1 = 2; + d2 = 8; + icon_state = "2-8" + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 + }, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzp" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzq" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzr" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzs" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzt" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzu" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzv" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzw" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzx" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzy" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzz" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzA" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzB" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzC" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzD" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzE" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzF" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzG" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzH" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzI" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzJ" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzK" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzL" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzM" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzN" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzO" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzP" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzQ" = ( +/obj/machinery/camera{ + c_tag = "Core-Command-Cargo Bridge 1"; + dir = 8; + network = list("SS13") + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzR" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzS" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzT" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzU" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzV" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzW" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzX" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzY" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dzZ" = ( +/obj/machinery/light{ + dir = 8 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAa" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAb" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAc" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAd" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAe" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAf" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAg" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAh" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 8 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAi" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAj" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_y = 0 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAk" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 4 + }, +/obj/structure/cable{ + d1 = 4; + d2 = 8; + icon_state = "4-8"; + pixel_y = 0 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAl" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 9 + }, +/obj/structure/cable{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAm" = ( +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAn" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAo" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAp" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAq" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAr" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAs" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAt" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAu" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAv" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAw" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAx" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAy" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 4 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAz" = ( +/obj/structure/lattice/catwalk, +/obj/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 + }, +/obj/structure/grille, +/obj/structure/window/reinforced{ + dir = 1 + }, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAA" = ( +/obj/machinery/camera{ + c_tag = "Core-Command-Cargo Bridge 2"; + network = list("SS13") + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAB" = ( +/obj/machinery/camera{ + c_tag = "Core-Command-Cargo Bridge 3"; + network = list("SS13") + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAC" = ( +/obj/machinery/power/apc{ + dir = 1; + name = "Cargo-AI-Command Bridge APC"; + pixel_y = 24 + }, +/obj/structure/cable/orange{ + d2 = 4; + icon_state = "0-4" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAD" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAE" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAF" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAG" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAH" = ( +/obj/machinery/camera{ + c_tag = "Core-Command-Cargo Bridge 3"; + network = list("SS13") + }, +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAI" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAJ" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAK" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAL" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAM" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAN" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAO" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAP" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAQ" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/plasteel/neutral/corner{ + tag = "icon-neutralcorner (NORTH)"; + icon_state = "neutralcorner"; + dir = 1; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/fore) +"dAR" = ( +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/plasteel/neutral/corner{ + tag = "icon-neutralcorner (NORTH)"; + icon_state = "neutralcorner"; + dir = 1; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/fore) +"dAS" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 5 + }, +/obj/structure/cable/orange{ + d1 = 1; + d2 = 4; + icon_state = "1-4" + }, +/obj/structure/cable/orange{ + d1 = 4; + d2 = 8; + icon_state = "4-8" + }, +/turf/open/floor/plasteel/neutral/corner{ + tag = "icon-neutralcorner (NORTH)"; + icon_state = "neutralcorner"; + dir = 1; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/fore) +"dAT" = ( +/obj/effect/landmark/lightsout, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAU" = ( +/obj/machinery/light, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAV" = ( +/obj/machinery/light/small, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAW" = ( +/obj/machinery/light, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAX" = ( +/obj/machinery/light, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAY" = ( +/obj/machinery/light/small, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dAZ" = ( +/obj/machinery/light, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dBa" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dBb" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dBc" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dBd" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dBe" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dBf" = ( +/turf/closed/wall/r_wall, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dBg" = ( +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/structure/lattice/catwalk, +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 10 + }, +/obj/structure/grille, +/obj/structure/window/reinforced, +/turf/open/space, +/area/construction/hallway{ + name = "Cargo-AI-Command Bridge" + }) +"dBh" = ( +/obj/machinery/light{ + icon_state = "tube1"; + dir = 8 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dBi" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dBj" = ( +/obj/effect/landmark/lightsout, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Service Bridge" + }) +"dBk" = ( +/obj/machinery/light/small{ + brightness = 3; + dir = 8 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dBl" = ( +/obj/machinery/power/apc{ + dir = 4; + name = "Command-Engineering Bridge APC"; + pixel_x = 24; + pixel_y = 0 + }, +/obj/structure/cable{ + icon_state = "0-2"; + pixel_y = 1; + d2 = 2 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dBm" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dBn" = ( +/obj/effect/landmark/lightsout, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Medical-Cargo Bridge" + }) +"dBo" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dBp" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dBq" = ( +/obj/machinery/light{ + icon_state = "tube1"; + dir = 8 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dBr" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dBs" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dBt" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dBu" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Command-Engineering Bridge" + }) +"dBv" = ( +/obj/machinery/door/airlock/glass, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/turf/open/floor/plasteel/neutral/corner{ + tag = "icon-neutralcorner (EAST)"; + icon_state = "neutralcorner"; + dir = 4; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/central) +"dBw" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/turf/open/floor/plasteel/neutral/corner{ + tag = "icon-neutralcorner (EAST)"; + icon_state = "neutralcorner"; + dir = 4; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/central) +"dBx" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/turf/open/floor/plasteel/neutral/corner{ + tag = "icon-neutralcorner (EAST)"; + icon_state = "neutralcorner"; + dir = 4; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/central) +"dBy" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2"; + pixel_y = 0 + }, +/turf/open/floor/plasteel/neutral/corner{ + tag = "icon-neutralcorner (EAST)"; + icon_state = "neutralcorner"; + dir = 4; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/central) +"dBz" = ( +/obj/structure/cable{ + d1 = 1; + d2 = 8; + icon_state = "1-8" + }, +/turf/open/floor/plasteel/neutral/corner{ + tag = "icon-neutralcorner (EAST)"; + icon_state = "neutralcorner"; + dir = 4; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/central) +"dBA" = ( +/obj/effect/landmark/lightsout, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Docking-Medical Bridge" + }) +"dBB" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/turf/closed/wall/r_wall{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/construction/hallway{ + name = "Service-Science Bridge" + }) +"dBC" = ( +/obj/structure/disposalpipe/segment, +/obj/machinery/power/apc{ + dir = 4; + name = "Service-Science Bridge APC"; + pixel_x = 23; + pixel_y = 2 + }, +/obj/structure/cable, +/turf/open/floor/engine{ + baseturf = /turf/open/floor/plating/asteroid/airless; + name = "reinforced floor" + }, +/area/construction/hallway{ + name = "Service-Science Bridge" + }) +"dBD" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/structure/cable{ + d1 = 1; + d2 = 2; + icon_state = "1-2" + }, +/turf/closed/wall/r_wall{ + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/construction/hallway{ + name = "Service-Science Bridge" + }) +"dBE" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/engine{ + baseturf = /turf/open/floor/plating/asteroid/airless; + name = "reinforced floor" + }, +/area/construction/hallway{ + name = "Service-Science Bridge" + }) +"dBF" = ( +/obj/structure/disposalpipe/segment, +/turf/open/floor/engine{ + baseturf = /turf/open/floor/plating/asteroid/airless; + name = "reinforced floor" + }, +/area/construction/hallway{ + name = "Service-Science Bridge" + }) +"dBG" = ( +/obj/effect/landmark/lightsout, +/turf/open/floor/engine, +/area/construction/hallway{ + name = "Science-Docking Bridge" + }) +"dBH" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/disposalpipe/segment, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel/neutral/corner{ + tag = "icon-neutralcorner (NORTH)"; + icon_state = "neutralcorner"; + dir = 1; + baseturf = /turf/open/floor/plating/asteroid/airless + }, +/area/hallway/primary/fore) (1,1,1) = {" aaa @@ -108308,7 +113320,7 @@ abE aaa aaa aaa -aaa +cKF aaa aaa aaa @@ -109523,11 +114535,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +cKF +cKF +cKF +cKF +cKF aaa abC aaa @@ -109780,11 +114792,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +cKF +cKF +cKF +cKF +cKF aaa abC aaa @@ -110037,11 +115049,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +cKF +cKF +cKF +cKF +cKF aaa abC aaa @@ -110294,11 +115306,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +cKF +cKF +cKF +cKF +cKF aaa abC aaa @@ -110551,11 +115563,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +cKF +cKF +cKF +cKF +cKF aaa abC aaa @@ -110808,11 +115820,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +cKF +cKF +cKF +cKF +cKF aaa abC aaa @@ -110879,18 +115891,18 @@ aLm aXC aXS aXS +dsX aXS aXS aXS +dsX +aXS +aXS +dsX aXS aXS aXS -aXS -aXS -aXS -aXS -aXS -aXS +dsX aXS aXS aZM @@ -110964,16 +115976,16 @@ cfN cga cga cga +dBB +cga +cga +dBB +cga +cga +dBB cga cga cga -cgT -cgT -cgT -cgT -cgT -cgT -cgT ciD cjg cjg @@ -111065,11 +116077,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +cKF +cKF +cKF +cKF +cKF aaa abC abE @@ -111133,24 +116145,24 @@ aSU aVB aSU aSR -ary -ary -ary -ary -ary -ary -ary -ary -aYI -ary -ary -ary -ary -ary -ary -ary -ary -ary +dsV +dsV +dsV +dsV +dsV +dsV +dsV +dth +dsV +dsV +dtx +dsV +dsV +dsV +dsV +dsV +dsV +dsV baa baw baY @@ -111225,13 +116237,13 @@ cgp cfO cfO cgU -cgU -cgU -cgU -cgU -cgU -cgU -cgU +cfO +cfO +cgp +cfO +cfO +cfO +cfO cjh cjF cjF @@ -111390,24 +116402,24 @@ aRD aRD aRD aRP -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz +dsV +dsV +dsV +dsV +dsV +dsV +dsV +dsV +dBj +dsV +dty +dsV +dsV +dsV +dsV +dsV +dsV +dsV bab bax baZ @@ -111474,21 +116486,21 @@ bTq bax bax bab -cfP -cfP -cfP -cfP -cfP -cfP -cfP -cgV -cgV -cgV -cgV -cgV -cgV -cgV -cgV +cfO +cfO +cfO +cfO +cfO +cfO +cfO +cfO +cfO +cfO +cfO +cfO +cfO +cfO +cfO cji cjG cjG @@ -111591,7 +116603,7 @@ abE abW acH acH -abW +acO acO acO acO @@ -111647,26 +116659,26 @@ aSN aSN aSN aSP -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA +dsV +dsV +dsV +dsY +dsV +dsV +dsV +dti +dsV +dsV +dtz +dtG +dtG +dtG +dtQ +dtG +dtG +dtG bac -bay +duk bba bbA bbA @@ -111735,17 +116747,17 @@ cfQ cfQ cfQ cfQ -cfQ -cfQ -cfQ +dBC +dBE +dBE cgW -chd -chd -cho -chd -chd -chd -chd +dBE +dBE +dBE +dBE +dBE +dBE +dBE cjj cTY ckn @@ -111848,7 +116860,7 @@ abE abW acH acH -abW +acO acO acO acO @@ -111907,18 +116919,18 @@ aLm aXD aXD aXD +dsZ aXD aXD aXD +dsZ +aXD +aXD +dsZ aXD aXD aXD -aXD -aXD -aXD -aXD -aXD -aXD +dsZ aXD aXD aXD @@ -111992,16 +117004,16 @@ cfR cgb cgb cgb +dBD +cgb +cgb +dBD +cgb +cgb +dBD cgb cgb cgb -cgX -cgX -cgX -cgX -cgX -cgX -cgX ciE cjg cjg @@ -112105,7 +117117,6 @@ abE abW acH acH -abW acO acO adF @@ -112114,6 +117125,7 @@ aeB aeB aeB aeB +aeB agr doX doZ @@ -112362,10 +117374,10 @@ abW abW abW abW -abW acO acO -adG +dsd +aec aeb aeC aeY @@ -112610,7 +117622,7 @@ aaa aaa aaa aaa -aaa +cKF aaa aaa abE @@ -112619,15 +117631,15 @@ abW abW abW abW -abW acO acO -adH +dse aec aeD aeD aeD aeD +aeD agt acO acO @@ -112867,7 +117879,7 @@ aaa aaa aaa aaa -aaa +cKF aaa aaa abE @@ -112876,10 +117888,10 @@ abE abW abW abW -abW acO acO adI +dsf aed aeE aeZ @@ -113124,7 +118136,7 @@ aaa aaa aaa aaa -aaa +cKF aaa aaa abE @@ -113133,12 +118145,12 @@ abE abW abW abW -abW acO acO adJ aee aeF +aeD afa afu afO @@ -113381,7 +118393,7 @@ aaa aaa aaa aaa -aaa +cKF aaa aaa abE @@ -113390,12 +118402,12 @@ abE abW abW abW -abW acO acO adK aef aef +aee afb aee afP @@ -113647,10 +118659,10 @@ abE abW abW abW -abW acO acO -adL +adM +aef aef aef aef @@ -113904,12 +118916,12 @@ abE abW abW abW -abW acO acO adM aeg aeG +dsg afc afv aeG @@ -114161,7 +119173,6 @@ abE abW abW abW -abW acO acO doV @@ -114173,6 +119184,7 @@ acO acO acO acO +acO afr afr afr @@ -114418,7 +119430,6 @@ abE abW abW acH -acH acO acO acO @@ -114428,20 +119439,21 @@ acO acO acO acO -acO -acO -aiO -ajI +afr +afr +afr +dsr +dsm akB all alK amA ant +apr +apr aol apr apr -apr -aol asV apr apr @@ -114684,22 +119696,22 @@ abW abW abW abW -abW -agy -agy -aiP -ajJ -ajJ -alm afr +dsh +dsm +dss +ajJ +akt +alm +dsA amB -anp -aom -aps +dsB aqg anp -aom -asW +dsE +dsG +dsH +anp aqg anp aom @@ -114941,13 +119953,11 @@ abW abW abW abW -abW -agy -agz -aiQ -agA -ajJ -ajJ +afr +dsi +dsn +dsn +dsx afr amC anu @@ -114957,6 +119967,8 @@ amC ard aon alH +dsI +alH amC avf aon @@ -115198,13 +120210,11 @@ acH acH abW abW -abW -afR -afR -agA -agA -agA -agA +afr +dsj +dso +dst +dsx afr amD ann @@ -115214,6 +120224,8 @@ amD ann aoo alH +dsJ +alH amD ann aoo @@ -115454,14 +120466,12 @@ acH acH acH abW -acH -acH -afR -afR -agy -ajJ -agA -agA +abW +afr +dsk +dsp +dsp +dsz afr amE anv @@ -115471,6 +120481,8 @@ aqh ann ann alH +dsJ +alH auc ann ann @@ -115711,14 +120723,12 @@ acH acH acH abW -acH -acH -acH -afR -agz +abW +afr +dsl +dsj +dsj ahq -agA -agA afr amF anw @@ -115728,6 +120738,8 @@ aqi anw asb alH +aiP +alH aud anw awt @@ -115968,14 +120980,7 @@ abW acH acH acH -acH -afR -agy -agy -agA -agA -agA -agA +abW afr afr afr @@ -115990,6 +120995,13 @@ afr afr afr afr +dsL +afr +afr +afr +afr +afr +afr afr afr afr @@ -116225,23 +121237,23 @@ abW acH acH acH -afR +abW +abW +abW +abW +abW +abW +abW +agy +agy +agy +agy +agy agy agA agA -agA -agA -ajJ -agA +aiP agy -agy -agy -agy -agy -agy -agy -adZ -adZ adZ adZ adZ @@ -116482,26 +121494,26 @@ abW acH acH acH -afR -agz -ahq -agA -agA -agA -agA +acH +acH +acH +acH +acH +acH +acH agy aig agy +agz +dsC +agz +aiO +ajI +dsM agy -agA -agA -agy -agy -afS -afS -afS -afV -afV +adZ +adZ +adZ adZ adZ azY @@ -116739,28 +121751,28 @@ abW abW abW acH -afR -agA -agA -aie -agA -agA -akC -agz +acH +acH +acH +acH +acH +acH +acH +agy alL akD amG -amG -alN -agA +aiP +agz +dsF agy -afV -asX -aue -avg -afS -axD -afS +agy +agy +adZ +adZ +adZ +adZ +adZ azY aBs aCi @@ -116996,28 +122008,28 @@ abW abW abW acH -afR -agA -agA -agA -agA -agA -akD -aln +acH +acH +acH +acH +acH +acH +acH +agy alM amG anx -amG -amG +dsD +ajI akC agz -afV -aym -auf -aym afS -akp -aOF +afS +afS +afV +afV +axD +afS cJJ aBt aCj @@ -117253,13 +122265,13 @@ abW abW abW acH -afR -agy -agA -aif -aiR -ajK -agy +acH +acH +acH +acH +acH +acH +abW agy alN alN @@ -117269,11 +122281,11 @@ agA afR afR afV -asY -aym -cYZ -akH -axE +asX +aue +avg +afS +akp ayA azY aBu @@ -117340,9 +122352,9 @@ aZm bon bpM cRM -arz -arz -bvm +duE +duE +dvD bwV byz bzM @@ -117511,25 +122523,25 @@ abW abW acH acH -agy -agy -aig +abW +abW +acH +acH +acH +acH afR afR afR afR +aiR +ajK afR -afR -afR -afR -agy -afR -aez -afV -afV -afV -afV +acH afV +aym +auf +aym +afS akp cYo cJK @@ -117597,9 +122609,9 @@ bjB arw bpN cRM -arz -arz -bvm +duE +duE +dvD bwW bvm aZn @@ -117768,26 +122780,26 @@ abW abW abW abW -adZ -adZ -adZ -aez -aez -aez -aez -aez -aez -aez -aez -adZ -adZ -aez -adZ -aez -aez -adZ -afS -akp +abW +abW +abW +acH +acH +acH +acH +acH +acH +acH +acH +abW +abW +acH +afV +asY +aym +cYZ +akH +axE cZm cJK aBs @@ -117854,8 +122866,8 @@ aaa arw bpN cRM -arz -aSQ +duE +duE bvu bwX bjB @@ -118039,9 +123051,9 @@ aez aez aez aez -aez afV -afS +afV +afV afV afV cZj @@ -118109,10 +123121,10 @@ aaa aaa aaa arw -bpN -cRM -arz -aSQ +dum +duv +duE +duE bvv arw aaa @@ -118368,9 +123380,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +duE +dvF arw aaa aaa @@ -118625,9 +123637,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +duE +dvF arw aaa aaa @@ -118882,9 +123894,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +duE +dvF arw aaa aaa @@ -119139,9 +124151,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +duE +dvF arw aaa aaa @@ -119394,10 +124406,10 @@ aaa aaa aaa arw -bpN -cRM -arz -aSQ +dum +duv +duE +dvl bvv arw aaa @@ -119653,9 +124665,9 @@ aaa arw bpN cRM -arz -btV -bvv +duE +duE +dvF arw aaa aaa @@ -119910,9 +124922,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +duE +dvF arw aaa aaa @@ -120167,9 +125179,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +duE +dvF arw aaa aaa @@ -120424,9 +125436,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +duE +dvF arw aaa aaa @@ -120679,10 +125691,10 @@ aaa aaa aaa arw -bpN -cRM -arz -aSQ +dum +dux +duE +duE bvv arw aaa @@ -120938,9 +125950,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +duE +dvF arw aaa aaa @@ -121195,9 +126207,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +duE +dvF arw aaa aaa @@ -121452,9 +126464,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +duE +dvF arw aaa aaa @@ -121707,10 +126719,10 @@ aaa aaa aaa arw -bpN -cRM -arz -aSQ +dum +dux +duE +dvm bvv arw aaa @@ -121956,7 +126968,7 @@ aaa aaa aaa aaa -aaa +cKF aaa aaa abC @@ -121966,9 +126978,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +dvn +dvF arw aaa aaa @@ -122223,9 +127235,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +dvn +dvF arw aaa aaa @@ -122480,9 +127492,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +dvn +dvF arw aaa aaa @@ -122737,9 +127749,9 @@ aaa arw bpN cRM -arz -btW -bvv +duE +dvn +dvF arw aaa aaa @@ -122810,8 +127822,8 @@ cph cpM cqB crL -cjG -ctv +csz +dyJ cUn cjU ckB @@ -122992,10 +128004,10 @@ aaa aaa aaa arw -bpN -cRM -arz -aSQ +dum +duv +duE +dvq bvv arw aaa @@ -123251,9 +128263,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +dvn +dvF arw aaa aaa @@ -123263,24 +128275,24 @@ bAd byQ bEj dpl -dpm +dpl dpn dpo dpp dpq dpr -dps -dpt +dpr +dpr +dpu +dpr +dpr +dpu +dpr +dpr +dpr +dpr +dpu dpu -dpv -dpw -dpx -dpy -dpz -dpB -dpD -dpF -dpH caf bBN bBN @@ -123325,7 +128337,7 @@ cpO cmY cjF cjG -ctv +dyK cUn cjU dlF @@ -123508,9 +128520,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +dvn +dvF arw aaa aaa @@ -123582,7 +128594,7 @@ cpP cmY cjF cjG -ctv +dyK cUn cgN dlG @@ -123765,9 +128777,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +dvn +dvF arw aaa aZt @@ -124022,9 +129034,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +dvn +dvF arw aZt aZt @@ -124053,8 +129065,8 @@ bYp bXG bOM cbr -dpN -dpP +dpJ +dpL cMH byS cbr @@ -124277,10 +129289,10 @@ aZf aZf aaa arw -bpN -cRM -arz -aSQ +dum +duv +duE +dvn bvv arw aZt @@ -124311,8 +129323,8 @@ bXG bOM byS dfU -dpQ -dpS +dpJ +dpL byS cbr dgD @@ -124351,8 +129363,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk cgN @@ -124536,9 +129548,9 @@ aaa arw bpN cRM -arz -aSQ -bvv +duE +dvn +dvF arw aZf aZt @@ -124570,9 +129582,9 @@ bAd diS djs dpT -dpW -dpY -dqa +dpp +dpq +dpL cMH cMH byS @@ -124608,9 +129620,9 @@ aaa aaa arw cqC -aQS -arz -dlz +dwX +dwX +cUy cuk cgN cgN @@ -124793,9 +129805,9 @@ aZf arw bpN cRM -arz -aSQ -bvv +duE +dvn +dvF arw aZf aZt @@ -124865,8 +129877,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -125050,8 +130062,8 @@ aZf boo bpO cRM -arz -aSQ +duE +dvn bvw bwY aZf @@ -125086,7 +130098,7 @@ cMV cbr byS cbr -dqc +dqb djm bAd aZt @@ -125122,8 +130134,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -125343,7 +130355,7 @@ cbr dgD cNc dht -dqd +dqb djO byS aZH @@ -125378,11 +130390,11 @@ aaa aaa aaa arw -cqC -aQS -arz -cUy -cuk +dwO +dxb +dwX +dyM +dwO aaa aaa aXR @@ -125565,7 +130577,7 @@ boq cQD cSs baO -bhM +dvr bal cKO bal @@ -125600,7 +130612,7 @@ cMW cbr cMH bAd -dqe +dqb djP djl aZH @@ -125636,8 +130648,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -125822,7 +130834,7 @@ bor cQW baN baO -bhM +dvr bal bwZ bal @@ -125857,7 +130869,7 @@ bOM bOM bOM byS -dqf +dqb bAe cMH aZH @@ -125893,8 +130905,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -126114,13 +131126,13 @@ cbi cbi bOM dge -dqg +dqb +dqr +dqr +dqs +dqs +dqr dqr -dqJ -dqR -dqZ -drh -drp aaa aaa aaa @@ -126150,8 +131162,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -126371,13 +131383,13 @@ cbj cbP bOM dfU -dqh +dqb dqs dqK dqS dra dri -drq +dqr aaa aaa aaa @@ -126407,8 +131419,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -126593,7 +131605,7 @@ bcY cQW baN baO -bhM +dvr bal bxa bcp @@ -126628,18 +131640,18 @@ cbi cbi bOM cbr -dqi -dqt +dqb +dqr +dqL dqL -dqT drb drj drr drx drD -drJ -drP -drV +drD +drD +drD drZ aaa aaa @@ -126663,11 +131675,11 @@ aaa aaa aaa arw -cqC -aQS -arz +dwO +dxg +dwX ctA -cuk +dwO abC abC aXR @@ -126892,10 +131904,10 @@ dqU drc drk drs -dry -drE +drs +drs drK -drQ +drO arw arw aaa @@ -126921,8 +131933,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -127143,17 +132155,17 @@ cbk bOM cbr dqk -dqv +dqr dqN dqV drd drl drt drz -drF +drt drL -drR -drW +drO +drO dsa aaa aaa @@ -127178,8 +132190,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -127399,8 +132411,8 @@ cbl cbQ bOM cbr -dql -dqw +dqk +dqs dqO dqW dre @@ -127435,8 +132447,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -127657,18 +132669,18 @@ cbk bOM cbr dqm -dqx +dqs dqP dqX drf drn drv drB -drH +drv drN -drT -drY -dsc +drO +drO +dsa aaa aaa aaa @@ -127692,8 +132704,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk abC @@ -127913,17 +132925,17 @@ bOM bOM bOM cbr -dqn -dqy -dqQ -dqY -drg -dro -drw -drC -drI +dqk +dqr +dqr +dqr +dqs +dqr +drs +drs +drs +drO drO -drU arw arw aaa @@ -127948,11 +132960,11 @@ aaa aaa aaa arw -cqC -aQS -arz +dwO +dxb +dwX cUy -cuk +dwO aaa aaa aXR @@ -128170,7 +133182,7 @@ cbm cbm bOM djs -dqo +dqk dgE byS aZH @@ -128206,8 +133218,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -128463,8 +133475,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -128720,8 +133732,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -128976,11 +133988,11 @@ aaa aaa aaa arw -cqC -aQS -arz -cUy -cuk +dwO +dxg +dwX +dyN +dwO aaa aaa aXR @@ -129199,7 +134211,7 @@ cbo bOM djG bAd -dqB +dqk bBN aZH aZt @@ -129234,10 +134246,10 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy -cuk +cqC aaa aaa aXR @@ -129440,7 +134452,7 @@ bOZ dhQ did div -bTM +dsN bUM bVM bRs @@ -129456,7 +134468,7 @@ cbS bOM bAd byS -dqC +dqk byS aZH aZH @@ -129491,8 +134503,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -129697,7 +134709,7 @@ dhF bQz die diw -bTM +dsO bUN bJx bTH @@ -129713,7 +134725,7 @@ cbo bOM bAd cMH -dqD +dqk byS aZH aZH @@ -129748,8 +134760,8 @@ aaa aaa arw cqC -aQS -arz +dwX +dwX cUy cuk aaa @@ -129954,7 +134966,7 @@ bPb dhS dif bSM -bTM +dsP bUO bVN bWA @@ -129970,7 +134982,7 @@ bOM bOM bAd bAd -dqE +dqk bBN aZH aZH @@ -130004,11 +135016,11 @@ aaa aaa aaa arw -cqC -aQS -arz +dwO +dxb +dwX ctB -cuk +dwO abC abC aXR @@ -130154,18 +135166,18 @@ aLm aXI aXX aXX +dta aXX aXX aXX +dta +aXX +aXX +dta aXX aXX aXX -aXX -aXX -aXX -aXX -aXX -aXX +dta aXX aXX aZT @@ -130227,7 +135239,7 @@ byS bAd byS cbr -dqF +dqk bBN aZH aZH @@ -130262,9 +135274,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dBG +dyO cuk aaa aaa @@ -130408,24 +135420,24 @@ aSU aSU aSU aSR -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary +dsW +dsW +dsW +dBh +dsW +dsW +dsW +dBi +dsW +dsW +dBi +dsW +dsW +dsW +dBh +dsW +dsW +dsW ban baN cQE @@ -130484,7 +135496,7 @@ djv byS bPt byP -dqG +dqk djk aZH aZt @@ -130519,9 +135531,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aaa @@ -130730,18 +135742,18 @@ bUR bVQ bWD dpA -dpC -dpE -dpG -dpI +dpA +dpA +dpA +dpA dpK -dpO -dpR +dpA +dpA dpU djw byP byP -dqH +dqk cMH aZH aZt @@ -130776,10 +135788,10 @@ aaa aaa arw cqC -aQS -arz -cUy -cuk +dwX +dwX +dyO +cqC aaa aaa aXR @@ -130922,31 +135934,31 @@ aSN aSN aSN aSP -arA -arA -arA -arA -arA -arA -arA -arA -aYK -arA -arA -arA -arA -arA -arA -arA -arA -arA -bap +dsW +dsW +dsW +dsW +dsW +dsW +dsW +dtl +dsW +dsW +dBl +dBm +dBm +dBm +dBm +dBm +dBm +dBm +dBv cQA -baP -baP +dBw +dBw bcq -baP -baP +dBw +dBz bek baP bfX @@ -130996,8 +136008,8 @@ cbr byP dpV dpX -dpZ -dqq +dpX +dpX dqI byS aZH @@ -131032,11 +136044,11 @@ aaa aaa aaa arw -cqC -aQS -arz -cUy -cuk +dwO +dxg +dwX +dyO +dwO abC abC aXR @@ -131182,18 +136194,18 @@ aLm aXJ aXY aXY +dtb aXY aXY aXY +dtb +aXY +aXY +dtb aXY aXY aXY -aXY -aXY -aXY -aXY -aXY -aXY +dtb aXY aXY aZU @@ -131290,9 +136302,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aaa @@ -131547,9 +136559,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aaa @@ -131804,9 +136816,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aaa @@ -132060,11 +137072,11 @@ aaa aaa aaa arw -cqC -aQS -arz -cUy -cuk +dwO +dxb +dwX +dyV +dwO aaa aaa aXR @@ -132318,9 +137330,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aaa @@ -132575,9 +137587,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aaa @@ -132832,9 +137844,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aaa @@ -133089,9 +138101,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk abC abC @@ -133345,11 +138357,11 @@ aaa aaa aaa arw -cqC -aQS -arz -ctC -cuk +dwO +dxg +dwX +dyO +dwO aaa aaa aXR @@ -133603,9 +138615,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aaa @@ -133860,9 +138872,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aaa @@ -134117,9 +139129,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk abC abC @@ -134374,9 +139386,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aaa @@ -134630,11 +139642,11 @@ aaa aaa aaa arw -cqC -aQS -arz -cUy -cuk +dwO +dxb +dwX +dza +dwO aaa aaa aXR @@ -134817,7 +139829,7 @@ boB bal baP cSv -bhP +dvu bvU bxw cbr @@ -134888,9 +139900,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aaa @@ -135145,9 +140157,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aaa @@ -135402,9 +140414,9 @@ aaa aaa arw cqC -aQS -arz -dlA +dwX +dwX +dyO cuk aaa aXR @@ -135476,37 +140488,37 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaf -aaf -aaf -aeh -aeh -aeh -aeh -aeh -aeh -aaa -aaa -ahT -ajS -ahT +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +abC aaa aaa aaa @@ -135520,8 +140532,8 @@ aaa aaa abC aaa -aaa -aaa +cKF +cKF aaa aaa aaa @@ -135588,7 +140600,7 @@ boE bal baP cSv -bhP +dvu bal bxz byS @@ -135659,9 +140671,9 @@ aaa aaa arw cqC -aQS -arz -cUy +dwX +dwX +dyO cuk aaa aXR @@ -135748,28 +140760,28 @@ aaa aaa aaa aaa -aaf -aaf -adg -adg -adg -adg -adg +aaa +aaa aaf aaf aaf -adg -adg -adg -adg -ajT +aeh +aeh +aeh +aeh +aeh +aeh +aaa +aaa ahT -aaa -aaa -aaa -aaa -aaa -aaa +ajS +ahT +cKF +cKF +cKF +cKF +cKF +cKF aaa aaa aaa @@ -135777,9 +140789,9 @@ aaa aaa abC aaa -aaa -aaa -aaa +cKF +cKF +cKF aaa aaa abW @@ -135845,7 +140857,7 @@ boF bal brr cSv -bhP +dvu bal bxA cMH @@ -136002,25 +141014,25 @@ aaa aaa aaa aaa +aaa +aaa +aaa +aaf +aaf +adg +adg +adg +adg +adg aaf aaf aaf -aaf -aaf -adg -adt -adt -adt adg adg adg adg -adg -adt -adt -adt ajT -aae +ahT aaa aaa aaa @@ -136034,9 +141046,9 @@ aaa aaa abC aaa -aaa -aaa -aaa +cKF +cKF +cKF aaa aaa abW @@ -136050,9 +141062,9 @@ abW aaa aOu aPm -aQS -arz -aSQ +ary +ary +ary aTC aUB aaa @@ -136256,28 +141268,27 @@ aaa aaa aaa aaa -aae -aae -aae -aae -aae -aae -aae -aae +aaa +aaa +aaa +aaf +aaf +aaf +aaf +aaf adg adt -adN -aei -aeH adt -afz adt -agV -ahJ -aip +adg +adg +adg +adg +adg adt -ajU -aae +adt +adt +ajT aae aaa aaa @@ -136289,11 +141300,12 @@ aaa aaa aaa aaa +aaa abC aaa -aaa -aaa -aaa +cKF +cKF +cKF aaa aaa aaa @@ -136307,9 +141319,9 @@ abW aaa arw aPn -aQS -arz -aSQ +ary +ary +ary aTD arw aaa @@ -136359,7 +141371,7 @@ boH bpV aQS cSC -aSQ +dvx bvV bxB aZt @@ -136508,9 +141520,9 @@ aaa aaa aaa aaa -aaf -aaf -aaf +aaa +aaa +aaa aaa aaa aae @@ -136523,19 +141535,19 @@ aae aae adg adt -adO -aej -aeI -afd -afA -afd -agW -ahK -aiq +adN +aei +aeH adt -ajT +afz +adt +agV +ahJ +aip +adt +ajU +aae aae -aaf aaa aaa aaa @@ -136548,9 +141560,9 @@ aaa aaa abC aaa -aaa -aaa -aaa +cKF +cKF +cKF aaa aaa aaa @@ -136564,9 +141576,9 @@ aaa aaa arw aPn -aQS -arz -aSQ +ary +ary +ary aTD arw aaa @@ -136616,7 +141628,7 @@ arw bpW aQS cSC -aSQ +dvx bvW arw aZt @@ -136764,12 +141776,12 @@ aaa aaa aaa aaa +aaa aaf aaf -aae -aae -aae -aae +aaf +aaa +aaa aae aae aae @@ -136779,22 +141791,22 @@ aae aae aae adg -adu adt +adO +aej +aeI +afd +afA +afd +agW +ahK +aiq adt -adt -adt -afB -afX -adt -adt -adt -aje ajT -aaf -aaf -aaf aae +aaf +aaa +aaa aaa aaa aaa @@ -136805,9 +141817,9 @@ aaa aaa abC aaa -aaa -aaa -aaa +cKF +cKF +cKF aaa aaa aaa @@ -136821,9 +141833,9 @@ aaa aaa arw aPn -aQS -arz -aSQ +ary +ary +ary aTD arw aaa @@ -136873,7 +141885,7 @@ arw bpW aQS cSC -aSQ +dvx bvW arw aZt @@ -137020,15 +142032,15 @@ aaa aaa aaa aaa -aae -aae -aae -aae -aae -aae -aae -aae +aaa aaf +aaf +aae +aae +aae +aae +aae +aae aae aae aae @@ -137036,23 +142048,23 @@ aae aae aae adg -adv -adP -aek -aeJ -afe -afC -afd -afd -ahL -air -ajf +adu +adt +adt +adt +adt +afB +afX +adt +adt +adt +aje ajT aaf aaf aaf aae -aaf +aaa aaa aaa aaa @@ -137062,9 +142074,9 @@ aaa aaa abC aaa -aaa -aaa -aaa +cKF +cKF +cKF aaa aaa aaa @@ -137077,11 +142089,11 @@ aaa aaa aaa arw -aPn -aQS -arz -aSQ -aTD +dAj +dAA +ary +dAU +dBa arw aaa aaa @@ -137127,11 +142139,11 @@ aaa abC aaa arw -bpW -aQS +dus +duB cSC -aSQ -bvW +dvA +dwa arw aZt aZt @@ -137276,7 +142288,7 @@ aaa aaa aaa aaa -aaf +aaa aae aae aae @@ -137286,28 +142298,28 @@ aae aae aae aaf -aaf -aaf -aaf -aaf -aaf -aaf -adg -adg -adQ -ael -aeK -adS -afD -adS -adt -ahM -ais +aae +aae +aae +aae +aae +aae adg +adv +adP +aek +aeJ +afe +afC +afd +afd +ahL +air +ajf ajT -aae aaf -aae +aaf +aaf aae aaf aaa @@ -137319,9 +142331,9 @@ aaa aaa abC aaa -aaa -aaa -aaa +cKF +cKF +cKF aaa aaa aaa @@ -137335,9 +142347,9 @@ aaa aaa arw aPn -aQS -arz -aSQ +ary +ary +ary aTD arw aaa @@ -137387,7 +142399,7 @@ arw bpW aQS cSC -buu +dvx bvW arw aaa @@ -137534,39 +142546,38 @@ aaa aaa aaa aaf +aae +aae +aae +aae +aae +aae +aae +aae +aaf +aaf aaf aaf -aal -aal -aal -aal -aal -aal -aal -aal -aal -aal -aal aaf aaf aaf adg -adR -aem -aeL -adS -afE -adS -adt -adt -adt adg -ajV -aae -aae -aae +adQ +ael +aeK +adS +afD +adS +adt +ahM +ais +adg +ajT aae aaf +aae +aae aaf aaa aaa @@ -137574,6 +142585,15 @@ aaa aaa aaa aaa +aaa +abC +aaa +cKF +cKF +cKF +aaa +aaa +aaa abC aaa aaa @@ -137581,20 +142601,12 @@ aaa aaa aaa aaa -aaa -abC -aaa -aaa -aaa -aaa -aaa -aaa -aaa +cKF arw aPn -aQT -arz -aSQ +ary +ary +ary aTD arw aaa @@ -137644,7 +142656,7 @@ arw bpW aQS cSC -aSQ +dvx bvW arw aaa @@ -137792,8 +142804,7 @@ aaa aaa aaf aaf -aal -aal +aaf aal aal aal @@ -137807,17 +142818,18 @@ aal aal aaf aaf -adw +aaf +adg +adR +aem +aeL adS +afE adS -adS -adS -afF -adS -adS -adS -adS -adw +adt +adt +adt +adg ajV aae aae @@ -137825,7 +142837,7 @@ aae aae aaf aaf -aaf +aaa aaa aaa aaa @@ -137833,9 +142845,9 @@ aaa aaa abC aaa -aaa -aaa -aaa +cKF +cKF +cKF aaa aaa aaa @@ -137849,9 +142861,9 @@ aaa aaa arw aPn -aQS -arz -aSQ +ary +ary +ary aTD arw aaa @@ -137901,7 +142913,7 @@ arw bpW aQS cSC -aSQ +dvx bvW arw aaa @@ -138051,35 +143063,35 @@ aaf aaf aal aal -aau -aax -aax -abl -aax -abM -aax -aax -aaw +aal +aal +aal +aal +aal +aal +aal +aal aal aal aal aaf +aaf adw -adT -aen -aeM adS -afG -afY -agX -ahN -ait +adS +adS +adS +afF +adS +adS +adS +adS adw ajV aae aae -aaf -aaf +aae +aae aaf aaf aaf @@ -138090,9 +143102,9 @@ aaa aaa abC aaa -aaa -aaa -aaa +cKF +cKF +cKF aaa aaa aaa @@ -138106,9 +143118,9 @@ aaa aaa arw aPn -aQS -arz -aSQ +ary +ary +ary aTD arw aaa @@ -138158,7 +143170,7 @@ arw bpW aQS cSC -aSQ +dvx bvW arw aaa @@ -138303,34 +143315,34 @@ aaa aaa aaa aaa -aae -aae -aae +aaa +aaf +aaf aal aal -aav +aau aax -aaw -aaw -abx aax +abl +aax +abM aax aax aaw -acL -cJi aal aal aal -adU -aeo +aaf +adw +adT +aen aeM -aff -aeM -afZ -agY -aeM -aiu +adS +afG +afY +agX +ahN +ait adw ajV aae @@ -138347,9 +143359,9 @@ aaa aaa abC aaa -aaa -aaa -aaa +cKF +cKF +cKF aaa aaa aaa @@ -138362,11 +143374,11 @@ aaa aaa aaa arw -aPn -aQS -arz -aSQ -aTD +dAj +ary +ary +dAV +dBa arw aaa aaa @@ -138412,11 +143424,11 @@ aaa abC aaa arw -bpW -aQS +dus +duC cSC -aSQ -bvW +dvB +dwa arw aaa aaa @@ -138565,36 +143577,36 @@ aae aae aal aal -aaw -aaE -aaS -cJk -aaX -abN -abZ -acn -acu +aav aax aaw +aaw +abx +aax +aax +aax +aaw +acL +cJi aal aal aal -aal -aal -aal -aal -aal -aga -agZ -ahO -aiv +adU +aeo +aeM +aff +aeM +afZ +agY +aeM +aiu adw -ajW -akI -akI -akI -akI -akI +ajV +aae +aae +aaf +aaf +aaf aaf aaf aaa @@ -138604,9 +143616,9 @@ aaa aaa abC aaa -aaa -aaa -aaa +cKF +cKF +cKF aaa aaa aaa @@ -138620,9 +143632,9 @@ aaa aaa arw aPn -aQS -arz -aSQ +ary +ary +ary aTD arw aaa @@ -138672,7 +143684,7 @@ arw bpW aQS cSC -aSQ +aQS bvW arw aaa @@ -138821,39 +143833,39 @@ aae aae aae aal -cJi +aal aaw -aaF -aaT -aax -aby +aaE +aaS +cJk aaX -aca +abN +abZ +acn +acu aax -acv -aax -dnz +aaw aal -adh -adx -adh -adh -adh -adh aal -agb -aha -ahP -aiw +aal +aal +aal +aal +aal +aal +aga +agZ +ahO +aiv adw -ajX -akJ -akJ -akJ -amY +ajW akI akI akI +akI +akI +aaf +aaf aaa aaa aaa @@ -138862,8 +143874,8 @@ aaa abC aaa aaa -aaa -aaa +cKF +cKF aaa aaa aaa @@ -138877,9 +143889,9 @@ aaa aaa arw aPn -aQS -arz -aSQ +ary +ary +ary aTD arw aaa @@ -138929,7 +143941,7 @@ arw bpW aQS cSC -aSQ +aQS bvW arw aaa @@ -139078,65 +144090,65 @@ aae aae aae aal -aal +cJi +aaw +aaF +aaT aax -aaG -aaU -abm -abm -abO +aby aaX +aca aax acv aax -aau +dnz aal -cJi +adh +adx +adh +adh +adh +adh aal -aal -aal -aal -cJi -aal -agc -ahb -aeM -aix +agb +aha +ahP +aiw adw -ajY -akK -als -als -amZ -anJ -aoO -apK -aqI -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw +ajX +akJ +akJ +akJ +amY +akI +akI +akI +cKF +cKF +cKF +cKF +cKF +abC +cKF +cKF +cKF +cKF +cKF +cKF +cKF +abC +cKF +cKF +cKF +cKF +cKF +cKF +cKF arw aPn -aQS -arz -aSQ +ary +ary +ary aTD arw aaa @@ -139186,7 +144198,7 @@ arw bpW aQS cSC -aSQ +aQS bvW arw aaa @@ -139337,63 +144349,63 @@ aae aal aal aax -aaH -aaS -abn -aaS -abP -aax +aaG +aaU +abm +abm +abO aaX -acw aax -acP +acv +aax +aau aal -aaw -ady -adV -aaw -ady -aaw +cJi aal -agd -ahc +aal +aal +aal +cJi +aal +agc +ahb +aeM +aix adw -adw -adw -agk -akL -akI -akI -akI -akI -akI -akI -akI -arx -arx -arx -arx -arx -arx -arx -arx -arx -arx -arx -arx -arx -arx -arx -arx -arx -arx -arx -arx -arx -aPo -aQS -arz -aSQ +ajY +akK +als +als +amZ +anJ +aoO +apK +baR +aqI +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +aPn +ary +ary +ary aTD arw abC @@ -139443,7 +144455,7 @@ arw bpW aQS cSC -dfN +aQS bvW arw aaa @@ -139593,65 +144605,65 @@ aae aae aal aal -aaw -aaI -aaS -aaS -aaS +aax aaH -aaE aaS -acx -abZ -abZ -acR -adi -adi -adi -adi -aeN -adi -acR -age -ahd -ahQ -aiy -ajg -ahQ -akM -alt -alt -ana -alt -alt -apL -aqJ +abn +aaS +abP +aax +aaX +acw +aax +acP +aal +aaw +ady +adV +aaw +ady +aaw +aal +agd +ahc +adw +adw +adw +agk +akL +akI +akI +akI +akI +akI +akI +akI +dzo +dzq +dzq +dzq +dzw +dzq +dzq +dzq +dzw +dzq +dzq +dzq +dzw +dzq +dzq +dzq +dzw +dzq +dzq +dzq +dzq +dAl +dAB ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -arz -arz -aSQ -aTD +dAU +dBa arw aaa aaa @@ -139697,11 +144709,11 @@ aaa abC aaa arw -bpW -aQS +dus +duB cSC -aSQ -bvW +dvC +dwa arw aaa aaa @@ -139850,67 +144862,67 @@ aae aae aal aal -aay -aaJ -aaV +aaw +aaI aaS -abz -abQ -acb -aco -acy -acK -abm -acS -adj -adz -adj -aep -aeO -adj -acS -agf -ahe -agk -aiz -ajh -agk -akN -alu -amc -anb -amc -amc -apM -aqK -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -dbJ +aaS +aaS +aaH +aaE +aaS +acx +abZ +abZ +acR +adi +adi +adi +adi +aeN +adi +acR +age +ahd +ahQ +aiy +ajg +ahQ +akM +alt +alt +ana +alt +alt +apL +aqJ +ary +ary +ary +ary +dzx +ary +ary +ary +dzG +ary +ary +ary +dzx +ary +ary +ary +dzG +ary +ary +ary +ary +dzx +ary +ary +ary aTD arw -aaa +cKF aaa aaa aaa @@ -139957,7 +144969,7 @@ arw bpW aQS cSC -aSQ +aQS bvW arw aaa @@ -140107,64 +145119,64 @@ aae aae aal aal -aaw -aaK -aaW +aay +aaJ +aaV aaS -aaS -aaw -aaE -aaS -acz -acc -acc -acT -adk -adA -adk -adk -adk -adk -acT -agg -ahf -ahR -aiA -aji -ahR -akO -alv -amd -anc -anK -amd -amd -aqL -arA -arA -arA -arA -arA -axa -arA -arA -arA -arA -arA -arA -arA -arA -arA -aJo -arA -arA -arA -arA -arA -arA -arz -arz -aSQ +abz +abQ +acb +aco +acy +acK +abm +acS +adj +adz +adj +aep +aeO +adj +acS +agf +ahe +agk +aiz +ajh +agk +akN +alu +amc +anb +amc +amc +apM +aqK +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +dAT +ary aTD arw aaa @@ -140214,7 +145226,7 @@ arw bpW aQS cSC -aSQ +aQS bvW arw aaa @@ -140364,64 +145376,64 @@ aae aae aal aal -aax aaw +aaK +aaW aaS -abo aaS -abR -aax -aaX -acA -aax -acP -aal -adl -adB aaw -aaw -adB -adl -aal -agh -ahg -agk -agk -agk -agk -akP -akI -akI -akI -akI -akI -akI -akI +aaE +aaS +acz +acc +acc +acT +adk +adA +adk +adk +adk +adk +acT +agg +ahf +ahR +aiA +aji +ahR +akO +alv +amd +anc +anK +amd +amd +aqL +ary +ary +ary +ary arB -arB -arB -arB -arB -arB -arB -arB -arB -arB -arB -arB -arB -arB -arB -arB -arB -arB -arB -arB -arB -aPp -aQS -arz -aSQ +ary +ary +ary +ary +ary +ary +ary +dzQ +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary +ary aTD arw aaa @@ -140471,7 +145483,7 @@ boI bpX aQS cSC -aSQ +aQS bvX bxC aaa @@ -140623,63 +145635,63 @@ aal aal aax aaw -aaX -aaw -aaw -aaw -aaX +aaS +abo +aaS +abR aax -acB +aaX +acA aax -aau +acP aal +adl +adB +aaw +aaw +adB +adl aal -aal -aal -aal -aal -aal -aal -agi -ahh -ahS -aiB +agh +ahg agk -ajZ -akQ -alw -ame -ame -anL -aoP -apN -aqM -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw +agk +agk +agk +akP +akI +akI +akI +akI +akI +akI +akI +dzp +dzp +dzp +dzp +dzy +dzp +dzp +dzp +dzy +dzp +dzp +dzp +dzy +dzp +dzp +dzp +dzy +dzp +dzp +dzp +dzp aPq -aQS -arz -aSQ -aTD +dAC +ary +dAU +dBa arw aaa aaa @@ -140877,65 +145889,65 @@ aae aae aae aal -cJi -aaw -aaF -aaT +aal aax -aby +aaw +aaX +aaw +aaw +aaw aaX -aca aax acB aax -aaw +aau aal -adh -adh -adh -aeq -adh -adh aal -agj -ahi -cYe +aal +aal +aal +aal +aal +aal +agi +ahh +ahS aiB agk -ajX -akJ -akJ -akJ -akJ -akI -akI -akI -abC -aaa -aaa -aaa -aaa -aaa -aaa -aaa -abC -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -abC -aaa -aaa -aaa +ajZ +akQ +alw +ame +ame +anL +aoP +apN +dzn +aqM arw -aPq -aQS -arz -aSQ +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +dAn +dAD +ary +ary aTD arw aaa @@ -141130,43 +146142,43 @@ aaa aaa aaa aaa -aaf -aaf -aaf -aal +aae +aae +aae aal +cJi aaw -aaE -aaS -cJk +aaF +aaT +aax +aby aaX -abS -acc -acp -acC +aca +aax +acB aax aaw aal +adh +adh +adh +aeq +adh +adh aal -aal -aal -aal -aal -aal -aal +agj +ahi +cYe +aiB agk -agk -agk -agk -agk -ajW +ajX +akJ +akJ +akJ +akJ akI akI akI -akI -akI -aaf -aaa abC aaa aaa @@ -141189,10 +146201,10 @@ aaa aaa aaa arw -aPq -aQS -arz -aSQ +dAn +dAD +ary +ary aTD arw aaa @@ -141387,42 +146399,50 @@ aaa aaa aaa aaa +aaf +aaf +aaf +aal +aal +aaw +aaE +aaS +cJk +aaX +abS +acc +acp +acC +aax +aaw +aal +aal +aal +aal +aal +aal +aal +aal +agk +agk +agk +agk +agk +ajW +akI +akI +akI +akI +akI +aaf aaa -aaf -aaf -aal -aal -aaz -aax -aaw -aaw -abA -aax -aax -aax -aaw -acL -cJi -aal -aal -aaf -aaf -aaf -aaf -aaf -aaf -aaf -aaf -aaf -aaf -aaf -ajV -aaf -aaf -aaf -aaf -aaf -aaf +abC +aaa +aaa +aaa +aaa +aaa +cKF aaa abC aaa @@ -141432,24 +146452,16 @@ aaa aaa aaa aaa -abC -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +cKF abC aaa aaa aaa arw -aPq -aQS -arz -aSQ +dAn +dAD +ary +ary aTD arw aaa @@ -141649,25 +146661,25 @@ aaf aaf aal aal -aau -aaL +aaz aax -abp -aax -abM -aax -aaL aaw -aal +aaw +abA +aax +aax +aax +aaw +acL +cJi aal aal aaf aaf -aae -aae -aae -aae -aae +aaf +aaf +aaf +aaf aaf aaf aaf @@ -141703,10 +146715,10 @@ aaa aaa aaa arw -aPq -aQS -arz -aSQ +dAn +dAD +ary +ary aTD arw aaa @@ -141906,18 +146918,18 @@ aaf aaf aal aal +aau +aaL +aax +abp +aax +abM +aax +aaL +aaw aal aal aal -aal -aal -aal -aal -aal -aal -aal -aal -aaf aaf aaf aae @@ -141960,11 +146972,11 @@ aaa aaa aaa arw -aPq -aQS -arz -aSQ -aTD +dAr +dAH +ary +dAV +dBa arw aaa aaa @@ -142159,7 +147171,6 @@ aaa aaa aaa aaa -aaa aaf aaf aal @@ -142173,24 +147184,25 @@ aal aal aal aal +aal +aal +aaf +aaf +aaf +aae +aae +aae +aae +aae aaf aaf aaf aaf -aae -aae -aae -aae -aae -aae -aae -aae -aae aaf ajV aaf -aae -aae +aaf +aaf aaf aaf aaf @@ -142215,12 +147227,12 @@ aaa abC aaa aaa -aaa +cKF arw -aPq -aQU -arz -aSQ +dAn +dAD +ary +ary aTD arw aaa @@ -142419,15 +147431,17 @@ aaa aaa aaf aaf -aaf -aaf -aaf -aaf -aaf -aaf -aaf -aaf -aaf +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal +aal aaf aaf aaf @@ -142438,8 +147452,6 @@ aae aae aae aae -aaf -aae aae aae aae @@ -142450,7 +147462,7 @@ aae aae aaf aaf -aaa +aaf aaa abC aaa @@ -142462,22 +147474,22 @@ aaa aaa abC aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +cKF +cKF +cKF +cKF +cKF +cKF +cKF abC aaa aaa aaa arw -aPq -aQS -arz -aSQ +dAn +dAD +ary +ary aTD arw aaa @@ -142677,18 +147689,18 @@ aaa aaf aaf aaf -aae -aae -aae -aae -aae aaf aaf aaf aaf -aae -aae -aae +aaf +aaf +aaf +aaf +aaf +aaf +aaf +aaf aae aae aae @@ -142703,10 +147715,10 @@ aae aaf ajV aaf +aae +aae +aaf aaf -aaa -aaa -aaa aaa aaa abC @@ -142731,10 +147743,10 @@ aaa aaa aaa arw -aPq -aQS -arz -aSQ +dAn +dAD +ary +ary aTD arw aaa @@ -142931,11 +147943,6 @@ aaa aaa aaa aaa -aaa -aaa -aaf -aaf -aaf aaf aaf aaf @@ -142944,7 +147951,10 @@ aae aae aae aae -aae +aaf +aaf +aaf +aaf aae aae aae @@ -142955,11 +147965,13 @@ aae aae aae aaf +aae +aae +aae +aae aaf +ajV aaf -ahT -aka -ahT aaf aaa aaa @@ -142988,10 +148000,10 @@ aaa aaa aaa arw -aPq -aQS -arz -aSQ +dAn +dAD +ary +ary aTD arw aaa @@ -143071,17 +148083,17 @@ bYL bZn bZn bZn +dwp bZn bZn bZn bZn +dwp bZn bZn bZn bZn -bZn -bZn -bZn +dwp bZn bZn bZn @@ -143190,11 +148202,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +aaf +aaf +aaf +aaf +aaf aaf aae aae @@ -143215,9 +148227,9 @@ aaf aaf aaf ahT -akb +aka ahT -aaa +aaf aaa aaa aaa @@ -143245,19 +148257,19 @@ aaa aaa aaa arw -aPq -aQS -arz -aSQ -aTD +dAr +dAD +ary +dAU +dBa arw aaa aaa -aaa -aaa -alx -alx -alx +cKF +cKF +cKF +cKF +cKF aaa aaa aaa @@ -143324,25 +148336,25 @@ bVU buw bXj buv -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary -ary +dwd +dwd +dwd +dwd +dwq +dwd +dwd +dwd +dwd +dwx +dwd +dwd +dwd +dwd +dwq +dwd +dwd +dwd +dwd buv bXj buw @@ -143452,7 +148464,7 @@ aaa aaa aaa aaa -aaa +aaf aae aae aae @@ -143470,26 +148482,26 @@ aae aae aaf aaf +aaf +ahT +akb +ahT +aaa +aaa +aaa +aaa aaa aaa abC -aaa -aaa -aaa -aaa -aaa -aaa -alx -alF -alx -alx -alx -alx -alx -aaa -aaa +cKF +cKF +cKF +cKF +cKF +cKF +cKF abC -aaa +cKF aaa aaa aaa @@ -143502,16 +148514,16 @@ aaa aaa aaa arw -aPq -aQS -arz -aSQ +dAn +dAD +ary +ary aTD arw aaa aaa aaa -alx +aaa alx alx alx @@ -143581,25 +148593,25 @@ bbs bbs bbs baU -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz +dwd +dwd +dwd +dwd +dwd +dwd +dwd +dwd +dwd +dBA +dwd +dwd +dwd +dwd +dwd +dwd +dwd +dwd +dwd baU bbs cgk @@ -143710,13 +148722,15 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +aae +aae +aae +aae +aae +aae +aae +aae +aae aae aae aae @@ -143725,44 +148739,42 @@ aae aae aaf aaf -aaf -ahT -abC -abC -abC +dzk +dzk +dzk abC aaa aaa aaa aaa +aaa +alx +alF alx alx alx alx alx -and -and -alx -alx -alx +aaa +aaa abC aaa aaa -alx -alx -alx -alx -alx +aaa +aaa +aaa +aaa +aaa aaa abC aaa aaa aaa arw -aPq -aQS -arz -aSQ +dAn +dAD +ary +ary aTD arw aaa @@ -143771,14 +148783,14 @@ aaa alx alx alx -alF -abC -abC -abC -abC -abC -abC -abC +alx +cKF +cKF +cKF +cKF +cKF +cKF +cKF abC aYG abC @@ -143838,34 +148850,34 @@ bSZ bSZ bSZ bYb -arA -arA -arA -arA -arA -cdj -arA -arA -arA -arA -arA -arA -arA -djU -arA -arA -arA -arA -arA -bYb -bSZ -bSZ -bSZ +dwd +dwd +dwd +dwd +dws +dwd +dwd +dwd +dwd +dwy +dwA +dwA +dwA +dwA +dwF +dwA +dwA +dwA +dwA +dwH +dwI +dwI +dwI cgA cgJ -bSZ -bRQ -cLb +dwI +dwM +dwN chu bkA bkA @@ -143988,54 +149000,54 @@ aaa aaa abC abC +aaa +aaa +aaa +aaa +alx +alx +alx +alx +alx +and +and +alx +alx +alx +abC +aaa +aaa +alx +alx +alx +alx +alx +aaa abC aaa aaa aaa +arw +dAn +dAD +ary +ary +aTD +arw +aaa +aaa +aaa alx alx -and alx -and -and -and -alx -alx -and alF -alx -and -and -alx -alx -alx -alx -aaa abC -aaa -aaa -aaa -aOv -aPr -aQS -arz -aSQ -aTE -aUC -aaa -aaa -akR -alx -alx -alx -alx -aaa -aaa -aaa -aaa -aaa -aaa -aaa +abC +abC +abC +abC +abC +abC abC aYG abC @@ -144099,17 +149111,17 @@ bYM bZo bZo bZo +dwt bZo bZo bZo bZo +dwt bZo bZo bZo bZo -bZo -bZo -bZo +dwt bZo bZo bZo @@ -144244,53 +149256,53 @@ aaa aaa aaa abC +abC +abC aaa -abC -abC +aaa +aaa +alx +alx +and +alx +and +and +and +alx +alx +and alF alx +and +and alx -and -and -afV -afV -afS -aez -afV -adZ -aez -afV -afV -aez -aez alx -and -and alx alx aaa -aaa -aaa -aKo -aOw -aKo -aQV -aRP -aSR -aLm -aUD -aLm -akR +abC +cKF +cKF +cKF +aOv +dAz +dAD +ary +ary +dBg +aUC +cKF +cKF akR alx alx alx alx -alx -alx -aaa -aaa -aaa +cKF +cKF +cKF +cKF +cKF aaa aaa abC @@ -144502,46 +149514,46 @@ aaa aaa abC aaa -aaa -aaa +abC +abC +alF alx alx and -aez +and +afV +afV +afS aez afV -aqH -afq -apx -cZd -cYm -aiS -azp -amb -aBV adZ +aez afV afV aez +aez +alx +and +and alx alx -alx -akR -akR +aaa +aaa +aaa aKo -aOx +aOw aKo aQW -aRD -aSS +aRP +aSR aLm -aUE +aUD aLm +akR +akR alx alx alx -and -and alx alx alx @@ -144759,54 +149771,54 @@ aaa aaa abC aaa -akR +aaa +aaa +alx alx and -and aez -afS +aez afV -aoQ +aqH afq -akq -alQ -akq -akq -akp -cYo -akp -cYl -akp +apx +cZd +cYm +aiS +azp amb -cYj +aBV +adZ +afV +afV aez -and -and +alx +alx +alx +akR +akR aKo -aLo -aLo +aOx aKo -aOy -aKo -aQW +dAQ aRD -aST -aLm -aUF -aLm +aSS aLm +aUE aLm alx +alx +alx and and alx alx alx -alx -alx aaa aaa -abC +aaa +aaa +aaa abC aYG abC @@ -145015,57 +150027,57 @@ aaa aaa aaa abC -akR +aaa akR alx and and aez -apO -aoR -ahr -ahr -ahr -cYY -avL -ahr -ahr -azq -cYY -ahr -ahr -aEj afS afV +aoQ +afq +akq +alQ +akq +akq +akp +cYo +akp +cYl +akp +amb +cYj aez -aez +and +and aKo -aLp -aMq -aNr -aOz -aPs -aQW +aLo +aLo +aKo +aOy +aKo +dAQ aRD -aSU +aST +aLm +aUF +aLm aLm -aUG -aVj -aVD aLm alx and -aXa -aXb -aXa -aXa -aYi +and +alx +alx +alx +alx alx aaa -aaa +cKF abC -aYF -aYH +abC +aYG abC aaa aaa @@ -145270,59 +150282,59 @@ aaa aaa aaa aaa -ajj -akc -anQ -dnE -ajn +aaa +abC +akR +akR +alx +and +and aez +apO +aoR +ahr +ahr +ahr +cYY +avL +ahr +ahr +azq +cYY +ahr +ahr +aEj afS afV -afq -anC -arC -arC -arC -arC -arC -arC -arC -arC -arC -arC -afq -anC -afS -adZ -aIf -adZ +aez +aez aKo -aLq -aMr -aNs -aOA -aPt -aQX +aLp +aMq +aNr +aOz +aPs +dAQ aRD -aSV +aSU aLm -aUH -aVk -aVE +aUG +aVj +aVD aLm -afV -afV +alx +and +aXa +aXb +aXa aXa -aXt -aXL -aXZ -aYi -aYi aYi +alx +aaa +aaa abC -abC -aYG -abC +aYF +aYH abC aaa aaa @@ -145527,60 +150539,60 @@ aaa aaa aaa aaa -ajk -alE -akd -dnF +ajj +akc +anQ +dnE ajn -ajn -aUW -aoQ -aoR -aqN -arC -asx -atB -asx -atC -atC -axN -azr -asx -arC -aqH -aEk -amb -akp -cZB +aez afS -aKp -aLr -aMs -aNt -aOB -aPu -aQY -aRF -aSW -cKe -aUI -aVl -aVF +afV +afq +anC +arC +arC +arC +arC +arC +arC +arC +arC +arC +arC +afq +anC +afS +adZ +aIf +adZ +aKo +aLq +aMr +aNs +aOA +aPt +dAS +aRD +aSV aLm -ajt -aqH -aXb -aXu -aXM -aYa -aYj -aYr -aYj -aYn -aYn -aYH +aUH +aVk +aVE +aLm +afV +afV +aXa +aXt +aXL +aXZ +aYi +aYi +aYi +abC +abC +aYG +abC abC -aaa aaa aaa aaa @@ -145784,58 +150796,58 @@ aaa aaa aaa aaa -ajl -ake -akS -aly -amf -ane -alr +ajk +alE +akd +dnF +ajn +ajn +aUW +aoQ aoR -apP -afV +aqN arC -asy -atC asx +atB asx -axb atC atC -aAH +axN +azr +asx arC +aqH +aEk +amb +akp +cZB afS -amI -aCr -aCr -aCr -aBA -aKo -aKo -aKo -aKo -aKo -aKo -aQZ -aRQ -aSX +aKp +aLr +aMs +aNt +aOB +aPu +aQY +aRF +aSW +cKe +aUI +aVl +aVF aLm -aUJ -aVe -aVG -aLm -alR -aWQ -aXc -aXv -aXN -aYb -aYi -aYi -aYi -abC -abC -abC +ajt +aqH +aXb +aXu +aXM +aYa +aYj +aYr +aYj +aYn +aYn +aYH abC abC abC @@ -146041,59 +151053,59 @@ aaa aaa aaa aaa -cJr -akf -akT +ajl +ake +akS aly -amg -ajn -anM -aoS -cYC -adZ -arC -asz -atD -auF -avM -atC -axO -atC -aAI -arC -adZ -afS +amf +ane +alr +aoR +apP afV -aiS -dad -dan -day +arC +asy +atC +asx +asx +axb +atC +atC +aAH +arC +afS +amI +aCr +aCr aCr aBA -cYl -dam +aKo +aKo +aKo +aKo +aKo +aKo +aQZ +aRQ +aSX aLm -aRa -aRK -aSY +aUJ +aVe +aVG aLm -aUK -aVf -aVH -aLm -aqH -anC -aXb -aXb -aXa -aXb +alR +aWQ +aXc +aXv +aXN +aYb aYi -alx -aaa -aaa -aaa -aaa -aaa +aYi +aYi +abC +abC +abC +abC aaa aaa aaa @@ -146298,53 +151310,53 @@ aaa aaa aaa aaa -ajl -akg -akU +cJr +akf +akT aly -amh +amg ajn -anN -aoT -adZ +anM +aoS +cYC adZ arC -asx +asz +atD +auF +avM atC -auG -avN -auG -axP axO +atC aAI arC adZ -adZ -cZM -cZM -cZM -cZM -cZM -cZM -anC +afS +afV +aiS +dad +dan +day +aCr +aBA cYl -afS -aPl -aRb -aRR -aSZ -aTF -aUL +dam aLm +aRa +aRK +aSY aLm +aUK +aVf +aVH aLm -aoR -apu -afS -alx -alx -alx -alx +aqH +anC +aXb +aXb +aXa +aXb +aYi alx aaa aaa @@ -146361,19 +151373,19 @@ aaa aaa aaa aaa -aaa +cKF bbq bbq bbq -baS -baS -baS -baS -baS -baS +bbq +bbq +bbq +bbq +bbq +cKp big bja -bjS +bjP deo blC dpb @@ -146556,52 +151568,52 @@ aaa aaa aaa ajl -akf +akg akU -alz -ami +aly +amh ajn -ajn -anV -anV -anV -arC -arC -arC -auH -avO -auH -arC -arC -aAJ -arC -anV -anV -cZM -cZV -daf -dap -daA -cZM -amI -ahr -aOo -aPv -aRc -aRS -aTa -aLm -aLm -aLm +anN +aoT adZ adZ +arC +asx +atC +auG +avN +auG +axP +axO +aAI +arC +adZ +adZ +cZM +cZM +cZM +cZM +cZM +cZM anC -afq -aLm -aLm +cYl +afS +aPl +aRb +aRR +aSZ +aTF +aUL aLm aLm aLm +aoR +apu +afS +alx +alx +alx +alx alx aaa aaa @@ -146621,16 +151633,16 @@ aaa aaa bbq bbq -bbo +bbq +baS +baS +baS +baS baS -bdG -bew -bfl -bgl baS big bja -bjP +bjS dew bkD bkD @@ -146815,51 +151827,50 @@ aaa ajl akf akU -alA -amh -anf +alz +ami ajn -aoU -cYD -aqO -arD -asA -atE -auI -avP -auI -axQ -azs -aAK -aBW -aCU -aEl -cZO -cZW -dag -daq -daB +ajn +anV +anV +anV +arC +arC +arC +auH +avO +auH +arC +arC +aAJ +arC +anV +anV cZM -daQ -aUW -avh -aPw -aRd -aRD -aTb +cZV +daf +dap +daA +cZM +amI +ahr +aOo +aPv +aRc +aRS +aTa +aLm +aLm aLm adZ adZ -adZ -aWh -apu -aez +anC +afq +aLm +aLm +aLm aLm -aMo -aMn -aYc aLm -alx alx aaa aaa @@ -146878,16 +151889,17 @@ aaa aaa aaa bbq +bbq bbo baS -bdH -bex -bex -bgm -bgY -bih -bjc -bjR +bdG +bew +bfl +bgl +baS +big +bja +bjP bkD blD bmC @@ -147069,55 +152081,55 @@ aaa aaa aaa aaa -cJs +ajl akf akU -aly -amj -ang -anO -aoV -apQ -apQ -arE -arE -cLT -arE -avQ -apQ -apQ -azt -aAL -aBX -cZA -aEn -cZP -cZX -dah -dar -daC +alA +amh +anf +ajn +aoU +cYD +aqO +arD +asA +atE +auI +avP +auI +axQ +azs +aAK +aBW +aCU +aEl +cZO +cZW +dag +daq +daB cZM -afV -aez -afV +daQ +aUW +avh +aPw +aRd +aRD +aTb aLm -aRe -aRT -aTc -aPv -aUM -ahr -ahr +adZ +adZ +adZ +aWh apu -afV aez aLm -aNp -aNp -aYd -aLm -aLm +aMo +aMn +aYc aLm +alx +alx aaa aaa aaa @@ -147134,17 +152146,17 @@ aaa aaa aaa aaa +bbq +bbo baS -baS -baS -bdI -bey -bey -bgn -baS -big -bbs -bjP +bdH +bex +bex +bgm +bgY +bih +bjc +bjR bkD blE bmD @@ -147326,82 +152338,82 @@ aaa aaa aaa aaa -ajl -akh -akV -alB -amk -anh -anP -aoW -aoW -aoW -arF -arF -aoW -arF -avR -aoU -aoU -aoU -aoU +cJs +akf +akU +aly +amj +ang +anO +aoV +apQ +apQ +arE +arE +cLT +arE +avQ +apQ +apQ +azt +aAL aBX -aoU +cZA aEn -cZQ +cZP cZX -dai -das -daD -anV -anV -anV -anV -anV -aRd -aRD -aTa -aPw -alr -aqH -aoy -afK +dah +dar +daC +cZM +afV +aez +afV +aLm +aRe +aRT +aTc +aPv +aUM +ahr +ahr +apu afV aez aLm -aXw -aXO -aXO -aYk -aYs -aYv -aYw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -arw -bar -baR -baR -bbR -bcv -bbR -bdJ -ber -ber -bgo +aNp +aNp +aYd +aLm +aLm +aLm +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +aaa +aaa baS -bii -bjd -bjT +baS +baS +bdI +bey +bey +bgn +baS +big +bja +bjP bkD blF bmE @@ -147583,82 +152595,82 @@ aaa aaa aaa aaa -ajm -aki -akW -alC -alD -ani -ajn +ajl +akh +akV +alB +amk +anh +anP +aoW +aoW +aoW +arF +arF +aoW +arF +avR aoU aoU -aqP -arG -asB -atF -asG -avS -axc -aoW -aoW -aoW -aBY -azy -cZI -cZR -cZZ -daj -dat -daE +aoU +aoU +aBX +aoU +aEn +cZQ +cZX +dai +das +daD anV -aMt -aNu -aOC -aPx -aRf -aRU +anV +anV +anV +anV +aRd +aRD aTa +aPw +alr +aqH +aoy +afK +afV +aez aLm -aLm -aLm -aLm -aLm -aLm -aLm -aLm -aXx -cKe -aLm -aLm -aLm -aLm -aYx -aYz -aYz -aYz -aYz -aYz -aYz -aYz -aYz -aYz -aYz -aYz -aYz -bas +aXw +aXO +aXO +aYk +aYs +aYv +aYw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +arw +bar +baR +baR +bbR +bcv +bbR +bdJ +ber +ber +bgo baS -baS -baS -baS -baS -baS -baS -baS -cKp -baS -bij -bbs -bjU +bii +bjd +bjT bkD bkD bkD @@ -147840,82 +152852,82 @@ aaa aaa aaa aaa -ajn -akj -ajn +ajm +aki +akW +alC alD -aml -anj +ani ajn aoU aoU -aoY -arH -asC +aqP +arG +asB +atF +asG +avS +axc +aoW +aoW +aoW +aBY +azy +cZI +cZR +cZZ +daj +dat +daE anV -auJ -avT -aoY -aoU -aoU -aAM -anV -aCW -aEn -anV -anV -anV -anV -anV -anV -aMu -aoU -aoU -aBX -aRg -aRD -aTd -aTG -aUN -aTG -aTG -aWi -aTG -aWR -dbP -aXy -aTG -aTG -aYl -aYt -cPO -cPT -cPT -cPT -cPT -cPT -cPT -aYU -cPT -cPT -cPT -cPT -cPT -cPT -cPT -cQC -bbr -cQJ -bcw -cQJ -cQJ -cQJ -bfm -cQJ -cQJ -bik -bbs -bjP +aMt +aNu +aOC +aPx +aRf +aRU +aTa +aLm +aLm +aLm +aLm +aLm +aLm +aLm +aLm +aXx +cKe +aLm +aLm +aLm +aLm +aYx +aYz +aYz +aYz +dtr +aYz +aYz +aYz +aYz +dtr +aYz +aYz +aYz +bas +baS +baS +baS +baS +baS +baS +baS +baS +cKp +baS +bij +bja +bjU bkD blG bmF @@ -148097,81 +153109,81 @@ aaa aaa aaa aaa -aaa -aaa -ajn -ajn ajn +akj ajn +alD +aml +anj ajn aoU aoU aoY -arI -arM -aoY -arM -arI -aoY -axR -azv -aAN +arH +asC anV -aCX -aEo -aBW -aHf -aIg -aJp -aKq -aLs -aMv +auJ +avT +aoY +aoU +aoU +aAM +anV +aCW +aEn +anV +anV +anV +anV +anV +anV +aMu aoU aoU aBX aRg -aRV -aTe aRD -aUO -aRD -aRD -aWj -aRD -aTS -aRD -aRD -aRD -aRD -aYm -aRD -aRP -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -arz -baU -bbs -bbT -bbs -bbs -bbs -bbs -bfn -bbs -bbs -bil -cKz +aTd +aTG +aUN +aTG +aTG +aWi +dBH +aWR +dbP +aXy +aTG +aTG +aYl +aYt +cPO +cPT +cPT +cPT +cPT +dts +aYU +aYU +aYU +aYU +dtV +aYU +aYU +aYU +aYU +cQC +bbr +cQJ +bcw +cQJ +cQJ +cQJ +bfm +cQJ +cQJ +bik +dul bjP bkD blE @@ -148356,80 +153368,80 @@ aaa aaa aaa aaa -aaa -akR -akR -akR +ajn +ajn +ajn +ajn +ajn +aoU +aoU +aoY +arI +arM +aoY +arM +arI +aoY +axR +azv +aAN anV -aoY -aoY -aoY -arH -asD -aoY -auK -avT -aoY -aoY -aoY -aoY -anV -aCY -aEp -aFJ -aHg -aIh -aoU -aEn -aoY -aMw +aCX +aEo +aBW +aHf +aIg +aJp +aKq +aLs +aMv aoU aoU -aPy -aRh -aRW -aTf -aTH -aUP -aVm -aVI -aWk -aWE -aWS -aXd -aQN -aXP -aQN -aQN -aQN -aQR -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -arA -baV -bbt -bbU -bcx -bdd -bdd -bez -bfo -bdd -bdd -bim -bcx -bjV +aBX +aRg +aRV +aTe +aRD +aUO +aRD +aRD +aWj +aRD +aTS +aRD +aRD +aRD +aRD +aYm +aRD +aRP +dtd +dtd +dtd +dtd +dtd +dtd +dBn +dtd +dtd +dtd +dtd +dtd +dtd +dtd +baU +bbs +bbT +bbs +bbs +bbs +bbs +bfn +bbs +bbs +bil +cKz +bjP bkD blF bmE @@ -148614,79 +153626,79 @@ aaa aaa aaa aaa -aaa -aaa -abC -arw -aoZ -aoZ -aoZ -arJ -asE -aoZ -auL -avU -aoZ -aoZ -aoZ -aaa +akR +akR +akR anV -aCZ -aEq -aFK -aHh +aoY +aoY +aoY +arH +asD +aoY +auK +avT +aoY +aoY +aoY +aoY +anV +aCY +aEp +aFJ +aHg +aIh aoU -aoU -aKr -aLt -aMx +aEn +aoY +aMw aoU aoU aPy -aPy -aRX -aTg -aTI -anV -aLm -aLm -aWl -aPJ -aPl -aLm -aLm -aLm -aLm -aLm -aLm -aLm -aYy -aYy -aYy -aYy -aYy -aYy -aYy -aYy -aYy -aYy -aYy -aYy -aYy -aYy -baS -baS -baS -baS -baS -bdK -baS -baS -baS -bgZ -bin -baS -bjW +aRh +aRW +aTf +aTH +aUP +aVm +aVI +aWk +aWE +aWS +aXd +aQN +aXP +aQN +aQN +aQN +aQR +dtd +dtd +dtd +dtd +dtu +dtd +dtd +dtd +dtd +dtu +dtd +dtd +dtd +dtd +baV +bbt +bbU +bcx +bdd +bdd +bez +bfo +bdd +bdd +bim +bcx +bjV bjW bjW bjW @@ -148876,73 +153888,73 @@ aaa abC arw aoZ -apR -apR -apR -apR -atG -apR -apR -apR -axS aoZ -aAO -aoY -aDa -aEr -aBY -aHi -aoU -aoU -aKs -aoY -aMy -aoU -aoU -aoU -aoU -aRY -azA -aTJ +aoZ +arJ +asE +aoZ +auL +avU +aoZ +aoZ +aoZ +aaa +anV +aCZ +aEq +aFK +aHh +aoU +aoU +aKr +aLt +aMx +aoU +aoU +aPy +aPy +aRX +aTg +aTI anV -alx aLm -aWm -aPI -aUR -dbQ -aXz aLm -alx -alx -alx -aaa -aaa -abC -aaa -aaa -aaa -aaa -abC -aaa -aaa -aaa -aaa -abC -aaa -aaa -baW -baW -bbo -bbo -bbq -bbq -bbq -bbq -bgs -bha -bio -bje +aWl +aPJ +aPl +aLm +aLm +aLm +aLm +aLm +aLm +aLm +aYy +aYy +aYy +aYy +dtv +aYy +aYy +aYy +aYy +dtv +aYy +aYy +aYy +aYy +baS +baS +baS +baS +baS +bdK +baS +baS +baS +bgZ +bin +baS bjW bkE blH @@ -149137,38 +154149,38 @@ apR apR apR apR +atG apR apR apR -apR -apR -azw -aAP +axS +aoZ +aAO aoY -aCW -aEs -anV -aHj -aIi -azy -aKt +aDa +aEr aBY -aMz -aoW -aoW -aoW -aoW -aRZ -cOC +aHi +aoU +aoU +aKs +aoY +aMy +aoU +aoU +aoU +aoU +aRY +azA aTJ anV alx aLm -aWn -aOl -daW -aXe -aXA +aWm +aPI +aUR +dbQ +aXz aLm alx alx @@ -149190,16 +154202,16 @@ aaa aaa baW baW -baW +bbo bbo bbq bbq bbq bbq -bgp -bhb -ddo -bjf +bgs +bha +bio +bje bjW bkF blI @@ -149405,46 +154417,46 @@ aoY aCW aEs anV -aHk -aCW -aJq -aKu -aLu -aMA -aoU -aoU -aoU -aoU -aRY -apb +aHj +aIi +azy +aKt +aBY +aMz +aoW +aoW +aoW +aoW +aRZ +cOC aTJ anV alx aLm -aMg -aWF -aWT -aXf -aNF +aWn +aOl +daW +aXe +aXA aLm alx alx alx -alx -aXR -aXR -aXR aaa -aXR -aXR -aXR -aXR aaa -aXR -aXR -aXR -aXR -aXR +abC +aaa +aaa +aaa +aaa +abC +aaa +aaa +aaa +aaa +abC +aaa +aaa baW baW baW @@ -149659,49 +154671,49 @@ apR azw aAP aoY -aDb -aEt -anV -aHl aCW +aEs +anV +aHk +aCW +aJq +aKu +aLu +aMA aoU -aKv -aoY -aMB -aNv -aOD -aPz -aRi -aSa -aTh -aTK +aoU +aoU +aoU +aRY +apb +aTJ anV alx aLm -aLm -aLm -aLm -aLm -aLm +aMg +aWF +aWT +aXf +aNF aLm alx alx alx alx +aXR +aXR +aXR aaa +aXR +aXR +aXR +aXR aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +aXR +aXR +aXR +aXR +aXR baW baW baW @@ -149912,35 +154924,35 @@ apR apR apR apR -axS -aoZ -aAQ +apR +azw +aAP aoY +aDb +aEt +anV +aHl aCW -aEs -anV -aHm -aCW -aJr -aKw -anV -anV -anV -anV -aPA -anV -aSb -avk -anV +aoU +aKv +aoY +aMB +aNv +aOD +aPz +aRi +aSa +aTh +aTK anV alx -and -and -alx -alx -alx -alx -alx +aLm +aLm +aLm +aLm +aLm +aLm +aLm alx alx alx @@ -150161,45 +155173,45 @@ aaa abC arw aoZ +apR +apR +apR +apR +apR +apR +apR +apR +axS aoZ -aoZ -arK -arK -aoZ -auM -arK -aoZ -aoZ -aoZ -aaa -anV -aCZ +aAQ +aoY +aCW aEs anV -aHn +aHm aCW -aoU -daF +aJr +aKw +anV +anV +anV +anV +aPA +anV +aSb +avk +anV anV -aez -aez -adZ -afV -akp -aSc -cOD -cZB -afS -alx -alx -alx -and alx and and -and -and -and +alx +alx +alx +alx +alx +alx +alx alx alx alx @@ -150411,54 +155423,54 @@ aaa aaa aaa aaa -dnA aaa -akR -akR -akR +aaa +aaa +aaa +abC +arw +aoZ +aoZ +aoZ +arK +arK +aoZ +auM +arK +aoZ +aoZ +aoZ +aaa anV -aoY -aoY -aoY -arL -asF -aoY -asF -arL -aoY -aoY -aoY -aoY -anV -aCY +aCZ aEs anV -aHo +aHn aCW aoU -aKx +daF anV aez aez adZ -afS -cYt -cYK -aiS -afS afV +akp +aSc +cOD +cZB +afS +alx +alx +alx and -and -and +alx and and and and and alx -and -and -and +alx alx alx aaa @@ -150668,42 +155680,42 @@ aaa aaa aaa aaa -dnB -dnD -dnD -dnD -dnD -anT -aoX -aoU -aoY -arM -arM -aoY -arM -arM -aoY -axT -azx -aAR +dnA +aaa +akR +akR +akR anV -aCX +aoY +aoY +aoY +arL +asF +aoY +asF +arL +aoY +aoY +aoY +aoY +anV +aCY aEs anV -aHp -aIj -aJs -aKy -aHp +aHo +aCW +aoU +aKx +anV aez aez +adZ afS -cYm -cYu -akp -akp -cYg +cYt +cYK +aiS afS +afV and and and @@ -150725,7 +155737,7 @@ aaa aaa aaa aaa -aaa +cKF aaa aaa aaa @@ -150925,50 +155937,50 @@ aaa aaa aaa aaa -dnC -akR -akR -akR -alx -anU -apa +dnB +dnD +dnD +dnD +dnD +anT +aoX aoU aoY -arL -arL +arM +arM aoY -arL -arL +arM +arM aoY -aoU -aoU -aAM +axT +azx +aAR anV -aDc +aCX aEs -aFL -aHq -aIk -aJt -aKz +anV +aHp +aIj +aJs +aKy aHp aez aez -aez -cYj +afS +cYm cYu -aXh +akp +akp +cYg afS -adZ -afS -aez -aez -afV -aez and and -alx -alx +and +and +and +and +and +and alx and and @@ -151182,54 +156194,54 @@ aaa aaa aaa aaa -aaa +dnC +akR akR akR alx -alx +anU +apa +aoU +aoY +arL +arL +aoY +arL +arL +aoY +aoU +aoU +aAM anV -apb -aoU -aoU -aoU -asG -atH -aoW -aoW -aoW -aoW -azy -aoW -aBY -aDd +aDc aEs -aFM +aFL aHq -aIl -aJu -aKA +aIk +aJt +aKz aHp -adZ aez aez -apx -cOz -afV +aez +cYj +cYu +aXh +afS adZ afS +aez +aez afV -afS -aWo -afK -afV -afS -afS -afV -alx -alx +aez +and +and alx alx alx +and +and +and alx aaa aaa @@ -151445,48 +156457,48 @@ akR alx alx anV -apc -apS -apS -arN -arN -cLU -arN -arN -apS -apS -azz -apS -aBZ -aDe -aEu -aFN +apb +aoU +aoU +aoU +asG +atH +aoW +aoW +aoW +aoW +azy +aoW +aBY +aDd +aEs +aFM aHq -aIm +aIl aJu -aKB +aKA aHp adZ +aez +aez +apx +cOz afV -afV -alR -amK -alS -afV -akp -akp -akp -akq -avh -awu -alr -aOF +adZ afS afV afS +aWo +afK afV -akR -akR +afS +afS +afV +alx +alx +alx +alx +alx akR aaa aaa @@ -151698,50 +156710,50 @@ aaa aaa aaa akR -alx +akR alx alx anV -apd -aoU -aoU -arO -arO -aoU -arO -arO -aoU -axU -azA -aoU -aBX -aoU -aEn -aFO +apc +apS +apS +arN +arN +cLU +arN +arN +apS +apS +azz +apS +aBZ +aDe +aEu +aFN aHq aIm aJu -aKC +aKB aHp -aHp -aNw -afS -alS -amK -akp -aOH -akp -akp -cYl -akp -afp +adZ afV +afV +alR +amK +alS +afV +akp +akp +akp akq -akp +avh +awu +alr +aOF afS -akp -akp -ajo +afV +afS +afV akR akR aaa @@ -151955,52 +156967,52 @@ aaa aaa aaa akR -akR +alx alx alx anV -ape -ape -aqQ -arP -asH -atI -auN -cZe -apQ -axV -azB -aAS -aBW -aDf -aEv -aFP +apd +aoU +aoU +arO +arO +aoU +arO +arO +aoU +axU +azA +aoU +aBX +aoU +aEn +aFO aHq -aIn -aJv -aKD -cNU -cOb -cOf -aOE -cOs -cYK -afS -afV -afV -afV -aez -afS -afV +aIm +aJu +aKC +aHp +aHp +aNw afS +alS +amK akp -aXg +aOH akp akp +cYl +akp +afp +afV +akq +akp +afS +akp akp ajo -aaa -aaa +akR +akR aaa aaa aaa @@ -152211,49 +157223,49 @@ aaa aaa aaa aaa -aaa akR akR -ank -ank -apf -apf -aqR -ank -ank -ank -ank -ank -ank -ank -azC -ank -ank +alx +alx anV -anV -anV -aHp -aHp -aHp -aHp -aHp -aHp -cYn -aCr -apu -dbk +ape +ape +aqQ +arP +asH +atI +auN +cZe +apQ +axV +azB +aAS +aBW +aDf +aEv +aFP +aHq +aIn +aJv +aKD +cNU +cOb +cOf +aOE +cOs +cYK afS -alx -and -and -and -alx -alx +afV +afV +afV +aez +afS +afV afS akp -aXh -afV -aXQ +aXg +akp +akp akp ajo aaa @@ -152469,49 +157481,49 @@ aaa aaa aaa aaa -aaa -aaa +akR +akR ank -anW -apg -apT -aqS -aph ank -atJ -atJ -avV -axd -axW -azD -aAT +apf +apf +aqR ank -adZ +ank +ank +ank +ank +ank +ank +azC +ank +ank +anV +anV +anV +aHp +aHp +aHp +aHp +aHp +aHp +cYn +aCr +apu +dbk afS -afV -adZ -adZ -aJw -aCr -day -aCr -aNx -aus -afq -afV -aez alx and and and -and +alx alx afS -aRj -aXi -afS -ala -ajr +akp +aXh +afV +aXQ +akp ajo aaa aaa @@ -152729,69 +157741,69 @@ aaa aaa aaa ank -anX +anW +apg +apT +aqS aph -apU -aqT -arQ -asI -atK -auO -auO -auO -avW -azE -avW ank -cZB -cYl -aoR -ahr -aqj -apu -akq -alS -akp -aNy -afS +atJ +atJ +avV +axd +axW +azD +aAT +ank adZ +afS +afV +adZ +adZ +aJw +aCr +day +aCr +aNx +aus +afq +afV aez -and alx and and and and alx -afV -afV -afV -afV -afV -afV -afV -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -bbp +afS +aRj +aXi +afS +ala +ajr +ajo +aaa +aaa +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +bbo bbo bbq bgp @@ -152983,72 +157995,72 @@ aaa aaa aaa aaa -akR -akR +aaa +aaa ank -anY -api -apV -apV -apV -asJ -atL -atL -avX -atL -atL -azF -aAU +anX +aph +apU +aqT +arQ +asI +atK +auO +auO +auO +avW +azE +avW ank -aDg -auE +cZB +cYl +aoR +ahr +aqj apu -aqH -afq -afq -aKE -adZ +akq +alS +akp +aNy +afS adZ +aez +and +alx +and +and +and +and +alx afV -adZ -alx -alx -alx -alx -and -and -and -and -alx -alx -akR -akR -alx -alx -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -baW +afV +afV +afV +afV +afV +afV +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +bbp bbo bbq bbq @@ -153241,29 +158253,32 @@ aaa aaa aaa akR -alx +akR ank -anZ -apj -apW -aqU -arR +anY +api +apV +apV +apV +asJ +atL +atL +avX +atL +atL +azF +aAU ank -atM -auP -avW -avW -axX -azG -aAV -ank -afK -aUW -aoy -apx -anN +aDg +auE +apu +aqH +afq +afq +aKE +adZ +adZ afV -afS adZ alx alx @@ -153273,15 +158288,12 @@ and and and and -and -and -and +alx alx akR akR -akR -akR -akR +alx +alx aaa aaa aaa @@ -153496,31 +158508,31 @@ aaa aaa aaa aaa -akR +aaa akR alx ank +anZ +apj +apW +aqU +arR ank +atM +auP +avW +avW +axX +azG +aAV ank -ank -ank -ank -ank -ank -auQ -avY -auQ -ank -ank -ank -ank +afK +aUW +aoy +apx +anN afV afS -afS -adZ -adZ -adZ -adZ adZ alx alx @@ -153534,7 +158546,7 @@ and and and alx -alx +akR akR akR akR @@ -153754,46 +158766,46 @@ aaa aaa aaa akR +akR +alx +ank +ank +ank +ank +ank +ank +ank +ank +auQ +avY +auQ +ank +ank +ank +ank +afV +afS +afS +adZ +adZ +adZ +adZ +adZ alx alx alx alx -alx +and +and +and +and +and +and +and alx alx akR akR -atN -auR -avW -avW -atN -akR -akR -alx -alx -and -and -and -alx -alx -alx -alx -and -and -and -and -and -and -and -and -alx -alx -alx -alx -alx -alx -alx akR akR aaa @@ -154010,32 +159022,32 @@ aaa aaa aaa aaa -aaa -alF akR -alF alx alx alx alx -aaa +alx +alx +alx +akR akR atN -auS +auR +avW avW -axe atN -aaa akR akR alx +alx and and and -and -and -and -and +alx +alx +alx +alx and and and @@ -154051,8 +159063,8 @@ alx alx alx alx -alx -alx +akR +akR aaa aaa aaa @@ -154268,48 +159280,48 @@ aaa aaa aaa aaa -abC -aaa -abC -aaa -aaa -aaa -aaa -aaa -aaa -atN -atN -avZ -atN -atN -aaa +alF +akR +alF +alx +alx +alx +alx aaa akR -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx -alx +atN +auS +avW +axe +atN aaa +akR +akR +alx +and +and +and +and +and +and +and +and +and +and +and +and +and +and +and +alx +alx +alx +alx +alx +alx +alx +alx +alx aaa aaa aaa @@ -154533,19 +159545,19 @@ aaa aaa aaa aaa -asK -asK -asL -awa -asL -asK -asK -aaa -aaa -aaa -aaa +aaa +atN +atN +avZ +atN +atN aaa aaa +akR +alx +alx +alx +alx alx alx alx @@ -154791,11 +159803,11 @@ aaa aaa aaa asK -atO -auT -auT -auU -axY +asK +asL +awa +asL +asK asK aaa aaa @@ -154803,52 +159815,52 @@ aaa aaa aaa aaa +alx +alx +alx +alx +alx +alx +alx +alx +alx +alx +alx +alx +alx +alx +alx +alx +alx +alx +alx +alx aaa aaa aaa aaa -alx -alx -alx -alx -alx -and -alx -alx -alx -and -alx -alF -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -abC -bbp +aaa +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +cKF +bbo bbo bbq bgs @@ -155047,16 +160059,13 @@ aaa aaa aaa aaa -asL -atP -auU +asK +atO +auT auT auU -axZ -azH -aaa -aaa -aaa +axY +asK aaa aaa aaa @@ -155072,41 +160081,44 @@ alx alx alx alx +and alx alx alx +and alx -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa -bbo +alF +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +abC +bbp bbq bgp bit @@ -155304,14 +160316,13 @@ aaa aaa aaa aaa -asK -atQ -auT +asL +atP +auU auT auU -aya -asK -aaa +axZ +azH aaa aaa aaa @@ -155329,6 +160340,11 @@ alx alx alx alx +alx +alx +alx +alx +alx aaa aaa aaa @@ -155338,10 +160354,6 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aac aab aaa aaa @@ -155562,11 +160574,11 @@ aaa aaa aaa asK -asK -asL -awb -asL -asK +atQ +auT +auT +auU +aya asK aaa aaa @@ -155577,9 +160589,15 @@ aaa aaa aaa aad -aab -aab -aab +aaa +aaa +aaa +aaa +aaa +alx +alx +alx +alx aaa aaa aaa @@ -155592,13 +160610,7 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aab -aaa -aaa +aac aaa aac aad @@ -155818,13 +160830,13 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa -aaa -aaa +asK +asK +asL +awb +asL +asK +asK aaa aaa aaa @@ -155853,7 +160865,7 @@ aaa aaa aaa aaa -aaa +aab aaa aaa aab diff --git a/_maps/map_files/CitadelStation/CitadelStation-1.2.1.dmm b/_maps/map_files/CitadelStation/CitadelStation-1.2.1.dmm index 7553242b36..84fb806587 100644 --- a/_maps/map_files/CitadelStation/CitadelStation-1.2.1.dmm +++ b/_maps/map_files/CitadelStation/CitadelStation-1.2.1.dmm @@ -1361,7 +1361,7 @@ "aAi" = (/obj/structure/table/wood,/obj/item/weapon/folder,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/asteroid},/area/library) "aAj" = (/obj/machinery/power/apc{dir = 8;name = "Library APC";pixel_x = -25},/obj/structure/cable{icon_state = "0-4";d2 = 4},/turf/open/floor/wood,/area/library) "aAk" = (/obj/structure/cable{d1 = 2;d2 = 8;icon_state = "2-8"},/turf/open/floor/wood,/area/library) -"aAl" = (/obj/effect/landmark/start{name = "Librarian"},/turf/open/floor/wood,/area/library) +"aAl" = (/obj/effect/landmark/start{name = "Curator"},/turf/open/floor/wood,/area/library) "aAm" = (/obj/machinery/light/small{dir = 4},/turf/open/floor/wood,/area/library) "aAn" = (/obj/machinery/light/small/built{tag = "icon-bulb1 (WEST)";icon_state = "bulb1";dir = 8},/obj/machinery/airalarm{frequency = 1439;locked = 0;pixel_y = 23},/turf/open/floor/wood,/area/crew_quarters/cafeteria{name = "Cafe"}) "aAo" = (/turf/open/floor/wood,/area/crew_quarters/cafeteria{name = "Cafe"}) @@ -1393,7 +1393,7 @@ "aAO" = (/obj/machinery/light/small{dir = 8},/turf/open/floor/wood{baseturf = /turf/open/floor/plating/asteroid},/area/maintenance/fore) "aAP" = (/obj/structure/chair/stool,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/asteroid},/area/maintenance/fore) "aAQ" = (/obj/machinery/door/airlock/maintenance_hatch,/turf/open/floor/noslip,/area/construction/hallway{name = "Secure Workstations Hallway"}) -"aAR" = (/obj/structure/closet/cabinet,/obj/item/toy/figure/assistant,/obj/item/toy/figure/atmos,/obj/item/toy/figure/bartender,/obj/item/toy/figure/borg,/obj/item/toy/figure/botanist,/obj/item/toy/figure/captain,/obj/item/toy/figure/cargotech,/obj/item/toy/figure/ce,/obj/item/toy/figure/chaplain,/obj/item/toy/figure/chef,/obj/item/toy/figure/chemist,/obj/item/toy/figure/clown,/obj/item/toy/figure/cmo,/obj/item/toy/figure/detective,/obj/item/toy/figure/dsquad,/obj/item/toy/figure/engineer,/obj/item/toy/figure/geneticist,/obj/item/toy/figure/hop,/obj/item/toy/figure/hos,/obj/item/toy/figure/ian,/obj/item/toy/figure/janitor,/obj/item/toy/figure/lawyer,/obj/item/toy/figure/librarian,/obj/item/toy/figure/md,/obj/item/toy/figure/mime,/obj/item/toy/figure/miner,/obj/item/toy/figure/ninja,/obj/item/toy/figure/qm,/obj/item/toy/figure/rd,/obj/item/toy/figure/roboticist,/obj/item/toy/figure/scientist,/obj/item/toy/figure/secofficer,/obj/item/toy/figure/syndie,/obj/item/toy/figure/virologist,/obj/item/toy/figure/warden,/obj/item/toy/figure/wizard,/obj/item/toy/minimeteor,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/asteroid},/area/library) +"aAR" = (/obj/structure/closet/cabinet,/obj/item/toy/figure/assistant,/obj/item/toy/figure/atmos,/obj/item/toy/figure/bartender,/obj/item/toy/figure/borg,/obj/item/toy/figure/botanist,/obj/item/toy/figure/captain,/obj/item/toy/figure/cargotech,/obj/item/toy/figure/ce,/obj/item/toy/figure/chaplain,/obj/item/toy/figure/chef,/obj/item/toy/figure/chemist,/obj/item/toy/figure/clown,/obj/item/toy/figure/cmo,/obj/item/toy/figure/detective,/obj/item/toy/figure/dsquad,/obj/item/toy/figure/engineer,/obj/item/toy/figure/geneticist,/obj/item/toy/figure/hop,/obj/item/toy/figure/hos,/obj/item/toy/figure/ian,/obj/item/toy/figure/janitor,/obj/item/toy/figure/lawyer,/obj/item/toy/figure/curator,/obj/item/toy/figure/md,/obj/item/toy/figure/mime,/obj/item/toy/figure/miner,/obj/item/toy/figure/ninja,/obj/item/toy/figure/qm,/obj/item/toy/figure/rd,/obj/item/toy/figure/roboticist,/obj/item/toy/figure/scientist,/obj/item/toy/figure/secofficer,/obj/item/toy/figure/syndie,/obj/item/toy/figure/virologist,/obj/item/toy/figure/warden,/obj/item/toy/figure/wizard,/obj/item/toy/minimeteor,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/asteroid},/area/library) "aAS" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/open/floor/wood{baseturf = /turf/open/floor/plating/asteroid},/area/library) "aAT" = (/obj/item/device/radio/intercom{dir = 4;name = "Station Intercom (General)";pixel_x = 0;pixel_y = -27},/turf/open/floor/wood{baseturf = /turf/open/floor/plating/asteroid},/area/library) "aAU" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 8;initialize_directions = 11},/turf/open/floor/wood{baseturf = /turf/open/floor/plating/asteroid},/area/library) diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index c46f6ea830..267a2a7b50 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -142,15 +142,15 @@ /area/solar/auxstarboard) "aap" = ( /obj/docking_port/stationary/random{ - id = "pod_asteroid1"; - name = "asteroid" + id = "pod_lavaland1"; + name = "lavaland" }, /turf/open/space, /area/space) "aaq" = ( /obj/docking_port/stationary/random{ - id = "pod_asteroid2"; - name = "asteroid" + id = "pod_lavaland2"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -203,7 +203,7 @@ }, /obj/machinery/computer/shuttle/pod{ pixel_x = -32; - possible_destinations = "pod_asteroid1"; + possible_destinations = "pod_lavaland1"; shuttleId = "pod1" }, /obj/effect/turf_decal/stripes/line{ @@ -226,7 +226,7 @@ }, /obj/machinery/computer/shuttle/pod{ pixel_x = -32; - possible_destinations = "pod_asteroid2"; + possible_destinations = "pod_lavaland2"; shuttleId = "pod2" }, /obj/effect/turf_decal/stripes/line{ @@ -10753,7 +10753,7 @@ /obj/effect/decal/cleanable/dirt, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/loadingarea{ - baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; + baseturf = /turf/open/space; dir = 8 }, /area/quartermaster/storage) @@ -11240,7 +11240,7 @@ /area/quartermaster/storage) "awJ" = ( /turf/open/floor/plasteel/loadingarea{ - baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; + baseturf = /turf/open/space; dir = 8 }, /area/quartermaster/storage) @@ -25977,7 +25977,7 @@ }, /obj/machinery/computer/shuttle/pod{ pixel_y = -32; - possible_destinations = "pod_asteroid3"; + possible_destinations = "pod_lavaland3"; shuttleId = "pod3" }, /obj/effect/turf_decal/stripes/line{ @@ -25996,8 +25996,8 @@ "aXK" = ( /obj/docking_port/stationary/random{ dir = 4; - id = "pod_asteroid4"; - name = "asteroid" + id = "pod_lavaland4"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -31236,7 +31236,7 @@ icon_state = "1-4" }, /turf/open/floor/plasteel/loadingarea{ - baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; + baseturf = /turf/open/space; dir = 8 }, /area/quartermaster/miningdock{ @@ -34793,7 +34793,6 @@ dir = 4 }, /turf/open/floor/plasteel{ - desc = ""; icon_state = "L14" }, /area/hallway/primary/central) @@ -52476,7 +52475,7 @@ name = "Queue Shutters" }, /turf/open/floor/plasteel/loadingarea{ - baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; + baseturf = /turf/open/space; dir = 8 }, /area/hallway/primary/central) @@ -62918,7 +62917,7 @@ "cpl" = ( /obj/structure/table/wood, /obj/item/weapon/clipboard, -/obj/item/toy/figure/librarian, +/obj/item/toy/figure/curator, /obj/machinery/airalarm{ dir = 8; icon_state = "alarm0"; @@ -63736,7 +63735,7 @@ /area/library) "cqF" = ( /obj/machinery/door/morgue{ - name = "Librarian's Study"; + name = "Curator's Study"; req_access_txt = "37" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, @@ -64356,10 +64355,12 @@ /turf/open/floor/plasteel/black, /area/library) "crP" = ( -/obj/structure/dresser, -/obj/machinery/computer/security/telescreen/entertainment{ - pixel_x = -32 - }, +/obj/structure/closet/crate, +/obj/item/clothing/shoes/workboots/mining, +/obj/item/clothing/under/rank/curator/treasure_hunter, +/obj/item/clothing/suit/curator, +/obj/item/clothing/head/curator, +/obj/item/weapon/storage/backpack/satchel/explorer, /turf/open/floor/plasteel/black, /area/library) "crQ" = ( @@ -67498,7 +67499,7 @@ desc = "This looks awfully familiar..."; icon_state = "curator" }, -/obj/item/clothing/under/rank/librarian/curator, +/obj/item/clothing/under/rank/curator/treasure_hunter, /turf/open/floor/carpet, /area/crew_quarters/sleep) "cxC" = ( @@ -70986,7 +70987,6 @@ "cDW" = ( /obj/machinery/atmospherics/pipe/manifold/supply/hidden, /turf/open/floor/plasteel{ - desc = ""; icon_state = "L13"; name = "floor" }, @@ -79512,8 +79512,13 @@ name = "Medbay Central" }) "cUf" = ( -/obj/machinery/smartfridge/chemistry, -/turf/closed/wall, +/obj/structure/grille, +/obj/machinery/door/poddoor/shutters/preopen{ + id = "chemisttop"; + name = "Chemisty Lobby Shutters" + }, +/obj/structure/window/reinforced/fulltile, +/turf/open/floor/plating, /area/medical/medbay{ name = "Medbay Central" }) @@ -79536,14 +79541,9 @@ name = "Medbay Central" }) "cUh" = ( -/obj/structure/grille, -/obj/structure/window/reinforced/fulltile, -/obj/machinery/door/poddoor/shutters/preopen{ - id = "chemisttop"; - name = "Chemisty Lobby Shutters" - }, /obj/structure/disposalpipe/segment, -/turf/open/floor/plating, +/obj/machinery/smartfridge/chemistry, +/turf/closed/wall, /area/medical/medbay{ name = "Medbay Central" }) @@ -82189,6 +82189,7 @@ /obj/item/weapon/grenade/chem_grenade, /obj/item/weapon/grenade/chem_grenade, /obj/item/weapon/grenade/chem_grenade, +/obj/item/weapon/screwdriver, /turf/open/floor/plasteel/whiteyellow/corner{ icon_state = "whiteyellowcorner"; dir = 8 @@ -96353,7 +96354,6 @@ }, /area/medical/morgue) "dAn" = ( -/turf/open/floor/plating, /obj/effect/decal/cleanable/dirt, /obj/machinery/atmospherics/pipe/manifold/supply/hidden{ icon_state = "manifold"; @@ -104160,7 +104160,7 @@ name = "emergency shower" }, /turf/open/floor/plasteel/whiteblue/side{ - baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; + baseturf = /turf/open/space; dir = 4 }, /area/shuttle/escape) @@ -105516,7 +105516,7 @@ /area/library/abandoned_library) "dSu" = ( /obj/structure/table/wood, -/obj/item/clothing/under/rank/librarian, +/obj/item/clothing/under/rank/curator, /obj/effect/spawner/lootdrop/maintenance{ lootcount = 2; name = "2maintenance loot spawner" @@ -108176,7 +108176,7 @@ /area/maintenance/fpmaint2/aft_port_maintenance) "dXu" = ( /obj/structure/table/wood/fancy, -/obj/item/weapon/spellbook/oneuse/smoke, +/obj/item/weapon/spellbook/oneuse/smoke/lesser, /obj/item/weapon/nullrod, /obj/item/organ/heart, /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater, @@ -112311,6 +112311,22 @@ }, /turf/open/floor/plasteel/neutral, /area/atmos) +"ehO" = ( +/obj/structure/displaycase/trophy, +/turf/open/floor/wood, +/area/library) +"ehP" = ( +/obj/structure/displaycase/trophy, +/turf/open/floor/wood, +/area/library) +"ehQ" = ( +/obj/structure/displaycase/trophy, +/turf/open/floor/wood, +/area/library) +"ehR" = ( +/obj/structure/displaycase/trophy, +/turf/open/floor/wood, +/area/library) (1,1,1) = {" aaa @@ -143544,7 +143560,7 @@ cbA cdn ceS cgp -chQ +ehO cjl ckP cjl @@ -143801,7 +143817,7 @@ cbB cdo ceS cgq -chQ +ehO cjl ckP cjl @@ -144315,7 +144331,7 @@ bWi cdq ceS cgp -chQ +ehO cjm ckP cmk @@ -144572,7 +144588,7 @@ cbC cdr ceT cgp -chQ +ehO cjn ckP cmk diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 320823a490..f30c7b69f3 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -1910,8 +1910,8 @@ /area/shuttle/pod_3) "adG" = ( /obj/docking_port/stationary/random{ - id = "pod_asteroid2"; - name = "asteroid" + id = "pod_lavaland2"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -1927,7 +1927,7 @@ }, /obj/machinery/computer/shuttle/pod{ pixel_x = -32; - possible_destinations = "pod_asteroid2"; + possible_destinations = "pod_lavaland2"; shuttleId = "pod2" }, /turf/open/floor/mineral/titanium/blue, @@ -23696,7 +23696,7 @@ }, /obj/machinery/computer/shuttle/pod{ pixel_y = -32; - possible_destinations = "pod_asteroid3"; + possible_destinations = "pod_lavaland3"; shuttleId = "pod3" }, /turf/open/floor/mineral/titanium/blue, @@ -27963,7 +27963,6 @@ dir = 4 }, /turf/open/floor/plasteel{ - desc = ""; icon_state = "L13"; name = "floor" }, @@ -28813,7 +28812,6 @@ icon_state = "4-8" }, /turf/open/floor/plasteel{ - desc = ""; icon_state = "L14" }, /area/hallway/primary/central) @@ -34140,8 +34138,8 @@ "bii" = ( /obj/docking_port/stationary/random{ dir = 4; - id = "pod_asteroid3"; - name = "asteroid" + id = "pod_lavaland3"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -45372,12 +45370,12 @@ name = "Port Maintenance" }) "bBr" = ( -/obj/structure/table/wood, /obj/machinery/airalarm{ dir = 4; pixel_x = -23; pixel_y = 0 }, +/obj/structure/displaycase/trophy, /turf/open/floor/wood, /area/library) "bBs" = ( @@ -47035,7 +47033,6 @@ name = "\improper Auxiliary Restrooms" }) "bEw" = ( -/obj/structure/table/wood, /obj/machinery/computer/security/telescreen/entertainment{ pixel_x = -32; pixel_y = 0 @@ -47044,6 +47041,7 @@ dir = 4; network = list("SS13") }, +/obj/structure/displaycase/trophy, /turf/open/floor/wood, /area/library) "bEx" = ( @@ -53664,6 +53662,12 @@ pixel_x = 30; pixel_y = 0 }, +/obj/structure/closet/crate, +/obj/item/clothing/shoes/workboots/mining, +/obj/item/clothing/under/rank/curator/treasure_hunter, +/obj/item/clothing/suit/curator, +/obj/item/clothing/head/curator, +/obj/item/weapon/storage/backpack/satchel/explorer, /turf/open/floor/engine/cult, /area/library) "bPY" = ( @@ -82483,7 +82487,7 @@ /area/chapel/office) "cMa" = ( /obj/structure/table/wood, -/obj/item/weapon/spellbook/oneuse/smoke{ +/obj/item/weapon/spellbook/oneuse/smoke/lesser{ name = "mysterious old book of " }, /obj/item/weapon/reagent_containers/food/drinks/bottle/holywater{ @@ -86084,8 +86088,8 @@ /area/toxins/xenobiology) "cSP" = ( /obj/docking_port/stationary/random{ - id = "pod_asteroid1"; - name = "asteroid" + id = "pod_lavaland1"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -86175,7 +86179,7 @@ }, /obj/machinery/computer/shuttle/pod{ pixel_x = -32; - possible_destinations = "pod_asteroid1"; + possible_destinations = "pod_lavaland1"; shuttleId = "pod1" }, /turf/open/floor/mineral/titanium/blue, @@ -86368,7 +86372,7 @@ }, /obj/machinery/computer/shuttle/pod{ pixel_y = -32; - possible_destinations = "pod_asteroid4"; + possible_destinations = "pod_lavaland4"; shuttleId = "pod4" }, /turf/open/floor/mineral/titanium/blue, @@ -87162,8 +87166,8 @@ "cUL" = ( /obj/docking_port/stationary/random{ dir = 4; - id = "pod_asteroid4"; - name = "asteroid" + id = "pod_lavaland4"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -95333,6 +95337,14 @@ icon_state = "xenomaint"; name = "Xeno Maintenance" }) +"dmD" = ( +/obj/structure/displaycase/trophy, +/turf/open/floor/wood, +/area/library) +"dmE" = ( +/obj/structure/displaycase/trophy, +/turf/open/floor/wood, +/area/library) (1,1,1) = {" aaa @@ -114481,7 +114493,7 @@ bwa bxU bzD bBr -bCT +bSx bEw bzE bHR @@ -114737,9 +114749,9 @@ bue bwb bxV bzE -bBs -bCU -bBs +dmD +bzE +dmD bzE bHR bJz @@ -128192,7 +128204,7 @@ cRi cRi daP cLE -cRi +dlV aaa aaa aaf @@ -128448,7 +128460,7 @@ daF daJ cRi bvT -dlV +cRi cRi cRi cRi @@ -128705,7 +128717,7 @@ cSn cSn cRi dmq -dlV +cRi cZv cZv cRi @@ -129733,7 +129745,7 @@ cSn daN cRi dmr -dlV +cRi cZv dbw cRi @@ -129990,7 +130002,7 @@ daI daM cRi cTA -dlV +cRi cRi cRi cRi diff --git a/_maps/map_files/Mining/Lavaland.dmm b/_maps/map_files/Mining/Lavaland.dmm index 778fb50c88..c37c4ca3a3 100644 --- a/_maps/map_files/Mining/Lavaland.dmm +++ b/_maps/map_files/Mining/Lavaland.dmm @@ -513,7 +513,7 @@ /obj/structure/cable{ d1 = 1; d2 = 4; - icon_state = "1-4"; + icon_state = "1-4" }, /obj/structure/cable{ d1 = 1; @@ -1040,7 +1040,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/brown{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; - dir = 1; + dir = 1 }, /area/mine/living_quarters) "cg" = ( @@ -1074,7 +1074,7 @@ /obj/structure/cable{ d1 = 1; d2 = 4; - icon_state = "1-4"; + icon_state = "1-4" }, /turf/open/floor/plasteel{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface @@ -1497,10 +1497,21 @@ /area/mine/living_quarters) "dd" = ( /obj/structure/table, -/obj/item/weapon/reagent_containers/food/drinks/beer, +/obj/item/weapon/reagent_containers/food/drinks/beer{ + pixel_x = 7; + pixel_y = 5 + }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 5 }, +/obj/item/weapon/reagent_containers/food/drinks/beer{ + pixel_x = -1; + pixel_y = 9 + }, +/obj/item/weapon/reagent_containers/food/drinks/beer{ + pixel_x = -8; + pixel_y = 0 + }, /turf/open/floor/plasteel/bar{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface }, @@ -1772,6 +1783,9 @@ pixel_x = -5; pixel_y = 30 }, +/obj/machinery/shower{ + dir = 8 + }, /turf/open/floor/plasteel/purple/corner{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface }, @@ -2192,7 +2206,7 @@ }, /turf/open/floor/plasteel/vault{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; - dir = 8; + dir = 8 }, /area/mine/maintenance) "ez" = ( @@ -2214,13 +2228,13 @@ /obj/machinery/iv_drip, /turf/open/floor/plasteel/whiteblue/side{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; - dir = 1; + dir = 1 }, /area/mine/living_quarters) "eB" = ( /turf/open/floor/plasteel/whiteblue/side{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; - dir = 1; + dir = 1 }, /area/mine/living_quarters) "eC" = ( @@ -2231,7 +2245,7 @@ }, /turf/open/floor/plasteel/whiteblue/side{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; - dir = 5; + dir = 5 }, /area/mine/living_quarters) "eD" = ( @@ -2398,7 +2412,7 @@ /obj/item/weapon/storage/firstaid/regular, /turf/open/floor/plasteel/whiteblue/side{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; - dir = 4; + dir = 4 }, /area/mine/living_quarters) "eU" = ( @@ -2512,6 +2526,7 @@ dir = 2; network = list("MINE") }, +/obj/structure/reagent_dispensers/watertank, /turf/open/floor/plasteel/brown{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 5 @@ -2520,7 +2535,7 @@ "fe" = ( /turf/open/floor/plasteel/brown/corner{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; - dir = 1; + dir = 1 }, /area/mine/production) "ff" = ( @@ -2578,7 +2593,7 @@ }, /turf/open/floor/plasteel/brown{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; - dir = 1; + dir = 1 }, /area/mine/living_quarters) "fm" = ( @@ -2600,7 +2615,7 @@ /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/brown{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; - dir = 1; + dir = 1 }, /area/mine/living_quarters) "fp" = ( @@ -2674,7 +2689,7 @@ /obj/structure/cable{ d1 = 1; d2 = 4; - icon_state = "1-4"; + icon_state = "1-4" }, /turf/open/floor/plasteel{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface @@ -2712,6 +2727,10 @@ /obj/machinery/light/small{ dir = 1 }, +/obj/structure/extinguisher_cabinet{ + pixel_x = -5; + pixel_y = 30 + }, /turf/open/floor/plasteel/purple/corner{ baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; dir = 4 @@ -2794,6 +2813,41 @@ /turf/open/floor/plating/asteroid/basalt/lava_land_surface, /turf/closed/indestructible/riveted, /area/space) +"fQ" = ( +/obj/machinery/shower{ + dir = 8 + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel/white, +/area/mine/laborcamp) +"fR" = ( +/obj/structure/sink/kitchen{ + dir = 4; + icon_state = "sink_alt"; + pixel_x = -13; + tag = "icon-sink_alt (EAST)" + }, +/turf/open/floor/plasteel{ + baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface + }, +/area/mine/laborcamp) +"fS" = ( +/obj/structure/reagent_dispensers/watertank, +/turf/open/floor/plasteel/purple/corner{ + baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface + }, +/area/mine/production) +"fT" = ( +/obj/structure/sink{ + dir = 4; + icon_state = "sink"; + pixel_x = 11; + tag = "icon-sink (EAST)" + }, +/turf/open/floor/plasteel/bar{ + baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface + }, +/area/mine/living_quarters) (1,1,1) = {" aa @@ -8919,7 +8973,7 @@ aA at at at -at +fR at au fH @@ -9175,7 +9229,7 @@ an an at at -at +fQ at dr an @@ -14594,8 +14648,8 @@ fj ee cT cZ -dg dk +fT ee al al @@ -18433,7 +18487,7 @@ af ab ab dx -dC +fS dK bI bS diff --git a/_maps/map_files/OmegaStation/OmegaStation.dmm b/_maps/map_files/OmegaStation/OmegaStation.dmm index 0e3fea852f..2af4f3bd30 100644 --- a/_maps/map_files/OmegaStation/OmegaStation.dmm +++ b/_maps/map_files/OmegaStation/OmegaStation.dmm @@ -7303,7 +7303,6 @@ icon_state = "1-2" }, /turf/open/floor/plasteel{ - desc = ""; icon_state = "L14" }, /area/hallway/primary/central{ @@ -9155,7 +9154,7 @@ }, /obj/effect/landmark/start/shaft_miner, /turf/open/floor/plasteel/loadingarea{ - baseturf = /turf/open/floor/plating/lava/smooth/lava_land_surface; + baseturf = /turf/open/space; dir = 8 }, /area/quartermaster/miningdock) @@ -16523,6 +16522,9 @@ /obj/machinery/status_display{ pixel_x = -32 }, +/obj/machinery/light{ + dir = 8 + }, /turf/open/floor/mineral/plastitanium/brig, /area/shuttle/escape) "aAb" = ( @@ -16558,6 +16560,9 @@ "aAf" = ( /obj/structure/table/reinforced, /obj/item/weapon/storage/fancy/donut_box, +/obj/machinery/light{ + dir = 4 + }, /turf/open/floor/plasteel/vault{ dir = 8 }, @@ -24133,6 +24138,9 @@ }, /obj/effect/decal/cleanable/dirt, /obj/effect/turf_decal/delivery, +/obj/machinery/light{ + dir = 8 + }, /turf/open/floor/plasteel, /area/shuttle/escape) "aME" = ( @@ -24187,6 +24195,9 @@ /obj/machinery/status_display{ pixel_x = 32 }, +/obj/machinery/light{ + dir = 4 + }, /turf/open/floor/plasteel/whiteblue/side{ dir = 5 }, @@ -25964,7 +25975,6 @@ icon_state = "4-8" }, /turf/open/floor/plasteel{ - desc = ""; icon_state = "L13"; name = "floor" }, @@ -30548,7 +30558,7 @@ /area/maintenance/starboard) "aXL" = ( /obj/machinery/door/morgue{ - name = "Librarian's Study"; + name = "Curator's Study"; req_access_txt = "37" }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, @@ -41920,6 +41930,294 @@ /area/ruin/unpowered{ name = "Asteroid" }) +"bvO" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/plasteel/neutral/side{ + dir = 1 + }, +/area/shuttle/escape) +"bvP" = ( +/obj/structure/chair{ + dir = 8 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/light/small{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/shuttle/escape) +"bvQ" = ( +/obj/structure/chair{ + dir = 4 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/light/small{ + dir = 8 + }, +/turf/open/floor/plasteel, +/area/shuttle/escape) +"bvR" = ( +/obj/machinery/light, +/turf/open/floor/plasteel/neutral/side, +/area/shuttle/escape) +"bvS" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bvT" = ( +/obj/structure/grille, +/obj/structure/window/shuttle, +/turf/open/floor/plating, +/area/shuttle/transport) +"bvU" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bvV" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bvW" = ( +/obj/machinery/door/airlock/external, +/turf/open/floor/pod/dark, +/area/shuttle/transport) +"bvX" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bvY" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bvZ" = ( +/obj/structure/grille, +/obj/structure/window/shuttle, +/turf/open/floor/plating, +/area/shuttle/transport) +"bwa" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bwb" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "propulsion_l" + }, +/turf/open/floor/plating/airless, +/area/shuttle/transport) +"bwc" = ( +/obj/structure/shuttle/engine/heater{ + icon_state = "heater"; + dir = 8 + }, +/obj/structure/window/reinforced, +/turf/open/floor/plating/airless, +/area/shuttle/transport) +"bwd" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bwe" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bwf" = ( +/obj/structure/chair, +/turf/open/floor/pod/dark, +/area/shuttle/transport) +"bwg" = ( +/obj/structure/chair, +/turf/open/floor/pod/dark, +/area/shuttle/transport) +"bwh" = ( +/obj/machinery/light{ + dir = 1 + }, +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwi" = ( +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwj" = ( +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwk" = ( +/obj/structure/chair, +/turf/open/floor/pod/dark, +/area/shuttle/transport) +"bwl" = ( +/obj/structure/chair, +/turf/open/floor/pod/dark, +/area/shuttle/transport) +"bwm" = ( +/obj/structure/grille, +/obj/structure/window/shuttle, +/turf/open/floor/plating, +/area/shuttle/transport) +"bwn" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "propulsion_l" + }, +/turf/open/floor/plating/airless, +/area/shuttle/transport) +"bwo" = ( +/obj/structure/shuttle/engine/heater{ + icon_state = "heater"; + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 4; + pixel_x = 0 + }, +/turf/open/floor/plating/airless, +/area/shuttle/transport) +"bwp" = ( +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwq" = ( +/obj/machinery/light/small, +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwr" = ( +/obj/machinery/door/airlock/titanium, +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bws" = ( +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwt" = ( +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwu" = ( +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwv" = ( +/obj/machinery/computer/shuttle/ferry/request, +/turf/open/floor/pod/dark, +/area/shuttle/transport) +"bww" = ( +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwx" = ( +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwy" = ( +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwz" = ( +/obj/machinery/door/airlock/titanium, +/obj/docking_port/mobile{ + dir = 8; + dwidth = 2; + height = 13; + id = "ferry"; + name = "ferry shuttle"; + port_angle = 0; + preferred_direction = 4; + roundstart_move = "ferry_away"; + width = 5 + }, +/obj/docking_port/stationary{ + dir = 8; + dwidth = 2; + height = 13; + id = "ferry_home"; + name = "port bay 2"; + turf_type = /turf/open/space; + width = 5 + }, +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwA" = ( +/obj/structure/shuttle/engine/propulsion{ + dir = 8; + icon_state = "propulsion_l" + }, +/turf/open/floor/plating/airless, +/area/shuttle/transport) +"bwB" = ( +/obj/structure/shuttle/engine/heater{ + icon_state = "heater"; + dir = 8 + }, +/obj/structure/window/reinforced{ + dir = 1; + pixel_y = 1 + }, +/turf/open/floor/plating/airless, +/area/shuttle/transport) +"bwC" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bwD" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bwE" = ( +/obj/structure/chair{ + dir = 1 + }, +/turf/open/floor/pod/dark, +/area/shuttle/transport) +"bwF" = ( +/obj/structure/chair{ + dir = 1 + }, +/turf/open/floor/pod/dark, +/area/shuttle/transport) +"bwG" = ( +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwH" = ( +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwI" = ( +/obj/machinery/light, +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwJ" = ( +/obj/structure/chair{ + dir = 1 + }, +/turf/open/floor/pod/dark, +/area/shuttle/transport) +"bwK" = ( +/obj/structure/chair{ + dir = 1 + }, +/turf/open/floor/pod/dark, +/area/shuttle/transport) +"bwL" = ( +/obj/structure/grille, +/obj/structure/window/shuttle, +/turf/open/floor/plating, +/area/shuttle/transport) +"bwM" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bwN" = ( +/obj/structure/grille, +/obj/structure/window/shuttle, +/turf/open/floor/plating, +/area/shuttle/transport) +"bwO" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bwP" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bwQ" = ( +/obj/machinery/door/airlock/external, +/turf/open/floor/pod/light, +/area/shuttle/transport) +"bwR" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bwS" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) +"bwT" = ( +/obj/structure/grille, +/obj/structure/window/shuttle, +/turf/open/floor/plating, +/area/shuttle/transport) +"bwU" = ( +/turf/closed/wall/mineral/titanium, +/area/shuttle/transport) (1,1,1) = {" aaa @@ -77290,7 +77588,7 @@ aaa aaa aaa aaa -aaa +bwn aaa aaa aaa @@ -77546,9 +77844,9 @@ aaa aaa aaa aaa -aaa -aaa -aaa +bwb +bwo +bwA aaa aaa aaa @@ -77803,9 +78101,9 @@ aaa aaa aaa aaa -aaa -aaa -aaa +bwc +bwp +bwB aaa aaa aaa @@ -78060,9 +78358,9 @@ aaa aaa aaa aaa -aaa -aaa -aaa +bwd +bwq +bwC aaa aaa aaa @@ -78316,11 +78614,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +bvS +bwe +bwr +bwD +bwM aaa aaa aaa @@ -78573,11 +78871,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +bvT +bwf +bws +bwE +bwN aaa aaa aaa @@ -78830,11 +79128,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +bvU +bwg +bwt +bwF +bwO aaa aaa aaa @@ -79087,11 +79385,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +bvV +bwh +bwu +bwG +bwP aaa aaa aaa @@ -79344,11 +79642,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +bvW +bwi +bwv +bwH +bwQ aaa aaa aaa @@ -79601,11 +79899,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +bvX +bwj +bww +bwI +bwR aaa aaa aaa @@ -79858,11 +80156,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +bvY +bwk +bwx +bwJ +bwS aaa aaa aaa @@ -80115,11 +80413,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +bvZ +bwl +bwy +bwK +bwT aaa aaa aaa @@ -80372,11 +80670,11 @@ aaa aaa aaa aaa -aaa -aaa -aaa -aaa -aaa +bwa +bwm +bwz +bwL +bwU aaa aaa aaa @@ -94203,7 +94501,7 @@ aAb axY aDl aEi -aEi +bvP aEi aEi aEi @@ -94715,13 +95013,13 @@ axY aAc axY aCp -aDl +bvO aEk aEj aGd aEl aEk -aJf +bvR aKn aLz axY @@ -95231,7 +95529,7 @@ aAd aCq aDl aEm -aEm +bvQ aEm aEm aEm diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index e0e721840d..56bcff286e 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -15105,7 +15105,7 @@ /area/maintenance/apmaint) "aEl" = ( /obj/structure/closet/coffin, -/obj/item/toy/figure/librarian, +/obj/item/toy/figure/curator, /turf/open/floor/plating, /area/maintenance/apmaint) "aEm" = ( @@ -32850,10 +32850,6 @@ /turf/open/floor/plasteel/white, /area/toxins/xenobiology) "bnU" = ( -/obj/machinery/door/airlock/research{ - name = "Kill Room Access"; - req_access_txt = "55" - }, /obj/structure/disposalpipe/segment{ dir = 4 }, diff --git a/_maps/map_files/PubbyStation/job_changes.dm b/_maps/map_files/PubbyStation/job_changes.dm index 8b26cd5b68..d366a15ae3 100644 --- a/_maps/map_files/PubbyStation/job_changes.dm +++ b/_maps/map_files/PubbyStation/job_changes.dm @@ -18,5 +18,5 @@ access += GLOB.access_crematorium minimal_access += GLOB.access_crematorium -MAP_REMOVE_JOB(librarian) +MAP_REMOVE_JOB(curator) MAP_REMOVE_JOB(lawyer) \ No newline at end of file diff --git a/_maps/map_files/TgStation/tgstation.2.1.3.dmm b/_maps/map_files/TgStation/tgstation.2.1.3.dmm index f2bf5eb504..220c1bd671 100644 --- a/_maps/map_files/TgStation/tgstation.2.1.3.dmm +++ b/_maps/map_files/TgStation/tgstation.2.1.3.dmm @@ -2501,7 +2501,7 @@ "afq" = ( /obj/machinery/computer/shuttle/pod{ pixel_y = -32; - possible_destinations = "pod_asteroid3"; + possible_destinations = "pod_lavaland3"; shuttleId = "pod3" }, /obj/structure/chair{ @@ -7787,8 +7787,8 @@ "aqG" = ( /obj/docking_port/stationary/random{ dir = 4; - id = "pod_asteroid3"; - name = "asteroid" + id = "pod_lavaland3"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -17330,7 +17330,6 @@ /area/hallway/primary/central) "aMf" = ( /turf/open/floor/plasteel{ - desc = ""; icon_state = "L13"; name = "floor" }, @@ -17836,7 +17835,6 @@ /area/hallway/primary/central) "aNB" = ( /turf/open/floor/plasteel{ - desc = ""; icon_state = "L14" }, /area/hallway/primary/central) @@ -19015,6 +19013,12 @@ /turf/open/floor/wood, /area/library) "aQr" = ( +/obj/structure/closet/crate, +/obj/item/clothing/shoes/workboots/mining, +/obj/item/clothing/under/rank/curator/treasure_hunter, +/obj/item/clothing/suit/curator, +/obj/item/clothing/head/curator, +/obj/item/weapon/storage/backpack/satchel/explorer, /obj/machinery/light/small, /turf/open/floor/engine/cult, /area/library) @@ -19510,7 +19514,7 @@ /turf/open/floor/wood, /area/library) "aRO" = ( -/obj/structure/bookcase/random/nonfiction, +/obj/structure/displaycase/trophy, /turf/open/floor/wood, /area/library) "aRP" = ( @@ -53823,8 +53827,8 @@ "cpe" = ( /obj/docking_port/stationary/random{ dir = 8; - id = "pod_asteroid2"; - name = "asteroid" + id = "pod_lavaland2"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -54079,7 +54083,7 @@ /obj/machinery/computer/shuttle/pod{ pixel_x = 0; pixel_y = -32; - possible_destinations = "pod_asteroid2"; + possible_destinations = "pod_lavaland2"; shuttleId = "pod2" }, /obj/structure/chair{ @@ -57394,8 +57398,8 @@ "cwV" = ( /obj/docking_port/stationary/random{ dir = 8; - id = "pod_asteroid1"; - name = "asteroid" + id = "pod_lavaland1"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -57508,7 +57512,7 @@ /obj/machinery/computer/shuttle/pod{ pixel_x = 0; pixel_y = -32; - possible_destinations = "pod_asteroid1"; + possible_destinations = "pod_lavaland1"; shuttleId = "pod1" }, /obj/structure/chair{ @@ -58424,7 +58428,7 @@ "czL" = ( /obj/machinery/computer/shuttle/pod{ pixel_y = -32; - possible_destinations = "pod_asteroid4"; + possible_destinations = "pod_lavaland4"; shuttleId = "pod4" }, /obj/structure/chair{ @@ -58455,8 +58459,8 @@ "czN" = ( /obj/docking_port/stationary/random{ dir = 4; - id = "pod_asteroid4"; - name = "asteroid" + id = "pod_lavaland4"; + name = "lavaland" }, /turf/open/space, /area/space) @@ -106507,7 +106511,7 @@ aIt aPd aIt aRO -aIt +aRO aUC aVP aXu @@ -106764,7 +106768,7 @@ aNV aPd aIt aRO -aIt +aRO aIt aVQ aXu diff --git a/_maps/map_files/generic/Centcomm.dmm b/_maps/map_files/generic/Centcomm.dmm index 9f7787b585..e3870a49f8 100644 --- a/_maps/map_files/generic/Centcomm.dmm +++ b/_maps/map_files/generic/Centcomm.dmm @@ -5586,7 +5586,7 @@ /area/centcom/ferry) "ot" = ( /obj/structure/closet/secure_closet/personal/cabinet, -/obj/item/clothing/under/rank/librarian/curator, +/obj/item/clothing/under/rank/curator/treasure_hunter, /obj/item/clothing/under/skirt/black, /obj/item/clothing/under/shorts/black, /obj/item/clothing/under/pants/track, diff --git a/code/__DEFINES/MC.dm b/code/__DEFINES/MC.dm index eb148e7b59..ebc69a5f2b 100644 --- a/code/__DEFINES/MC.dm +++ b/code/__DEFINES/MC.dm @@ -13,6 +13,10 @@ #define MC_AVERAGE_FAST(average, current) (0.7 * (average) + 0.3 * (current)) #define MC_AVERAGE(average, current) (0.8 * (average) + 0.2 * (current)) #define MC_AVERAGE_SLOW(average, current) (0.9 * (average) + 0.1 * (current)) + +#define MC_AVG_FAST_UP_SLOW_DOWN(average, current) (average > current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current)) +#define MC_AVG_SLOW_UP_FAST_DOWN(average, current) (average < current ? MC_AVERAGE_SLOW(average, current) : MC_AVERAGE_FAST(average, current)) + #define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;} #define START_PROCESSING(Processor, Datum) if (!Datum.isprocessing) {Datum.isprocessing = 1;Processor.processing += Datum} diff --git a/code/__DEFINES/antagonists.dm b/code/__DEFINES/antagonists.dm index d30a2d098f..433f44e095 100644 --- a/code/__DEFINES/antagonists.dm +++ b/code/__DEFINES/antagonists.dm @@ -1,3 +1,4 @@ -#define ANTAG_DATUM_CULT /datum/antagonist/cult -#define ANTAG_DATUM_CLOCKCULT /datum/antagonist/clockcult -#define ANTAG_DATUM_CLOCKCULT_SILENT /datum/antagonist/clockcult/silent \ No newline at end of file +#define ANTAG_DATUM_CULT /datum/antagonist/cult +#define ANTAG_DATUM_CULT_MASTER /datum/antagonist/cult/master +#define ANTAG_DATUM_CLOCKCULT /datum/antagonist/clockcult +#define ANTAG_DATUM_CLOCKCULT_SILENT /datum/antagonist/clockcult/silent \ No newline at end of file diff --git a/code/__DEFINES/clockcult.dm b/code/__DEFINES/clockcult.dm index 9c86e031ab..acc0cdc9ab 100644 --- a/code/__DEFINES/clockcult.dm +++ b/code/__DEFINES/clockcult.dm @@ -37,15 +37,15 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us #define JUDGEMENT_CV_REQ 300 //general component/cooldown things -#define SLAB_PRODUCTION_TIME 900 //how long(deciseconds) slabs require to produce a single component; defaults to 1 minute 30 seconds +#define SLAB_PRODUCTION_TIME 450 //how long(deciseconds) slabs require to produce a single component; defaults to 45 seconds -#define SLAB_SERVANT_SLOWDOWN 300 //how much each servant above 5 slows down slab-based generation; defaults to 30 seconds per sevant +#define SLAB_SERVANT_SLOWDOWN 150 //how much each servant above 5 slows down slab-based generation; defaults to 15 seconds per sevant -#define SLAB_SLOWDOWN_MAXIMUM 2700 //maximum slowdown from additional servants; defaults to 4 minutes 30 seconds +#define SLAB_SLOWDOWN_MAXIMUM 1350 //maximum slowdown from additional servants; defaults to 2 minutes 15 seconds -#define CACHE_PRODUCTION_TIME 600 //how long(deciseconds) caches require to produce a component; defaults to 1 minute +#define CACHE_PRODUCTION_TIME 300 //how long(deciseconds) caches require to produce a component; defaults to 30 seconds -#define ACTIVE_CACHE_SLOWDOWN 100 //how many additional deciseconds caches take to produce a component for each linked cache; defaults to 10 seconds +#define ACTIVE_CACHE_SLOWDOWN 50 //how many additional deciseconds caches take to produce a component for each linked cache; defaults to 5 seconds #define LOWER_PROB_PER_COMPONENT 10 //how much each component in the cache reduces the weight of getting another of that component type @@ -87,9 +87,9 @@ GLOBAL_LIST_EMPTY(all_scripture) //a list containing scripture instances; not us #define GATEWAY_RATVAR_ARRIVAL 300 //when progress is at or above this, game over ratvar's here everybody go home -#define ARK_SUMMON_COST 3 //how many of each component an Ark costs to summon +#define ARK_SUMMON_COST 5 //how many of each component an Ark costs to summon -#define ARK_CONSUME_COST 7 //how many of each component an Ark needs to consume to activate +#define ARK_CONSUME_COST 15 //how many of each component an Ark needs to consume to activate //Objective text define #define CLOCKCULT_OBJECTIVE "Construct the Ark of the Clockwork Justicar and free Ratvar." diff --git a/code/__DEFINES/jobs.dm b/code/__DEFINES/jobs.dm index 6d5310364f..cea01afc2a 100644 --- a/code/__DEFINES/jobs.dm +++ b/code/__DEFINES/jobs.dm @@ -32,7 +32,7 @@ #define BOTANIST (1<<2) #define COOK (1<<3) #define JANITOR (1<<4) -#define LIBRARIAN (1<<5) +#define CURATOR (1<<5) #define QUARTERMASTER (1<<6) #define CARGOTECH (1<<7) #define MINER (1<<8) diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index fd98a68e07..7cfed2b483 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -16,10 +16,10 @@ #define LIGHTING_BASE_MATRIX \ list \ ( \ - LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ - LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ - LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ - LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ + 1, 1, 1, 0, \ + 1, 1, 1, 0, \ + 1, 1, 1, 0, \ + 1, 1, 1, 0, \ 0, 0, 0, 1 \ ) \ @@ -78,4 +78,11 @@ #define DYNAMIC_LIGHTING_ENABLED 1 //dynamic lighting enabled #define DYNAMIC_LIGHTING_FORCED 2 //dynamic lighting enabled even if the area doesn't require power #define DYNAMIC_LIGHTING_IFSTARLIGHT 3 //dynamic lighting enabled only if starlight is. -#define IS_DYNAMIC_LIGHTING(A) A.dynamic_lighting \ No newline at end of file +#define IS_DYNAMIC_LIGHTING(A) A.dynamic_lighting + + +//code assumes higher numbers override lower numbers. +#define LIGHTING_NO_UPDATE 0 +#define LIGHTING_VIS_UPDATE 1 +#define LIGHTING_CHECK_UPDATE 2 +#define LIGHTING_FORCE_UPDATE 3 \ No newline at end of file diff --git a/code/__DEFINES/menu.dm b/code/__DEFINES/menu.dm new file mode 100644 index 0000000000..2730adf87c --- /dev/null +++ b/code/__DEFINES/menu.dm @@ -0,0 +1,3 @@ +#define CHECKBOX_NONE 0 +#define CHECKBOX_GROUP 1 +#define CHECKBOX_TOGGLE 2 \ No newline at end of file diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index bc5816dbb9..043158da11 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -31,5 +31,10 @@ ///////////// #define STATUS_EFFECT_SIGILMARK /datum/status_effect/sigil_mark +#define STATUS_EFFECT_BELLIGERENT /datum/status_effect/belligerent //forces the affected to walk, doing damage if they try to run + +#define STATUS_EFFECT_MANIAMOTOR /datum/status_effect/maniamotor //disrupts, damages, and confuses the affected as long as they're in range of the motor +#define MAX_MANIA_SEVERITY 100 //how high the mania severity can go +#define MANIA_DAMAGE_TO_CONVERT 90 //how much damage is required before it'll convert affected targets #define STATUS_EFFECT_HISWRATH /datum/status_effect/his_wrath //His Wrath. diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index c0797819bc..8f340bff46 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -457,6 +457,7 @@ #define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= L.len ? L[I] : null) : L[I]) : null) #define LAZYLEN(L) length(L) #define LAZYCLEARLIST(L) if(L) L.Cut() +#define SANITIZE_LIST(L) ( islist(L) ? L : list() ) /* Definining a counter as a series of key -> numeric value entries diff --git a/code/__HELPERS/_logging.dm b/code/__HELPERS/_logging.dm index 2785ba896f..a2a878211a 100644 --- a/code/__HELPERS/_logging.dm +++ b/code/__HELPERS/_logging.dm @@ -20,13 +20,13 @@ /proc/log_admin(text) GLOB.admin_log.Add(text) if (config.log_admin) - GLOB.diary << "\[[time_stamp()]]ADMIN: [text]" + GLOB.world_game_log << "\[[time_stamp()]]ADMIN: [text]" //Items using this proc are stripped from public logs - use with caution /proc/log_admin_private(text) GLOB.admin_log.Add(text) if (config.log_admin) - GLOB.diary << "\[[time_stamp()]]ADMINPRIVATE: [text]" + GLOB.world_game_log << "\[[time_stamp()]]ADMINPRIVATE: [text]" /proc/log_adminsay(text) if (config.log_adminchat) @@ -38,67 +38,64 @@ /proc/log_game(text) if (config.log_game) - GLOB.diary << "\[[time_stamp()]]GAME: [text]" + GLOB.world_game_log << "\[[time_stamp()]]GAME: [text]" /proc/log_vote(text) if (config.log_vote) - GLOB.diary << "\[[time_stamp()]]VOTE: [text]" + GLOB.world_game_log << "\[[time_stamp()]]VOTE: [text]" /proc/log_access(text) if (config.log_access) - GLOB.diary << "\[[time_stamp()]]ACCESS: [text]" + GLOB.world_game_log << "\[[time_stamp()]]ACCESS: [text]" /proc/log_say(text) if (config.log_say) - GLOB.diary << "\[[time_stamp()]]SAY: [text]" + GLOB.world_game_log << "\[[time_stamp()]]SAY: [text]" /proc/log_prayer(text) if (config.log_prayer) - GLOB.diary << "\[[time_stamp()]]PRAY: [text]" + GLOB.world_game_log << "\[[time_stamp()]]PRAY: [text]" /proc/log_law(text) if (config.log_law) - GLOB.diary << "\[[time_stamp()]]LAW: [text]" + GLOB.world_game_log << "\[[time_stamp()]]LAW: [text]" /proc/log_ooc(text) if (config.log_ooc) - GLOB.diary << "\[[time_stamp()]]OOC: [text]" + GLOB.world_game_log << "\[[time_stamp()]]OOC: [text]" /proc/log_whisper(text) if (config.log_whisper) - GLOB.diary << "\[[time_stamp()]]WHISPER: [text]" + GLOB.world_game_log << "\[[time_stamp()]]WHISPER: [text]" /proc/log_emote(text) if (config.log_emote) - GLOB.diary << "\[[time_stamp()]]EMOTE: [text]" + GLOB.world_game_log << "\[[time_stamp()]]EMOTE: [text]" /proc/log_attack(text) if (config.log_attack) - GLOB.diaryofmeanpeople << "\[[time_stamp()]]ATTACK: [text]" + GLOB.world_attack_log << "\[[time_stamp()]]ATTACK: [text]" /proc/log_pda(text) if (config.log_pda) - GLOB.diary << "\[[time_stamp()]]PDA: [text]" + GLOB.world_game_log << "\[[time_stamp()]]PDA: [text]" /proc/log_comment(text) if (config.log_pda) //reusing the PDA option because I really don't think news comments are worth a config option - GLOB.diary << "\[[time_stamp()]]COMMENT: [text]" + GLOB.world_game_log << "\[[time_stamp()]]COMMENT: [text]" /proc/log_chat(text) if (config.log_pda) - GLOB.diary << "\[[time_stamp()]]CHAT: [text]" + GLOB.world_game_log << "\[[time_stamp()]]CHAT: [text]" /proc/log_sql(text) if(config.sql_enabled) - GLOB.diary << "\[[time_stamp()]]SQL: [text]" + GLOB.world_game_log << "\[[time_stamp()]]SQL: [text]" //This replaces world.log so it displays both in DD and the file /proc/log_world(text) - if(config && config.log_runtimes) - world.log = GLOB.runtime_diary - world.log << text - world.log = null + GLOB.world_runtime_log << text world.log << text // Helper procs for building detailed log lines diff --git a/code/__HELPERS/bandetect.dm b/code/__HELPERS/bandetect.dm deleted file mode 100644 index 19c0d37838..0000000000 --- a/code/__HELPERS/bandetect.dm +++ /dev/null @@ -1,37 +0,0 @@ -#define YOUNG 4 - - -/client/proc/join_date_check(y,m,d) - var/datum/DBQuery/query_datediff = SSdbcore.NewQuery("SELECT DATEDIFF(Now(),'[y]-[m]-[d]')") - - if(!query_datediff.Execute()) - return FALSE - - if(query_datediff.NextRow()) - var/diff = text2num(query_datediff.item[1]) - if(config.use_account_age_for_jobs) - player_age = max(0,diff) //So job code soesn't freak out if they are time traveling. - if(diff < YOUNG) - var/msg = "(IP: [address], ID: [computer_id]) is a new BYOND account made on [y]-[m]-[d]." - if(diff < 0) - msg += " They are also apparently from the future." - message_admins("[key_name_admin(src)] [msg]") - return TRUE -#undef YOUNG - - -/client/proc/findJoinDate() - var/http[] = world.Export("http://byond.com/members/[src.ckey]?format=text") - if(!http) - log_world("Failed to connect to byond age check for [src.ckey]") - return FALSE - - var/F = file2text(http["CONTENT"]) - if(F) - var/regex/R = regex("joined = \"(\\d{4})-(\\d{2})-(\\d{2})\"") - if(!R.Find(F)) - CRASH("Age check regex failed") - var/y = R.group[1] - var/m = R.group[2] - var/d = R.group[3] - return join_date_check(y,m,d) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 6bc79fb7d5..db405d2878 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -6,6 +6,7 @@ ) #define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL)) +#define CULT_POLL_WAIT 2400 /proc/get_area(atom/A) if (!istype(A)) @@ -313,10 +314,10 @@ // Will return a list of active candidates. It increases the buffer 5 times until it finds a candidate which is active within the buffer. -/proc/get_candidates(be_special_type, afk_bracket = config.inactivity_period, jobbanType) +/proc/get_candidates(be_special_type, afk_bracket = config.inactivity_period, jobbanType) var/list/candidates = list() // Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000)) - while(!candidates.len && afk_bracket < config.afk_period) + while(!candidates.len && afk_bracket < config.afk_period) for(var/mob/dead/observer/G in GLOB.player_list) if(G.client != null) if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) @@ -414,68 +415,83 @@ return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y) -/proc/showCandidatePollWindow(mob/dead/observer/G, poll_time, Question, list/candidates, ignore_category, time_passed, flashwindow = TRUE) +/proc/showCandidatePollWindow(mob/M, poll_time, Question, list/candidates, ignore_category, time_passed, flashwindow = TRUE) set waitfor = 0 - G << 'sound/misc/notice2.ogg' //Alerting them to their consideration + M << 'sound/misc/notice2.ogg' //Alerting them to their consideration if(flashwindow) - window_flash(G.client) - switch(ignore_category ? askuser(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No","Never for this round", StealFocus=0, Timeout=poll_time) : askuser(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No", StealFocus=0, Timeout=poll_time)) + window_flash(M.client) + switch(ignore_category ? askuser(M,Question,"Please answer in [poll_time/10] seconds!","Yes","No","Never for this round", StealFocus=0, Timeout=poll_time) : askuser(M,Question,"Please answer in [poll_time/10] seconds!","Yes","No", StealFocus=0, Timeout=poll_time)) if(1) - to_chat(G, "Choice registered: Yes.") + to_chat(M, "Choice registered: Yes.") if((world.time-time_passed)>poll_time) - to_chat(G, "Sorry, you were too late for the consideration!") - G << 'sound/machines/buzz-sigh.ogg' + to_chat(M, "Sorry, you answered too late to be considered!") + M << 'sound/machines/buzz-sigh.ogg' + candidates -= M else - candidates += G + candidates += M if(2) - to_chat(G, "Choice registered: No.") + to_chat(M, "Choice registered: No.") + candidates -= M if(3) var/list/L = GLOB.poll_ignore[ignore_category] if(!L) GLOB.poll_ignore[ignore_category] = list() - GLOB.poll_ignore[ignore_category] += G.ckey - to_chat(G, "Choice registered: Never for this round.") + GLOB.poll_ignore[ignore_category] += M.ckey + to_chat(M, "Choice registered: Never for this round.") + candidates -= M + else + candidates -= M -/proc/pollCandidates(var/Question, var/jobbanType, var/datum/game_mode/gametypeCheck, var/be_special_flag = 0, var/poll_time = 300, var/ignore_category = null, flashwindow = TRUE) - var/list/mob/dead/observer/candidates = list() +/proc/pollGhostCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE) + var/list/candidates = list() + + for(var/mob/dead/observer/G in GLOB.player_list) + candidates += G + + pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category, flashwindow, candidates) + + return candidates + +/proc/pollCandidates(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, ignore_category = null, flashwindow = TRUE, list/group = null) var/time_passed = world.time if (!Question) Question = "Would you like to be a special role?" - for(var/mob/dead/observer/G in GLOB.player_list) - if(!G.key || !G.client || (ignore_category && GLOB.poll_ignore[ignore_category] && G.ckey in GLOB.poll_ignore[ignore_category])) + for(var/m in group) + var/mob/M = m + if(!M.key || !M.client || (ignore_category && GLOB.poll_ignore[ignore_category] && M.ckey in GLOB.poll_ignore[ignore_category])) continue if(be_special_flag) - if(!(G.client.prefs) || !(be_special_flag in G.client.prefs.be_special)) + if(!(M.client.prefs) || !(be_special_flag in M.client.prefs.be_special)) continue - if (gametypeCheck) - if(!gametypeCheck.age_check(G.client)) + if(gametypeCheck) + if(!gametypeCheck.age_check(M.client)) continue - if (jobbanType) - if(jobban_isbanned(G, jobbanType) || jobban_isbanned(G, "Syndicate")) + if(jobbanType) + if(jobban_isbanned(M, jobbanType) || jobban_isbanned(M, "Syndicate")) continue - showCandidatePollWindow(G, poll_time, Question, candidates, ignore_category, time_passed, flashwindow) + showCandidatePollWindow(M, poll_time, Question, group, ignore_category, time_passed, flashwindow) sleep(poll_time) - //Check all our candidates, to make sure they didn't log off during the wait period. - for(var/mob/dead/observer/G in candidates) - if(!G.key || !G.client) - candidates.Remove(G) + //Check all our candidates, to make sure they didn't log off or get deleted during the wait period. + for(var/mob/M in group) + if(!M.key || !M.client) + group -= M - listclearnulls(candidates) + listclearnulls(group) - return candidates + return group /proc/pollCandidatesForMob(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, mob/M, ignore_category = null) - var/list/L = pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category) + var/list/L = pollGhostCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category) if(!M || QDELETED(M) || !M.loc) return list() return L /proc/pollCandidatesForMobs(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, list/mobs, ignore_category = null) - var/list/L = pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category) + var/list/L = pollGhostCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category) var/i=1 for(var/v in mobs) var/atom/A = v @@ -485,6 +501,55 @@ ++i return L +/proc/pollCultists(var/mob/living/Nominee) // Cult Master Poll + if(world.time < CULT_POLL_WAIT) + to_chat(Nominee, "It would be premature to select a leader while everyone is still settling in, try again in [round((CULT_POLL_WAIT-world.time)/10)] seconds.") + return + for(var/datum/mind/B in SSticker.mode.cult) + if(B.current) + B.current.verbs -= /mob/living/proc/cult_master + if(!B.current.incapacitated()) + B.current << 'sound/hallucinations/im_here1.ogg' + to_chat(B.current, "Acolyte [Nominee] has asserted that they are worthy of leading the cult. A vote will be called shortly.") + sleep(250) + var/list/asked_cultists = list() + for(var/datum/mind/B in SSticker.mode.cult) + if(B.current && B.current != Nominee && !B.current.incapacitated()) + B.current << 'sound/magic/exit_blood.ogg' + asked_cultists += B.current + var/list/yes_voters = pollCandidates("[Nominee] seeks to lead your cult, do you support [Nominee.p_them()]?", poll_time = 1200, group = asked_cultists) + sleep(300) + if(QDELETED(Nominee) || Nominee.incapacitated()) + for(var/datum/mind/B in SSticker.mode.cult) + if(B.current) + B.current.verbs += /mob/living/proc/cult_master + if(!B.current.incapacitated()) + to_chat(B.current,"[Nominee] has died in the process of attempting to win the cult's support!") + return FALSE + if(!Nominee.mind) + for(var/datum/mind/B in SSticker.mode.cult) + if(B.current) + B.current.verbs += /mob/living/proc/cult_master + if(!B.current.incapacitated()) + to_chat(B.current,"[Nominee] has gone insane and catatonic in the process of attempting to win the cult's support!") + return FALSE + if(LAZYLEN(yes_voters) <= LAZYLEN(asked_cultists) * 0.5) + for(var/datum/mind/B in SSticker.mode.cult) + if(B.current) + B.current.verbs += /mob/living/proc/cult_master + if(!B.current.incapacitated()) + to_chat(B.current, "[Nominee] could not win the cult's support and shall continue to serve as an acolyte.") + return FALSE + SSticker.mode.remove_cultist(Nominee.mind, FALSE) + Nominee.mind.add_antag_datum(ANTAG_DATUM_CULT_MASTER) + GLOB.cult_mastered = TRUE + for(var/datum/mind/B in SSticker.mode.cult) + if(!B.current.incapacitated()) + to_chat(B.current,"[Nominee] has won the cult's support and is now their master. Follow [Nominee.p_their()] orders to the best of your ability!") + return TRUE + +/proc/poll_helper(var/mob/living/M) + /proc/makeBody(mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character if(!G_found || !G_found.key) return @@ -513,7 +578,7 @@ winset(C, "mainwindow", "flash=5") /proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank) - if(!SSticker.IsRoundInProgress() || !character) + if(!SSticker.IsRoundInProgress() || !character) return var/area/A = get_area(character) var/message = "\ diff --git a/code/__HELPERS/matrices.dm b/code/__HELPERS/matrices.dm index 2e34624df5..8b77b170e0 100644 --- a/code/__HELPERS/matrices.dm +++ b/code/__HELPERS/matrices.dm @@ -24,7 +24,6 @@ //doesn't have an object argument because this is "Stacking" with the animate call above //3 billion% intentional - //Dumps the matrix data in format a-f /matrix/proc/tolist() . = list() diff --git a/code/__HELPERS/text_vr.dm b/code/__HELPERS/text_vr.dm index 06aadb6708..7cd683f456 100644 --- a/code/__HELPERS/text_vr.dm +++ b/code/__HELPERS/text_vr.dm @@ -24,4 +24,4 @@ GLOBAL_LIST_EMPTY(whitelisted_species_list) /proc/log_mentor(text) GLOB.mentor_log.Add(text) - GLOB.diary << "\[[time_stamp()]]MENTOR: [text]" \ No newline at end of file + GLOB.world_game_log << "\[[time_stamp()]]MENTOR: [text]" \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 1da1b50aa3..d0fcb3bcbe 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1342,6 +1342,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) //This prevents RCEs from badmins //kevinz000 if you touch this I will hunt you down GLOBAL_VAR_INIT(valid_HTTPSGet, FALSE) +GLOBAL_PROTECT(valid_HTTPSGet) /proc/HTTPSGet(url) if(findtext(url, "\"")) GLOB.valid_HTTPSGet = FALSE diff --git a/code/_globalvars/game_modes.dm b/code/_globalvars/game_modes.dm index 153ebbf089..299113795d 100644 --- a/code/_globalvars/game_modes.dm +++ b/code/_globalvars/game_modes.dm @@ -3,3 +3,12 @@ GLOBAL_VAR_INIT(secret_force_mode, "secret") // if this is anything but "secret" GLOBAL_VAR_INIT(wavesecret, 0) // meteor mode, delays wave progression, terrible name GLOBAL_DATUM(start_state, /datum/station_state) // Used in round-end report + +// Cult, needs to be global so admin cultists are functional +GLOBAL_VAR_INIT(blood_target, null) // Cult Master's target or Construct's Master +GLOBAL_DATUM(blood_target_image, /image) +GLOBAL_DATUM(sac_mind, /datum/mind) +GLOBAL_VAR_INIT(sac_image, null) +GLOBAL_VAR_INIT(cult_mastered, FALSE) +GLOBAL_VAR_INIT(reckoning_complete, FALSE) +GLOBAL_VAR_INIT(sac_complete, FALSE) \ No newline at end of file diff --git a/code/_globalvars/lists/maintenance_loot.dm b/code/_globalvars/lists/maintenance_loot.dm index 849c5248a0..59885b3432 100644 --- a/code/_globalvars/lists/maintenance_loot.dm +++ b/code/_globalvars/lists/maintenance_loot.dm @@ -104,5 +104,6 @@ GLOBAL_LIST_INIT(maintenance_loot, list( /obj/item/weapon/storage/secure/briefcase = 3, /obj/item/weapon/storage/toolbox/artistic = 2, /obj/item/toy/eightball = 1, + /obj/item/weapon/storage/daki = 3, "" = 3 )) diff --git a/code/_globalvars/lists/poll_ignore.dm b/code/_globalvars/lists/poll_ignore.dm index ff6a4edd40..fadd68526d 100644 --- a/code/_globalvars/lists/poll_ignore.dm +++ b/code/_globalvars/lists/poll_ignore.dm @@ -5,5 +5,6 @@ #define POLL_IGNORE_POSSESSED_BLADE "possessed_blade" #define POLL_IGNORE_ALIEN_LARVA "alien_larva" #define POLL_IGNORE_CLOCKWORK_MARAUDER "clockwork_marauder" +#define POLL_IGNORE_SYNDICATE "syndicate" GLOBAL_LIST_EMPTY(poll_ignore) diff --git a/code/_globalvars/logging.dm b/code/_globalvars/logging.dm index 35adcef36c..00665bdfe2 100644 --- a/code/_globalvars/logging.dm +++ b/code/_globalvars/logging.dm @@ -1,28 +1,34 @@ -GLOBAL_VAR(diary) -GLOBAL_PROTECT(diary) -GLOBAL_VAR(runtime_diary) -GLOBAL_PROTECT(runtime_diary) -GLOBAL_VAR(diaryofmeanpeople) -GLOBAL_PROTECT(diaryofmeanpeople) -GLOBAL_VAR(href_logfile) -GLOBAL_PROTECT(href_logfile) - -GLOBAL_LIST_EMPTY(bombers) -GLOBAL_PROTECT(bombers) -GLOBAL_LIST_EMPTY(admin_log) -GLOBAL_PROTECT(admin_log) -GLOBAL_LIST_EMPTY(lastsignalers) //keeps last 100 signals here in format: "[src] used \ref[src] @ location [src.loc]: [freq]/[code]" -GLOBAL_PROTECT(lastsignalers) -GLOBAL_LIST_EMPTY(lawchanges) //Stores who uploaded laws to which silicon-based lifeform, and what the law was -GLOBAL_PROTECT(lawchanges) - -GLOBAL_LIST_EMPTY(combatlog) -GLOBAL_PROTECT(combatlog) -GLOBAL_LIST_EMPTY(IClog) -GLOBAL_PROTECT(IClog) -GLOBAL_LIST_EMPTY(OOClog) -GLOBAL_PROTECT(OOClog) -GLOBAL_LIST_EMPTY(adminlog) -GLOBAL_PROTECT(adminlog) - +GLOBAL_VAR(log_directory) +GLOBAL_PROTECT(log_directory) +GLOBAL_VAR(world_game_log) +GLOBAL_PROTECT(world_game_log) +GLOBAL_VAR(world_runtime_log) +GLOBAL_PROTECT(world_runtime_log) +GLOBAL_VAR(world_attack_log) +GLOBAL_PROTECT(world_attack_log) +GLOBAL_VAR(world_href_log) +GLOBAL_PROTECT(world_href_log) +GLOBAL_VAR(round_id) +GLOBAL_PROTECT(round_id) +GLOBAL_VAR(config_error_log) +GLOBAL_PROTECT(config_error_log) + +GLOBAL_LIST_EMPTY(bombers) +GLOBAL_PROTECT(bombers) +GLOBAL_LIST_EMPTY(admin_log) +GLOBAL_PROTECT(admin_log) +GLOBAL_LIST_EMPTY(lastsignalers) //keeps last 100 signals here in format: "[src] used \ref[src] @ location [src.loc]: [freq]/[code]" +GLOBAL_PROTECT(lastsignalers) +GLOBAL_LIST_EMPTY(lawchanges) //Stores who uploaded laws to which silicon-based lifeform, and what the law was +GLOBAL_PROTECT(lawchanges) + +GLOBAL_LIST_EMPTY(combatlog) +GLOBAL_PROTECT(combatlog) +GLOBAL_LIST_EMPTY(IClog) +GLOBAL_PROTECT(IClog) +GLOBAL_LIST_EMPTY(OOClog) +GLOBAL_PROTECT(OOClog) +GLOBAL_LIST_EMPTY(adminlog) +GLOBAL_PROTECT(adminlog) + GLOBAL_LIST_EMPTY(active_turfs_startlist) \ No newline at end of file diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 0fe37a9286..9272abbdb6 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -107,64 +107,112 @@ var/obj/item/W = get_active_held_item() - if(W == A) W.attack_self(src) update_inv_hands() return - - // operate three levels deep here (item in backpack in src; item in box in backpack in src, not any deeper) - if(A.ClickAccessible(src, depth=INVENTORY_DEPTH)) - // No adjacency needed + + //These are always reachable. + //User itself, current loc, and user inventory + if(DirectAccess(A)) if(W) - melee_item_attack_chain(src, W, A, params) + melee_item_attack_chain(src,W,A,params) else if(ismob(A)) changeNext_move(CLICK_CD_MELEE) UnarmedAttack(A) return - - if(!isturf(loc)) // This is going to stop you from telekinesing from inside a closet, but I don't shed many tears for that + + //Can't reach anything else in lockers or other weirdness + if(!loc.AllowClick()) return - // Allows you to click on a box's contents, if that box is on the ground, but no deeper than that - if(isturf(A) || isturf(A.loc) || (A.loc && isturf(A.loc.loc))) - if(Adjacent(A) || (W && CheckReach(src, A, W.reach))) //Adjacent or reaching attacks - if(W) - melee_item_attack_chain(src, W, A, params) - else - if(ismob(A)) - changeNext_move(CLICK_CD_MELEE) - UnarmedAttack(A, 1) - return - else // non-adjacent click - if(W) - W.afterattack(A,src,0,params) // 0: not Adjacent - else - RangedAttack(A, params) + //Standard reach turf to turf or reaching inside storage + if(CanReach(A,W)) + if(W) + melee_item_attack_chain(src,W,A,params) + else + if(ismob(A)) + changeNext_move(CLICK_CD_MELEE) + UnarmedAttack(A,1) + else + if(W) + W.afterattack(A,src,0,params) + else + RangedAttack(A,params) + +/atom/movable/proc/CanReach(atom/target,obj/item/tool,view_only = FALSE) + if(isturf(target) || isturf(target.loc) || DirectAccess(target)) //Directly accessible atoms + if(Adjacent(target) || (tool && CheckToolReach(src, target, tool.reach))) //Adjacent or reaching attacks + return TRUE + else + //Things inside storage insde another storage + //Eg Contents of a box in a backpack + var/atom/outer_storage = get_atom_on_turf(target) + if(outer_storage == target) //whatever that is we don't want infinite loop. + return FALSE + if(outer_storage && CanReach(outer_storage,tool) && outer_storage.CanReachStorage(target,src,view_only ? STORAGE_VIEW_DEPTH : INVENTORY_DEPTH)) + return TRUE + return FALSE + +//Can [target] in this container be reached by [user], can't be more than [depth] levels deep +/atom/proc/CanReachStorage(atom/target,user,depth) + return FALSE + +/obj/item/weapon/storage/CanReachStorage(atom/target,user,depth) + while(target && depth > 0) + target = target.loc + depth-- + if(target == src) + return TRUE + return FALSE + +/atom/movable/proc/DirectAccess(atom/target) + if(target == src) + return TRUE + if(target == loc) + return TRUE + +/mob/DirectAccess(atom/target) + if(..()) + return TRUE + if(target in contents) //This could probably use moving down and restricting to inventory only + return TRUE + return FALSE + +/mob/living/DirectAccess(atom/target) + if(..()) //Lightweight checks first + return TRUE + if(target in GetAllContents()) + return TRUE + +/atom/proc/AllowClick() + return FALSE + +/turf/AllowClick() + return TRUE -/proc/CheckReach(atom/movable/here, atom/movable/there, reach) +/proc/CheckToolReach(atom/movable/here, atom/movable/there, reach) if(!here || !there) return switch(reach) if(0) - return here.loc == there.loc + return FALSE if(1) - return here.Adjacent(there) + return FALSE //here.Adjacent(there) if(2 to INFINITY) - var/obj/dummy = new(get_turf(here)) //We'll try to move this every tick, failing if we can't + var/obj/dummy = new(get_turf(here)) dummy.pass_flags |= PASSTABLE + dummy.invisibility = INVISIBILITY_ABSTRACT for(var/i in 1 to reach) //Limit it to that many tries var/turf/T = get_step(dummy, get_dir(dummy, there)) - if(dummy.loc == there.loc) + if(dummy.CanReach(there)) qdel(dummy) - return 1 - if(there.density && dummy in range(1, there)) //For windows and suchlike - qdel(dummy) - return 1 + return TRUE if(!dummy.Move(T)) //we're blocked! qdel(dummy) return + qdel(dummy) // Default behavior: ignore double clicks (the second click that makes the doubleclick call already calls for a normal click) /mob/proc/DblClickOn(atom/A, params) @@ -304,21 +352,6 @@ /atom/proc/CtrlShiftClick(mob/user) return -/* - Helper to check can the mob click/access an item. - Used by mob inventory and storage items. -*/ -/atom/proc/ClickAccessible(mob/user, depth=1) - if(src == user.loc || (src in user.contents)) - return TRUE - - if(loc && depth > 1) - return loc.ClickAccessible(user, depth-1) - -/turf/ClickAccessible(mob/user, depth=1) - return - - /* Misc helpers diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 8c62d68963..ce7014d765 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -21,7 +21,7 @@ #define ui_inventory "WEST:6,SOUTH:5" //Middle left indicators -#define ui_lingchemdisplay "WEST:6,CENTER-1:15" +#define ui_lingchemdisplay "WEST,CENTER-1:15" #define ui_lingstingdisplay "WEST:6,CENTER-3:11" #define ui_crafting "12:-10,1:5" #define ui_building "12:-10,1:21" @@ -104,17 +104,18 @@ #define ui_health "EAST-1:28,CENTER-1:15" #define ui_internal "EAST-1:28,CENTER:17" -//borgs and aliens -#define ui_alien_nightvision "EAST-1:28,CENTER:17" +//borgs #define ui_borg_health "EAST-1:28,CENTER-1:15" //borgs have the health display where humans have the pressure damage indicator. -#define ui_alien_health "EAST-1:28,CENTER-1:15" //aliens have the health display where humans have the pressure damage indicator. -#define ui_alienplasmadisplay "EAST-1:28,CENTER-2:15" -#define ui_alien_queen_finder "EAST-1:28,CENTER-3:15" -//constructs -#define ui_construct_pull "EAST,CENTER-2:15" -#define ui_construct_health "EAST,CENTER:15" //same as borgs and humans - +//aliens +#define ui_alien_health "EAST,CENTER-1:15" //aliens have the health display where humans have the pressure damage indicator. +#define ui_alienplasmadisplay "EAST,CENTER-2:15" +#define ui_alien_queen_finder "EAST,CENTER-3:15" + +//constructs +#define ui_construct_pull "EAST,CENTER-2:15" +#define ui_construct_health "EAST,CENTER:15" //same as borgs and humans + // AI #define ui_ai_core "SOUTH:6,WEST" diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm index 9c8fe9750a..7cbd997db6 100644 --- a/code/_onclick/hud/alert.dm +++ b/code/_onclick/hud/alert.dm @@ -42,6 +42,7 @@ thealert.override_alerts = override if(override) thealert.timeout = null + thealert.mob_viewer = src if(new_master) var/old_layer = new_master.layer @@ -96,6 +97,7 @@ var/severity = 0 var/alerttooltipstyle = "" var/override_alerts = FALSE //If it is overriding other alerts of the same type + var/mob/mob_viewer //the mob viewing this alert /obj/screen/alert/MouseEntered(location,control,params) @@ -256,6 +258,102 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." icon_state = "blobbernaut_nofactory" alerttooltipstyle = "blob" +// BLOODCULT + +/obj/screen/alert/bloodsense + name = "Blood Sense" + desc = "Allows you to sense blood that is manipulated by dark magicks." + icon_state = "cult_sense" + alerttooltipstyle = "cult" + var/static/image/narnar + var/angle = 0 + var/mob/living/simple_animal/hostile/construct/Cviewer = null + +/obj/screen/alert/bloodsense/Initialize() + . = ..() + if(!narnar) + narnar = new('icons/mob/screen_alert.dmi', "mini_nar") + START_PROCESSING(SSprocessing, src) + +/obj/screen/alert/bloodsense/Destroy() + Cviewer = null + STOP_PROCESSING(SSprocessing, src) + return ..() + +/obj/screen/alert/bloodsense/process() + var/atom/blood_target + if(GLOB.blood_target) + if(!get_turf(GLOB.blood_target)) + GLOB.blood_target = null + else + blood_target = GLOB.blood_target + if(Cviewer) + if(Cviewer.seeking && Cviewer.master) + blood_target = Cviewer.master + if(!blood_target && !GLOB.sac_complete) + if(icon_state == "runed_sense0") + return + animate(src, transform = null, time = 1, loop = 0) + angle = 0 + cut_overlays() + icon_state = "runed_sense0" + desc = "Nar-Sie demands that [GLOB.sac_mind] be sacrificed before the summoning ritual can begin." + add_overlay(GLOB.sac_image) + return + if(!blood_target && GLOB.sac_complete) + if(icon_state == "runed_sense1") + return + animate(src, transform = null, time = 1, loop = 0) + angle = 0 + cut_overlays() + icon_state = "runed_sense1" + desc = "The sacrifice is complete, prepare to summon Nar-Sie!" + add_overlay(narnar) + return + if(!blood_target) + return + var/turf/P = get_turf(blood_target) + var/turf/Q = get_turf(mob_viewer) + var/area/A = get_area(P) + if(P.z != Q.z) //The target is on a different Z level, we cannot sense that far. + return + desc = "You are currently tracking [blood_target] in [A.name]." + var/target_angle = Get_Angle(Q, P) + var/target_dist = get_dist(P, Q) + cut_overlays() + switch(target_dist) + if(0 to 1) + icon_state = "runed_sense2" + if(2 to 8) + icon_state = "arrow8" + if(9 to 15) + icon_state = "arrow7" + if(16 to 22) + icon_state = "arrow6" + if(23 to 29) + icon_state = "arrow5" + if(30 to 36) + icon_state = "arrow4" + if(37 to 43) + icon_state = "arrow3" + if(44 to 50) + icon_state = "arrow2" + if(51 to 57) + icon_state = "arrow1" + if(58 to 64) + icon_state = "arrow0" + if(65 to 400) + icon_state = "arrow" + var/difference = target_angle - angle + angle = target_angle + if(!difference) + return + var/matrix/final = matrix(transform) + final.Turn(difference) + animate(src, transform = final, time = 5, loop = 0) + + + // CLOCKCULT /obj/screen/alert/clockwork alerttooltipstyle = "clockcult" @@ -393,6 +491,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion." textlist += "
" else textlist += "Seconds until Ratvar's arrival: [G.get_arrival_text(TRUE)]
" + break if(unconverted_ais_exist) if(unconverted_ais_exist > 1) textlist += "[unconverted_ais_exist] unconverted AIs exist!
" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index b1b4a1cbb3..f6a3688626 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -208,7 +208,6 @@ mymob.reload_fullscreen() update_parallax_pref(screenmob) - /datum/hud/human/show_hud(version = 0,mob/viewmob) ..() hidden_inventory_update(viewmob) @@ -266,3 +265,6 @@ E.screen_loc = ui_equip_position(mymob) if(mymob.hud_used) show_hud(HUD_STYLE_STANDARD,mymob) + +/datum/hud/proc/update_locked_slots() + return \ No newline at end of file diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index f35579c16b..8453b12085 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -124,7 +124,6 @@ inv_box.icon = ui_style inv_box.slot_id = slot_w_uniform inv_box.icon_state = "uniform" -// inv_box.icon_full = "template" inv_box.screen_loc = ui_iclothing toggleable_inventory += inv_box @@ -133,7 +132,6 @@ inv_box.icon = ui_style inv_box.slot_id = slot_wear_suit inv_box.icon_state = "suit" -// inv_box.icon_full = "template" inv_box.screen_loc = ui_oclothing toggleable_inventory += inv_box @@ -155,7 +153,6 @@ inv_box.name = "id" inv_box.icon = ui_style inv_box.icon_state = "id" -// inv_box.icon_full = "template_small" inv_box.screen_loc = ui_id inv_box.slot_id = slot_wear_id static_inventory += inv_box @@ -164,7 +161,6 @@ inv_box.name = "mask" inv_box.icon = ui_style inv_box.icon_state = "mask" -// inv_box.icon_full = "template" inv_box.screen_loc = ui_mask inv_box.slot_id = slot_wear_mask toggleable_inventory += inv_box @@ -173,7 +169,6 @@ inv_box.name = "neck" inv_box.icon = ui_style inv_box.icon_state = "neck" -// inv_box.icon_full = "template" inv_box.screen_loc = ui_neck inv_box.slot_id = slot_neck toggleable_inventory += inv_box @@ -182,7 +177,6 @@ inv_box.name = "back" inv_box.icon = ui_style inv_box.icon_state = "back" -// inv_box.icon_full = "template_small" inv_box.screen_loc = ui_back inv_box.slot_id = slot_back static_inventory += inv_box @@ -191,7 +185,6 @@ inv_box.name = "storage1" inv_box.icon = ui_style inv_box.icon_state = "pocket" -// inv_box.icon_full = "template_small" inv_box.screen_loc = ui_storage1 inv_box.slot_id = slot_l_store static_inventory += inv_box @@ -200,7 +193,6 @@ inv_box.name = "storage2" inv_box.icon = ui_style inv_box.icon_state = "pocket" -// inv_box.icon_full = "template_small" inv_box.screen_loc = ui_storage2 inv_box.slot_id = slot_r_store static_inventory += inv_box @@ -209,7 +201,6 @@ inv_box.name = "suit storage" inv_box.icon = ui_style inv_box.icon_state = "suit_storage" -// inv_box.icon_full = "template" inv_box.screen_loc = ui_sstore1 inv_box.slot_id = slot_s_store static_inventory += inv_box @@ -233,7 +224,6 @@ inv_box.name = "gloves" inv_box.icon = ui_style inv_box.icon_state = "gloves" -// inv_box.icon_full = "template" inv_box.screen_loc = ui_gloves inv_box.slot_id = slot_gloves toggleable_inventory += inv_box @@ -242,7 +232,6 @@ inv_box.name = "eyes" inv_box.icon = ui_style inv_box.icon_state = "glasses" -// inv_box.icon_full = "template" inv_box.screen_loc = ui_glasses inv_box.slot_id = slot_glasses toggleable_inventory += inv_box @@ -251,7 +240,6 @@ inv_box.name = "ears" inv_box.icon = ui_style inv_box.icon_state = "ears" -// inv_box.icon_full = "template" inv_box.screen_loc = ui_ears inv_box.slot_id = slot_ears toggleable_inventory += inv_box @@ -260,7 +248,6 @@ inv_box.name = "head" inv_box.icon = ui_style inv_box.icon_state = "head" -// inv_box.icon_full = "template" inv_box.screen_loc = ui_head inv_box.slot_id = slot_head toggleable_inventory += inv_box @@ -269,7 +256,6 @@ inv_box.name = "shoes" inv_box.icon = ui_style inv_box.icon_state = "shoes" -// inv_box.icon_full = "template" inv_box.screen_loc = ui_shoes inv_box.slot_id = slot_shoes toggleable_inventory += inv_box @@ -327,6 +313,18 @@ inv_slots[inv.slot_id] = inv inv.update_icon() +/datum/hud/human/update_locked_slots() + if(!mymob) + return + var/mob/living/carbon/human/H = mymob + var/datum/species/S = H.dna.species + for(var/obj/screen/inventory/inv in (static_inventory + toggleable_inventory)) + if(inv.slot_id) + if(inv.slot_id in S.no_equip) + inv.alpha = 128 + else + inv.alpha = initial(inv.alpha) + /datum/hud/human/hidden_inventory_update(mob/viewer) if(!mymob) return diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index fd3fe6d685..4d9c819ef9 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -43,10 +43,8 @@ var/log_attack = 0 // log attack messages var/log_adminchat = 0 // log admin chat messages var/log_pda = 0 // log pda messages - var/log_hrefs = 0 // log all links clicked in-game. Could be used for debugging and tracking down exploits var/log_twitter = 0 // log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases. var/log_world_topic = 0 // log all world.Topic() calls - var/log_runtimes = FALSE // log runtimes into a file var/sql_enabled = 0 // for sql switching var/allow_admin_ooccolor = 0 // Allows admins with relevant permissions to have their own ooc colour var/allow_vote_restart = 0 // allow votes to restart @@ -66,9 +64,9 @@ var/respawn = 1 var/guest_jobban = 1 var/usewhitelist = 0 - var/inactivity_period = 3000 //time in ds until a player is considered inactive - var/afk_period = 6000 //time in ds until a player is considered afk and kickable - var/kick_inactive = FALSE //force disconnect for inactive players + var/inactivity_period = 3000 //time in ds until a player is considered inactive + var/afk_period = 6000 //time in ds until a player is considered afk and kickable + var/kick_inactive = FALSE //force disconnect for inactive players var/load_jobs_from_txt = 0 var/automute_on = 0 //enables automuting/spam prevention var/minimal_access_threshold = 0 //If the number of players is larger than this threshold, minimal access will be turned on. @@ -129,6 +127,7 @@ var/forbid_peaceborg = 0 var/panic_bunker = 0 // prevents new people it hasn't seen before from connecting var/notify_new_player_age = 0 // how long do we notify admins of a new player + var/notify_new_player_account_age = 0 // how long do we notify admins of a new byond account var/irc_first_connection_alert = 0 // do we notify the irc channel when somebody is connecting for the first time? var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors @@ -269,7 +268,7 @@ if(M.config_tag) if(!(M.config_tag in modes)) // ensure each mode is added only once - GLOB.diary << "Adding game mode [M.name] ([M.config_tag]) to configuration." + GLOB.config_error_log << "Adding game mode [M.name] ([M.config_tag]) to configuration." modes += M.config_tag mode_names[M.config_tag] = M.name probabilities[M.config_tag] = M.probability @@ -291,7 +290,7 @@ GLOB.abandon_allowed = respawn /datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist - var/list/Lines = world.file2list(filename) + var/list/Lines = world.file2list(filename) for(var/t in Lines) if(!t) @@ -358,8 +357,6 @@ log_adminchat = 1 if("log_pda") log_pda = 1 - if("log_hrefs") - log_hrefs = 1 if("log_twitter") log_twitter = 1 if("log_world_topic") @@ -410,12 +407,12 @@ usewhitelist = TRUE if("allow_metadata") allow_Metadata = 1 - if("inactivity_period") - inactivity_period = text2num(value) * 10 //documented as seconds in config.txt - if("afk_period") - afk_period = text2num(value) * 10 // ^^^ + if("inactivity_period") + inactivity_period = text2num(value) * 10 //documented as seconds in config.txt + if("afk_period") + afk_period = text2num(value) * 10 // ^^^ if("kick_inactive") - kick_inactive = TRUE + kick_inactive = TRUE if("load_jobs_from_txt") load_jobs_from_txt = 1 if("forbid_singulo_possession") @@ -476,6 +473,8 @@ panic_bunker = 1 if("notify_new_player_age") notify_new_player_age = text2num(value) + if("notify_new_player_account_age") + notify_new_player_account_age = text2num(value) if("irc_first_connection_alert") irc_first_connection_alert = 1 if("check_randomizer") @@ -493,12 +492,6 @@ ipintel_save_bad = text2num(value) if("aggressive_changelog") aggressive_changelog = 1 - if("log_runtimes") - log_runtimes = TRUE - var/newlog = file("data/logs/runtimes/runtime-[time2text(world.realtime, "YYYY-MM-DD")].log") - if(GLOB.runtime_diary != newlog) - world.log << "Now logging runtimes to data/logs/runtimes/runtime-[time2text(world.realtime, "YYYY-MM-DD")].log" - GLOB.runtime_diary = newlog if("autoconvert_notes") autoconvert_notes = 1 if("allow_webclient") @@ -542,7 +535,7 @@ if("error_msg_delay") error_msg_delay = text2num(value) else - GLOB.diary << "Unknown setting in configuration: '[name]'" + GLOB.config_error_log << "Unknown setting in configuration: '[name]'" else if(type == "game_options") switch(name) @@ -605,13 +598,13 @@ if(mode_name in modes) continuous[mode_name] = 1 else - GLOB.diary << "Unknown continuous configuration definition: [mode_name]." + GLOB.config_error_log << "Unknown continuous configuration definition: [mode_name]." if("midround_antag") var/mode_name = lowertext(value) if(mode_name in modes) midround_antag[mode_name] = 1 else - GLOB.diary << "Unknown midround antagonist configuration definition: [mode_name]." + GLOB.config_error_log << "Unknown midround antagonist configuration definition: [mode_name]." if("midround_antag_time_check") midround_antag_time_check = text2num(value) if("midround_antag_life_check") @@ -627,9 +620,9 @@ if(mode_name in modes) min_pop[mode_name] = text2num(mode_value) else - GLOB.diary << "Unknown minimum population configuration definition: [mode_name]." + GLOB.config_error_log << "Unknown minimum population configuration definition: [mode_name]." else - GLOB.diary << "Incorrect minimum population configuration definition: [mode_name] [mode_value]." + GLOB.config_error_log << "Incorrect minimum population configuration definition: [mode_name] [mode_value]." if("max_pop") var/pop_pos = findtext(value, " ") var/mode_name = null @@ -641,9 +634,9 @@ if(mode_name in modes) max_pop[mode_name] = text2num(mode_value) else - GLOB.diary << "Unknown maximum population configuration definition: [mode_name]." + GLOB.config_error_log << "Unknown maximum population configuration definition: [mode_name]." else - GLOB.diary << "Incorrect maximum population configuration definition: [mode_name] [mode_value]." + GLOB.config_error_log << "Incorrect maximum population configuration definition: [mode_name] [mode_value]." if("shuttle_refuel_delay") shuttle_refuel_delay = text2num(value) if("show_game_type_odds") @@ -671,9 +664,9 @@ if(prob_name in modes) probabilities[prob_name] = text2num(prob_value) else - GLOB.diary << "Unknown game mode probability configuration definition: [prob_name]." + GLOB.config_error_log << "Unknown game mode probability configuration definition: [prob_name]." else - GLOB.diary << "Incorrect probability configuration definition: [prob_name] [prob_value]." + GLOB.config_error_log << "Incorrect probability configuration definition: [prob_name] [prob_value]." if("protect_roles_from_antagonist") protect_roles_from_antagonist = 1 @@ -720,7 +713,7 @@ // Value is in the form "LAWID,NUMBER" var/list/L = splittext(value, ",") if(L.len != 2) - GLOB.diary << "Invalid LAW_WEIGHT: " + t + GLOB.config_error_log << "Invalid LAW_WEIGHT: " + t continue var/lawid = L[1] var/weight = text2num(L[2]) @@ -776,8 +769,8 @@ mentors_mobname_only = 1 if ("mentor_legacy_system") mentor_legacy_system = 1 - else - GLOB.diary << "Unknown setting in configuration: '[name]'" + // else + // GLOB.config_error_log << "Adding game mode [M.name] ([M.config_tag]) to configuration." fps = round(fps) if(fps <= 0) @@ -785,7 +778,7 @@ /datum/configuration/proc/loadmaplist(filename) - var/list/Lines = world.file2list(filename) + var/list/Lines = world.file2list(filename) var/datum/map_config/currentmap = null for(var/t in Lines) @@ -831,11 +824,11 @@ maplist[currentmap.map_name] = currentmap currentmap = null else - GLOB.diary << "Unknown command in map vote config: '[command]'" + GLOB.config_error_log << "Unknown command in map vote config: '[command]'" /datum/configuration/proc/loadsql(filename) - var/list/Lines = world.file2list(filename) + var/list/Lines = world.file2list(filename) for(var/t in Lines) if(!t) continue @@ -875,7 +868,7 @@ if("feedback_tableprefix") global.sqlfdbktableprefix = value else - GLOB.diary << "Unknown setting in configuration: '[name]'" + GLOB.config_error_log << "Unknown setting in configuration: '[name]'" /datum/configuration/proc/pick_mode(mode_name) // I wish I didn't have to instance the game modes in order to look up diff --git a/code/controllers/globals.dm b/code/controllers/globals.dm index cd86e0d97c..89f8a81f20 100644 --- a/code/controllers/globals.dm +++ b/code/controllers/globals.dm @@ -52,6 +52,12 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars) /datum/controller/global_vars/Initialize() gvars_datum_init_order = list() gvars_datum_protected_varlist = list("gvars_datum_protected_varlist") + + //See https://github.com/tgstation/tgstation/issues/26954 + for(var/I in typesof(/datum/controller/global_vars/proc)) + var/CLEANBOT_RETURNS = "[I]" + pass(CLEANBOT_RETURNS) + for(var/I in vars - gvars_datum_in_built_vars) var/start_tick = world.time call(src, "InitGlobal[I]")() diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 01d0ac3447..0df2c8cc73 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -280,7 +280,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) // because sleeps are processed in the order received, so longer sleeps are more likely to run first if (world.tick_usage > TICK_LIMIT_MC) sleep_delta += 2 - GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING - (TICK_LIMIT_RUNNING * 0.5) + GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING * 0.5 sleep(world.tick_lag * (processing + sleep_delta)) continue @@ -421,26 +421,31 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) else tick_precentage = tick_remaining - GLOB.CURRENT_TICKLIMIT = world.tick_usage + tick_precentage + tick_precentage = max(tick_precentage*0.5, tick_precentage-queue_node.tick_overrun) + + GLOB.CURRENT_TICKLIMIT = round(world.tick_usage + tick_precentage) if (!(queue_node_flags & SS_TICKER)) ran_non_ticker = TRUE ran = TRUE - tick_usage = world.tick_usage + queue_node_paused = (queue_node.state == SS_PAUSED || queue_node.state == SS_PAUSING) last_type_processed = queue_node queue_node.state = SS_RUNNING + tick_usage = world.tick_usage var/state = queue_node.ignite(queue_node_paused) + tick_usage = world.tick_usage - tick_usage + if (state == SS_RUNNING) state = SS_IDLE current_tick_budget -= queue_node_priority - tick_usage = world.tick_usage - tick_usage + if (tick_usage < 0) tick_usage = 0 - + queue_node.tick_overrun = max(0, MC_AVG_FAST_UP_SLOW_DOWN(queue_node.tick_overrun, tick_usage-tick_precentage)) queue_node.state = state if (state == SS_PAUSED) @@ -467,13 +472,13 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) queue_node.times_fired++ if (queue_node_flags & SS_TICKER) - queue_node.next_fire = world.time + (world.tick_lag * queue_node.wait) + queue_node.next_fire = world.time + (world.tick_lag * (queue_node.wait + (queue_node.tick_overrun/100))) else if (queue_node_flags & SS_POST_FIRE_TIMING) - queue_node.next_fire = world.time + queue_node.wait + queue_node.next_fire = world.time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun/100)) else if (queue_node_flags & SS_KEEP_TIMING) queue_node.next_fire += queue_node.wait else - queue_node.next_fire = queue_node.queued_time + queue_node.wait + queue_node.next_fire = queue_node.queued_time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun/100)) queue_node.queued_time = 0 diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index f37a9159ef..3332b1c45d 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -17,6 +17,7 @@ var/next_fire = 0 //scheduled world.time for next fire() var/cost = 0 //average time to execute var/tick_usage = 0 //average tick usage + var/tick_overrun = 0 //average tick overrun var/state = SS_IDLE //tracks the current state of the ss, running, paused, etc. var/paused_ticks = 0 //ticks this ss is taking to run right now. var/paused_tick_usage //total tick_usage of all of our runs while pausing this run @@ -168,7 +169,7 @@ if(can_fire && !(SS_NO_FIRE in flags)) - msg = "[round(cost,1)]ms|[round(tick_usage,1)]%|[round(ticks,0.1)]\t[msg]" + msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]" else msg = "OFFLINE\t[msg]" diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 1b14b352df..a807202c9e 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -42,6 +42,7 @@ SUBSYSTEM_DEF(blackbox) msg_cargo = SSblackbox.msg_cargo msg_other = SSblackbox.msg_other + feedback = SSblackbox.feedback //no touchie @@ -84,25 +85,13 @@ SUBSYSTEM_DEF(blackbox) if (!SSdbcore.Connect()) return - var/round_id - - var/datum/DBQuery/query_feedback_max_id = SSdbcore.NewQuery("SELECT MAX(round_id) AS round_id FROM [format_table_name("feedback")]") - if(!query_feedback_max_id.Execute()) - return - while (query_feedback_max_id.NextRow()) - round_id = query_feedback_max_id.item[1] - - if (!isnum(round_id)) - round_id = text2num(round_id) - round_id++ - var/sqlrowlist = "" for (var/datum/feedback_variable/FV in feedback) if (sqlrowlist != "") sqlrowlist += ", " //a comma (,) at the start of the first row to insert will trigger a SQL error - sqlrowlist += "(null, Now(), [round_id], \"[sanitizeSQL(FV.get_variable())]\", [FV.get_value()], \"[sanitizeSQL(FV.get_details())]\")" + sqlrowlist += "(null, Now(), [GLOB.round_id], \"[sanitizeSQL(FV.get_variable())]\", [FV.get_value()], \"[sanitizeSQL(FV.get_details())]\")" if (sqlrowlist == "") return diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index a3255b73e4..c37e10b28c 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -308,7 +308,6 @@ SUBSYSTEM_DEF(job) Debug("DO non-human failed, Player: [player], Job:[job.title]") continue - // If the player wants that job on this level, then try give it to him. if(player.client.prefs.GetJobDepartment(job, level) & job.flag) @@ -319,6 +318,7 @@ SUBSYSTEM_DEF(job) unassigned -= player break + // Hand out random jobs to the people who didn't get any in the last check // Also makes sure that they got their preference correct for(var/mob/dead/new_player/player in unassigned) diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index eb61e5ef39..35d8a3d08f 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -36,18 +36,10 @@ SUBSYSTEM_DEF(lighting) for (i in 1 to GLOB.lighting_update_lights.len) var/datum/light_source/L = GLOB.lighting_update_lights[i] - if (L.check() || QDELETED(L) || L.force_update) - L.remove_lum() - if (!QDELETED(L)) - L.apply_lum() + L.update_corners() - else if (L.vis_update) //We smartly update only tiles that became (in) visible to use. - L.smart_vis_update() + L.needs_update = LIGHTING_NO_UPDATE - L.vis_update = FALSE - L.force_update = FALSE - L.needs_update = FALSE - if(init_tick_checks) CHECK_TICK else if (MC_TICK_CHECK) diff --git a/code/controllers/subsystem/pai.dm b/code/controllers/subsystem/pai.dm index dfb41c8905..ea6d57088f 100644 --- a/code/controllers/subsystem/pai.dm +++ b/code/controllers/subsystem/pai.dm @@ -150,7 +150,7 @@ SUBSYSTEM_DEF(pai) if(!(ROLE_PAI in G.client.prefs.be_special)) continue //G << 'sound/misc/server-ready.ogg' //Alerting them to their consideration - to_chat(G, "Someone is requesting a pAI personality! Use the pAI button to submit yourself as one.") + to_chat(G, "[user] is requesting a pAI personality! Use the pAI button to submit yourself as one.") addtimer(CALLBACK(src, .proc/spam_again), spam_delay) var/list/available = list() for(var/datum/paiCandidate/c in SSpai.candidates) diff --git a/code/controllers/subsystem/persistence.dm b/code/controllers/subsystem/persistence.dm index 6b3e47054c..ec76d623b1 100644 --- a/code/controllers/subsystem/persistence.dm +++ b/code/controllers/subsystem/persistence.dm @@ -9,7 +9,6 @@ SUBSYSTEM_DEF(persistence) var/list/obj/structure/chisel_message/chisel_messages = list() var/list/saved_messages = list() - var/savefile/chisel_messages_sav var/savefile/trophy_sav var/list/saved_trophies = list() @@ -75,14 +74,14 @@ SUBSYSTEM_DEF(persistence) break //Who's been duping the bird?! /datum/controller/subsystem/persistence/proc/LoadChiselMessages() - chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav") + var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav") var/saved_json chisel_messages_sav[SSmapping.config.map_name] >> saved_json if(!saved_json) return - var/saved_messages = json_decode(saved_json) + var/list/saved_messages = json_decode(saved_json) for(var/item in saved_messages) if(!islist(item)) @@ -104,16 +103,19 @@ SUBSYSTEM_DEF(persistence) var/obj/structure/chisel_message/M = new(T) - M.unpack(item) - if(!M.loc) - M.persists = FALSE - qdel(M) + if(!QDELETED(M)) + M.unpack(item) + + log_world("Loaded [saved_messages.len] engraved messages on map [SSmapping.config.map_name]") /datum/controller/subsystem/persistence/proc/LoadTrophies() trophy_sav = new /savefile("data/npc_saves/TrophyItems.sav") var/saved_json trophy_sav >> saved_json + if(!saved_json) + return + var/decoded_json = json_decode(saved_json) if(!islist(decoded_json)) @@ -172,9 +174,13 @@ SUBSYSTEM_DEF(persistence) secret_satchels[SSmapping.config.map_name] << old_secret_satchels /datum/controller/subsystem/persistence/proc/CollectChiselMessages() + var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav") + for(var/obj/structure/chisel_message/M in chisel_messages) saved_messages += list(M.pack()) + log_world("Saved [saved_messages.len] engraved messages on map [SSmapping.config.map_name]") + chisel_messages_sav[SSmapping.config.map_name] << json_encode(saved_messages) /datum/controller/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M) @@ -190,4 +196,4 @@ SUBSYSTEM_DEF(persistence) data["path"] = T.showpiece.type data["message"] = T.trophy_message data["placer_key"] = T.placer_key - saved_trophies += list(data) \ No newline at end of file + saved_trophies += list(data) diff --git a/code/controllers/subsystem/processing/flightpacks.dm b/code/controllers/subsystem/processing/flightpacks.dm index 1d85811878..0639f64810 100644 --- a/code/controllers/subsystem/processing/flightpacks.dm +++ b/code/controllers/subsystem/processing/flightpacks.dm @@ -5,7 +5,7 @@ PROCESSING_SUBSYSTEM_DEF(flightpacks) stat_tag = "FM" flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING - var/flightsuit_processing = FLIGHTSUIT_PROCESSING_FULL + var/flightsuit_processing = FLIGHTSUIT_PROCESSING_NONE /datum/controller/subsystem/processing/flightpacks/Initialize() sync_flightsuit_processing() diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index f3ac66e001..abf05aad72 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -625,8 +625,8 @@ SUBSYSTEM_DEF(ticker) if(selected_tip) m = selected_tip else - var/list/randomtips = world.file2list("config/tips.txt") - var/list/memetips = world.file2list("config/sillytips.txt") + var/list/randomtips = world.file2list("strings/tips.txt") + var/list/memetips = world.file2list("strings/sillytips.txt") if(randomtips.len && prob(95)) m = pick(randomtips) else if(memetips.len) diff --git a/code/datums/antagonists/datum_cult.dm b/code/datums/antagonists/datum_cult.dm index 30c0aa8450..9016331440 100644 --- a/code/datums/antagonists/datum_cult.dm +++ b/code/datums/antagonists/datum_cult.dm @@ -2,9 +2,55 @@ var/datum/action/innate/cultcomm/communion = new /datum/antagonist/cult/Destroy() - qdel(communion) + QDEL_NULL(communion) return ..() +/datum/antagonist/cult/proc/add_objectives() + var/list/target_candidates = list() + for(var/mob/living/carbon/human/player in GLOB.player_list) + if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && !is_convertable_to_cult(player) && (player != owner) && player.stat != DEAD) + target_candidates += player.mind + if(target_candidates.len == 0) + message_admins("Cult Sacrifice: Could not find unconvertable target, checking for convertable target.") + for(var/mob/living/carbon/human/player in GLOB.player_list) + if(player.mind && !player.mind.has_antag_datum(ANTAG_DATUM_CULT) && (player != owner) && player.stat != DEAD) + target_candidates += player.mind + listclearnulls(target_candidates) + if(LAZYLEN(target_candidates)) + GLOB.sac_mind = pick(target_candidates) + if(!GLOB.sac_mind) + message_admins("Cult Sacrifice: ERROR - Null target chosen!") + else + var/datum/job/sacjob = SSjob.GetJob(GLOB.sac_mind.assigned_role) + var/datum/preferences/sacface = GLOB.sac_mind.current.client.prefs + var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) + reshape.Shift(SOUTH, 4) + reshape.Shift(EAST, 1) + reshape.Crop(7,4,26,31) + reshape.Crop(-5,-3,26,30) + GLOB.sac_image = reshape + else + message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") + GLOB.sac_complete = TRUE + SSticker.mode.cult_objectives += "sacrifice" + SSticker.mode.cult_objectives += "eldergod" + +/datum/antagonist/cult/proc/cult_memorization(datum/mind/cult_mind) + var/mob/living/current = cult_mind.current + for(var/obj_count = 1,obj_count <= SSticker.mode.cult_objectives.len,obj_count++) + var/explanation + switch(SSticker.mode.cult_objectives[obj_count]) + if("sacrifice") + if(GLOB.sac_mind) + explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it." + else + explanation = "The veil has already been weakened here, proceed to the final objective." + if("eldergod") + explanation = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie' with nine acolytes on it. You must do this after sacrificing your target." + if(!silent) + to_chat(current, "Objective #[obj_count]: [explanation]") + cult_mind.memory += "Objective #[obj_count]: [explanation]
" + /datum/antagonist/cult/can_be_owned(datum/mind/new_owner) . = ..() if(.) @@ -12,14 +58,17 @@ /datum/antagonist/cult/on_gain() . = ..() - SSticker.mode.cult += owner + var/mob/living/current = owner.current + if(!LAZYLEN(SSticker.mode.cult_objectives)) + add_objectives() + SSticker.mode.cult += owner // Only add after they've been given objectives + cult_memorization(owner) + if(jobban_isbanned(current, ROLE_CULTIST)) + addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, current, ROLE_CULTIST, ROLE_CULTIST), 0) SSticker.mode.update_cult_icons_added(owner) - if(istype(SSticker.mode, /datum/game_mode/cult)) - var/datum/game_mode/cult/C = SSticker.mode - C.memorize_cult_objectives(owner) - if(jobban_isbanned(owner.current, ROLE_CULTIST)) - addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner.current, ROLE_CULTIST, ROLE_CULTIST), 0) - owner.current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) + current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) + if(GLOB.blood_target && GLOB.blood_target_image && current.client) + current.client.images += GLOB.blood_target_image /datum/antagonist/cult/apply_innate_effects(mob/living/mob_override) . = ..() @@ -28,7 +77,10 @@ current = mob_override current.faction |= "cult" current.verbs += /mob/living/proc/cult_help + if(!GLOB.cult_mastered) + current.verbs += /mob/living/proc/cult_master communion.Grant(current) + current.throw_alert("bloodsense", /obj/screen/alert/bloodsense) /datum/antagonist/cult/remove_innate_effects(mob/living/mob_override) . = ..() @@ -38,13 +90,59 @@ current.faction -= "cult" current.verbs -= /mob/living/proc/cult_help communion.Remove(current) + owner.current.verbs -= /mob/living/proc/cult_master + for(var/datum/action/innate/cultmast/H in owner.current.actions) + qdel(H) + current.clear_alert("bloodsense") /datum/antagonist/cult/on_removal() owner.wipe_memory() SSticker.mode.cult -= owner SSticker.mode.update_cult_icons_removed(owner) - to_chat(owner, "An unfamiliar white light flashes through your mind, cleansing the taint of the Dark One and all your memories as its servant.") - owner.current.log_message("Has renounced the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) if(!silent) - owner.current.visible_message("[owner] looks like [owner.current.p_they()] just reverted to their old faith!") + to_chat(owner.current, "An unfamiliar white light flashes through your mind, cleansing the taint of the Geometer and all your memories as her servant.") + owner.current.log_message("Has renounced the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) + owner.current.visible_message("[owner.current] looks like [owner.current.p_they()] just reverted to their old faith!") + if(GLOB.blood_target && GLOB.blood_target_image && owner.current.client) + owner.current.client.images -= GLOB.blood_target_image . = ..() + +/datum/antagonist/cult/master + var/datum/action/innate/cultmast/finalreck/reckoning = new + var/datum/action/innate/cultmast/cultmark/bloodmark = new + +/datum/antagonist/cult/master/Destroy() + QDEL_NULL(reckoning) + QDEL_NULL(bloodmark) + return ..() + +/datum/antagonist/cult/master/on_gain() + . = ..() + var/mob/living/current = owner.current + SSticker.mode.set_antag_hud(current, "cultmaster") + +/datum/antagonist/cult/master/greet() + to_chat(owner.current, "You are the cult's Master. As the cult's Master, you have a unique title and loud voice when communicating, are capable of marking \ + targets, such as a location or a noncultist, to direct the cult to them, and, finally, you are capable of summoning the entire living cult to your location once.") + to_chat(owner.current, "Use these abilities to direct the cult to victory at any cost.") + +/datum/antagonist/cult/master/apply_innate_effects(mob/living/mob_override) + . = ..() + var/mob/living/current = owner.current + if(mob_override) + current = mob_override + if(!GLOB.reckoning_complete) + reckoning.Grant(current) + bloodmark.Grant(current) + current.update_action_buttons_icon() + current.apply_status_effect(/datum/status_effect/cult_master) + +/datum/antagonist/cult/master/remove_innate_effects(mob/living/mob_override) + . = ..() + var/mob/living/current = owner.current + if(mob_override) + current = mob_override + reckoning.Remove(current) + bloodmark.Remove(current) + current.update_action_buttons_icon() + current.remove_status_effect(/datum/status_effect/cult_master) diff --git a/code/datums/antagonists/datum_cult.dm.rej b/code/datums/antagonists/datum_cult.dm.rej deleted file mode 100644 index 0fc846a73c..0000000000 --- a/code/datums/antagonists/datum_cult.dm.rej +++ /dev/null @@ -1,25 +0,0 @@ -diff a/code/datums/antagonists/datum_cult.dm b/code/datums/antagonists/datum_cult.dm (rejected hunks) -@@ -5,13 +5,20 @@ - qdel(communion) - return ..() - -+/datum/antagonist/cult/can_be_owned(datum/mind/new_owner) -+ . = ..() -+ if(.) -+ . = is_convertable_to_cult(new_owner.current) -+ - /datum/antagonist/cult/on_gain() - . = ..() -- if(!owner) -- return -+ SSticker.mode.cult += owner -+ SSticker.mode.update_cult_icons_added(owner) -+ if(istype(SSticker.mode, /datum/game_mode/cult)) -+ var/datum/game_mode/cult/C = SSticker.mode -+ C.memorize_cult_objectives(owner) - if(jobban_isbanned(owner.current, ROLE_CULTIST)) - addtimer(CALLBACK(SSticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner.current, ROLE_CULTIST, ROLE_CULTIST), 0) -- SSticker.mode.update_cult_icons_added(owner) - owner.current.log_message("Has been converted to the cult of Nar'Sie!", INDIVIDUAL_ATTACK_LOG) - - /datum/antagonist/cult/apply_innate_effects(mob/living/mob_override) diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm index b9358817e3..b90e2ec652 100644 --- a/code/datums/helper_datums/getrev.dm +++ b/code/datums/helper_datums/getrev.dm @@ -75,10 +75,12 @@ if(GLOB.revdata.parentcommit) to_chat(src, "Server revision compiled on: [GLOB.revdata.date]") + var/prefix = "" if(GLOB.revdata.testmerge.len) to_chat(src, GLOB.revdata.GetTestMergeInfo()) - to_chat(src, "Based off master commit:") - to_chat(src, "[GLOB.revdata.parentcommit]") + prefix = "Based off master commit: " + var/pc = GLOB.revdata.parentcommit + to_chat(src, "[prefix][copytext(pc, 1, min(length(pc), 7))]") else to_chat(src, "Revision unknown") to_chat(src, "Current Infomational Settings:") diff --git a/code/datums/holocall.dm b/code/datums/holocall.dm index 57cd50df5d..cdd0bc956b 100644 --- a/code/datums/holocall.dm +++ b/code/datums/holocall.dm @@ -1,3 +1,164 @@ + +#define HOLOPAD_MAX_DIAL_TIME 200 + +/mob/camera/aiEye/remote/holo/setLoc() + . = ..() + var/obj/machinery/holopad/H = origin + H.move_hologram(eye_user, loc) + +//this datum manages it's own references + +/datum/holocall + var/mob/living/user //the one that called + var/obj/machinery/holopad/calling_holopad //the one that sent the call + var/obj/machinery/holopad/connected_holopad //the one that answered the call (may be null) + var/list/dialed_holopads //all things called, will be cleared out to just connected_holopad once answered + + var/mob/camera/aiEye/remote/holo/eye //user's eye, once connected + var/obj/effect/overlay/holo_pad_hologram/hologram //user's hologram, once connected + + var/call_start_time + +//creates a holocall made by `caller` from `calling_pad` to `callees` +/datum/holocall/New(mob/living/caller, obj/machinery/holopad/calling_pad, list/callees) + call_start_time = world.time + user = caller + calling_pad.outgoing_call = src + calling_holopad = calling_pad + dialed_holopads = list() + + for(var/I in callees) + var/obj/machinery/holopad/H = I + if(!QDELETED(H) && H.is_operational()) + dialed_holopads += H + LAZYADD(H.holo_calls, src) + + if(!dialed_holopads.len) + calling_pad.say("Connection failure.") + qdel(src) + return + + testing("Holocall started") + +//cleans up ALL references :) +/datum/holocall/Destroy() + QDEL_NULL(eye) + + user.reset_perspective() + + user = null + hologram.HC = null + hologram = null + calling_holopad.outgoing_call = null + + for(var/I in dialed_holopads) + var/obj/machinery/holopad/H = I + LAZYREMOVE(H.holo_calls, src) + dialed_holopads.Cut() + + if(calling_holopad) + calling_holopad.SetLightsAndPower() + calling_holopad = null + if(connected_holopad) + connected_holopad.SetLightsAndPower() + connected_holopad = null + + testing("Holocall destroyed") + + return ..() + +//Gracefully disconnects a holopad `H` from a call. Pads not in the call are ignored. Notifies participants of the disconnection +/datum/holocall/proc/Disconnect(obj/machinery/holopad/H) + testing("Holocall disconnect") + if(H == connected_holopad) + calling_holopad.say("[usr] disconnected.") + else if(H == calling_holopad && connected_holopad) + connected_holopad.say("[usr] disconnected.") + + ConnectionFailure(H, TRUE) + +//Forcefully disconnects a holopad `H` from a call. Pads not in the call are ignored. +/datum/holocall/proc/ConnectionFailure(obj/machinery/holopad/H, graceful = FALSE) + testing("Holocall connection failure: graceful [graceful]") + if(H == connected_holopad || H == calling_holopad) + if(!graceful) + calling_holopad.say("Connection failure.") + qdel(src) + return + + LAZYREMOVE(H.holo_calls, src) + dialed_holopads -= H + if(!dialed_holopads.len) + if(graceful) + calling_holopad.say("Call rejected.") + testing("No recipients, terminating") + qdel(src) + +//Answers a call made to a holopad `H` which cannot be the calling holopad. Pads not in the call are ignored +/datum/holocall/proc/Answer(obj/machinery/holopad/H) + testing("Holocall answer") + if(H == calling_holopad) + CRASH("How cute, a holopad tried to answer itself.") + + if(!(H in dialed_holopads)) + return + + if(connected_holopad) + CRASH("Multi-connection holocall") + + for(var/I in dialed_holopads) + if(I == H) + continue + Disconnect(I) + + for(var/I in H.holo_calls) + var/datum/holocall/HC = I + if(HC != src) + HC.Disconnect(H) + + connected_holopad = H + + if(!Check()) + return + + hologram = H.activate_holo(user) + hologram.HC = src + + //eyeobj code is horrid, this is the best copypasta I could make + eye = new + eye.origin = H + eye.eye_initialized = TRUE + eye.eye_user = user + eye.name = "Camera Eye ([user.name])" + user.remote_control = eye + user.reset_perspective(eye) + eye.setLoc(H.loc) + +//Checks the validity of a holocall and qdels itself if it's not. Returns TRUE if valid, FALSE otherwise +/datum/holocall/proc/Check() + for(var/I in dialed_holopads) + var/obj/machinery/holopad/H = I + if(!H.is_operational()) + ConnectionFailure(H) + + if(QDELETED(src)) + return FALSE + + . = !QDELETED(user) && !user.incapacitated() && !QDELETED(calling_holopad) && calling_holopad.is_operational() && user.loc == calling_holopad.loc + + if(.) + if(connected_holopad) + . = !QDELETED(connected_holopad) && connected_holopad.is_operational() + else + . = world.time < (call_start_time + HOLOPAD_MAX_DIAL_TIME) + if(!.) + calling_holopad.say("No answer recieved.") + calling_holopad.temp = "" + + if(!.) + testing("Holocall Check fail") + qdel(src) +======= #define HOLOPAD_MAX_DIAL_TIME 200 /mob/camera/aiEye/remote/holo/setLoc() diff --git a/code/datums/mind.dm b/code/datums/mind.dm index ccbbbdd6c2..b0361e9296 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -44,9 +44,7 @@ var/datum/job/assigned_job var/list/datum/objective/objectives = list() - var/list/datum/objective/special_verbs = list() - var/list/cult_words = list() var/list/spell_list = list() // Wizard mode & "Give Spell" badmin button. var/datum/faction/faction //associated faction @@ -54,7 +52,7 @@ var/linglink var/miming = 0 // Mime's vow of silence - var/list/antag_datums + var/list/antag_datums var/antag_hud_icon_state = null //this mind's ANTAG_HUD should have this icon_state var/datum/atom_hud/antag/antag_hud = null //this mind's antag HUD var/datum/gang/gang_datum //Which gang this mind belongs to, if any @@ -73,10 +71,10 @@ /datum/mind/Destroy() SSticker.minds -= src - if(islist(antag_datums)) - for(var/i in antag_datums) - qdel(i) - antag_datums = null + if(islist(antag_datums)) + for(var/i in antag_datums) + qdel(i) + antag_datums = null return ..() /datum/mind/proc/get_language_holder() @@ -104,12 +102,12 @@ new_character.mind.current = null var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list - var/mob/living/old_current = current + var/mob/living/old_current = current current = new_character //associate ourself with our new body new_character.mind = src //and associate our new body with ourself - for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body - var/datum/antagonist/A = a - A.on_body_transfer(old_current, current) + for(var/a in antag_datums) //Makes sure all antag datums effects are applied in the new body + var/datum/antagonist/A = a + A.on_body_transfer(old_current, current) if(iscarbon(new_character)) var/mob/living/carbon/C = new_character C.last_mind = src @@ -125,42 +123,42 @@ /datum/mind/proc/wipe_memory() memory = null -// Datum antag mind procs -/datum/mind/proc/add_antag_datum(datum_type) - if(!datum_type) - return - var/datum/antagonist/A = new datum_type(src) - if(!A.can_be_owned(src)) - qdel(A) - return - LAZYADD(antag_datums, A) - A.on_gain() - return A - -/datum/mind/proc/remove_antag_datum(datum_type) - if(!datum_type) - return - var/datum/antagonist/A = has_antag_datum(datum_type) - if(A) - A.on_removal() - return TRUE - -/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us. - for(var/a in antag_datums) - var/datum/antagonist/A = a - A.on_removal() - -/datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE) - if(!datum_type) - return - . = FALSE - for(var/a in antag_datums) - var/datum/antagonist/A = a - if(check_subtypes && istype(A, datum_type)) - return A - else if(A.type == datum_type) - return A - +// Datum antag mind procs +/datum/mind/proc/add_antag_datum(datum_type) + if(!datum_type) + return + var/datum/antagonist/A = new datum_type(src) + if(!A.can_be_owned(src)) + qdel(A) + return + LAZYADD(antag_datums, A) + A.on_gain() + return A + +/datum/mind/proc/remove_antag_datum(datum_type) + if(!datum_type) + return + var/datum/antagonist/A = has_antag_datum(datum_type) + if(A) + A.on_removal() + return TRUE + +/datum/mind/proc/remove_all_antag_datums() //For the Lazy amongst us. + for(var/a in antag_datums) + var/datum/antagonist/A = a + A.on_removal() + +/datum/mind/proc/has_antag_datum(datum_type, check_subtypes = TRUE) + if(!datum_type) + return + . = FALSE + for(var/a in antag_datums) + var/datum/antagonist/A = a + if(check_subtypes && istype(A, datum_type)) + return A + else if(A.type == datum_type) + return A + /* Removes antag type's references from a mind. objectives, uplinks, powers etc are all handled. @@ -286,7 +284,7 @@ creator.faction |= current.faction if(creator.mind.special_role) - message_admins("[key_name_admin(current)](?) has been created by [key_name_admin(creator)](?), an antagonist.") + message_admins("[ADMIN_LOOKUPFLW(current)] has been created by [ADMIN_LOOKUPFLW(creator)], an antagonist.") to_chat(current, "Despite your creators current allegiances, your true master remains [creator.real_name]. If their loyalities change, so do yours. This will never change unless your creator's body is destroyed.") /datum/mind/proc/show_memory(mob/recipient, window=1) @@ -307,7 +305,7 @@ to_chat(recipient, "[output]") /datum/mind/proc/edit_memory() - if(!SSticker.HasRoundStarted()) + if(!SSticker.HasRoundStarted()) alert("Not before round-start!", "Alert") return @@ -1195,7 +1193,7 @@ log_admin("[key_name_admin(usr)] has made [current] unable to ascend as a devil.") return if(!ishuman(current) && !iscyborg(current)) - to_chat(usr, "This only works on humans and cyborgs!") + to_chat(usr, "This only works on humans and cyborgs!") return SSticker.mode.devils += src special_role = "devil" @@ -1244,17 +1242,17 @@ log_admin("[key_name(usr)] turned [current] into abductor.") SSticker.mode.update_abductor_icons_added(src) if("equip") - if(!ishuman(current)) - to_chat(usr, "This only works on humans!") - return - - var/mob/living/carbon/human/H = current + if(!ishuman(current)) + to_chat(usr, "This only works on humans!") + return + + var/mob/living/carbon/human/H = current var/gear = alert("Agent or Scientist Gear","Gear","Agent","Scientist") if(gear) if(gear=="Agent") - H.equipOutfit(/datum/outfit/abductor/agent) + H.equipOutfit(/datum/outfit/abductor/agent) else - H.equipOutfit(/datum/outfit/abductor/scientist) + H.equipOutfit(/datum/outfit/abductor/scientist) else if (href_list["monkey"]) var/mob/living/L = current @@ -1451,15 +1449,8 @@ special_role = "Cultist" to_chat(current, "You catch a glimpse of the Realm of Nar-Sie, The Geometer of Blood. You now see how flimsy the world is, you see that it should be open to the knowledge of Nar-Sie.") to_chat(current, "Assist your new compatriots in their dark dealings. Their goal is yours, and yours is theirs. You serve the Dark One above all else. Bring It back.") - var/datum/game_mode/cult/cult = SSticker.mode - - if (istype(cult)) - cult.memorize_cult_objectives(src) - else - var/explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it." - to_chat(current, "Objective #1: [explanation]") - memory += "Objective #1: [explanation]
" - + var/datum/antagonist/cult/C + C.cult_memorization(src) var/mob/living/carbon/human/H = current if (!SSticker.mode.equip_cultist(current)) to_chat(H, "Spawning an amulet from your Master failed.") @@ -1523,8 +1514,8 @@ H.set_species(/datum/species/abductor) var/datum/species/abductor/S = H.dna.species - if(role == "Scientist") - S.scientist = TRUE + if(role == "Scientist") + S.scientist = TRUE S.team = team var/list/obj/effect/landmark/abductor/agent_landmarks = new @@ -1543,8 +1534,8 @@ if("Agent") L = agent_landmarks[team] if("Scientist") - L = scientist_landmarks[team] - H.forceMove(L.loc) + L = scientist_landmarks[team] + H.forceMove(L.loc) /datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S) spell_list += S diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm index 3a54db4e0a..011363f001 100644 --- a/code/datums/ruins/lavaland.dm +++ b/code/datums/ruins/lavaland.dm @@ -42,6 +42,7 @@ However, all the inhabitants seem to do is grow drugs and guns." suffix = "lavaland_surface_seed_vault.dmm" cost = 10 + allow_duplicates = FALSE /datum/map_template/ruin/lavaland/ash_walker name = "Ash Walker Nest" diff --git a/code/datums/shuttles.dm b/code/datums/shuttles.dm index 774e0794ff..d3427ac983 100644 --- a/code/datums/shuttles.dm +++ b/code/datums/shuttles.dm @@ -72,7 +72,7 @@ /datum/map_template/shuttle/emergency/meteor suffix = "meteor" - name = "An Asteroid With Engines Strapped To It" + name = "Asteroid With Engines Strapped To It" description = "A hollowed out asteroid with engines strapped to it. Due to its size and difficulty in steering it, this shuttle may damage the docking area." admin_notes = "This shuttle will likely crush escape, killing anyone there." credit_cost = -5000 diff --git a/code/datums/status_effects/buffs.dm b/code/datums/status_effects/buffs.dm index 3f261c7991..a0338f72b0 100644 --- a/code/datums/status_effects/buffs.dm +++ b/code/datums/status_effects/buffs.dm @@ -13,6 +13,7 @@ /datum/status_effect/shadow_mend/on_apply() owner.visible_message("Violet light wraps around [owner]'s body!", "Violet light wraps around your body!") playsound(owner, 'sound/magic/Teleport_app.ogg', 50, 1) + return ..() /datum/status_effect/shadow_mend/tick() owner.adjustBruteLoss(-15) @@ -77,6 +78,7 @@ progbar = new(owner, duration, owner) progbar.bar.color = list("#FAE48C", "#FAE48C", "#FAE48C", rgb(0,0,0)) progbar.update(duration - world.time) + return ..() /datum/status_effect/vanguard_shield/tick() progbar.update(duration - world.time) @@ -129,6 +131,7 @@ animate(owner, color = oldcolor, time = 150, easing = EASE_IN) addtimer(CALLBACK(owner, /atom/proc/update_atom_colour), 150) playsound(owner, 'sound/magic/Ethereal_Enter.ogg', 50, 1) + return ..() /datum/status_effect/inathneqs_endowment/on_remove() add_logs(owner, null, "lost Inath-neq's invulnerability") @@ -180,6 +183,7 @@ /datum/status_effect/his_grace/on_apply() add_logs(owner, null, "gained His Grace's stun immunity") owner.add_stun_absorption("hisgrace", INFINITY, 3, null, "His Grace protects you from the stun!") + return ..() /datum/status_effect/his_grace/tick() bloodlust = 0 @@ -213,6 +217,7 @@ /datum/status_effect/wish_granters_gift/on_apply() to_chat(owner, "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(full_heal = 1, admin_revive = 1) @@ -223,3 +228,32 @@ name = "Wish Granter's Immortality" desc = "You are being resurrected!" icon_state = "wish_granter" + +/datum/status_effect/cult_master + id = "The Cult Master" + duration = -1 + tick_interval = 100 + alert_type = null + var/alive = TRUE + +/datum/status_effect/cult_master/proc/deathrattle() + var/area/A = get_area(owner) + for(var/datum/mind/B in SSticker.mode.cult) + if(isliving(B.current)) + var/mob/living/M = B.current + M << 'sound/hallucinations/veryfar_noise.ogg' + to_chat(M, "The Cult's Master, [owner], has fallen in the [A]!") + + +/datum/status_effect/cult_master/tick() + if(owner.stat != DEAD && !alive) + alive = TRUE + return + if(owner.stat == DEAD && alive) + alive = FALSE + deathrattle() + +/datum/status_effect/cult_master/on_remove() + deathrattle() + . = ..() + diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index f78a3ae522..9f6e481edb 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -29,3 +29,136 @@ owner.adjustBruteLoss(0.1) owner.adjustFireLoss(0.1) owner.adjustToxLoss(0.2, TRUE, TRUE) + +/datum/status_effect/belligerent + id = "belligerent" + duration = 70 + tick_interval = 0 //tick as fast as possible + status_type = STATUS_EFFECT_REPLACE + alert_type = /obj/screen/alert/status_effect/belligerent + var/leg_damage_on_toggle = 2 //damage on initial application and when the owner tries to toggle to run + var/cultist_damage_on_toggle = 10 //damage on initial application and when the owner tries to toggle to run, but to cultists + +/obj/screen/alert/status_effect/belligerent + name = "Belligerent" + desc = "Kneel, her-eti'c." + icon_state = "belligerent" + alerttooltipstyle = "clockcult" + +/datum/status_effect/belligerent/on_apply() + return do_movement_toggle(TRUE) + +/datum/status_effect/belligerent/tick() + if(!do_movement_toggle()) + qdel(src) + +/datum/status_effect/belligerent/proc/do_movement_toggle(force_damage) + var/number_legs = owner.get_num_legs() + if(iscarbon(owner) && !is_servant_of_ratvar(owner) && !owner.null_rod_check() && number_legs) + if(force_damage || owner.m_intent != MOVE_INTENT_WALK) + if(GLOB.ratvar_awakens) + owner.Weaken(1) + if(iscultist(owner)) + owner.apply_damage(cultist_damage_on_toggle * 0.5, BURN, "l_leg") + owner.apply_damage(cultist_damage_on_toggle * 0.5, BURN, "r_leg") + else + owner.apply_damage(leg_damage_on_toggle * 0.5, BURN, "l_leg") + owner.apply_damage(leg_damage_on_toggle * 0.5, BURN, "r_leg") + if(owner.m_intent != MOVE_INTENT_WALK) + if(!iscultist(owner)) + to_chat(owner, "Your leg[number_legs > 1 ? "s shiver":" shivers"] with pain!") + else //Cultists take extra burn damage + to_chat(owner, "Your leg[number_legs > 1 ? "s burn":" burns"] with pain!") + owner.toggle_move_intent() + return TRUE + return FALSE + +/datum/status_effect/belligerent/on_remove() + if(owner.m_intent == MOVE_INTENT_WALK) + owner.toggle_move_intent() + + +/datum/status_effect/maniamotor + id = "maniamotor" + duration = -1 + tick_interval = 10 + status_type = STATUS_EFFECT_MULTIPLE + alert_type = null + var/obj/structure/destructible/clockwork/powered/mania_motor/motor + var/severity = 0 //goes up to a maximum of MAX_MANIA_SEVERITY + var/warned_turnoff = FALSE //if we've warned that the motor is off + var/warned_outofsight = FALSE //if we've warned that the target is out of sight of the motor + var/static/list/mania_messages = list("Go nuts.", "Take a crack at crazy.", "Make a bid for insanity.", "Get kooky.", "Move towards mania.", "Become bewildered.", "Wax wild.", \ + "Go round the bend.", "Land in lunacy.", "Try dementia.", "Strive to get a screw loose.", "Advance forward.", "Approach the transmitter.", "Touch the antennae.", \ + "Move towards the mania motor.", "Come closer.", "Get over here already!", "Keep your eyes on the motor.") + var/static/list/flee_messages = list("Oh, NOW you flee.", "Get back here!", "If you were smarter, you'd come back.", "Only fools run.", "You'll be back.") + var/static/list/turnoff_messages = list("Why would they turn it-", "What are these idi-", "Fools, fools, all of-", "Are they trying to c-", "All this effort just f-") + var/static/list/powerloss_messages = list("\"Oh, the id**ts di***t s***e en**** pow**...\"", "\"D*dn't **ey mak* an **te***c*i*n le**?\"", "\"The** f**ls for**t t* make a ***** *f-\"", \ + "\"No, *O, you **re so cl***-\"", "You hear a yell of frustration, cut off by static.") + +/datum/status_effect/maniamotor/Destroy() + motor = null + return ..() + +/datum/status_effect/maniamotor/tick() + var/is_servant = is_servant_of_ratvar(owner) + var/span_part = severity > 50 ? "" : "_small" //let's save like one check + if(QDELETED(motor)) + if(!is_servant) + to_chat(owner, "You feel a frustrated voice quietly fade from your mind...") + qdel(src) + return + if(!motor.active) //it being off makes it fall off much faster + if(!is_servant && !warned_turnoff) + if(motor.total_accessable_power() > motor.mania_cost) + to_chat(owner, "\"[text2ratvar(pick(turnoff_messages))]\"") + else + to_chat(owner, "[text2ratvar(pick(powerloss_messages))]") + warned_turnoff = TRUE + severity = max(severity - 2, 0) + if(!severity) + qdel(src) + return + else + if(prob(severity * 2)) + warned_turnoff = FALSE + if(!(owner in viewers(7, motor))) //not being in range makes it fall off slightly faster + if(!is_servant && !warned_outofsight) + to_chat(owner, "\"[text2ratvar(pick(flee_messages))]\"") + warned_outofsight = TRUE + severity = max(severity - 1, 0) + if(!severity) + qdel(src) + return + else if(prob(severity * 2)) + warned_outofsight = FALSE + if(is_servant) //heals servants of braindamage, hallucination, druggy, dizziness, and confusion + if(owner.hallucination) + owner.hallucination = 0 + if(owner.druggy) + owner.adjust_drugginess(-owner.druggy) + if(owner.dizziness) + owner.dizziness = 0 + if(owner.confused) + owner.confused = 0 + severity = 0 + else if(!owner.null_rod_check() && owner.stat != DEAD && severity) + var/static/hum = get_sfx('sound/effects/screech.ogg') //same sound for every proc call + if(owner.getToxLoss() > MANIA_DAMAGE_TO_CONVERT) + if(is_eligible_servant(owner)) + to_chat(owner, "\"[text2ratvar("You are mine and his, now.")]\"") + add_servant_of_ratvar(owner) + owner.Paralyse(5) + else + if(prob(severity * 0.15)) + to_chat(owner, "\"[text2ratvar(pick(mania_messages))]\"") + owner.playsound_local(get_turf(motor), hum, severity, 1) + owner.adjust_drugginess(Clamp(max(severity * 0.075, 1), 0, max(0, 50 - owner.druggy))) //7.5% of severity per second, minimum 1 + if(owner.hallucination < 50) + owner.hallucination = min(owner.hallucination + max(severity * 0.075, 1), 50) //7.5% of severity per second, minimum 1 + if(owner.dizziness < 50) + owner.dizziness = min(owner.dizziness + round(severity * 0.05, 1), 50) //5% of severity per second above 10 severity + if(owner.confused < 25) + owner.confused = min(owner.confused + round(severity * 0.025, 1), 25) //2.5% of severity per second above 20 severity + owner.adjustToxLoss(severity * 0.02, TRUE, TRUE) //2% of severity per second + severity-- diff --git a/code/datums/status_effects/gas.dm b/code/datums/status_effects/gas.dm index c2c070dbec..ff92b67978 100644 --- a/code/datums/status_effects/gas.dm +++ b/code/datums/status_effects/gas.dm @@ -16,6 +16,7 @@ cube = icon('icons/effects/freeze.dmi', "ice_cube") owner.add_overlay(cube) owner.update_canmove() + return ..() /datum/status_effect/freon/tick() owner.update_canmove() diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm index 51b4f8fc5f..61c8607975 100644 --- a/code/datums/status_effects/status_effect.dm +++ b/code/datums/status_effects/status_effect.dm @@ -10,6 +10,7 @@ var/status_type = STATUS_EFFECT_UNIQUE //How many of the effect can be on one mob, and what happens when you try to add another var/on_remove_on_mob_delete = FALSE //if we call on_remove() when the mob is deleted var/alert_type = /obj/screen/alert/status_effect //the alert thrown by the status effect, contains name and description + var/obj/screen/alert/status_effect/linked_alert = null //the alert itself, if it exists /datum/status_effect/New(mob/living/new_owner) if(new_owner) @@ -30,16 +31,16 @@ /datum/status_effect/proc/start_ticking() if(!src) return - if(!owner) + if(!owner || !on_apply()) qdel(src) return - on_apply() if(duration != -1) duration = world.time + initial(duration) tick_interval = world.time + initial(tick_interval) if(alert_type) var/obj/screen/alert/status_effect/A = owner.throw_alert(id, alert_type) A.attached_effect = src //so the alert can reference us, if it needs to + linked_alert = A //so we can reference the alert, if we need to START_PROCESSING(SSfastprocess, src) /datum/status_effect/process() @@ -53,6 +54,8 @@ qdel(src) /datum/status_effect/proc/on_apply() //Called whenever the buff is applied. + return TRUE + /datum/status_effect/proc/tick() //Called every tick. /datum/status_effect/proc/on_remove() //Called whenever the buff expires or is removed; do note that at the point this is called, it is out of the owner's status_effects but owner is not yet null /datum/status_effect/proc/be_replaced() //Called instead of on_remove when a status effect is replaced by itself or when a status effect with on_remove_on_mob_delete = FALSE has its mob deleted @@ -103,3 +106,11 @@ for(var/datum/status_effect/S in status_effects) if(initial(S1.id) == S.id) return S + +/mob/living/proc/has_status_effect_list(effect) //returns a list of effects with matching IDs that the mod owns; use for effects there can be multiple of + . = list() + if(status_effects) + var/datum/status_effect/S1 = effect + for(var/datum/status_effect/S in status_effects) + if(initial(S1.id) == S.id) + . += S diff --git a/code/game/atoms.dm b/code/game/atoms.dm index cc9ea86682..4a0f05602b 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -274,6 +274,7 @@ return /atom/proc/ex_act(severity, target) + set waitfor = FALSE contents_explosion(severity, target) /atom/proc/blob_act(obj/structure/blob/B) diff --git a/code/game/gamemodes/antag_spawner.dm b/code/game/gamemodes/antag_spawner.dm index 74c16cf132..5b568970d9 100644 --- a/code/game/gamemodes/antag_spawner.dm +++ b/code/game/gamemodes/antag_spawner.dm @@ -155,7 +155,8 @@ if(!(check_usability(user))) return - var/list/nuke_candidates = pollCandidatesForMob("Do you want to play as a syndicate [borg_to_spawn ? "[lowertext(borg_to_spawn)] cyborg":"operative"]?", ROLE_OPERATIVE, null, ROLE_OPERATIVE, 150, src) + to_chat(user, "You activate [src] and wait for confirmation.") + var/list/nuke_candidates = pollCandidatesForMob("Do you want to play as a syndicate [borg_to_spawn ? "[lowertext(borg_to_spawn)] cyborg":"operative"]?", ROLE_OPERATIVE, null, ROLE_OPERATIVE, 150, POLL_IGNORE_SYNDICATE, src) if(nuke_candidates.len) if(!(check_usability(user))) return diff --git a/code/game/gamemodes/changeling/changeling_power.dm b/code/game/gamemodes/changeling/changeling_power.dm index 67eb216d58..489228a30c 100644 --- a/code/game/gamemodes/changeling/changeling_power.dm +++ b/code/game/gamemodes/changeling/changeling_power.dm @@ -13,8 +13,6 @@ var/req_dna = 0 //amount of dna needed to use this ability. Changelings always have atleast 1 var/req_human = 0 //if you need to be human to use this ability var/req_stat = CONSCIOUS // CONSCIOUS, UNCONSCIOUS or DEAD - var/genetic_damage = 0 // genetic damage caused by using the sting. Nothing to do with cloneloss. - var/max_genetic_damage = 100 // hard counter for spamming abilities. Not used/balanced much yet. var/always_keep = 0 // important for abilities like revive that screw you if you lose them. var/ignores_fakedeath = FALSE // usable with the FAKEDEATH flag @@ -39,7 +37,7 @@ if(sting_action(user, target)) SSblackbox.add_details("changeling_powers",name) sting_feedback(user, target) - take_chemical_cost(c) + c.chem_charges -= chemical_cost /obj/effect/proc_holder/changeling/proc/sting_action(mob/user, mob/target) return 0 @@ -47,10 +45,6 @@ /obj/effect/proc_holder/changeling/proc/sting_feedback(mob/user, mob/target) return 0 -/obj/effect/proc_holder/changeling/proc/take_chemical_cost(datum/changeling/changeling) - changeling.chem_charges -= chemical_cost - changeling.geneticdamage += genetic_damage - //Fairly important to remember to return 1 on success >.< /obj/effect/proc_holder/changeling/proc/can_sting(mob/user, mob/target) if(!ishuman(user) && !ismonkey(user)) //typecast everything from mob to carbon from this point onwards @@ -71,9 +65,6 @@ if((user.status_flags & FAKEDEATH) && (!ignores_fakedeath)) to_chat(user, "We are incapacitated.") return 0 - if(c.geneticdamage > max_genetic_damage) - to_chat(user, "Our genomes are still reassembling. We need time to recover first.") - return 0 return 1 //used in /mob/Stat() diff --git a/code/game/gamemodes/changeling/powers/absorb.dm b/code/game/gamemodes/changeling/powers/absorb.dm index 6a52ab9312..b6b3372ae3 100644 --- a/code/game/gamemodes/changeling/powers/absorb.dm +++ b/code/game/gamemodes/changeling/powers/absorb.dm @@ -4,7 +4,6 @@ chemical_cost = 0 dna_cost = 0 req_human = 1 - max_genetic_damage = 100 /obj/effect/proc_holder/changeling/absorbDNA/can_sting(mob/living/carbon/user) if(!..()) diff --git a/code/game/gamemodes/changeling/powers/biodegrade.dm b/code/game/gamemodes/changeling/powers/biodegrade.dm index 453dec9375..6e2d6b0ddd 100644 --- a/code/game/gamemodes/changeling/powers/biodegrade.dm +++ b/code/game/gamemodes/changeling/powers/biodegrade.dm @@ -5,9 +5,6 @@ chemical_cost = 30 //High cost to prevent spam dna_cost = 2 req_human = 1 - genetic_damage = 10 - max_genetic_damage = 0 - /obj/effect/proc_holder/changeling/biodegrade/sting_action(mob/living/carbon/human/user) var/used = FALSE // only one form of shackles removed per use diff --git a/code/game/gamemodes/changeling/powers/chameleon_skin.dm b/code/game/gamemodes/changeling/powers/chameleon_skin.dm index 1f18f628a8..3be5103105 100644 --- a/code/game/gamemodes/changeling/powers/chameleon_skin.dm +++ b/code/game/gamemodes/changeling/powers/chameleon_skin.dm @@ -5,9 +5,6 @@ dna_cost = 2 chemical_cost = 25 req_human = 1 - genetic_damage = 10 - max_genetic_damage = 50 - /obj/effect/proc_holder/changeling/chameleon_skin/sting_action(mob/user) var/mob/living/carbon/human/H = user //SHOULD always be human, because req_human = 1 diff --git a/code/game/gamemodes/changeling/powers/fakedeath.dm b/code/game/gamemodes/changeling/powers/fakedeath.dm index 798f8030e0..e35f04d9e7 100644 --- a/code/game/gamemodes/changeling/powers/fakedeath.dm +++ b/code/game/gamemodes/changeling/powers/fakedeath.dm @@ -5,8 +5,6 @@ dna_cost = 0 req_dna = 1 req_stat = DEAD - max_genetic_damage = 100 - //Fake our own death and fully heal. You will appear to be dead but regenerate fully after a short delay. /obj/effect/proc_holder/changeling/fakedeath/sting_action(mob/living/user) diff --git a/code/game/gamemodes/changeling/powers/humanform.dm b/code/game/gamemodes/changeling/powers/humanform.dm index 743dbc91e9..d92e622c2d 100644 --- a/code/game/gamemodes/changeling/powers/humanform.dm +++ b/code/game/gamemodes/changeling/powers/humanform.dm @@ -2,10 +2,7 @@ name = "Human Form" desc = "We change into a human." chemical_cost = 5 - genetic_damage = 3 req_dna = 1 - max_genetic_damage = 3 - //Transform into a human. /obj/effect/proc_holder/changeling/humanform/sting_action(mob/living/carbon/user) diff --git a/code/game/gamemodes/changeling/powers/lesserform.dm b/code/game/gamemodes/changeling/powers/lesserform.dm index 538803de00..06824f9bed 100644 --- a/code/game/gamemodes/changeling/powers/lesserform.dm +++ b/code/game/gamemodes/changeling/powers/lesserform.dm @@ -3,7 +3,6 @@ desc = "We debase ourselves and become lesser. We become a monkey." chemical_cost = 5 dna_cost = 1 - genetic_damage = 3 req_human = 1 //Transform into a monkey. diff --git a/code/game/gamemodes/changeling/powers/linglink.dm b/code/game/gamemodes/changeling/powers/linglink.dm index fc4b91b650..232774c937 100644 --- a/code/game/gamemodes/changeling/powers/linglink.dm +++ b/code/game/gamemodes/changeling/powers/linglink.dm @@ -4,7 +4,6 @@ chemical_cost = 0 dna_cost = 0 req_human = 1 - max_genetic_damage = 100 /obj/effect/proc_holder/changeling/linglink/can_sting(mob/living/carbon/user) if(!..()) diff --git a/code/game/gamemodes/changeling/powers/mutations.dm b/code/game/gamemodes/changeling/powers/mutations.dm index 54e8ea1e38..aef9b6f1d2 100644 --- a/code/game/gamemodes/changeling/powers/mutations.dm +++ b/code/game/gamemodes/changeling/powers/mutations.dm @@ -16,7 +16,6 @@ helptext = "Yell at Miauw and/or Perakp" chemical_cost = 1000 dna_cost = -1 - genetic_damage = 1000 var/silent = FALSE var/weapon_type @@ -67,7 +66,6 @@ helptext = "Yell at Miauw and/or Perakp" chemical_cost = 1000 dna_cost = -1 - genetic_damage = 1000 var/helmet_type = /obj/item var/suit_type = /obj/item @@ -89,7 +87,7 @@ return 1 var/mob/living/carbon/human/H = user if(istype(H.wear_suit, suit_type) || istype(H.head, helmet_type)) - H.visible_message("[H] casts off their [suit_name_simple]!", "We cast off our [suit_name_simple][genetic_damage > 0 ? ", temporarily weakening our genomes." : "."]", "You hear the organic matter ripping and tearing!") + H.visible_message("[H] casts off their [suit_name_simple]!", "We cast off our [suit_name_simple].", "You hear the organic matter ripping and tearing!") H.temporarilyRemoveItemFromInventory(H.head, TRUE) //The qdel on dropped() takes care of it H.temporarilyRemoveItemFromInventory(H.wear_suit, TRUE) H.update_inv_wear_suit() @@ -100,7 +98,6 @@ H.add_splatter_floor() playsound(H.loc, 'sound/effects/splat.ogg', 50, 1) //So real sounds - changeling.geneticdamage += genetic_damage //Casting off a space suit leaves you weak for a few seconds. changeling.chem_recharge_slowdown -= recharge_slowdown return 1 @@ -139,9 +136,7 @@ helptext = "We may retract our armblade in the same manner as we form it. Cannot be used while in lesser form." chemical_cost = 20 dna_cost = 2 - genetic_damage = 10 req_human = 1 - max_genetic_damage = 20 weapon_type = /obj/item/weapon/melee/arm_blade weapon_name_simple = "blade" @@ -217,9 +212,7 @@ and Harm will stun it, and stab it if we're also holding a sharp weapon. Cannot be used while in lesser form." chemical_cost = 10 dna_cost = 2 - genetic_damage = 5 req_human = 1 - max_genetic_damage = 10 weapon_type = /obj/item/weapon/gun/magic/tentacle weapon_name_simple = "tentacle" silent = TRUE @@ -381,9 +374,7 @@ helptext = "Organic tissue cannot resist damage forever; the shield will break after it is hit too much. The more genomes we absorb, the stronger it is. Cannot be used while in lesser form." chemical_cost = 20 dna_cost = 1 - genetic_damage = 12 req_human = 1 - max_genetic_damage = 20 weapon_type = /obj/item/weapon/shield/changeling weapon_name_simple = "shield" @@ -430,12 +421,10 @@ /obj/effect/proc_holder/changeling/suit/organic_space_suit name = "Organic Space Suit" desc = "We grow an organic suit to protect ourselves from space exposure." - helptext = "We must constantly repair our form to make it space-proof, reducing chemical production while we are protected. Retreating the suit damages our genomes. Cannot be used in lesser form." + 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." chemical_cost = 20 dna_cost = 2 - genetic_damage = 8 req_human = 1 - max_genetic_damage = 20 suit_type = /obj/item/clothing/suit/space/changeling helmet_type = /obj/item/clothing/head/helmet/space/changeling @@ -477,12 +466,10 @@ /obj/effect/proc_holder/changeling/suit/armor name = "Chitinous Armor" desc = "We turn our skin into tough chitin to protect us from damage." - helptext = "Upkeep of the armor requires a low expenditure of chemicals. The armor is strong against brute force, but does not provide much protection from lasers. Retreating the armor damages our genomes. Cannot be used in lesser form." + helptext = "Upkeep of the armor requires a low expenditure of chemicals. The armor is strong against brute force, but does not provide much protection from lasers. Cannot be used in lesser form." chemical_cost = 20 dna_cost = 1 - genetic_damage = 11 req_human = 1 - max_genetic_damage = 20 recharge_slowdown = 0.25 suit_type = /obj/item/clothing/suit/armor/changeling diff --git a/code/game/gamemodes/changeling/powers/tiny_prick.dm b/code/game/gamemodes/changeling/powers/tiny_prick.dm index c44a32c24d..ad6bf81e7c 100644 --- a/code/game/gamemodes/changeling/powers/tiny_prick.dm +++ b/code/game/gamemodes/changeling/powers/tiny_prick.dm @@ -40,10 +40,9 @@ return if(!AStar(user, target.loc, /turf/proc/Distance, user.mind.changeling.sting_range, simulated_only = 0)) return - if(target.mind && target.mind.changeling) - sting_feedback(user,target) - take_chemical_cost(user.mind.changeling) - return + if(target.mind && target.mind.changeling) + sting_feedback(user, target) + user.mind.changeling.chem_charges -= chemical_cost return 1 /obj/effect/proc_holder/changeling/sting/sting_feedback(mob/user, mob/target) @@ -62,7 +61,6 @@ sting_icon = "sting_transform" chemical_cost = 40 dna_cost = 3 - genetic_damage = 100 var/datum/changelingprofile/selected_dna = null /obj/effect/proc_holder/changeling/sting/transformation/Click() @@ -117,8 +115,6 @@ sting_icon = "sting_armblade" chemical_cost = 20 dna_cost = 1 - genetic_damage = 20 - max_genetic_damage = 10 /obj/item/weapon/melee/arm_blade/false desc = "A grotesque mass of flesh that used to be your arm. Although it looks dangerous at first, you can tell it's actually quite dull and useless." diff --git a/code/game/gamemodes/changeling/powers/transform.dm b/code/game/gamemodes/changeling/powers/transform.dm index f9aca83d04..9d0b095cc2 100644 --- a/code/game/gamemodes/changeling/powers/transform.dm +++ b/code/game/gamemodes/changeling/powers/transform.dm @@ -5,7 +5,6 @@ dna_cost = 0 req_dna = 1 req_human = 1 - max_genetic_damage = 3 /obj/item/clothing/glasses/changeling name = "flesh" diff --git a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm index 6c56295c05..cf709f09b0 100644 --- a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm +++ b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm @@ -54,8 +54,11 @@ clockwork_desc = "A sigil that will stun the next non-Servant to cross it." icon_state = "sigildull" layer = HIGH_SIGIL_LAYER - alpha = 60 + alpha = 75 color = "#FAE48C" + light_range = 1.4 + light_power = 1 + light_color = "#FAE48C" sigil_name = "Sigil of Transgression" /obj/effect/clockwork/sigil/transgression/sigil_effects(mob/living/L) @@ -93,10 +96,6 @@ sigil_name = "Sigil of Submission" var/glow_type -/obj/effect/clockwork/sigil/submission/New() - ..() - update_light() - /obj/effect/clockwork/sigil/submission/proc/post_channel(mob/living/L) /obj/effect/clockwork/sigil/submission/sigil_effects(mob/living/L) @@ -202,6 +201,21 @@ and [structure_number] Clockwork Structure[structure_number == 1 ? "":"s"] [structure_number == 1 ? "is":"are"] in range.") if(iscyborg(user)) to_chat(user, "You can recharge from the [sigil_name] by crossing it.") + else if(!GLOB.ratvar_awakens) + to_chat(user, "Hitting the [sigil_name] with brass sheets will convert them to power at a rate of 1 brass sheet to [POWER_FLOOR]W power.") + if(!GLOB.ratvar_awakens) + to_chat(user, "You can recharge Clockwork Proselytizers from the [sigil_name].") + +/obj/effect/clockwork/sigil/transmission/attackby(obj/item/I, mob/living/user, params) + if(is_servant_of_ratvar(user) && istype(I, /obj/item/stack/tile/brass) && !GLOB.ratvar_awakens) + var/obj/item/stack/tile/brass/B = I + user.visible_message("[user] places [B] on [src], causing it to disintegrate into glowing orange energy!", \ + "You charge the [sigil_name] with [B], providing it with [B.amount * POWER_FLOOR]W of power.") + modify_charge(-(B.amount * POWER_FLOOR)) + playsound(src, 'sound/effects/light_flicker.ogg', (B.amount * POWER_FLOOR) * 0.01, 1) + qdel(B) + return TRUE + return ..() /obj/effect/clockwork/sigil/transmission/sigil_effects(mob/living/L) if(is_servant_of_ratvar(L)) @@ -214,9 +228,7 @@ if(!cyborg_checks(cyborg)) return to_chat(cyborg, "You start to charge from the [sigil_name]...") - if(!do_after(cyborg, 50, target = src)) - return - if(!cyborg_checks(cyborg)) + if(!do_after(cyborg, 50, target = src, extra_checks = CALLBACK(src, .proc/cyborg_checks, cyborg, TRUE))) return var/giving_power = min(Floor(cyborg.cell.maxcharge - cyborg.cell.charge, MIN_CLOCKCULT_POWER), power_charge) //give the borg either all our power or their missing power floored to MIN_CLOCKCULT_POWER if(modify_charge(giving_power)) @@ -228,23 +240,27 @@ animate(cyborg, color = previous_color, time = 100) addtimer(CALLBACK(cyborg, /atom/proc/update_atom_colour), 100) -/obj/effect/clockwork/sigil/transmission/proc/cyborg_checks(mob/living/silicon/robot/cyborg) +/obj/effect/clockwork/sigil/transmission/proc/cyborg_checks(mob/living/silicon/robot/cyborg, silent) if(!cyborg.cell) - to_chat(cyborg, "You have no cell!") + if(!silent) + to_chat(cyborg, "You have no cell!") return FALSE if(!power_charge) - to_chat(cyborg, "The [sigil_name] has no stored power!") + if(!silent) + to_chat(cyborg, "The [sigil_name] has no stored power!") return FALSE if(cyborg.cell.charge > cyborg.cell.maxcharge - MIN_CLOCKCULT_POWER) - to_chat(cyborg, "You are already at maximum charge!") + if(!silent) + to_chat(cyborg, "You are already at maximum charge!") return FALSE if(cyborg.has_status_effect(STATUS_EFFECT_POWERREGEN)) - to_chat(cyborg, "You are already regenerating power!") + if(!silent) + to_chat(cyborg, "You are already regenerating power!") return FALSE return TRUE -/obj/effect/clockwork/sigil/transmission/New() - ..() +/obj/effect/clockwork/sigil/transmission/Initialize() + . = ..() update_glow() /obj/effect/clockwork/sigil/transmission/proc/modify_charge(amount) @@ -265,7 +281,7 @@ if(!power_charge) set_light(0) else - set_light(round(alpha*0.02, 1), round(alpha*0.005, 1)) + set_light(max(alpha*0.02, 1.4), max(alpha*0.01, 0.1)) //Vitality Matrix: Drains health from non-servants to heal or even revive servants. /obj/effect/clockwork/sigil/vitality @@ -299,8 +315,7 @@ if((is_servant_of_ratvar(L) && L.suiciding) || sigil_active) return visible_message("[src] begins to glow bright blue!") - animate(src, alpha = 255, time = 10) - addtimer(CALLBACK(src, .proc/update_alpha), 10) + animate(src, alpha = 255, time = 10, flags = ANIMATION_END_NOW) //we may have a previous animation going. finish it first, then do this one without delay. sleep(10) //as long as they're still on the sigil and are either not a servant or they're a servant AND it has remaining vitality while(L && (!is_servant_of_ratvar(L) || (is_servant_of_ratvar(L) && (GLOB.ratvar_awakens || vitality))) && get_turf(L) == get_turf(src)) @@ -369,12 +384,4 @@ animation_number = initial(animation_number) sigil_active = FALSE visible_message("[src] slowly stops glowing!") - if(sigil_active || alpha == 255) - animate(src, alpha = initial(alpha), time = 10) - addtimer(CALLBACK(src, .proc/update_alpha), 10) - -/obj/effect/clockwork/sigil/vitality/proc/update_alpha() - if(sigil_active) - alpha = 255 - else - alpha = initial(alpha) + animate(src, alpha = initial(alpha), time = 10, flags = ANIMATION_END_NOW) diff --git a/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm b/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm index 1c49d36693..5c1d3fb5fb 100644 --- a/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm +++ b/code/game/gamemodes/clock_cult/clock_effects/spatial_gateway.dm @@ -180,17 +180,26 @@ return procure_gateway(invoker, time_duration, gateway_uses, two_way) var/istargetobelisk = istype(target, /obj/structure/destructible/clockwork/powered/clockwork_obelisk) var/issrcobelisk = istype(src, /obj/structure/destructible/clockwork/powered/clockwork_obelisk) - if(issrcobelisk && !anchored) - to_chat(invoker, "[src] is no longer secured!") - return FALSE + if(issrcobelisk) + if(!anchored) + to_chat(invoker, "[src] is no longer secured!") + return FALSE + var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/CO = src //foolish as I am, how I set this proc up makes substypes unfeasible + if(CO.active) + to_chat(invoker, "[src] is now sustaining a gateway!") + return FALSE if(istargetobelisk) if(!target.anchored) to_chat(invoker, "That [target.name] is no longer secured!") return procure_gateway(invoker, time_duration, gateway_uses, two_way) var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/CO = target + if(CO.active) + to_chat(invoker, "That [target.name] is sustaining a gateway, and cannot recieve another!") + return procure_gateway(invoker, time_duration, gateway_uses, two_way) var/efficiency = CO.get_efficiency_mod() gateway_uses = round(gateway_uses * (2 * efficiency), 1) time_duration = round(time_duration * (2 * efficiency), 1) + CO.active = TRUE //you'd be active in a second but you should update immediately invoker.visible_message("The air in front of [invoker] ripples before suddenly tearing open!", \ "With a word, you rip open a [two_way ? "two-way":"one-way"] rift to [input_target_key]. It will last for [time_duration / 10] seconds and has [gateway_uses] use[gateway_uses > 1 ? "s" : ""].") var/obj/effect/clockwork/spatial_gateway/S1 = new(issrcobelisk ? get_turf(src) : get_step(get_turf(invoker), invoker.dir)) diff --git a/code/game/gamemodes/clock_cult/clock_helpers/component_helpers.dm b/code/game/gamemodes/clock_cult/clock_helpers/component_helpers.dm index e3c456460c..120ed0ff60 100644 --- a/code/game/gamemodes/clock_cult/clock_helpers/component_helpers.dm +++ b/code/game/gamemodes/clock_cult/clock_helpers/component_helpers.dm @@ -22,6 +22,12 @@ else for(var/i in GLOB.clockwork_component_cache) .[i] = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*GLOB.clockwork_component_cache[i], 1) + for(var/obj/structure/destructible/clockwork/massive/celestial_gateway/G in GLOB.all_clockwork_objects) + if(G.still_needs_components()) + for(var/i in G.required_components) + if(!G.required_components[i]) + . -= i + break . = pickweight(.) //returns a component name from a component id @@ -37,6 +43,8 @@ return "Replicant Alloy" if(HIEROPHANT_ANSIBLE) return "Hierophant Ansible" + else + return null //returns a component acronym from a component id /proc/get_component_acronym(id) @@ -51,6 +59,8 @@ return "RA" if(HIEROPHANT_ANSIBLE) return "HA" + else + return null //returns a component id from a component name /proc/get_component_id(name) @@ -65,6 +75,8 @@ return REPLICANT_ALLOY if("Hierophant Ansible") return HIEROPHANT_ANSIBLE + else + return null //returns a component spanclass from a component id /proc/get_component_span(id) @@ -121,6 +133,8 @@ return /obj/effect/overlay/temp/ratvar/component/alloy if(HIEROPHANT_ANSIBLE) return /obj/effect/overlay/temp/ratvar/component/ansible + else + return null //returns a type for a component from a component id /proc/get_component_type(id) @@ -134,4 +148,6 @@ if(REPLICANT_ALLOY) return /obj/item/clockwork/component/replicant_alloy if(HIEROPHANT_ANSIBLE) - return /obj/item/clockwork/component/hierophant_ansible \ No newline at end of file + return /obj/item/clockwork/component/hierophant_ansible + else + return null \ No newline at end of file diff --git a/code/game/gamemodes/clock_cult/clock_helpers/proselytizer_helpers.dm b/code/game/gamemodes/clock_cult/clock_helpers/proselytizer_helpers.dm index c6954bb67e..529f38d832 100644 --- a/code/game/gamemodes/clock_cult/clock_helpers/proselytizer_helpers.dm +++ b/code/game/gamemodes/clock_cult/clock_helpers/proselytizer_helpers.dm @@ -286,6 +286,28 @@ user.visible_message("[user]'s [proselytizer.name] stops covering [src] with glowing orange energy.", \ "You finish repairing [src]. It is now at [obj_integrity]/[max_integrity] integrity.") +//Hitting a sigil of transmission will try to charge from it. +/obj/effect/clockwork/sigil/transmission/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer) + . = TRUE + var/list/charge_values = list() + if(!proselytizer.sigil_charge_checks(charge_values, src, user)) + return + user.visible_message("[user]'s [proselytizer.name] starts draining glowing orange energy from [src]...", \ + "You start recharging your [proselytizer.name]...") + proselytizer.recharging = src + while(proselytizer && user && src) + if(!do_after(user, 10, target = src, extra_checks = CALLBACK(proselytizer, /obj/item/clockwork/clockwork_proselytizer.proc/sigil_charge_checks, charge_values, src, user, TRUE))) + break + modify_charge(charge_values["power_gain"]) + proselytizer.modify_stored_power(charge_values["power_gain"]) + playsound(src, 'sound/effects/light_flicker.ogg', charge_values["power_gain"] * 0.1, 1) + + if(proselytizer) + proselytizer.recharging = null + if(user) + user.visible_message("[user]'s [proselytizer.name] stops draining glowing orange energy from [src].", \ + "You finish recharging your [proselytizer.name]. It now contains [proselytizer.get_power()]W/[proselytizer.get_max_power()]W power.") + //Proselytizer mob heal proc, to avoid as much copypaste as possible. /mob/living/proc/proselytizer_heal(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer) var/list/repair_values = list() diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm b/code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm index 25e2138b81..60df56b6ef 100644 --- a/code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm +++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_proselytizer.dm @@ -12,6 +12,7 @@ var/uses_power = TRUE var/metal_to_power = FALSE var/repairing = null //what we're currently repairing, if anything + var/obj/effect/clockwork/sigil/transmission/recharging = null //the sigil we're charging from, if any var/speed_multiplier = 1 //how fast this proselytizer works var/charge_rate = MIN_CLOCKCULT_POWER //how much power we gain every two seconds var/charge_delay = 2 //how many proccess ticks remain before we can start to charge @@ -140,10 +141,11 @@ /obj/item/clockwork/clockwork_proselytizer/attack_self(mob/living/user) if(is_servant_of_ratvar(user)) - if(!can_use_power(POWER_WALL_TOTAL)) - to_chat(user, "[src] requires [POWER_WALL_TOTAL]W of power to produce brass sheets!") - return - modify_stored_power(-POWER_WALL_TOTAL) + if(uses_power) + if(!can_use_power(POWER_WALL_TOTAL)) + to_chat(user, "[src] requires [POWER_WALL_TOTAL]W of power to produce brass sheets!") + return + modify_stored_power(-POWER_WALL_TOTAL) playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) new/obj/item/stack/tile/brass(user.loc, 5) to_chat(user, "You user [stored_power ? "some":"all"] of [src]'s power to produce some brass sheets. It now stores [get_power()]W/[get_max_power()]W of power.") @@ -182,6 +184,9 @@ if(repairing) to_chat(user, "You are currently repairing [repairing] with [src]!") return FALSE + if(recharging) + to_chat(user, "You are currently recharging [src] from the [recharging.sigil_name]!") + return FALSE var/list/proselytize_values = target.proselytize_vals(user, src) //relevant values for proselytizing stuff, given as an associated list if(!islist(proselytize_values)) if(proselytize_values != TRUE) //if we get true, fail, but don't send a message for whatever reason @@ -237,7 +242,7 @@ /obj/item/clockwork/clockwork_proselytizer/proc/proselytize_checks(list/proselytize_values, atom/target, expected_type, mob/user, silent) //checked constantly while proselytizing if(!islist(proselytize_values) || !target || QDELETED(target) || !user) return FALSE - if(repairing) + if(repairing || recharging) return FALSE if(target.type != expected_type) return FALSE @@ -296,3 +301,20 @@ [round(repair_values["amount_to_heal"]*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER)]W to fully repair [target == user ? "yourself" : "[target.p_them()]"]!
") return FALSE return TRUE + +//checked constantly while charging from a sigil +/obj/item/clockwork/clockwork_proselytizer/proc/sigil_charge_checks(list/charge_values, obj/effect/clockwork/sigil/transmission/sigil, mob/user, silent) + if(!islist(charge_values) || !sigil || QDELETED(sigil) || !user) + return FALSE + if(can_use_power(RATVAR_POWER_CHECK)) + return FALSE + charge_values["power_gain"] = Clamp(sigil.power_charge, 0, POWER_WALL_MINUS_FLOOR) + if(!charge_values["power_gain"]) + if(!silent) + to_chat(user, "The [sigil.sigil_name] contains no power!") + return FALSE + if(stored_power + charge_values["power_gain"] > max_power) + if(!silent) + to_chat(user, "Your [name] contains too much power to charge from the [sigil.sigil_name]!") + return FALSE + return TRUE diff --git a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm index 35caabab5a..8b3aa01533 100644 --- a/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm +++ b/code/game/gamemodes/clock_cult/clock_items/clockwork_slab.dm @@ -326,13 +326,19 @@ if(production_time != SLAB_PRODUCTION_TIME+SLAB_SLOWDOWN_MAXIMUM) production_text_addon = ", which increases for each human or silicon servant above [SCRIPT_SERVANT_REQ]" production_time = production_time/600 - var/production_text = "[round(production_time)] minute\s" + var/list/production_text + if(round(production_time)) + production_text = list("[round(production_time)] minute\s") if(production_time != round(production_time)) production_time -= round(production_time) production_time *= 60 - production_text += " and [round(production_time, 1)] second\s" + if(!LAZYLEN(production_text)) + production_text = list("[round(production_time, 1)] second\s") + else + production_text += " and [round(production_time, 1)] second\s" production_text += "" production_text += production_text_addon + production_text = production_text.Join() textlist = list("
Chetr nyy hagehguf-naq-ubabe Ratvar.

\ \ diff --git a/code/game/gamemodes/clock_cult/clock_items/wraith_spectacles.dm b/code/game/gamemodes/clock_cult/clock_items/wraith_spectacles.dm index 1b6c80af73..6d17fe4e74 100644 --- a/code/game/gamemodes/clock_cult/clock_items/wraith_spectacles.dm +++ b/code/game/gamemodes/clock_cult/clock_items/wraith_spectacles.dm @@ -129,6 +129,7 @@ if(ishuman(owner)) var/mob/living/carbon/human/H = owner apply_eye_damage(H) + return ..() /datum/status_effect/wraith_spectacles/tick() if(!ishuman(owner)) diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm index 25576f5710..21da8fab00 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_applications.dm @@ -10,7 +10,7 @@ It will penetrate mindshield implants once before disappearing." invocations = list("Divinity, enslave...", "...all who trespass here!") channel_time = 70 - consumed_components = list(BELLIGERENT_EYE = 2, GEIS_CAPACITOR = 1, HIEROPHANT_ANSIBLE = 1) + consumed_components = list(BELLIGERENT_EYE = 4, GEIS_CAPACITOR = 2, HIEROPHANT_ANSIBLE = 2) whispered = TRUE object_path = /obj/effect/clockwork/sigil/submission/accession prevent_path = /obj/effect/clockwork/sigil/submission @@ -32,7 +32,7 @@ It grows faster to invoke with more adjacent Servants." invocations = list("Shield us...", "...with the...", "... fragments of Engine!") channel_time = 100 - consumed_components = list(VANGUARD_COGWHEEL = 2, REPLICANT_ALLOY = 1, HIEROPHANT_ANSIBLE = 1) + consumed_components = list(VANGUARD_COGWHEEL = 4, REPLICANT_ALLOY = 2, HIEROPHANT_ANSIBLE = 2) usage_tip = "This scripture will replace all weaker armor worn by affected Servants." tier = SCRIPTURE_APPLICATION multiple_invokers_used = TRUE @@ -99,7 +99,7 @@ If it remains close to you, you will gradually regain health up to a low amount, but it will die if it goes too far from you." invocations = list("Fright's will...", "...call forth...") channel_time = 100 - consumed_components = list(BELLIGERENT_EYE = 1, VANGUARD_COGWHEEL = 1, GEIS_CAPACITOR = 2) + consumed_components = list(BELLIGERENT_EYE = 2, VANGUARD_COGWHEEL = 2, GEIS_CAPACITOR = 4) usage_tip = "Marauders are useful as personal bodyguards and frontline warriors." tier = SCRIPTURE_APPLICATION primary_component = GEIS_CAPACITOR @@ -135,7 +135,7 @@ if(!check_special_requirements()) return FALSE to_chat(invoker, "The tendril shivers slightly as it selects a marauder...") - var/list/marauder_candidates = pollCandidates("Do you want to play as the clockwork marauder of [invoker.real_name]?", ROLE_SERVANT_OF_RATVAR, null, FALSE, 50, POLL_IGNORE_CLOCKWORK_MARAUDER) + var/list/marauder_candidates = pollGhostCandidates("Do you want to play as the clockwork marauder of [invoker.real_name]?", ROLE_SERVANT_OF_RATVAR, null, FALSE, 50, POLL_IGNORE_CLOCKWORK_MARAUDER) if(!check_special_requirements()) return FALSE if(!marauder_candidates.len) @@ -160,7 +160,7 @@ and exceptional speed, though taking damage will temporarily slow it down." invocations = list("Call forth...", "...the soldiers of Armorer.") channel_time = 80 - consumed_components = list(BELLIGERENT_EYE = 1, VANGUARD_COGWHEEL = 1, REPLICANT_ALLOY = 2) + consumed_components = list(BELLIGERENT_EYE = 2, VANGUARD_COGWHEEL = 2, REPLICANT_ALLOY = 4) object_path = /obj/structure/destructible/clockwork/shell/fragment creator_message = "You form an anima fragment, a powerful soul vessel receptacle." observer_message = "The slab disgorges a puddle of black metal that expands and forms into a strange shell!" @@ -179,7 +179,7 @@ desc = "Places a sigil that stores energy to power clockwork structures." invocations = list("Divinity...", "...power our creations!") channel_time = 70 - consumed_components = list(VANGUARD_COGWHEEL = 1, GEIS_CAPACITOR = 1, HIEROPHANT_ANSIBLE = 2) + consumed_components = list(VANGUARD_COGWHEEL = 2, GEIS_CAPACITOR = 2, HIEROPHANT_ANSIBLE = 4) whispered = TRUE object_path = /obj/effect/clockwork/sigil/transmission creator_message = "A sigil silently appears below you. It will automatically power clockwork structures near it." @@ -199,7 +199,7 @@ desc = "Creates a clockwork totem that sabotages nearby machinery and funnels drained power into nearby Sigils of Transmission or the area's APC." invocations = list("May this totem...", "...shroud the false suns!") channel_time = 80 - consumed_components = list(BELLIGERENT_EYE = 3, REPLICANT_ALLOY = 1, HIEROPHANT_ANSIBLE = 1) + consumed_components = list(BELLIGERENT_EYE = 5, REPLICANT_ALLOY = 2, HIEROPHANT_ANSIBLE = 2) object_path = /obj/structure/destructible/clockwork/powered/interdiction_lens creator_message = "You form an interdiction lens, which disrupts cameras and radios and drains power." observer_message = "A brass totem rises from the ground, a purple gem appearing in its center!" @@ -218,22 +218,22 @@ /datum/clockwork_scripture/create_object/mania_motor descname = "Powered Structure, Area Denial" name = "Mania Motor" - desc = "Creates a mania motor which will cause brain damage and hallucinations in nearby non-Servant humans. It will also try to convert humans directly adjecent to the motor." + desc = "Creates a mania motor which causes minor damage and a variety of negative mental effects in nearby non-Servant humans, potentially up to and including conversion." invocations = list("May this transmitter...", "...break the will of all who oppose us!") channel_time = 80 - consumed_components = list(GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 1, HIEROPHANT_ANSIBLE = 1) + consumed_components = list(GEIS_CAPACITOR = 5, REPLICANT_ALLOY = 2, HIEROPHANT_ANSIBLE = 2) object_path = /obj/structure/destructible/clockwork/powered/mania_motor - creator_message = "You form a mania motor which will cause brain damage and hallucinations in nearby humans while active." + creator_message = "You form a mania motor, which causes minor damage and negative mental effects in non-Servants." observer_message = "A two-pronged machine rises from the ground!" invokers_required = 2 multiple_invokers_used = TRUE - usage_tip = "Eligible non-Servant humans next to the motor will be converted at an additional power cost. It will also cure hallucinations and brain damage in nearby Servants." + usage_tip = "It will also cure hallucinations and brain damage in nearby Servants." tier = SCRIPTURE_APPLICATION one_per_tile = TRUE primary_component = GEIS_CAPACITOR sort_priority = 8 quickbind = TRUE - quickbind_desc = "Creates a Mania Motor, which can convert adjacent non-Servants with power." + quickbind_desc = "Creates a Mania Motor, which causes minor damage and negative mental effects in non-Servants." //Tinkerer's Daemon: Creates an efficient machine that rapidly produces components at a power cost. @@ -244,7 +244,7 @@ and there is at least one existing cache." invocations = list("May this generator...", "...collect Engine parts that yet hold greatness!") channel_time = 80 - consumed_components = list(BELLIGERENT_EYE = 1, GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 3) + consumed_components = list(BELLIGERENT_EYE = 2, GEIS_CAPACITOR = 2, REPLICANT_ALLOY = 5) object_path = /obj/structure/destructible/clockwork/powered/tinkerers_daemon creator_message = "You form a tinkerer's daemon which can rapidly collect components at a power cost." invokers_required = 2 @@ -278,7 +278,7 @@ desc = "Creates a clockwork obelisk that can broadcast messages over the Hierophant Network or open a Spatial Gateway to any living Servant or clockwork obelisk." invocations = list("May this obelisk...", "...take us to all places!") channel_time = 80 - consumed_components = list(BELLIGERENT_EYE = 1, VANGUARD_COGWHEEL = 1, HIEROPHANT_ANSIBLE = 3) + consumed_components = list(BELLIGERENT_EYE = 2, VANGUARD_COGWHEEL = 2, HIEROPHANT_ANSIBLE = 5) object_path = /obj/structure/destructible/clockwork/powered/clockwork_obelisk creator_message = "You form a clockwork obelisk which can broadcast messages or produce Spatial Gateways." observer_message = "A brass obelisk appears hanging in midair!" diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm index 023cd50dd1..b49b0c5819 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_drivers.dm @@ -17,23 +17,10 @@ sort_priority = 1 quickbind = TRUE quickbind_desc = "Forces nearby non-Servants to walk, doing minor damage with each chant.
Maximum 15 chants." - var/noncultist_damage = 2 //damage per chant to noncultists - var/cultist_damage = 8 //damage per chant to non-walking cultists /datum/clockwork_scripture/channeled/belligerent/chant_effects(chant_number) for(var/mob/living/carbon/C in hearers(7, invoker)) - var/number_legs = C.get_num_legs() - if(!is_servant_of_ratvar(C) && !C.null_rod_check() && number_legs) //you have legs right - C.apply_damage(noncultist_damage * 0.5, BURN, "l_leg") - C.apply_damage(noncultist_damage * 0.5, BURN, "r_leg") - if(C.m_intent != MOVE_INTENT_WALK) - if(!iscultist(C)) - to_chat(C, "Your leg[number_legs > 1 ? "s shiver":" shivers"] with pain!") - else //Cultists take extra burn damage - to_chat(C, "Your leg[number_legs > 1 ? "s burn":" burns"] with pain!") - C.apply_damage(cultist_damage * 0.5, BURN, "l_leg") - C.apply_damage(cultist_damage * 0.5, BURN, "r_leg") - C.toggle_move_intent() + C.apply_status_effect(STATUS_EFFECT_BELLIGERENT) return TRUE @@ -272,7 +259,7 @@ var/static/prev_cost = 0 /datum/clockwork_scripture/create_object/tinkerers_cache/creation_update() - var/cache_cost_increase = min(round(GLOB.clockwork_caches*0.25), 5) + var/cache_cost_increase = min(round(GLOB.clockwork_caches*0.4), 10) if(cache_cost_increase != prev_cost) prev_cost = cache_cost_increase consumed_components = list(BELLIGERENT_EYE = 0, VANGUARD_COGWHEEL = 0, GEIS_CAPACITOR = 0, REPLICANT_ALLOY = 1, HIEROPHANT_ANSIBLE = 0) diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm index 0dbd2d46e8..25bedd79d3 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_revenant.dm @@ -9,7 +9,7 @@ desc = "Taps the limitless power of Inath-neq, one of Ratvar's four generals. The benevolence of Inath-Neq will grant complete invulnerability to all Servants in range for fifteen seconds." invocations = list("I call upon you, Vanguard!!", "Let the Resonant Cogs turn once more!!", "Grant me and my allies the strength to vanquish our foes!!") channel_time = 100 - consumed_components = list(VANGUARD_COGWHEEL = 4, GEIS_CAPACITOR = 2, REPLICANT_ALLOY = 2, HIEROPHANT_ANSIBLE = 2) + consumed_components = list(VANGUARD_COGWHEEL = 10, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 3, HIEROPHANT_ANSIBLE = 3) usage_tip = "Servants affected by this scripture are only weak to things that outright destroy bodies, such as bombs or the singularity." tier = SCRIPTURE_REVENANT primary_component = VANGUARD_COGWHEEL @@ -44,7 +44,7 @@ for all non-servant humans on the same z-level as them. The power of this scripture falls off somewhat with distance, and certain things may reduce its effects." invocations = list("I call upon you, Fright!!", "Let your power shatter the sanity of the weak-minded!!", "Let your tendrils hold sway over all!!") channel_time = 150 - consumed_components = list(BELLIGERENT_EYE = 3, VANGUARD_COGWHEEL = 3, GEIS_CAPACITOR = 6, HIEROPHANT_ANSIBLE = 3) + consumed_components = list(BELLIGERENT_EYE = 6, VANGUARD_COGWHEEL = 6, GEIS_CAPACITOR = 10, HIEROPHANT_ANSIBLE = 6) usage_tip = "Causes brain damage, hallucinations, confusion, and dizziness in massive amounts." tier = SCRIPTURE_REVENANT sort_priority = 3 @@ -108,7 +108,7 @@ clockwork proselytizers will charge very rapidly." invocations = list("I call upon you, Armorer!!", "Let your machinations reign on this miserable station!!", "Let your power flow through the tools of your master!!") channel_time = 150 - consumed_components = list(BELLIGERENT_EYE = 3, VANGUARD_COGWHEEL = 3, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 6) + consumed_components = list(BELLIGERENT_EYE = 6, VANGUARD_COGWHEEL = 6, GEIS_CAPACITOR = 6, REPLICANT_ALLOY = 10) usage_tip = "Ocular wardens will become empowered, clockwork proselytizers will require no alloy, tinkerer's daemons will produce twice as quickly, \ and interdiction lenses, mania motors, tinkerer's daemons, and clockwork obelisks will all require no power." tier = SCRIPTURE_REVENANT @@ -153,7 +153,7 @@ will be struck by devastating lightning bolts." invocations = list("I call upon you, Amperage!!", "Let your energy flow through me!!", "Let your boundless power shatter stars!!") channel_time = 100 - consumed_components = list(BELLIGERENT_EYE = 2, GEIS_CAPACITOR = 2, REPLICANT_ALLOY = 2, HIEROPHANT_ANSIBLE = 4) + consumed_components = list(BELLIGERENT_EYE = 3, GEIS_CAPACITOR = 3, REPLICANT_ALLOY = 3, HIEROPHANT_ANSIBLE = 10) usage_tip = "Struck targets will also be knocked down for about sixteen seconds." tier = SCRIPTURE_REVENANT primary_component = HIEROPHANT_ANSIBLE diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm index f7fcc8c299..bc5ec1b9d8 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm @@ -9,7 +9,7 @@ desc = "Forms an automatic short-range turret which will automatically attack nearby unrestrained non-Servants that can see it." invocations = list("Guardians...", "...of the Engine...", "...defend us!") channel_time = 120 - consumed_components = list(BELLIGERENT_EYE = 1, REPLICANT_ALLOY = 1) + consumed_components = list(BELLIGERENT_EYE = 2, REPLICANT_ALLOY = 1) object_path = /obj/structure/destructible/clockwork/ocular_warden creator_message = "You form an ocular warden, which will automatically attack nearby unrestrained non-Servants that can see it." observer_message = "A brass eye takes shape and slowly rises into the air, its red iris glaring!" @@ -36,7 +36,7 @@ desc = "Creates a small shell fitted for soul vessels. Adding an active soul vessel to it results in a small construct with tools and an inbuilt proselytizer." invocations = list("Call forth...", "...the workers of Armorer.") channel_time = 60 - consumed_components = list(BELLIGERENT_EYE = 1, HIEROPHANT_ANSIBLE = 1) + consumed_components = list(BELLIGERENT_EYE = 2, HIEROPHANT_ANSIBLE = 1) object_path = /obj/structure/destructible/clockwork/shell/cogscarab creator_message = "You form a cogscarab, a constructor soul vessel receptacle." observer_message = "The slab disgorges a puddle of black metal that contracts and forms into a strange shell!" @@ -56,7 +56,7 @@ Matrices have drained from non-Servants. Dead Servants can be revived by this sigil if there is vitality equal to the target Servant's non-oxygen damage." invocations = list("Divinity...", "...steal their life...", "...for these shells!") channel_time = 60 - consumed_components = list(BELLIGERENT_EYE = 1, VANGUARD_COGWHEEL = 1) + consumed_components = list(BELLIGERENT_EYE = 1, VANGUARD_COGWHEEL = 2) whispered = TRUE object_path = /obj/effect/clockwork/sigil/vitality creator_message = "A vitality matrix appears below you. It will drain life from non-Servants and heal Servants that cross it." @@ -77,7 +77,7 @@ chant_invocations = list("Mend our dents!", "Heal our scratches!", "Repair our gears!") chant_amount = 10 chant_interval = 20 - consumed_components = list(VANGUARD_COGWHEEL = 1, REPLICANT_ALLOY = 1) + consumed_components = list(VANGUARD_COGWHEEL = 2, REPLICANT_ALLOY = 1) usage_tip = "This is a very effective way to rapidly reinforce a base after an attack." tier = SCRIPTURE_SCRIPT primary_component = VANGUARD_COGWHEEL @@ -177,6 +177,7 @@ new /obj/effect/overlay/temp/heal(T, "#1E8CE1") else break + new /obj/effect/overlay/temp/ratvar/mending_mantra(get_turf(invoker)) return TRUE @@ -187,7 +188,7 @@ desc = "Places a luminous sigil that will enslave any valid beings standing on it after a time." invocations = list("Divinity, enlighten...", "...those who trespass here!") channel_time = 60 - consumed_components = list(BELLIGERENT_EYE = 1, GEIS_CAPACITOR = 1) + consumed_components = list(BELLIGERENT_EYE = 1, GEIS_CAPACITOR = 2) whispered = TRUE object_path = /obj/effect/clockwork/sigil/submission creator_message = "A luminous sigil appears below you. The next non-servant to cross it will be enslaved after a brief time if they do not move." @@ -207,7 +208,7 @@ desc = "Forms an ancient positronic brain with an overriding directive to serve Ratvar." invocations = list("Herd the souls of...", "...the blasphemous damned!") channel_time = 30 - consumed_components = list(VANGUARD_COGWHEEL = 1, GEIS_CAPACITOR = 1) + consumed_components = list(VANGUARD_COGWHEEL = 1, GEIS_CAPACITOR = 2) whispered = TRUE object_path = /obj/item/device/mmi/posibrain/soul_vessel creator_message = "You form a soul vessel, which can be used in-hand to attract spirits, or used on an unconscious or dead human to extract their consciousness." @@ -227,7 +228,7 @@ desc = "Forms a device that, when used on certain objects, converts them into their Ratvarian equivalents. It requires power to function." invocations = list("With this device...", "...his presence shall be made known.") channel_time = 20 - consumed_components = list(GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 1) + consumed_components = list(GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 2) whispered = TRUE object_path = /obj/item/clockwork/clockwork_proselytizer/preloaded creator_message = "You form a clockwork proselytizer." @@ -248,7 +249,7 @@ vanish three minutes after being summoned." invocations = list("Grant me...", "...the might of brass!") channel_time = 20 - consumed_components = list(REPLICANT_ALLOY = 1, HIEROPHANT_ANSIBLE = 1) + consumed_components = list(REPLICANT_ALLOY = 2, HIEROPHANT_ANSIBLE = 1) whispered = TRUE usage_tip = "You can impale human targets with the spear by pulling them, then attacking. Throwing the spear at a mob will do massive damage and stun them, but break the spear." tier = SCRIPTURE_SCRIPT @@ -307,7 +308,7 @@ Each servant assisting in the invocation adds one additional use and four additional seconds to the gateway's uses and duration." invocations = list("Spatial Gateway...", "...activate!") channel_time = 80 - consumed_components = list(VANGUARD_COGWHEEL = 1, HIEROPHANT_ANSIBLE = 1) + consumed_components = list(VANGUARD_COGWHEEL = 1, HIEROPHANT_ANSIBLE = 2) multiple_invokers_used = TRUE multiple_invokers_optional = TRUE usage_tip = "This gateway is strictly one-way and will only allow things through the invoker's portal." @@ -356,7 +357,7 @@ chant_invocations = list("Use charge to kill!", "Slay with power!", "Hunt with energy!") chant_amount = 4 chant_interval = 5 - consumed_components = list(GEIS_CAPACITOR = 1, HIEROPHANT_ANSIBLE = 1) + consumed_components = list(GEIS_CAPACITOR = 1, HIEROPHANT_ANSIBLE = 2) usage_tip = "Though it requires you to stand still, this scripture can do massive damage." tier = SCRIPTURE_SCRIPT primary_component = HIEROPHANT_ANSIBLE diff --git a/code/game/gamemodes/clock_cult/clock_structures/clockwork_obelisk.dm b/code/game/gamemodes/clock_cult/clock_structures/clockwork_obelisk.dm index 2bebb4c9a5..580f5fbed5 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/clockwork_obelisk.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/clockwork_obelisk.dm @@ -58,7 +58,7 @@ var/input = stripped_input(usr, "Please choose a message to send over the Hierophant Network.", "Hierophant Broadcast", "") if(!is_servant_of_ratvar(user) || !input || !user.canUseTopic(src, !issilicon(user))) return - if(anchored) + if(!anchored) to_chat(user, "[src] is no longer secured!") return FALSE if(active) @@ -84,7 +84,8 @@ return if(procure_gateway(user, round(100 * get_efficiency_mod(), 1), round(5 * get_efficiency_mod(), 1), 1)) process() - if(!active) + if(!active) //we won't be active if nobody has sent a gateway to us + active = TRUE clockwork_say(user, text2ratvar("Spatial Gateway, activate!")) return return_power(gateway_cost) //if we didn't return above, ie, successfully create a gateway, we give the power back @@ -92,7 +93,8 @@ /obj/structure/destructible/clockwork/powered/clockwork_obelisk/process() if(!anchored) return - if(locate(/obj/effect/clockwork/spatial_gateway) in loc) + var/obj/effect/clockwork/spatial_gateway/SG = locate(/obj/effect/clockwork/spatial_gateway) + if(SG && SG.timerid) //it's a valid gateway, we're active icon_state = active_icon density = 0 active = TRUE diff --git a/code/game/gamemodes/clock_cult/clock_structures/mania_motor.dm b/code/game/gamemodes/clock_cult/clock_structures/mania_motor.dm index 09372044a9..dd26b5d404 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/mania_motor.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/mania_motor.dm @@ -1,8 +1,8 @@ -//Mania Motor: A pair of antenna that, while active, cause braindamage and hallucinations in nearby human mobs. +//Mania Motor: A pair of antenna that, while active, cause a variety of negative mental effects in nearby human mobs. /obj/structure/destructible/clockwork/powered/mania_motor name = "mania motor" desc = "A pair of antenna with what appear to be sockets around the base. It reminds you of an antlion." - clockwork_desc = "A transmitter that allows Sevtug to whisper into the minds of nearby non-servants, causing hallucinations and brain damage as long as it remains powered." + clockwork_desc = "A transmitter that allows Sevtug to whisper into the minds of nearby non-servants, causing a variety of negative mental effects, up to and including conversion." icon_state = "mania_motor_inactive" active_icon = "mania_motor" inactive_icon = "mania_motor_inactive" @@ -16,22 +16,11 @@ /obj/item/clockwork/alloy_shards/small = 2, \ /obj/item/clockwork/component/geis_capacitor/antennae = 1) var/mania_cost = 150 - var/convert_cost = 150 - var/static/list/mania_messages = list("Go nuts.", "Take a crack at crazy.", "Make a bid for insanity.", "Get kooky.", "Move towards mania.", "Become bewildered.", "Wax wild.", \ - "Go round the bend.", "Land in lunacy.", "Try dementia.", "Strive to get a screw loose.") - var/static/list/compel_messages = list("Come closer.", "Approach the transmitter.", "Touch the antennae.", "I always have to deal with idiots. Move towards the mania motor.", \ - "Advance forward and place your head between the antennae - that's all it's good for.", "If you were smarter, you'd be over here already.", "Move FORWARD, you fool.") - var/static/list/convert_messages = list("You won't do. Go to sleep while I tell these nitwits how to convert you.", "You are insufficient. I must instruct these idiots in the art of conversion.", \ - "Oh of course, someone we can't convert. These servants are fools.", "How hard is it to use a Sigil, anyway? All it takes is dragging someone onto it.", \ - "How do they fail to use a Sigil of Accession, anyway?", "Why is it that all servants are this inept?", "It's quite likely you'll be stuck here for a while.") - var/static/list/close_messages = list("Well, you can't reach the motor from THERE, you moron.", "Interesting location. I'd prefer if you went somewhere you could ACTUALLY TOUCH THE ANTENNAE!", \ - "Amazing. You somehow managed to wedge yourself somewhere you can't actually reach the motor from.", "Such a show of idiocy is unparalleled. Perhaps I should put you on display?", \ - "Did you do this on purpose? I can't imagine you doing so accidentally. Oh, wait, I can.", "How is it that such smart creatures can still do something AS STUPID AS THIS!") /obj/structure/destructible/clockwork/powered/mania_motor/examine(mob/user) ..() if(is_servant_of_ratvar(user) || isobserver(user)) - to_chat(user, "It requires [mania_cost]W to run, and at least [convert_cost]W to attempt to convert humans adjacent to it.") + to_chat(user, "It requires [mania_cost]W to run.") /obj/structure/destructible/clockwork/powered/mania_motor/forced_disable(bad_effects) if(active) @@ -60,82 +49,17 @@ if(!try_use_power(mania_cost)) forced_disable(FALSE) return - var/turf/T = get_turf(src) - var/hum = get_sfx('sound/effects/screech.ogg') //like playsound, same sound for everyone affected var/efficiency = get_efficiency_mod() for(var/mob/living/carbon/human/H in viewers(7, src)) - if(is_servant_of_ratvar(H)) //heals servants of braindamage, hallucination, druggy, dizziness, and confusion - var/brainloss = H.getBrainLoss() - if(brainloss) - H.adjustBrainLoss(-brainloss) - if(H.hallucination) - H.hallucination = 0 - if(H.druggy) - H.adjust_drugginess(-H.druggy) - if(H.dizziness) - H.dizziness = 0 - if(H.confused) - H.confused = 0 - else if(!H.null_rod_check() && H.stat != DEAD) - var/distance = 0 + get_dist(T, get_turf(H)) - var/falloff_distance = min((110) - distance * 10, 80) - var/sound_distance = falloff_distance * 0.5 - var/targetbrainloss = H.getBrainLoss() - if(distance > 3 && prob(falloff_distance * 0.5)) - to_chat(H, "\"[text2ratvar(pick(mania_messages))]\"") - if(distance <= 1) - if(!H.Adjacent(src)) - to_chat(H, "\"[text2ratvar(pick(close_messages))]\"") - H.playsound_local(T, hum, sound_distance, 1) - else if(!try_use_power(convert_cost)) - visible_message("[src]'s antennae fizzle quietly.") - playsound(src, 'sound/effects/light_flicker.ogg', 50, 1) - else - H.playsound_local(T, hum, 80, 1) - if(!H.stat) - if(H.getBrainLoss() < 100) - H.adjustBrainLoss(20 * efficiency) - H.visible_message("[H] reaches out and touches [src].", "You touch [src] involuntarily.") - else - H.Paralyse(3) - else if(is_eligible_servant(H)) - to_chat(H, "\"[text2ratvar("You are mine and his, now.")]\"") - add_servant_of_ratvar(H) - H.Paralyse(5) - else - H.playsound_local(T, hum, sound_distance, 1) - switch(distance) - if(0 to 3) - if(prob(falloff_distance * 0.5)) - if(prob(falloff_distance)) - to_chat(H, "\"[text2ratvar(pick(mania_messages))]\"") - else - to_chat(H, "\"[text2ratvar(pick(compel_messages))]\"") - if(targetbrainloss <= 40) - H.adjustBrainLoss(3 * efficiency) - H.adjust_drugginess(Clamp(7 * efficiency, 0, 50 - H.druggy)) - H.hallucination = min(H.hallucination + (7 * efficiency), 50) - H.dizziness = min(H.dizziness + (3 * efficiency), 20) - H.confused = min(H.confused + (3 * efficiency), 20) - if(3 to 5) - if(targetbrainloss <= 20) - H.adjustBrainLoss(2 * efficiency) - H.adjust_drugginess(Clamp(5 * efficiency, 0, 25 - H.druggy)) - H.hallucination = min(H.hallucination + (5 * efficiency), 25) - H.dizziness = min(H.dizziness + (2 * efficiency), 10) - H.confused = min(H.confused + (2 * efficiency), 10) - if(5 to 6) - if(targetbrainloss <= 10) - H.adjustBrainLoss(1 * efficiency) - H.adjust_drugginess(Clamp(2 * efficiency, 0, 20 - H.druggy)) - H.hallucination = min(H.hallucination + (2 * efficiency), 20) - H.dizziness = min(H.dizziness + (2 * efficiency), 5) - H.confused = min(H.confused + (2 * efficiency), 5) - if(6 to 7) - if(targetbrainloss <= 5) - H.adjustBrainLoss(1 * efficiency) - H.adjust_drugginess(Clamp(2 * efficiency, 0, 10 - H.druggy)) - H.hallucination = min(H.hallucination + (2 * efficiency), 10) - if(7 to INFINITY) - H.adjust_drugginess(Clamp(2 * efficiency, 0, 5 - H.druggy)) - H.hallucination = min(H.hallucination + (2 * efficiency), 5) + if(is_servant_of_ratvar(H)) + continue + var/list/effects = H.has_status_effect_list(STATUS_EFFECT_MANIAMOTOR) + var/datum/status_effect/maniamotor/M + for(var/datum/status_effect/maniamotor/MM in effects) + if(MM.motor == src) + M = MM + break + if(!M) + M = H.apply_status_effect(STATUS_EFFECT_MANIAMOTOR) + M.motor = src + M.severity = Clamp(M.severity + ((11 - get_dist(src, H)) * efficiency * efficiency), 0, MAX_MANIA_SEVERITY) diff --git a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm index 614a22a6f5..a8dfb2dd4a 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/ratvar_the_clockwork_justicar.dm @@ -28,7 +28,7 @@ var/mutable_appearance/alert_overlay = mutable_appearance('icons/effects/clockwork_effects.dmi', "ratvar_alert") var/area/A = get_area(src) notify_ghosts("The Justiciar's light calls to you! Reach out to Ratvar in [A.name] to be granted a shell to spread his glory!", null, source = src, alert_overlay = alert_overlay) - INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency..proc/request, null, 0) + INVOKE_ASYNC(SSshuttle.emergency, /obj/docking_port/mobile/emergency..proc/request, null, 0, 0) /obj/structure/destructible/clockwork/massive/ratvar/Destroy() GLOB.ratvar_awakens-- @@ -77,7 +77,7 @@ if(!prey && LAZYLEN(meals)) prey = pick(meals) to_chat(prey, "\"You will do, heretic.\"\n\ - ") + You feel something massive turn its crushing focus to you...") prey << 'sound/effects/ratvar_reveal.ogg' else if((!istype(prey, /obj/singularity/narsie) && prob(10) && LAZYLEN(meals) > 1) || prey.z != z || !(prey in meals)) diff --git a/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm b/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm index 22ea9e2ce5..b0a17338ff 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/tinkerers_daemon.dm @@ -18,7 +18,7 @@ var/static/mutable_appearance/component_glow = mutable_appearance('icons/obj/clockwork_objects.dmi', "t_random_component") var/component_id_to_produce var/production_time = 0 //last time we produced a component - var/production_cooldown = 120 + var/production_cooldown = 60 /obj/structure/destructible/clockwork/powered/tinkerers_daemon/Initialize() . = ..() diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index 7780ae5db9..3b30d3e44a 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -1,34 +1,31 @@ - - /datum/game_mode var/list/datum/mind/cult = list() var/list/cult_objectives = list() + var/eldergod = 1 //for the summon god objective /proc/iscultist(mob/living/M) return istype(M) && M.mind && M.mind.has_antag_datum(ANTAG_DATUM_CULT) /proc/is_sacrifice_target(datum/mind/mind) - if(SSticker.mode.name == "cult") - var/datum/game_mode/cult/cult_mode = SSticker.mode - if(mind == cult_mode.sacrifice_target) - return 1 - return 0 + if(mind == GLOB.sac_mind) + return TRUE + return FALSE /proc/is_convertable_to_cult(mob/living/M) if(!istype(M)) - return 0 + return FALSE if(M.mind) if(ishuman(M) && (M.mind.assigned_role in list("Captain", "Chaplain"))) - return 0 + return FALSE if(is_sacrifice_target(M.mind)) - return 0 + return FALSE if(M.mind.enslaved_to && !iscultist(M.mind.enslaved_to)) - return 0 + return FALSE else - return 0 + return FALSE if(M.isloyal() || issilicon(M) || isbot(M) || isdrone(M) || is_servant_of_ratvar(M)) - return 0 //can't convert machines, shielded, or ratvar's dogs - return 1 + return FALSE //can't convert machines, shielded, or ratvar's dogs + return TRUE /datum/game_mode/cult name = "cult" @@ -47,14 +44,13 @@ Crew: Prevent the cult from expanding and drive it out." var/finished = 0 - var/eldergod = 1 //for the summon god objective var/acolytes_needed = 10 //for the survive objective var/acolytes_survived = 0 - var/datum/mind/sacrifice_target = null//The target to be sacrificed var/list/cultists_to_cult = list() //the cultists we'll convert + /datum/game_mode/cult/pre_setup() cult_objectives += "sacrifice" cult_objectives += "eldergod" @@ -82,22 +78,6 @@ return (cultists_to_cult.len>=required_enemies) -/datum/game_mode/cult/proc/memorize_cult_objectives(datum/mind/cult_mind) - for(var/obj_count = 1,obj_count <= cult_objectives.len,obj_count++) - var/explanation - switch(cult_objectives[obj_count]) - if("survive") - explanation = "Our knowledge must live on. Make sure at least [acolytes_needed] acolytes escape on the shuttle to spread their work on an another station." - if("sacrifice") - if(sacrifice_target) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role] via invoking a Sacrifice rune with them on it and three acolytes around it." - else - explanation = "Free objective." - if("eldergod") - explanation = "Summon Nar-Sie by invoking the rune 'Summon Nar-Sie' with nine acolytes on it. You must do this after sacrificing your target." - to_chat(cult_mind.current, "Objective #[obj_count]: [explanation]") - cult_mind.memory += "Objective #[obj_count]: [explanation]
" - /datum/game_mode/cult/post_setup() modePlayer += cultists_to_cult if("sacrifice" in cult_objectives) @@ -108,9 +88,18 @@ if(player.mind && !(player.mind in cultists_to_cult)) possible_targets += player.mind if(possible_targets.len > 0) - sacrifice_target = pick(possible_targets) - if(!sacrifice_target) + GLOB.sac_mind = pick(possible_targets) + if(!GLOB.sac_mind) message_admins("Cult Sacrifice: ERROR - Null target chosen!") + else + var/datum/job/sacjob = SSjob.GetJob(GLOB.sac_mind.assigned_role) + var/datum/preferences/sacface = GLOB.sac_mind.current.client.prefs + var/icon/reshape = get_flat_human_icon(null, sacjob, sacface) + reshape.Shift(SOUTH, 4) + reshape.Shift(EAST, 1) + reshape.Crop(7,4,26,31) + reshape.Crop(-5,-3,26,30) + GLOB.sac_image = reshape else message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!") for(var/datum/mind/cult_mind in cultists_to_cult) @@ -198,7 +187,7 @@ if(cult_objectives.Find("eldergod")) cult_fail += eldergod //1 by default, 0 if the elder god has been summoned at least once if(cult_objectives.Find("sacrifice")) - if(sacrifice_target && !GLOB.sacrificed.Find(sacrifice_target)) //if the target has been GLOB.sacrificed, ignore this step. otherwise, add 1 to cult_fail + if(GLOB.sac_mind && GLOB.sac_complete) //if the target has been GLOB.sacrificed, ignore this step. otherwise, add 1 to cult_fail cult_fail++ return cult_fail //if any objectives aren't met, failure @@ -243,16 +232,12 @@ SSblackbox.add_details("cult_objective","cult_survive|FAIL|[acolytes_needed]") SSticker.news_report = CULT_FAILURE if("sacrifice") - if(sacrifice_target) - if(sacrifice_target in GLOB.sacrificed) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Success!" - SSblackbox.add_details("cult_objective","cult_sacrifice|SUCCESS") - else if(sacrifice_target && sacrifice_target.current) - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail." - SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL") - else - explanation = "Sacrifice [sacrifice_target.name], the [sacrifice_target.assigned_role]. Fail (Gibbed)." - SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL|GIBBED") + if(GLOB.sac_complete) + explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Success!" + SSblackbox.add_details("cult_objective","cult_sacrifice|SUCCESS") + else + explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Fail." + SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL") if("eldergod") if(!eldergod) explanation = "Summon Nar-Sie. Success!" @@ -269,12 +254,45 @@ return 1 -/datum/game_mode/proc/auto_declare_completion_cult() - if( cult.len || (SSticker && istype(SSticker.mode,/datum/game_mode/cult)) ) - var/text = "
The cultists were:" - for(var/datum/mind/cultist in cult) - text += printplayer(cultist) - - text += "
" - - to_chat(world, text) +/datum/game_mode/proc/datum_cult_completion() + var/text = "" + var/acolytes_survived = 0 + for(var/datum/mind/cult_mind in cult) + if (cult_mind.current && cult_mind.current.stat != DEAD) + if(cult_mind.current.onCentcom() || cult_mind.current.onSyndieBase()) + acolytes_survived++ + var/cult_fail = 0 + cult_fail += eldergod + if(!GLOB.sac_complete) + cult_fail++ + if(!cult_fail) + SSblackbox.set_details("round_end_result","win - cult win") + SSblackbox.set_val("round_end_result",acolytes_survived) + to_chat(world, "The cult has succeeded! Nar-sie has snuffed out another torch in the void!") + else + SSblackbox.set_details("round_end_result","loss - staff stopped the cult") + SSblackbox.set_val("round_end_result",acolytes_survived) + to_chat(world, "The staff managed to stop the cult! Dark words and heresy are no match for Nanotrasen's finest!") + if(cult_objectives.len) + text += "
The cultists' objectives were:" + for(var/obj_count in 1 to 2) + var/explanation + switch(cult_objectives[obj_count]) + if("sacrifice") + if(GLOB.sac_complete) + explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Success!" + SSblackbox.add_details("cult_objective","cult_sacrifice|SUCCESS") + else + explanation = "Sacrifice [GLOB.sac_mind], the [GLOB.sac_mind.assigned_role]. Fail." + SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL") + if("eldergod") + if(!eldergod) + explanation = "Summon Nar-Sie. Success!" + SSblackbox.add_details("cult_objective","cult_narsie|SUCCESS") + SSticker.news_report = CULT_SUMMON + else + explanation = "Summon Nar-Sie. Fail." + SSblackbox.add_details("cult_objective","cult_narsie|FAIL") + SSticker.news_report = CULT_FAILURE + text += "
Objective #[obj_count]: [explanation]" + to_chat(world, text) diff --git a/code/game/gamemodes/cult/cult_comms.dm b/code/game/gamemodes/cult/cult_comms.dm index 40c7bbece8..ffaaf46b80 100644 --- a/code/game/gamemodes/cult/cult_comms.dm +++ b/code/game/gamemodes/cult/cult_comms.dm @@ -1,3 +1,5 @@ +// Contains cult communion, guide, and cult master abilities +#define MARK_COOLDOWN /datum/action/innate/cultcomm name = "Communion" @@ -19,11 +21,22 @@ cultist_commune(usr, input) /proc/cultist_commune(mob/living/user, message) + var/my_message if(!message) return - user.whisper("O bidai nabora se[pick("'","`")]sma!") + user.whisper("O bidai nabora se[pick("'","`")]sma!", language = /datum/language/common) user.whisper(html_decode(message)) - var/my_message = "[(ishuman(user) ? "Acolyte" : "Construct")] [findtextEx(user.name, user.real_name) ? user.name : "[user.real_name] (as [user.name])"]: [message]" + var/title = "Acolyte" + var/span = "cultitalic" + if(user.mind && user.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER)) + span = "cultlarge" + if(ishuman(user)) + title = "Master" + else + title = "Lord" + else if(!ishuman(user)) + title = "Construct" + my_message = "[title] [findtextEx(user.name, user.real_name) ? user.name : "[user.real_name] (as [user.name])"]: [message]" for(var/mob/M in GLOB.mob_list) if(iscultist(M)) to_chat(M, my_message) @@ -65,3 +78,159 @@ popup.set_content(text) popup.open() return 1 + +/mob/living/proc/cult_master() + set category = "Cultist" + set name = "Assert Leadership" + pollCultists(src) // This proc handles the distribution of cult master actions + +/datum/action/innate/cultmast + background_icon_state = "bg_demon" + buttontooltipstyle = "cult" + check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS + +/datum/action/innate/cultmast/IsAvailable() + if(!owner.mind || !owner.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER)) + return 0 + return ..() + +/datum/action/innate/cultmast/finalreck + name = "Final Reckoning" + desc = "A single-use spell that brings the entire cult to the master's location." + button_icon_state = "sintouch" + +/datum/action/innate/cultmast/finalreck/Activate() + for(var/i in 1 to 4) + chant(i) + var/list/destinations = list() + for(var/turf/T in orange(1, owner)) + if(!is_blocked_turf(T, TRUE)) + destinations += T + if(!LAZYLEN(destinations)) + to_chat(owner, "You need more space to summon the cult!") + return + if(do_after(owner, 30, target = owner)) + for(var/datum/mind/B in SSticker.mode.cult) + if(B.current && B.current.stat != DEAD) + var/turf/mobloc = get_turf(B.current) + switch(i) + if(1) + new /obj/effect/overlay/temp/cult/sparks(mobloc, B.current.dir) + playsound(mobloc, "sparks", 50, 1) + if(2) + new /obj/effect/overlay/temp/dir_setting/cult/phase/out(mobloc, B.current.dir) + playsound(mobloc, "sparks", 75, 1) + if(3) + new /obj/effect/overlay/temp/dir_setting/cult/phase(mobloc, B.current.dir) + playsound(mobloc, "sparks", 100, 1) + if(4) + playsound(mobloc, 'sound/magic/exit_blood.ogg', 100, 1) + if(B.current != owner) + B.current.setDir(SOUTH) + var/turf/final = pick(destinations) + new /obj/effect/overlay/temp/cult/blood(final) + addtimer(CALLBACK(B.current, /mob/.proc/reckon, final), 10) + else + return + GLOB.reckoning_complete = TRUE + Remove(owner) + +/mob/proc/reckon(turf/final) + new /obj/effect/overlay/temp/cult/blood/out(get_turf(src)) + forceMove(final) + +/datum/action/innate/cultmast/finalreck/proc/chant(chant_number) + switch(chant_number) + if(1) + owner.say("C'arta forbici!", language = /datum/language/common) + if(2) + owner.say("Pleggh e'ntrath!", language = /datum/language/common) + playsound(get_turf(owner),'sound/magic/clockwork/narsie_attack.ogg', 50, 1) + if(3) + owner.say("Barhah hra zar'garis!", language = /datum/language/common) + playsound(get_turf(owner),'sound/magic/clockwork/narsie_attack.ogg', 75, 1) + if(4) + owner.say("N'ath reth sh'yro eth d'rekkathnor!!!", language = /datum/language/common) + playsound(get_turf(owner),'sound/magic/clockwork/narsie_attack.ogg', 100, 1) + +/datum/action/innate/cultmast/cultmark + name = "Mark Target" + desc = "Marks a target for the cult." + button_icon_state = "cult_mark" + var/obj/effect/proc_holder/cultmark/CM + var/cooldown = 0 + var/base_cooldown = 1200 + +/datum/action/innate/cultmast/cultmark/New() + CM = new() + CM.attached_action = src + ..() + +/datum/action/innate/cultmast/cultmark/IsAvailable() + if(!owner.mind || !owner.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER)) + return 0 + if(cooldown > world.time) + if(!CM.active) + owner << "You need to wait [round((cooldown - world.time) * 0.1)] seconds before you can mark another target!" + return 0 + return ..() + +/datum/action/innate/cultmast/cultmark/Destroy() + QDEL_NULL(CM) + return ..() + +/datum/action/innate/cultmast/cultmark/Activate() + CM.toggle(owner) //the important bit + return TRUE + +/obj/effect/proc_holder/cultmark + active = FALSE + ranged_mousepointer = 'icons/effects/cult_target.dmi' + var/datum/action/innate/cultmast/cultmark/attached_action + +/obj/effect/proc_holder/cultmark/Destroy() + attached_action = null + return ..() + +/obj/effect/proc_holder/cultmark/proc/toggle(mob/user) + if(active) + remove_ranged_ability("You cease the marking ritual.") + else + add_ranged_ability(user, "You prepare to mark a target for your cult...") + +/obj/effect/proc_holder/cultmark/InterceptClickOn(mob/living/caller, params, atom/target) + if(..()) + return + if(ranged_ability_user.incapacitated()) + remove_ranged_ability() + return + var/turf/T = get_turf(ranged_ability_user) + if(!isturf(T)) + return FALSE + if(target in view(7, get_turf(ranged_ability_user))) + GLOB.blood_target = target + var/area/A = get_area(target) + attached_action.cooldown = world.time + attached_action.base_cooldown + addtimer(CALLBACK(attached_action.owner, /mob.proc/update_action_buttons_icon), attached_action.base_cooldown) + GLOB.blood_target_image = image('icons/effects/cult_target.dmi', target, "glow", ABOVE_MOB_LAYER) + GLOB.blood_target_image.appearance_flags = RESET_COLOR + GLOB.blood_target_image.pixel_x = -target.pixel_x + GLOB.blood_target_image.pixel_y = -target.pixel_y + for(var/datum/mind/B in SSticker.mode.cult) + if(B.current && B.current.stat != DEAD && B.current.client) + to_chat(B.current, "Master [ranged_ability_user] has marked [GLOB.blood_target] in the [A.name] as the cult's top priority, get there immediately!") + B.current << pick(sound('sound/hallucinations/over_here2.ogg',0,1,75), sound('sound/hallucinations/over_here3.ogg',0,1,75)) + B.current.client.images += GLOB.blood_target_image + attached_action.owner.update_action_buttons_icon() + remove_ranged_ability("The marking rite is complete! It will last for 90 seconds.") + addtimer(CALLBACK(GLOBAL_PROC, .proc/reset_blood_target), 900, TIMER_OVERRIDE) + return TRUE + return FALSE + +/proc/reset_blood_target() + for(var/datum/mind/B in SSticker.mode.cult) + if(B.current && B.current.stat != DEAD && B.current.client) + if(GLOB.blood_target) + to_chat(B.current,"The blood mark has expired!") + B.current.client.images -= GLOB.blood_target_image + QDEL_NULL(GLOB.blood_target) \ No newline at end of file diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index a90aeb78bc..6058e8f605 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -213,7 +213,7 @@ flags_inv = HIDEJUMPSUIT allowed = list(/obj/item/weapon/tome,/obj/item/weapon/melee/cultblade) body_parts_covered = CHEST|GROIN|LEGS|ARMS - armor = list(melee = -50, bullet = -50, laser = -100,energy = -50, bomb = -50, bio = -50, rad = -50, fire = 0, acid = 0) + armor = list(melee = -50, bullet = -50, laser = -50,energy = -50, bomb = -50, bio = -50, rad = -50, fire = 0, acid = 0) slowdown = -1 hoodtype = /obj/item/clothing/head/hooded/berserkerhood diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm index 843d16592a..069a422480 100644 --- a/code/game/gamemodes/cult/ritual.dm +++ b/code/game/gamemodes/cult/ritual.dm @@ -133,7 +133,7 @@ This file contains the arcane tome files. text += "Talisman of Armaments
The Talisman of Arming will equip the user with armored robes, a backpack, an eldritch longsword, an empowered bola, and a pair of boots. Any items that cannot \ be equipped will not be summoned. Attacking a fellow cultist with it will instead equip them.

" - text += "Talisman of Horrors
The Talisman of Horror must be applied directly to the victim, it will shatter your victim's mind with visions of the endtimes that may incapitate them.

" + text += "Talisman of Horrors
The Talisman of Horror, unlike other talismans, can be applied at range, without the victim noticing. It will cause the victim to have severe hallucinations after a short while.

" text += "Talisman of Shackling
The Talisman of Shackling must be applied directly to the victim, it has 4 uses and cuffs victims with magic shackles that disappear when removed.

" @@ -197,35 +197,30 @@ This file contains the arcane tome files. if(!src || QDELETED(src) || !Adjacent(user) || user.incapacitated() || !check_rune_turf(Turf, user)) return if(ispath(rune_to_scribe, /obj/effect/rune/narsie)) - if(SSticker.mode.name == "cult") - var/datum/game_mode/cult/cult_mode = SSticker.mode - if(!("eldergod" in cult_mode.cult_objectives)) - to_chat(user, "Nar-Sie does not wish to be summoned!") - return - if(cult_mode.sacrifice_target && !(cult_mode.sacrifice_target in GLOB.sacrificed)) - to_chat(user, "The sacrifice is not complete. The portal would lack the power to open if you tried!") - return - if(!cult_mode.eldergod) - to_chat(user, "\"I am already here. There is no need to try to summon me now.\"") - return - if((loc.z && loc.z != ZLEVEL_STATION) || !A.blob_allowed) - to_chat(user, "The Geometer is not interested in lesser locations; the station is the prize!") - return - var/confirm_final = alert(user, "This is the FINAL step to summon Nar-Sie, it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No") - if(confirm_final == "No") - to_chat(user, "You decide to prepare further before scribing the rune.") - return - Turf = get_turf(user) - A = get_area(src) - if(!check_rune_turf(Turf, user) || (loc.z && loc.z != ZLEVEL_STATION)|| !A.blob_allowed) - return - priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensionsal Affairs", 'sound/AI/spanomalies.ogg') - for(var/B in spiral_range_turfs(1, user, 1)) - var/obj/structure/emergency_shield/sanguine/N = new(B) - shields += N - else + if(!("eldergod" in SSticker.mode.cult_objectives)) to_chat(user, "Nar-Sie does not wish to be summoned!") return + if(!GLOB.sac_complete) + to_chat(user, "The sacrifice is not complete. The portal would lack the power to open if you tried!") + return + if(!SSticker.mode.eldergod) + to_chat(user, "\"I am already here. There is no need to try to summon me now.\"") + return + if((loc.z && loc.z != ZLEVEL_STATION) || !A.blob_allowed) + to_chat(user, "The Geometer is not interested in lesser locations; the station is the prize!") + return + var/confirm_final = alert(user, "This is the FINAL step to summon Nar-Sie; it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No") + if(confirm_final == "No") + to_chat(user, "You decide to prepare further before scribing the rune.") + return + Turf = get_turf(user) + A = get_area(src) + if(!check_rune_turf(Turf, user) || (loc.z && loc.z != ZLEVEL_STATION)|| !A.blob_allowed) + return + priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/AI/spanomalies.ogg') + for(var/B in spiral_range_turfs(1, user, 1)) + var/obj/structure/emergency_shield/sanguine/N = new(B) + shields += N user.visible_message("[user] [user.blood_volume ? "cuts open their arm and begins writing in their own blood":"begins sketching out a strange design"]!", \ "You [user.blood_volume ? "slice open your arm and ":""]begin drawing a sigil of the Geometer.") if(user.blood_volume) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 3a80ed54b3..4573b460da 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -148,8 +148,7 @@ structure_check() searches for nearby cultist structures required for the invoca /obj/effect/rune/proc/fail_invoke() //This proc contains the effects of a rune if it is not invoked correctly, through either invalid wording or not enough cultists. By default, it's just a basic fizzle. - visible_message("The markings pulse with a \ - small flash of red light, then fall dark.") + visible_message("The markings pulse with a small flash of red light, then fall dark.") var/oldcolor = color color = rgb(255, 0, 0) animate(src, color = oldcolor, time = 5) @@ -309,10 +308,11 @@ structure_check() searches for nearby cultist structures required for the invoca A.forceMove(target) if(movedsomething) ..() - visible_message("There is a sharp crack of inrushing air, and everything above the rune disappears!") + visible_message("There is a sharp crack of inrushing air, and everything above the rune disappears!", null, "You hear a sharp crack.") to_chat(user, "You[moveuserlater ? "r vision blurs, and you suddenly appear somewhere else":" send everything above the rune away"].") if(moveuserlater) user.forceMove(target) + target.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") else fail_invoke() @@ -398,23 +398,23 @@ structure_check() searches for nearby cultist structures required for the invoca return 1 /obj/effect/rune/convert/proc/do_sacrifice(mob/living/sacrificial, list/invokers) + var/big_sac = FALSE if((((ishuman(sacrificial) || iscyborg(sacrificial)) && sacrificial.stat != DEAD) || is_sacrifice_target(sacrificial.mind)) && invokers.len < 3) for(var/M in invokers) to_chat(M, "[sacrificial] is too greatly linked to the world! You need three acolytes!") log_game("Offer rune failed - not enough acolytes and target is living or sac target") return FALSE - var/sacrifice_fulfilled = FALSE - if(sacrificial.mind) GLOB.sacrificed += sacrificial.mind if(is_sacrifice_target(sacrificial.mind)) - sacrifice_fulfilled = TRUE + GLOB.sac_complete = TRUE + big_sac = TRUE else GLOB.sacrificed += sacrificial new /obj/effect/overlay/temp/cult/sac(get_turf(src)) for(var/M in invokers) - if(sacrifice_fulfilled) + if(big_sac) to_chat(M, "\"Yes! This is the one I desire! You have done well.\"") else if(ishuman(sacrificial) || iscyborg(sacrificial)) @@ -451,7 +451,7 @@ structure_check() searches for nearby cultist structures required for the invoca scribe_delay = 450 //how long the rune takes to create scribe_damage = 40.1 //how much damage you take doing it var/used - var/ignore_gamemode = FALSE + var/ignore_gamemode = TRUE /obj/effect/rune/narsie/Initialize(mapload, set_keyword) . = ..() @@ -490,7 +490,7 @@ structure_check() searches for nearby cultist structures required for the invoca //BEGIN THE SUMMONING used = 1 ..() - send_to_playing_players('sound/effects/dimensional_rend.ogg') //There used to be a message for this but every time it was changed it got edgier so I removed it + send_to_playing_players('sound/effects/dimensional_rend.ogg') var/turf/T = get_turf(src) sleep(40) if(src) diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm index 2411f0c40d..166cb6f528 100644 --- a/code/game/gamemodes/cult/talisman.dm +++ b/code/game/gamemodes/cult/talisman.dm @@ -147,9 +147,10 @@ if(is_blocked_turf(target, TRUE)) to_chat(user, "The target rune is blocked. Attempting to teleport to it would be massively unwise.") return ..(user, 0) - user.visible_message("Dust flows from [user]'s hand, and [user.p_they()] disappear in a flash of red light!", \ - "You speak the words of the talisman and find yourself somewhere else!") + user.visible_message("Dust flows from [user]'s hand, and [user.p_they()] disappear with a sharp crack!", \ + "You speak the words of the talisman and find yourself somewhere else!", "You hear a sharp crack.") user.forceMove(target) + target.visible_message("There is a boom of outrushing air as something appears above the rune!", null, "You hear a boom.") return ..() @@ -293,12 +294,12 @@ invocation = "Lo'Nab Na'Dm!" creation_time = 80 -/obj/item/weapon/paper/talisman/horror/attack(mob/living/target, mob/living/user) - if(iscultist(user)) - to_chat(user, "You disturb [target] with visons of the end!") +/obj/item/weapon/paper/talisman/horror/afterattack(mob/living/target, mob/living/user) + if(iscultist(user) && (get_dist(user, target) < 7)) + to_chat(user, "You disturb [target] with visions of madness!") if(iscarbon(target)) var/mob/living/carbon/H = target - H.reagents.add_reagent("mindbreaker", 25) + H.reagents.add_reagent("mindbreaker", 12) if(is_servant_of_ratvar(target)) to_chat(target, "You see a brief but horrible vision of Ratvar, rusted and scrapped, being torn apart.") target.emote("scream") diff --git a/code/game/gamemodes/devil/devil_game_mode.dm b/code/game/gamemodes/devil/devil_game_mode.dm index 9a528a1240..c275ac790a 100644 --- a/code/game/gamemodes/devil/devil_game_mode.dm +++ b/code/game/gamemodes/devil/devil_game_mode.dm @@ -2,7 +2,7 @@ name = "devil" config_tag = "devil" antag_flag = ROLE_DEVIL - protected_jobs = list("Lawyer", "Librarian", "Chaplain", "Head of Security", "Captain", "AI") + protected_jobs = list("Lawyer", "Curator", "Chaplain", "Head of Security", "Captain", "AI") required_players = 0 required_enemies = 1 recommended_enemies = 4 diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index a496715af2..700bfe5f3a 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -85,7 +85,6 @@ SSblackbox.set_details("game_mode","[SSticker.mode]") if(GLOB.revdata.commit) SSblackbox.set_details("revision","[GLOB.revdata.commit]") - SSblackbox.set_details("server_ip","[world.internet_address]:[world.port]") if(report) addtimer(CALLBACK(src, .proc/send_intercept, 0), rand(waittime_l, waittime_h)) generate_station_goals() @@ -258,6 +257,8 @@ if(escaped_total > 0) SSblackbox.set_val("escaped_total",escaped_total) send2irc("Server", "Round just ended.") + if(cult.len && !istype(SSticker.mode,/datum/game_mode/cult)) + datum_cult_completion() return 0 diff --git a/code/game/gamemodes/gang/dominator.dm b/code/game/gamemodes/gang/dominator.dm index 54099070cd..3b9dce8c3b 100644 --- a/code/game/gamemodes/gang/dominator.dm +++ b/code/game/gamemodes/gang/dominator.dm @@ -1,3 +1,5 @@ +#define DOM_BLOCKED_SPAM_CAP 6 + /obj/machinery/dominator name = "dominator" desc = "A visibly sinister device. Looks like you can break it if you hit it enough." @@ -13,9 +15,20 @@ var/datum/gang/gang var/operating = 0 //0=standby or broken, 1=takeover var/warned = 0 //if this device has set off the warning at <3 minutes yet + var/spam_prevention = DOM_BLOCKED_SPAM_CAP //first message is immediate var/datum/effect_system/spark_spread/spark_system var/obj/effect/countdown/dominator/countdown +/proc/dominator_excessive_walls(atom/A) + var/open = 0 + for(var/turf/T in circleviewturfs(center=A,radius=3)) + if(!istype(T, /turf/closed)) + open++ + if(open < 40) + return TRUE + else + return FALSE + /obj/machinery/dominator/tesla_act() qdel(src) @@ -48,6 +61,16 @@ if(gang && gang.is_dominating) var/time_remaining = gang.domination_time_remaining() if(time_remaining > 0) + if(dominator_excessive_walls(src)) + gang.domination_timer += 2 + playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0) + if(spam_prevention < DOM_BLOCKED_SPAM_CAP) + spam_prevention++ + else + gang.message_gangtools("Warning: There are too many walls around your gang's dominator, its signal is being blocked!") + say("Error: Takeover signal is currently blocked! There are too many walls within 3 standard units of this device.") + spam_prevention = 0 + return . = TRUE playsound(loc, 'sound/items/timer.ogg', 10, 0) if(!warned && (time_remaining < 180)) diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm index 9c31edf55f..12191ac44a 100644 --- a/code/game/gamemodes/gang/gang.dm +++ b/code/game/gamemodes/gang/gang.dm @@ -249,7 +249,7 @@ GLOBAL_LIST_INIT(gang_colors_pool, list("red","orange","yellow","green","blue"," return gang_bosses /proc/determine_domination_time(var/datum/gang/G) - return max(180,900 - (round((G.territory.len/GLOB.start_state.num_territories)*100, 1) * 12)) + return max(180,480 - (round((G.territory.len/GLOB.start_state.num_territories)*100, 1) * 9)) ////////////////////////////////////////////////////////////////////// //Announces the end of the game with all relavent information stated// @@ -312,7 +312,9 @@ GLOBAL_LIST_INIT(gang_colors_pool, list("red","orange","yellow","green","blue"," G.domination(0.5) priority_announce("Multiple station takeover attempts have made simultaneously. Conflicting takeover attempts appears to have restarted.","Network Alert") else + var/datum/gang/G = winners[1] + G.is_dominating = FALSE SSticker.mode.explosion_in_progress = 1 - SSticker.station_explosion_cinematic(1) + SSticker.station_explosion_cinematic(1,"gang war", null) SSticker.mode.explosion_in_progress = 0 - SSticker.force_ending = pick(winners) + SSticker.force_ending = TRUE diff --git a/code/game/gamemodes/gang/gang_datum.dm b/code/game/gamemodes/gang/gang_datum.dm index 3c54d5436b..805cac552f 100644 --- a/code/game/gamemodes/gang/gang_datum.dm +++ b/code/game/gamemodes/gang/gang_datum.dm @@ -13,6 +13,7 @@ var/list/territory = list() var/list/territory_new = list() var/list/territory_lost = list() + var/recalls = 1 var/dom_attempts = 2 var/points = 15 var/datum/atom_hud/antag/gang/ganghud @@ -262,4 +263,4 @@ ganghud = new() /datum/gang/multiverse/income() - return \ No newline at end of file + return diff --git a/code/game/gamemodes/gang/gang_items.dm b/code/game/gamemodes/gang/gang_items.dm index a8732c1046..724191c642 100644 --- a/code/game/gamemodes/gang/gang_items.dm +++ b/code/game/gamemodes/gang/gang_items.dm @@ -108,10 +108,16 @@ /datum/gang_item/weapon/ammo/get_cost_display(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool) return " ↳" + ..() //this is pretty hacky but it looks nice on the popup +/datum/gang_item/weapon/shuriken + name = "Shuriken" + id = "shuriken" + cost = 3 + item_path = /obj/item/weapon/throwing_star + /datum/gang_item/weapon/switchblade name = "Switchblade" id = "switchblade" - cost = 10 + cost = 5 item_path = /obj/item/weapon/switchblade /datum/gang_item/weapon/pistol @@ -125,6 +131,18 @@ id = "pistol_ammo" cost = 10 item_path = /obj/item/ammo_box/magazine/m10mm + +/datum/gang_item/weapon/sniper + name = ".50cal Sniper Rifle" + id = "sniper" + cost = 40 + item_path = /obj/item/weapon/gun/ballistic/automatic/sniper_rifle + +/datum/gang_item/weapon/ammo/sniper_ammo + name = "Standard .50cal Sniper Rounds" + id = "sniper_ammo" + cost = 15 + item_path = /obj/item/ammo_box/magazine/sniper_rounds /datum/gang_item/weapon/uzi name = "Uzi SMG" @@ -138,30 +156,8 @@ id = "uzi_ammo" cost = 40 item_path = /obj/item/ammo_box/magazine/uzim9mm - -//SLEEPING CARP - -/datum/gang_item/weapon/bostaff - name = "Bo Staff" - id = "bostaff" - cost = 10 - item_path = /obj/item/weapon/twohanded/bostaff - -/datum/gang_item/weapon/sleeping_carp_scroll - name = "Sleeping Carp Scroll (one-use)" - id = "sleeping_carp_scroll" - cost = 30 - item_path = /obj/item/weapon/sleeping_carp_scroll - spawn_msg = "Anyone who reads the sleeping carp scroll will learn secrets of the sleeping carp martial arts style." - -/datum/gang_item/weapon/wrestlingbelt - name = "Wrestling Belt" - id = "wrastling_belt" - cost = 20 - item_path = /obj/item/weapon/storage/belt/champion/wrestling - spawn_msg = "Anyone wearing the wresting belt will know how to be effective with wrestling." - - + + /////////////////// //EQUIPMENT /////////////////// @@ -175,6 +171,12 @@ id = "spraycan" cost = 5 item_path = /obj/item/toy/crayon/spraycan/gang + +/datum/gang_item/equipment/sharpener + name = "Sharpener" + id = "whetstone" + cost = 3 + item_path = /obj/item/weapon/sharpener /datum/gang_item/equipment/necklace name = "Gold Necklace" @@ -182,12 +184,31 @@ cost = 1 item_path = /obj/item/clothing/neck/necklace/dope + +/datum/gang_item/equipment/emp + name = "EMP Grenade" + id = "EMP" + cost = 5 + item_path = /obj/item/weapon/grenade/empgrenade + /datum/gang_item/equipment/c4 name = "C4 Explosive" id = "c4" - cost = 10 + cost = 7 item_path = /obj/item/weapon/grenade/plastic/c4 +/datum/gang_item/equipment/frag + name = "Fragmentation Grenade" + id = "frag nade" + cost = 10 + item_path = /obj/item/weapon/grenade/syndieminibomb/concussion/frag + +/datum/gang_item/equipment/stimpack + name = "Black Market Stimulants" + id = "stimpack" + cost = 15 + item_path = /obj/item/weapon/reagent_containers/syringe/stimulants + /datum/gang_item/equipment/implant_breaker name = "Implant Breaker" id = "implant_breaker" @@ -284,7 +305,11 @@ if(obj.density) to_chat(user, "There's not enough room here!") return FALSE - + + if(dominator_excessive_walls(user)) + to_chat(user, "span class='warning'>The dominator will not function here! The dominator requires an open space within three standard units so that walls do not interfere with the signal.
") + return FALSE + if(!(usrarea.type in gang.territory|gang.territory_new)) to_chat(user, "The dominator can be spawned only on territory controlled by your gang!") return FALSE diff --git a/code/game/gamemodes/gang/recaller.dm b/code/game/gamemodes/gang/recaller.dm index 0885b32612..f67bcad50a 100644 --- a/code/game/gamemodes/gang/recaller.dm +++ b/code/game/gamemodes/gang/recaller.dm @@ -168,6 +168,9 @@ if(recalling) to_chat(usr, "Error: Recall already in progress.") return 0 + + if(!gang.recalls) + to_chat(usr, "Error: Unable to access communication arrays. Firewall has logged our signature and is blocking all further attempts.") gang.message_gangtools("[usr] is attempting to recall the emergency shuttle.") recalling = 1 @@ -209,6 +212,7 @@ userturf = get_turf(user) if(userturf.z == 1) //Check one more time that they are on station. if(SSshuttle.cancelEvac(user)) + gang.recalls -= 1 return 1 to_chat(loc, "\icon[src]No response recieved. Emergency shuttle cannot be recalled at this time.") diff --git a/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm b/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm index aa633e1ef5..574e48fc68 100644 --- a/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm +++ b/code/game/gamemodes/miniantags/abduction/abductee_objectives.dm @@ -20,7 +20,7 @@ explanation_text = "Your brain is broken... you can only communicate in" /datum/objective/abductee/speech/New() - var/style = pick(list("pantomime", "rhyme", "haiku", "extended metaphors", "riddles", "extremely literal terms", "sound effects", "military jargon")) + var/style = pick(list("pantomime", "rhyme", "haiku", "extended metaphors", "riddles", "extremely literal terms", "sound effects", "military jargon", "three word sentences")) explanation_text+= " [style]." /datum/objective/abductee/capture @@ -146,3 +146,25 @@ /datum/objective/abductee/sixthsense explanation_text = "You died back there and went to heaven... or is it hell? No one here seems to know they're dead. Convince them, and maybe you can escape this limbo." + +/datum/objective/abductee/toupefallacy + explanation_text = "There are alien parasites masquerading as people's hair. Save people from this invasion." + +/datum/objective/abductee/everyoneisthesame + explanation_text = "There is only one other person in existence, he is just really good at pretending to be multiple people." + +/datum/objective/abductee/forbiddennumber + explanation_text = "Numbers, how do they work?" //Shouldn't ever see this. + +/datum/objective/abductee/forbiddennumber/New() + var/number = rand(2,10) + explanation_text = "Ignore anything in a set of [number], they don't exist." + +/datum/objective/abductee/foreignname + explanation_text = "No matter how they say it, other people keep mispronouncing your name. Be sure to correct them whenever possible." + +/datum/objective/abductee/pairoff + explanation_text = "Being alone and in large groups are both frightening. Try to be alone with only one other person whenever possible." + +/datum/objective/abductee/takeblame + explanation_text = "Try to get formally executed for a crime you didn't commit, without a false confession." diff --git a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm index 193aecd9ce..8f3dfb7ac3 100644 --- a/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm +++ b/code/game/gamemodes/miniantags/abduction/machinery/experiment.dm @@ -116,12 +116,13 @@ else dat += "

Subject Status :

" dat += "[occupant.name] => " - switch(occupant.stat) - if(0) + var/mob/living/mob_occupant = occupant + switch(mob_occupant.stat) + if(CONSCIOUS) dat += "Conscious" - if(1) + if(UNCONSCIOUS) dat += "Unconscious" - else + else // DEAD dat += "Deceased" dat += "
" dat += "[flash]" @@ -146,9 +147,11 @@ if(href_list["close"]) close_machine() return - if(occupant && occupant.stat != DEAD) - if(href_list["experiment"]) - flash = Experiment(occupant,href_list["experiment"]) + if(occupant) + var/mob/living/mob_occupant = occupant + if(mob_occupant.stat != DEAD) + if(href_list["experiment"]) + flash = Experiment(occupant,href_list["experiment"]) updateUsrDialog() add_fingerprint(usr) diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index 7260d8221f..265688a15b 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -14,6 +14,7 @@ var/icon_reveal = "revenant_revealed" var/icon_stun = "revenant_stun" var/icon_drain = "revenant_draining" + var/stasis = 0 incorporeal_move = 3 invisibility = INVISIBILITY_REVENANT health = INFINITY //Revenants don't use health, they use essence instead @@ -94,6 +95,8 @@ //Life, Stat, Hud Updates, and Say /mob/living/simple_animal/revenant/Life() + if(stasis) + return if(revealed && essence <= 0) death() if(unreveal_time && world.time >= unreveal_time) @@ -200,9 +203,8 @@ death() /mob/living/simple_animal/revenant/death() - if(!revealed || stat == DEAD) //Revenants cannot die if they aren't revealed //or are already dead + if(!revealed || stasis) //Revenants cannot die if they aren't revealed //or are already dead return 0 - ..(1) to_chat(src, "NO! No... it's too late, you can feel your essence [pick("breaking apart", "drifting away")]...") notransform = TRUE revealed = TRUE @@ -217,9 +219,12 @@ var/reforming_essence = essence_regen_cap //retain the gained essence capacity var/obj/item/weapon/ectoplasm/revenant/R = new(get_turf(src)) R.essence = max(reforming_essence - 15 * perfectsouls, 75) //minus any perfect souls - R.client_to_revive = src.client //If the essence reforms, the old revenant is put back in the body - ghostize() - qdel(src) + R.client_to_revive = client //If the essence reforms, the old revenant is put back in the body + R.revenant = src + invisibility = INVISIBILITY_ABSTRACT + revealed = 0 + stasis = 1 + ghostize(0)//Don't re-enter invisible corpse return @@ -302,6 +307,18 @@ to_chat(src, "Lost [essence_amt]E[source ? " from [source]":""].") return 1 +/mob/living/simple_animal/revenant/proc/death_reset() + revealed = FALSE + unreveal_time = 0 + notransform = 0 + unstun_time = 0 + inhibited = FALSE + draining = FALSE + incorporeal_move = 3 + invisibility = INVISIBILITY_REVENANT + alpha=255 + stasis = 0 + //reforming /obj/item/weapon/ectoplasm/revenant @@ -314,11 +331,15 @@ var/reforming = TRUE var/inert = FALSE var/client/client_to_revive + var/mob/living/simple_animal/revenant/revenant /obj/item/weapon/ectoplasm/revenant/New() ..() addtimer(CALLBACK(src, .proc/try_reform), 600) +/obj/item/weapon/ectoplasm/revenant/proc/scatter() + qdel(src) + /obj/item/weapon/ectoplasm/revenant/proc/try_reform() if(reforming) reforming = FALSE @@ -333,14 +354,14 @@ user.visible_message("[user] scatters [src] in all directions.", \ "You scatter [src] across the area. The particles slowly fade away.") user.drop_item() - qdel(src) + scatter() /obj/item/weapon/ectoplasm/revenant/throw_impact(atom/hit_atom) ..() if(inert) return visible_message("[src] breaks into particles upon impact, which fade away to nothingness.") - qdel(src) + scatter() /obj/item/weapon/ectoplasm/revenant/examine(mob/user) ..() @@ -350,47 +371,51 @@ to_chat(user, "It is shifting and distorted. It would be wise to destroy this.") /obj/item/weapon/ectoplasm/revenant/proc/reform() - if(QDELETED(src) || inert) + 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.") loc = get_turf(src) //In case it's in a backpack or someone's hand - var/mob/living/simple_animal/revenant/R = new(get_turf(src)) + revenant.forceMove(loc) if(client_to_revive) for(var/mob/M in GLOB.dead_mob_list) if(M.client == client_to_revive) //Only recreates the mob if the mob the client is in is dead - R.client = client_to_revive + revenant.client = client_to_revive key_of_revenant = client_to_revive.key 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 = get_candidates(ROLE_REVENANT) + var/list/candidates = pollCandidatesForMob("Do you want to be [revenant.name] (reforming)?", "revenant", null, ROLE_REVENANT, 50, revenant) if(!candidates.len) - qdel(R) + qdel(revenant) message_admins("No candidates were found for the new revenant. Oh well!") inert = TRUE visible_message("[src] settles down and seems lifeless.") return var/client/C = pick(candidates) + revenant.client = C key_of_revenant = C.key if(!key_of_revenant) - qdel(R) + qdel(revenant) message_admins("No ckey was found for the new revenant. Oh well!") inert = TRUE visible_message("[src] settles down and seems lifeless.") return - var/datum/mind/player_mind = new /datum/mind(key_of_revenant) - R.essence_regen_cap = essence - R.essence = R.essence_regen_cap - player_mind.active = 1 - player_mind.transfer_to(R) - player_mind.assigned_role = "revenant" - player_mind.special_role = "Revenant" - SSticker.mode.traitors |= player_mind + message_admins("[key_of_revenant] has been [client_to_revive ? "re":""]made into a revenant by reforming ectoplasm.") log_game("[key_of_revenant] was [client_to_revive ? "re":""]made as a revenant by reforming ectoplasm.") visible_message("[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/weapon/ectoplasm/revenant/Destroy() + if(!QDELETED(revenant)) + qdel(revenant) + ..() //objectives /datum/objective/revenant diff --git a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm index c66b48a6c8..f3ddb6d4be 100644 --- a/code/game/gamemodes/nuclear/pinpointer.dm +++ b/code/game/gamemodes/nuclear/pinpointer.dm @@ -17,6 +17,7 @@ var/atom/movable/constant_target = null //The thing we're always focused on, if we're in the right mode var/target_x = 0 //The target coordinates if we're tracking those var/target_y = 0 + var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination var/nuke_warning = FALSE // If we've set off a miniature alarm about an armed nuke var/mode = TRACK_NUKE_DISK //What are we looking for? @@ -111,7 +112,7 @@ var/mob/living/closest_operative = get_closest_atom(/mob/living/carbon/human, possible_targets, here) if(closest_operative) target = closest_operative - if(TRACK_ATOM) + if(TRACK_ATOM) if(constant_target) target = constant_target if(TRACK_COORDINATES) @@ -129,7 +130,7 @@ if(here.z != there.z) icon_state = "pinon[nuke_warning ? "alert" : ""]null" return - if(here == there) + if(get_dist_euclidian(here,there)<=minimum_range) icon_state = "pinon[nuke_warning ? "alert" : ""]direct" else setDir(get_dir(here, there)) @@ -171,3 +172,6 @@ desc = "An integrated tracking device, jury-rigged to search for living Syndicate operatives." mode = TRACK_OPERATIVES flags = NODROP + + + diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 6ac0ab8c7c..039b4cc3a4 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -67,7 +67,14 @@ /datum/objective/proc/update_explanation_text() //Default does nothing, override where needed -/datum/objective/proc/give_special_equipment() +/datum/objective/proc/give_special_equipment(special_equipment) + if(owner && owner.current) + if(ishuman(owner.current)) + var/mob/living/carbon/human/H = owner.current + var/list/slots = list ("backpack" = slot_in_backpack) + for(var/eq_path in special_equipment) + var/obj/O = new eq_path + H.equip_in_one_of_slots(O, slots) /datum/objective/assassinate var/target_role_type=0 @@ -94,6 +101,14 @@ else explanation_text = "Free Objective" +/datum/objective/assassinate/internal + var/stolen = 0 //Have we already eliminated this target? + +/datum/objective/assassinate/internal/update_explanation_text() + ..() + if(target && !target.current) + explanation_text = "Assassinate [target.name], who was obliterated" + /datum/objective/mutiny var/target_role_type=0 @@ -468,7 +483,7 @@ GLOBAL_LIST_EMPTY(possible_items) steal_target = targetinfo.targetitem explanation_text = "Steal [targetinfo.name]." dangerrating = targetinfo.difficulty - give_special_equipment() + give_special_equipment(targetinfo.special_equipment) return steal_target else explanation_text = "Free objective" @@ -511,15 +526,6 @@ GLOBAL_LIST_EMPTY(possible_items) return 1 return 0 -/datum/objective/steal/give_special_equipment() - if(owner && owner.current && targetinfo) - if(ishuman(owner.current)) - var/mob/living/carbon/human/H = owner.current - var/list/slots = list ("backpack" = slot_in_backpack) - for(var/eq_path in targetinfo.special_equipment) - var/obj/O = new eq_path - H.equip_in_one_of_slots(O, slots) - GLOBAL_LIST_EMPTY(possible_items_special) /datum/objective/steal/special //ninjas are so special they get their own subtype good for them @@ -695,6 +701,9 @@ GLOBAL_LIST_EMPTY(possible_items_special) explanation_text = "Destroy [target.name], the experimental AI." else explanation_text = "Free Objective" + +/datum/objective/destroy/internal + var/stolen = FALSE //Have we already eliminated this target? /datum/objective/steal_five_of_type explanation_text = "Steal at least five items!" diff --git a/code/game/gamemodes/traitor/double_agents.dm b/code/game/gamemodes/traitor/double_agents.dm index cb6609ebe6..2ee546c7aa 100644 --- a/code/game/gamemodes/traitor/double_agents.dm +++ b/code/game/gamemodes/traitor/double_agents.dm @@ -1,9 +1,13 @@ +#define PINPOINTER_MINIMUM_RANGE 15 +#define PINPOINTER_EXTRA_RANDOM_RANGE 10 +#define PINPOINTER_PING_TIME 40 + /datum/game_mode/traitor/internal_affairs name = "Internal Affairs" config_tag = "internal_affairs" employer = "Internal Affairs" - required_players = 25 - required_enemies = 5 + required_players = 25 + required_enemies = 5 recommended_enemies = 8 reroll_friendly = 0 traitor_name = "Nanotrasen Internal Affairs Agent" @@ -18,15 +22,189 @@ var/list/target_list = list() var/list/late_joining_list = list() + /datum/game_mode/traitor/internal_affairs/post_setup() var/i = 0 for(var/datum/mind/traitor in traitors) i++ if(i + 1 > traitors.len) i = 0 - target_list[traitor] = traitors[i + 1] + target_list[traitor] = traitors[i+1] ..() + +/datum/status_effect/agent_pinpointer + id = "agent_pinpointer" + duration = -1 + tick_interval = PINPOINTER_PING_TIME + alert_type = /obj/screen/alert/status_effect/agent_pinpointer + var/minimum_range = PINPOINTER_MINIMUM_RANGE + var/mob/scan_target = null + +/obj/screen/alert/status_effect/agent_pinpointer + name = "Internal Affairs Integrated Pinpointer" + desc = "Even stealthier than a normal implant." + icon = 'icons/obj/device.dmi' + icon_state = "pinon" + +/datum/status_effect/agent_pinpointer/proc/point_to_target() //If we found what we're looking for, show the distance and direction + if(!scan_target) + linked_alert.icon_state = "pinonnull" + return + var/turf/here = get_turf(owner) + var/turf/there = get_turf(scan_target) + if(here.z != there.z) + linked_alert.icon_state = "pinonnull" + return + if(get_dist_euclidian(here,there)<=minimum_range + rand(0, PINPOINTER_EXTRA_RANDOM_RANGE)) + linked_alert.icon_state = "pinondirect" + else + linked_alert.setDir(get_dir(here, there)) + switch(get_dist(here, there)) + if(1 to 8) + linked_alert.icon_state = "pinonclose" + if(9 to 16) + linked_alert.icon_state = "pinonmedium" + if(16 to INFINITY) + linked_alert.icon_state = "pinonfar" + + +/datum/status_effect/agent_pinpointer/proc/scan_for_target() + scan_target = null + if(owner) + if(owner.mind) + if(owner.mind.objectives) + for(var/datum/objective/objective_ in owner.mind.objectives) + if(!is_internal_objective(objective_)) + continue + var/datum/objective/assassinate/internal/objective = objective_ + var/mob/current = objective.target.current + if(current&¤t.stat!=DEAD) + scan_target = current + break + + +/datum/status_effect/agent_pinpointer/tick() + if(!owner) + qdel(src) + return + scan_for_target() + point_to_target() + +/proc/give_pinpointer(datum/mind/owner) + if(owner && owner.current) + owner.current.apply_status_effect(/datum/status_effect/agent_pinpointer) + + +/datum/internal_agent_state + var/traitored = FALSE + var/datum/mind/owner = null + var/list/datum/mind/targets_stolen = list() + +/proc/is_internal_objective(datum/objective/O) + return (istype(O, /datum/objective/assassinate/internal)||istype(O, /datum/objective/destroy/internal)) + +/proc/replace_escape_objective(datum/mind/owner) + if(!owner||!owner.objectives) + return + for (var/objective_ in owner.objectives) + if(!(istype(objective_, /datum/objective/escape)||istype(objective_,/datum/objective/survive))) + continue + owner.objectives -= objective_ + var/datum/objective/martyr/martyr_objective = new + martyr_objective.owner = owner + owner.objectives += martyr_objective + +/proc/reinstate_escape_objective(datum/mind/owner) + if(!owner||!owner.objectives) + return + for (var/objective_ in owner.objectives) + if(!istype(objective_, /datum/objective/martyr)) + continue + owner.objectives -= objective_ + if(issilicon(owner)) + var/datum/objective/survive/survive_objective = new + survive_objective.owner = owner + owner.objectives += survive_objective + else + var/datum/objective/escape/escape_objective = new + escape_objective.owner = owner + owner.objectives += escape_objective + +/datum/internal_agent_state/proc/steal_targets(datum/mind/victim) + if(!owner.current||owner.current.stat==DEAD) //Should already be guaranteed if this is only called from steal_targets_timer_func, but better to be safe code than sorry code + return + var/already_traitored = traitored + to_chat(owner.current, " Target eliminated: [victim.name]") + for(var/objective_ in victim.objectives) + if(istype(objective_, /datum/objective/assassinate/internal)) + var/datum/objective/assassinate/internal/objective = objective_ + if(objective.target==owner) + traitored = TRUE + else if(targets_stolen.Find(objective.target) == 0) + var/datum/objective/assassinate/internal/new_objective = new + new_objective.owner = owner + new_objective.target = objective.target + new_objective.update_explanation_text() + owner.objectives += new_objective + targets_stolen += objective.target + var/status_text = objective.check_completion() ? "neutralised" : "active" + to_chat(owner.current, " New target added to database: [objective.target.name] ([status_text]) ") + else if(istype(objective_, /datum/objective/destroy/internal)) + var/datum/objective/destroy/internal/objective = objective_ + var/datum/objective/destroy/internal/new_objective = new + if(objective.target==owner) + traitored = TRUE + else if(targets_stolen.Find(objective.target) == 0) + new_objective.owner = owner + new_objective.target = objective.target + new_objective.update_explanation_text() + owner.objectives += new_objective + targets_stolen += objective.target + var/status_text = objective.check_completion() ? "neutralised" : "active" + to_chat(owner.current, " New target added to database: [objective.target.name] ([status_text]) ") + if(traitored&&!already_traitored) + for(var/objective_ in owner.objectives) + if(!is_internal_objective(objective_)) + continue + var/datum/objective/assassinate/internal/objective = objective_ + if(!objective.check_completion()) + traitored = FALSE + return + to_chat(owner.current," All the other agents are dead, and you're the last loose end. Stage a Syndicate terrorist attack to cover up for today's events. You no longer have any limits on collateral damage.") + replace_escape_objective(owner) + + + +/datum/internal_agent_state/proc/steal_targets_timer_func() + if(owner&&owner.current&&owner.current.stat!=DEAD) + for(var/objective_ in owner.objectives) + if(!is_internal_objective(objective_)) + continue + var/datum/objective/assassinate/internal/objective = objective_ + if(!objective.target) + continue + if(objective.check_completion()) + if(objective.stolen) + continue + else + steal_targets(objective.target) + objective.stolen = TRUE + else + if(objective.stolen) + var/fail_msg = "Your sensors tell you that [objective.target.current.real_name], one of the targets you were meant to have killed, pulled one over on you, and is still alive - do the job properly this time! " + if(traitored) + fail_msg += " The truth could still slip out! Cease any terrorist actions as soon as possible, unneeded property damage or loss of employee life will lead to your contract being terminated." + reinstate_escape_objective(owner) + traitored = FALSE + to_chat(owner.current, fail_msg) + objective.stolen = FALSE + add_steal_targets_timer(owner) + +/datum/internal_agent_state/proc/add_steal_targets_timer() + var/datum/callback/C = new(src, .steal_targets_timer_func) + addtimer(C, 30) + /datum/game_mode/traitor/internal_affairs/forge_traitor_objectives(datum/mind/traitor) if(target_list.len && target_list[traitor]) // Is a double agent @@ -34,13 +212,13 @@ // Assassinate var/datum/mind/target_mind = target_list[traitor] if(issilicon(target_mind.current)) - var/datum/objective/destroy/destroy_objective = new + var/datum/objective/destroy/internal/destroy_objective = new destroy_objective.owner = traitor destroy_objective.target = target_mind destroy_objective.update_explanation_text() traitor.objectives += destroy_objective else - var/datum/objective/assassinate/kill_objective = new + var/datum/objective/assassinate/internal/kill_objective = new kill_objective.owner = traitor kill_objective.target = target_mind kill_objective.update_explanation_text() @@ -55,6 +233,11 @@ var/datum/objective/escape/escape_objective = new escape_objective.owner = traitor traitor.objectives += escape_objective + var/datum/internal_agent_state/state = new + state.owner=traitor + state.add_steal_targets_timer() + if(!issilicon(traitor.current)) + give_pinpointer(traitor) else ..() // Give them standard objectives. @@ -106,14 +289,18 @@ /datum/game_mode/traitor/internal_affairs/greet_traitor(datum/mind/traitor) var/crime = pick("distribution of contraband" , "unauthorized erotic action on duty", "embezzlement", "piloting under the influence", "dereliction of duty", "syndicate collaboration", "mutiny", "multiple homicides", "corporate espionage", "recieving bribes", "malpractice", "worship of prohbited life forms", "possession of profane texts", "murder", "arson", "insulting their manager", "grand theft", "conspiracy", "attempting to unionize", "vandalism", "gross incompetence") - to_chat(traitor.current, "You are the [traitor_name].") - to_chat(traitor.current, "Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.") + to_chat(traitor.current, "You are the [traitor_name].") + to_chat(traitor.current, "Your target is suspected of [crime], and you have been tasked with eliminating them by any means necessary to avoid a costly and embarrassing public trial.") to_chat(traitor.current, "While you have a license to kill, unneeded property damage or loss of employee life will lead to your contract being terminated.") - to_chat(traitor.current, "For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.") - to_chat(traitor.current, "Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.") + to_chat(traitor.current, "For the sake of plausible deniability, you have been equipped with an array of captured Syndicate weaponry available via uplink.") + to_chat(traitor.current, "Finally, watch your back. Your target has friends in high places, and intel suggests someone may have taken out a contract of their own to protect them.") traitor.announce_objectives() /datum/game_mode/traitor/internal_affairs/give_codewords(mob/living/traitor_mob) - return \ No newline at end of file + return + +#undef PINPOINTER_EXTRA_RANDOM_RANGE +#undef PINPOINTER_MINIMUM_RANGE +#undef PINPOINTER_PING_TIME diff --git a/code/game/gamemodes/wizard/soulstone.dm b/code/game/gamemodes/wizard/soulstone.dm index 7ccf7a6b7e..09412a79ac 100644 --- a/code/game/gamemodes/wizard/soulstone.dm +++ b/code/game/gamemodes/wizard/soulstone.dm @@ -54,7 +54,7 @@ if(!ishuman(M))//If target is not a human. return ..() if(iscultist(M)) - to_chat(user, "\"Come now, do not capture your fellow's soul.\"") + to_chat(user, "\"Come now, do not capture your bretheren's soul.\"") return add_logs(user, M, "captured [M.name]'s soul", src) @@ -132,11 +132,11 @@ if("VICTIM") var/mob/living/carbon/human/T = target - if(SSticker.mode.name == "cult" && T.mind == SSticker.mode:sacrifice_target) + if(is_sacrifice_target(T.mind)) if(iscultist(user)) to_chat(user, "\"This soul is mine. SACRIFICE THEM!\"") else - to_chat(user, "The soulstone doesn't work for no apparent reason.") + to_chat(user, "The soulstone seems to reject this soul.") return 0 if(contents.len) to_chat(user, "Capture failed!: The soulstone is full! Free an existing soul to make room.") @@ -188,7 +188,10 @@ else makeNewConstruct(/mob/living/simple_animal/hostile/construct/builder/noncult, A, user, 0, T.loc) - + for(var/datum/mind/B in SSticker.mode.cult) + if(B == A.mind) + SSticker.mode.cult -= A.mind + SSticker.mode.update_cult_icons_removed(A.mind) qdel(T) user.drop_item() qdel(src) @@ -200,6 +203,9 @@ var/mob/living/simple_animal/hostile/construct/newstruct = new ctype((loc_override) ? (loc_override) : (get_turf(target))) if(stoner) newstruct.faction |= "\ref[stoner]" + newstruct.master = stoner + var/datum/action/innate/seek_master/SM = new() + SM.Grant(newstruct) newstruct.key = target.key if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker && SSticker.mode) SSticker.mode.add_cultist(newstruct.mind, 0) @@ -207,6 +213,9 @@ to_chat(newstruct, "You are still bound to serve the cult[stoner ? " and [stoner]":""], follow their orders and help them complete their goals at all costs.") else if(stoner) to_chat(newstruct, "You are still bound to serve your creator, [stoner], follow their orders and help them complete their goals at all costs.") + newstruct.throw_alert("bloodsense", /obj/screen/alert/bloodsense) + var/obj/screen/alert/bloodsense/BS = newstruct.alerts["bloodsense"] + BS.Cviewer = newstruct newstruct.cancel_camera() @@ -244,7 +253,7 @@ break if(!chosen_ghost) //Failing that, we grab a ghost - var/list/consenting_candidates = pollCandidates("Would you like to play as a Shade?", "Cultist", null, ROLE_CULTIST, poll_time = 50) + var/list/consenting_candidates = pollGhostCandidates("Would you like to play as a Shade?", "Cultist", null, ROLE_CULTIST, poll_time = 50) if(consenting_candidates.len) chosen_ghost = pick(consenting_candidates) if(!T) diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index b25187195d..06e241896f 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -778,6 +778,9 @@ icon_state ="booksmoke" desc = "This book is overflowing with the dank arts." +/obj/item/weapon/spellbook/oneuse/smoke/lesser //Chaplain smoke book + spell = /obj/effect/proc_holder/spell/targeted/smoke/lesser + /obj/item/weapon/spellbook/oneuse/smoke/recoil(mob/user) ..() to_chat(user,"Your stomach rumbles...") @@ -786,6 +789,7 @@ if(user.nutrition <= 0) user.nutrition = 0 + /obj/item/weapon/spellbook/oneuse/blind spell = /obj/effect/proc_holder/spell/targeted/trigger/blind spellname = "blind" diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 5dc8ea3f20..d45859a371 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -79,7 +79,8 @@ /obj/machinery/sleeper/close_machine(mob/user) if((isnull(user) || istype(user)) && state_open && !panel_open) ..(user) - if(occupant && occupant.stat != DEAD) + var/mob/living/mob_occupant = occupant + if(mob_occupant && mob_occupant.stat != DEAD) to_chat(occupant, "You feel cool air surround you. You go numb as your senses turn inward.") /obj/machinery/sleeper/emp_act(severity) @@ -128,27 +129,30 @@ data["chems"] += list(list("name" = R.name, "id" = R.id, "allowed" = chem_allowed(chem))) data["occupant"] = list() - if(occupant) - data["occupant"]["name"] = occupant.name - data["occupant"]["stat"] = occupant.stat - data["occupant"]["health"] = occupant.health - data["occupant"]["maxHealth"] = occupant.maxHealth + var/mob/living/mob_occupant = occupant + if(mob_occupant) + data["occupant"]["name"] = mob_occupant.name + data["occupant"]["stat"] = mob_occupant.stat + data["occupant"]["health"] = mob_occupant.health + data["occupant"]["maxHealth"] = mob_occupant.maxHealth data["occupant"]["minHealth"] = HEALTH_THRESHOLD_DEAD - data["occupant"]["bruteLoss"] = occupant.getBruteLoss() - data["occupant"]["oxyLoss"] = occupant.getOxyLoss() - data["occupant"]["toxLoss"] = occupant.getToxLoss() - data["occupant"]["fireLoss"] = occupant.getFireLoss() - data["occupant"]["cloneLoss"] = occupant.getCloneLoss() - data["occupant"]["brainLoss"] = occupant.getBrainLoss() + data["occupant"]["bruteLoss"] = mob_occupant.getBruteLoss() + data["occupant"]["oxyLoss"] = mob_occupant.getOxyLoss() + data["occupant"]["toxLoss"] = mob_occupant.getToxLoss() + data["occupant"]["fireLoss"] = mob_occupant.getFireLoss() + data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss() + data["occupant"]["brainLoss"] = mob_occupant.getBrainLoss() data["occupant"]["reagents"] = list() if(occupant.reagents.reagent_list.len) - for(var/datum/reagent/R in occupant.reagents.reagent_list) + for(var/datum/reagent/R in mob_occupant.reagents.reagent_list) data["occupant"]["reagents"] += list(list("name" = R.name, "volume" = R.volume)) return data /obj/machinery/sleeper/ui_act(action, params) if(..()) return + var/mob/living/mob_occupant = occupant + switch(action) if("door") if(state_open) @@ -158,9 +162,9 @@ . = TRUE if("inject") var/chem = params["chem"] - if(!is_operational() || !occupant) + if(!is_operational() || !mob_occupant) return - if(occupant.health < min_health && chem != "epinephrine") + if(mob_occupant.health < min_health && chem != "epinephrine") return if(inject_chem(chem)) . = TRUE @@ -177,10 +181,11 @@ return TRUE /obj/machinery/sleeper/proc/chem_allowed(chem) - if(!occupant) + var/mob/living/mob_occupant = occupant + if(!mob_occupant) return - var/amount = occupant.reagents.get_reagent_amount(chem) + 10 <= 20 * efficiency - var/occ_health = occupant.health > min_health || chem == "epinephrine" + var/amount = mob_occupant.reagents.get_reagent_amount(chem) + 10 <= 20 * efficiency + var/occ_health = mob_occupant.health > min_health || chem == "epinephrine" return amount && occ_health /obj/machinery/sleeper/proc/reset_chem_buttons() diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 824b50b168..0e5b78af7c 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -121,10 +121,12 @@ /obj/machinery/clonepod/examine(mob/user) ..() + var/mob/living/mob_occupant = occupant if(mess) to_chat(user, "It's filled with blood and viscera. You swear you can see it moving...") - if (is_operational() && (!isnull(occupant)) && (occupant.stat != DEAD)) - to_chat(user, "Current clone cycle is [round(get_completion())]% complete.") + if(is_operational() && mob_occupant) + if(mob_occupant.stat != DEAD) + to_chat(user, "Current clone cycle is [round(get_completion())]% complete.") /obj/machinery/clonepod/return_air() // We want to simulate the clone not being in contact with @@ -136,7 +138,10 @@ return GM /obj/machinery/clonepod/proc/get_completion() - . = (100 * ((occupant.health + 100) / (heal_level + 100))) + . = FALSE + var/mob/living/mob_occupant = occupant + if(mob_occupant) + . = (100 * ((mob_occupant.health + 100) / (heal_level + 100))) /obj/machinery/clonepod/attack_ai(mob/user) return examine(user) @@ -172,11 +177,11 @@ var/mob/living/carbon/human/H = new /mob/living/carbon/human(src) - if(clonemind.changeling) - var/obj/item/organ/brain/B = H.getorganslot("brain") - B.vital = FALSE - B.decoy_override = TRUE - + if(clonemind.changeling) + var/obj/item/organ/brain/B = H.getorganslot("brain") + B.vital = FALSE + B.decoy_override = TRUE + H.hardset_dna(ui, se, H.real_name, null, mrace, features) if(efficiency > 2) @@ -204,13 +209,13 @@ clonemind.transfer_to(H) - if(grab_ghost_when == CLONER_FRESH_CLONE) - H.grab_ghost() - to_chat(H, "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?
") + if(grab_ghost_when == CLONER_FRESH_CLONE) + H.grab_ghost() + to_chat(H, "Consciousness slowly creeps over you as your body regenerates.
So this is what cloning feels like?
") if(grab_ghost_when == CLONER_MATURE_CLONE) - H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost - to_chat(H.get_ghost(TRUE), "Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.") + H.ghostize(TRUE) //Only does anything if they were still in their old body and not already a ghost + to_chat(H.get_ghost(TRUE), "Your body is beginning to regenerate in a cloning pod. You will become conscious when it is complete.") if(H) H.faction |= factions @@ -223,25 +228,26 @@ //Grow clones to maturity then kick them out. FREELOADERS /obj/machinery/clonepod/process() + var/mob/living/mob_occupant = occupant if(!is_operational()) //Autoeject if power is lost - if (occupant) + if(mob_occupant) go_out() connected_message("Clone Ejected: Loss of power.") - else if((occupant) && (occupant.loc == src)) - if((occupant.stat == DEAD) || (occupant.suiciding) || occupant.hellbound) //Autoeject corpses and suiciding dudes. + else if(mob_occupant && (mob_occupant.loc == src)) + if((mob_occupant.stat == DEAD) || (mob_occupant.suiciding) || mob_occupant.hellbound) //Autoeject corpses and suiciding dudes. connected_message("Clone Rejected: Deceased.") - SPEAK("The cloning of [occupant.real_name] has been \ + SPEAK("The cloning of [mob_occupant.real_name] has been \ aborted due to unrecoverable tissue failure.") go_out() - else if(occupant.cloneloss > (100 - heal_level)) - occupant.Paralyse(4) + else if(mob_occupant.cloneloss > (100 - heal_level)) + mob_occupant.Paralyse(4) //Slowly get that clone healed and finished. - occupant.adjustCloneLoss(-((speed_coeff/2) * config.damage_multiplier)) - var/progress = CLONE_INITIAL_DAMAGE - occupant.getCloneLoss() + mob_occupant.adjustCloneLoss(-((speed_coeff/2) * config.damage_multiplier)) + var/progress = CLONE_INITIAL_DAMAGE - mob_occupant.getCloneLoss() // To avoid the default cloner making incomplete clones progress += (100 - MINIMUM_HEAL_LEVEL) var/milestone = CLONE_INITIAL_DAMAGE / flesh_number @@ -252,24 +258,24 @@ var/obj/item/I = pick_n_take(unattached_flesh) if(isorgan(I)) var/obj/item/organ/O = I - O.Insert(occupant) + O.Insert(mob_occupant) else if(isbodypart(I)) var/obj/item/bodypart/BP = I - BP.attach_limb(occupant) + BP.attach_limb(mob_occupant) //Premature clones may have brain damage. - occupant.adjustBrainLoss(-((speed_coeff/2) * config.damage_multiplier)) + mob_occupant.adjustBrainLoss(-((speed_coeff/2) * config.damage_multiplier)) check_brine() use_power(7500) //This might need tweaking. - else if((occupant.cloneloss <= (100 - heal_level))) + else if((mob_occupant.cloneloss <= (100 - heal_level))) connected_message("Cloning Process Complete.") - SPEAK("The cloning cycle of [occupant.real_name] is complete.") + SPEAK("The cloning cycle of [mob_occupant.real_name] is complete.") go_out() - else if ((!occupant) || (occupant.loc != src)) + else if (!mob_occupant || mob_occupant.loc != src) occupant = null if (!mess && !panel_open) icon_state = "pod_0" @@ -305,16 +311,19 @@ to_chat(user, "-% Successfully stored \ref[P.buffer] [P.buffer.name] in buffer %-") return + var/mob/living/mob_occupant = occupant if(W.GetID()) if(!check_access(W)) to_chat(user, "Access Denied.") return - if(!(occupant || mess)) + if(!(mob_occupant || mess)) to_chat(user, "Error: Pod has no occupant.") return else connected_message("Authorized Ejection") - SPEAK("An authorized ejection of [clonemind.name] has occurred.") + + SPEAK("An authorized ejection of [clonemind.name] has occurred.") + to_chat(user, "You force an emergency ejection. ") go_out() else @@ -339,54 +348,63 @@ /obj/machinery/clonepod/proc/go_out() countdown.stop() + var/mob/living/mob_occupant = occupant if(mess) //Clean that mess and dump those gibs! mess = FALSE - new /obj/effect/gibspawner/generic(loc) + new /obj/effect/gibspawner/generic(loc) audible_message("You hear a splat.") icon_state = "pod_0" return - if(!occupant) + if(!mob_occupant) return - if(grab_ghost_when == CLONER_MATURE_CLONE) - occupant.grab_ghost() - to_chat(occupant, "There is a bright flash!
You feel like a new being.
") - occupant.flash_act() - var/turf/T = get_turf(src) + if(grab_ghost_when == CLONER_MATURE_CLONE) + mob_occupant.grab_ghost() + to_chat(occupant, "There is a bright flash!
You feel like a new being.
") + mob_occupant.flash_act() + + var/turf/T = get_turf(src) occupant.forceMove(T) icon_state = "pod_0" - occupant.domutcheck(1) //Waiting until they're out before possible monkeyizing. The 1 argument forces powers to manifest. + mob_occupant.domutcheck(1) //Waiting until they're out before possible monkeyizing. The 1 argument forces powers to manifest. + occupant = null /obj/machinery/clonepod/proc/malfunction() - if(occupant) + var/mob/living/mob_occupant = occupant + if(mob_occupant) connected_message("Critical Error!") SPEAK("Critical error! Please contact a Thinktronic Systems \ technician, as your warranty may be affected.") mess = TRUE - for(var/obj/item/O in unattached_flesh) - qdel(O) + + for(var/obj/item/O in unattached_flesh) + qdel(O) + icon_state = "pod_g" - if(occupant.mind != clonemind) - clonemind.transfer_to(occupant) - occupant.grab_ghost() // We really just want to make you suffer. - flash_color(occupant, flash_color="#960000", flash_time=100) - to_chat(occupant, "Agony blazes across your consciousness as your body is torn apart.
Is this what dying is like? Yes it is.
") + if(mob_occupant.mind != clonemind) + clonemind.transfer_to(mob_occupant) + mob_occupant.grab_ghost() // We really just want to make you suffer. + flash_color(mob_occupant, flash_color="#960000", flash_time=100) + to_chat(mob_occupant, "Agony blazes across your consciousness as your body is torn apart.
Is this what dying is like? Yes it is.
") playsound(src.loc, 'sound/machines/warning-buzzer.ogg', 50, 0) - occupant << sound('sound/hallucinations/veryfar_noise.ogg',0,1,50) - QDEL_IN(occupant, 40) + mob_occupant << sound('sound/hallucinations/veryfar_noise.ogg',0,1,50) + QDEL_IN(mob_occupant, 40) /obj/machinery/clonepod/relaymove(mob/user) if(user.stat == CONSCIOUS) go_out() /obj/machinery/clonepod/emp_act(severity) - if((occupant || mess) && prob(100/(severity*efficiency))) + + var/mob/living/mob_occupant = occupant + if(mob_occupant && prob(100/(severity*efficiency))) connected_message(Gibberish("EMP-caused Accidental Ejection", 0)) - SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of [clonemind.name] prematurely." ,0)) + SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of [mob_occupant.real_name] prematurely." ,0)) + go_out() ..() diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index afa054428a..48819f91e2 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -186,21 +186,23 @@ // Scanner if (!isnull(src.scanner)) + var/mob/living/scanner_occupant = scanner.occupant + dat += "

Scanner Functions

" dat += "
" - if (!src.scanner.occupant) + if(!scanner_occupant) dat += "Scanner Unoccupied" else if(loading) - dat += "[src.scanner.occupant] => Scanning..." + dat += "[scanner_occupant] => Scanning..." else - if (src.scanner.occupant.ckey != scantemp_ckey) + if(scanner_occupant.ckey != scantemp_ckey) scantemp = "Ready to Scan" - scantemp_ckey = src.scanner.occupant.ckey - dat += "[src.scanner.occupant] => [scantemp]" + scantemp_ckey = scanner_occupant.ckey + dat += "[scanner_occupant] => [scantemp]" dat += "
" - if (src.scanner.occupant) + if(scanner_occupant) dat += "Start Scan" dat += "
[src.scanner.locked ? "Unlock Scanner" : "Lock Scanner"]" else diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index 65fbee45f0..e3b47873e6 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -56,7 +56,7 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) jobs["Bartender"] = 61 jobs["Cook"] = 62 jobs["Botanist"] = 63 - jobs["Librarian"] = 64 + jobs["Curator"] = 64 jobs["Chaplain"] = 65 jobs["Clown"] = 66 jobs["Mime"] = 67 diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 3772dacbdb..0c2894f056 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -113,7 +113,8 @@ to_chat(R.connected_ai, "

ALERT - Cyborg detonation detected: [R.name]
") R.ResetSecurityCodes() else - message_admins("[key_name_admin(usr)] (FLW) detonated [key_name(R, R.client)](JMP)!") + var/turf/T = get_turf(R) + message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name(R, R.client)][ADMIN_JMP(T)]!") log_game("\[key_name(usr)] detonated [key_name(R)]!") if(R.connected_ai) to_chat(R.connected_ai, "

ALERT - Cyborg detonation detected: [R.name]
") @@ -127,7 +128,7 @@ if(can_control(usr, R)) var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort") if(choice == "Confirm" && can_control(usr, R) && !..()) - message_admins("[key_name_admin(usr)] (FLW) [R.canmove ? "locked down" : "released"] [key_name(R, R.client)](FLW)!") + message_admins("[ADMIN_LOOKUPFLW(usr)] [R.canmove ? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!") log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R)]!") R.SetLockdown(!R.lockcharge) to_chat(R, "[!R.lockcharge ? "Your lockdown has been lifted!" : "You have been locked down!"]") diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 4bb872b347..fd026e4686 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -58,7 +58,12 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/uplinker/proc/donateTC(amt, addLog = 1) if(uplinkholder && linkedboss) - if(amt <= uplinkholder.hidden_uplink.telecrystals) + if(amt < 0) + linkedboss.storedcrystals += uplinkholder.hidden_uplink.telecrystals + if(addLog) + linkedboss.logTransfer("[src] donated [uplinkholder.hidden_uplink.telecrystals] telecrystals to [linkedboss].") + uplinkholder.hidden_uplink.telecrystals = 0 + else if(amt <= uplinkholder.hidden_uplink.telecrystals) uplinkholder.hidden_uplink.telecrystals -= amt linkedboss.storedcrystals += amt if(addLog) @@ -66,7 +71,12 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E /obj/machinery/computer/telecrystals/uplinker/proc/giveTC(amt, addLog = 1) if(uplinkholder && linkedboss) - if(amt <= linkedboss.storedcrystals) + if(amt < 0) + uplinkholder.hidden_uplink.telecrystals += linkedboss.storedcrystals + if(addLog) + linkedboss.logTransfer("[src] received [linkedboss.storedcrystals] telecrystals from [linkedboss].") + linkedboss.storedcrystals = 0 + else if(amt <= linkedboss.storedcrystals) uplinkholder.hidden_uplink.telecrystals += amt linkedboss.storedcrystals -= amt if(addLog) @@ -89,7 +99,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E if(uplinkholder) dat += "[uplinkholder.hidden_uplink.telecrystals] telecrystals remain in this uplink.
" if(linkedboss) - dat += "Donate TC: 1 | 5" + dat += "Donate TC: 1 | 5 | All" dat += "
Eject Uplink" @@ -103,11 +113,9 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E if(..()) return - if(href_list["donate1"]) - donateTC(1) - - if(href_list["donate5"]) - donateTC(5) + if(href_list["donate"]) + var/tcamt = text2num(href_list["donate"]) + donateTC(tcamt) if(href_list["eject"]) ejectuplink() @@ -162,7 +170,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E var/dat = "" dat += "Scan for TC stations.
" - dat += "This [src] has [storedcrystals] telecrystals available for distribution.
" + dat += "[storedcrystals] telecrystals are available for distribution.
" dat += "

" @@ -171,10 +179,10 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E if(A.uplinkholder) dat += "[A.uplinkholder.hidden_uplink.telecrystals] telecrystals." if(storedcrystals) - dat+= "
Add TC: 1 | 5" + dat+= "
Add TC: 1 | 5 | 10 | All" dat += "
" - if(TCstations.len) + if(TCstations.len && storedcrystals) dat += "

Evenly distribute remaining TC.

" @@ -195,13 +203,11 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E if(href_list["scan"]) scanUplinkers() - if(href_list["give1"]) - var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["give1"]) - A.giveTC(1) - - if(href_list["give5"]) - var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["give5"]) - A.giveTC(5) + if(href_list["give"]) + var/tcamt = text2num(href_list["give"]) + if(TCstations.len) // sanity + var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["target"]) in TCstations + A.giveTC(tcamt) if(href_list["distrib"]) var/sanity = 0 diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm index af59f63888..d572b3e9dc 100644 --- a/code/game/machinery/dna_scanner.dm +++ b/code/game/machinery/dna_scanner.dm @@ -105,13 +105,14 @@ ..() // search for ghosts, if the corpse is empty and the scanner is connected to a cloner - if(occupant) + var/mob/living/mob_occupant = occupant + if(mob_occupant) if(locate(/obj/machinery/computer/cloning, get_step(src, NORTH)) \ || locate(/obj/machinery/computer/cloning, get_step(src, SOUTH)) \ || locate(/obj/machinery/computer/cloning, get_step(src, EAST)) \ || locate(/obj/machinery/computer/cloning, get_step(src, WEST))) - if(!occupant.suiciding && !(occupant.disabilities & NOCLONE) && !occupant.hellbound) - occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!", source = src) + if(!mob_occupant.suiciding && !(mob_occupant.disabilities & NOCLONE) && !mob_occupant.hellbound) + mob_occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!", source = src) var/obj/machinery/computer/scan_consolenew/console for(dir in list(NORTH,EAST,SOUTH,WEST)) @@ -157,4 +158,4 @@ if(..(user,1,0)) //don't set the machine, since there's no dialog return - toggle_open(user) \ No newline at end of file + toggle_open(user) diff --git a/code/game/machinery/gulag_teleporter.dm b/code/game/machinery/gulag_teleporter.dm index 92a550b17c..5979abdc29 100644 --- a/code/game/machinery/gulag_teleporter.dm +++ b/code/game/machinery/gulag_teleporter.dm @@ -136,13 +136,14 @@ The console is located at computer/gulag_teleporter.dm /obj/machinery/gulag_teleporter/proc/strip_occupant() if(linked_reclaimer) linked_reclaimer.stored_items[occupant] = list() - for(var/obj/item/W in occupant) - if(!is_type_in_typecache(W, required_items) && occupant.temporarilyRemoveItemFromInventory(W)) + var/mob/living/mob_occupant = occupant + for(var/obj/item/W in mob_occupant) + if(!is_type_in_typecache(W, required_items) && mob_occupant.temporarilyRemoveItemFromInventory(W)) if(istype(W, /obj/item/weapon/restraints/handcuffs)) W.forceMove(get_turf(src)) continue if(linked_reclaimer) - linked_reclaimer.stored_items[occupant] += W + linked_reclaimer.stored_items[mob_occupant] += W linked_reclaimer.contents += W W.forceMove(linked_reclaimer) else diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index 7c80817699..12fcd5ec91 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -294,7 +294,9 @@ GLOBAL_LIST_EMPTY(holopads) Hologram.add_atom_colour("#77abff", FIXED_COLOUR_PRIORITY) Hologram.Impersonation = user + Hologram.language_holder = user.get_language_holder() + Hologram.mouse_opacity = 0//So you can't click on it. Hologram.layer = FLY_LAYER//Above all the other objects/mobs. Or the vast majority of them. Hologram.anchored = 1//So space wind cannot drag it. @@ -392,4 +394,4 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ req_components = list(/obj/item/weapon/stock_parts/capacitor = 1) #undef HOLOPAD_PASSIVE_POWER_USAGE -#undef HOLOGRAM_POWER_USAGE +#undef HOLOGRAM_POWER_USAGE \ No newline at end of file diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 6cd8e75798..96b0029134 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -1,8 +1,8 @@ /* Overview: - Used to create objects that need a per step proc call. Default definition of 'New()' + Used to create objects that need a per step proc call. Default definition of 'Initialize()' stores a reference to src machine in global 'machines list'. Default definition - of 'Del' removes reference to src machine in global 'machines list'. + of 'Destroy' removes reference to src machine in global 'machines list'. Class Variables: use_power (num) @@ -44,7 +44,7 @@ Class Variables: EMPED:16 -- temporary broken by EMP pulse Class Procs: - New() 'game/machinery/machine.dm' + Initialize() 'game/machinery/machine.dm' Destroy() 'game/machinery/machine.dm' @@ -118,14 +118,15 @@ Class Procs: var/panel_open = 0 var/state_open = 0 var/critical_machine = FALSE //If this machine is critical to station operation and should have the area be excempted from power failures. - var/mob/living/occupant = null + var/list/occupant_typecache = list(/mob/living) // turned into typecache in Initialize + var/atom/movable/occupant = null var/unsecuring_tool = /obj/item/weapon/wrench var/interact_open = 0 // Can the machine be interacted with when in maint/when the panel is open. var/interact_offline = 0 // Can the machine be interacted with while de-powered. var/speed_process = 0 // Process as fast as possible? /obj/machinery/Initialize() - if (!armor) + if(!armor) armor = list(melee = 25, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 70) . = ..() GLOB.machines += src @@ -135,6 +136,8 @@ Class Procs: START_PROCESSING(SSfastprocess, src) power_change() + occupant_typecache = typecacheof(occupant_typecache) + /obj/machinery/Destroy() GLOB.machines.Remove(src) if(!speed_process) @@ -176,16 +179,24 @@ Class Procs: L.update_canmove() occupant = null -/obj/machinery/proc/close_machine(mob/living/target = null) +/obj/machinery/proc/close_machine(atom/movable/target = null) state_open = 0 density = 1 if(!target) - for(var/mob/living/carbon/C in loc) - if(C.buckled || C.has_buckled_mobs()) + for(var/am in loc) + if(!is_type_in_typecache(am, occupant_typecache)) continue - else - target = C - if(target && !target.buckled && !target.has_buckled_mobs()) + var/atom/movable/AM = am + if(AM.has_buckled_mobs()) + continue + if(isliving(AM)) + var/mob/living/L = am + if(L.buckled) + continue + target = am + + var/mob/living/mobtarget = target + if(target && !target.has_buckled_mobs() && (!isliving(target) || !mobtarget.buckled)) occupant = target target.forceMove(src) updateUsrDialog() diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index 6735aa7609..2d3765a934 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -251,6 +251,8 @@ GLOBAL_LIST_INIT(pipeID2State, list( var/mob/living/carbon/C = user for(var/i=1 to 20) C.vomit(0,1,0,4,0) + if(prob(20)) + C.spew_organ() sleep(5) C.blood_volume = 0 return(OXYLOSS|BRUTELOSS) diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index b8ba21fd35..56b13f0e46 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -1,6 +1,9 @@ #define TURRET_STUN 0 #define TURRET_LETHAL 1 +#define POPUP_ANIM_TIME 5 +#define POPDOWN_ANIM_TIME 5 //Be sure to change the icon animation at the same time or it'll look bad + /obj/machinery/porta_turret name = "turret" icon = 'icons/obj/turrets.dmi' @@ -364,6 +367,10 @@ var/list/targets = list() var/turretview = view(scan_range, base) for(var/A in turretview) + var/atom/AA = A + if(AA.invisibility>SEE_INVISIBLE_LIVING) + continue + if(check_anomalies)//if it's set to check for simple animals if(istype(A, /mob/living/simple_animal)) var/mob/living/simple_animal/SA = A @@ -418,7 +425,7 @@ raising = 1 if(cover) flick("popup", cover) - sleep(10) + sleep(POPUP_ANIM_TIME) raising = 0 if(cover) cover.icon_state = "openTurretCover" @@ -434,7 +441,7 @@ raising = 1 if(cover) flick("popdown", cover) - sleep(10) + sleep(POPDOWN_ANIM_TIME) raising = 0 if(cover) cover.icon_state = "turretCover" diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm index 57e6ee3f09..c65c0029ff 100644 --- a/code/game/machinery/recycler.dm +++ b/code/game/machinery/recycler.dm @@ -121,7 +121,7 @@ var/atom/movable/AM = i var/obj/item/bodypart/head/as_head = AM var/obj/item/device/mmi/as_mmi = AM - var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) + var/brain_holder = istype(AM, /obj/item/organ/brain) || (istype(as_head) && as_head.brain) || (istype(as_mmi) && as_mmi.brain) || istype(AM, /mob/living/brain) if(isliving(AM) || brain_holder) if(emagged) if(!brain_holder) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 7fc0f98b1c..e81774e147 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -211,13 +211,13 @@ uv = TRUE locked = TRUE update_icon() - if(occupant) + if(occupant) + var/mob/living/mob_occupant = occupant if(uv_super) - occupant.adjustFireLoss(rand(20, 36)) + mob_occupant.adjustFireLoss(rand(20, 36)) else - occupant.adjustFireLoss(rand(10, 16)) - if(iscarbon(occupant)) - occupant.emote("scream") + mob_occupant.adjustFireLoss(rand(10, 16)) + mob_occupant.emote("scream") addtimer(CALLBACK(src, .proc/cook), 50) else uv_cycles = initial(uv_cycles) @@ -368,14 +368,15 @@ else if(!helmet && !mask && !suit && !storage && !occupant) return else - if(occupant) - to_chat(occupant, "[src]'s confines grow warm, then hot, then scorching. You're being burned [!occupant.stat ? "alive" : "away"]!") + if(occupant) + var/mob/living/mob_occupant = occupant + to_chat(mob_occupant, "[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!") cook() . = TRUE if("dispense") if(!state_open) return - + var/static/list/valid_items = list("helmet", "suit", "mask", "storage") var/item_name = params["item"] if(item_name in valid_items) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 7d02e70671..fd40f7e273 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -56,6 +56,7 @@ var/dish_quants = list() //used by the snack machine's custom compartment to count dishes. var/obj/item/weapon/vending_refill/refill_canister = null //The type of refill canisters used by this machine. + var/refill_count = 3 //The number of canisters the vending machine uses /obj/machinery/vending/Initialize() ..() @@ -88,7 +89,9 @@ /obj/machinery/vending/cola = "Robust Softdrinks", /obj/machinery/vending/cigarette = "ShadyCigs Deluxe", /obj/machinery/vending/autodrobe = "AutoDrobe", - /obj/machinery/vending/clothing = "ClothesMate") + /obj/machinery/vending/clothing = "ClothesMate", + /obj/machinery/vending/medical = "NanoMed Plus", + /obj/machinery/vending/wallmed = "NanoMed") /obj/item/weapon/circuitboard/machine/vendor/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/weapon/screwdriver)) @@ -104,7 +107,7 @@ /obj/item/weapon/circuitboard/machine/vendor/proc/set_type(var/obj/machinery/vending/typepath) build_path = typepath name = "[names_paths[build_path]] Vendor (Machine Board)" - req_components = list(initial(typepath.refill_canister) = 3) + req_components = list(initial(typepath.refill_canister) = initial(typepath.refill_count)) /obj/item/weapon/circuitboard/machine/vendor/apply_default_parts(obj/machinery/M) for(var/typepath in names_paths) @@ -113,7 +116,6 @@ break ..() - /obj/machinery/vending/Destroy() qdel(wires) wires = null @@ -307,7 +309,10 @@ if(panel_open) attack_hand(user) return - else if(istype(W, /obj/item/weapon/coin) && premium.len > 0) + else if(istype(W, /obj/item/weapon/coin)) + if(!premium.len) + to_chat(user, "[src] doesn't have a coin slot.") + return if(!user.drop_item()) return W.loc = src @@ -732,8 +737,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C icon_state = "sustenance" products = list(/obj/item/weapon/reagent_containers/food/snacks/tofu = 24, /obj/item/weapon/reagent_containers/food/drinks/ice = 12, - /obj/item/weapon/reagent_containers/food/snacks/candy_corn = 6, - /obj/item/weapon/reagent_containers/glass/beaker/waterbottle = 10) + /obj/item/weapon/reagent_containers/food/snacks/candy_corn = 6, + /obj/item/weapon/reagent_containers/glass/beaker/waterbottle = 10) contraband = list(/obj/item/weapon/kitchen/knife = 6, /obj/item/weapon/reagent_containers/food/drinks/coffee = 12, /obj/item/weapon/tank/internals/emergency_oxygen = 6, @@ -750,7 +755,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C products = list(/obj/item/weapon/reagent_containers/food/drinks/soda_cans/cola = 10,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/space_mountain_wind = 10, /obj/item/weapon/reagent_containers/food/drinks/soda_cans/dr_gibb = 10,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/starkist = 10, /obj/item/weapon/reagent_containers/food/drinks/soda_cans/space_up = 10,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/pwr_game = 10, - /obj/item/weapon/reagent_containers/food/drinks/soda_cans/lemon_lime = 10,/obj/item/weapon/reagent_containers/glass/beaker/waterbottle = 10) + /obj/item/weapon/reagent_containers/food/drinks/soda_cans/lemon_lime = 10,/obj/item/weapon/reagent_containers/glass/beaker/waterbottle = 10) contraband = list(/obj/item/weapon/reagent_containers/food/drinks/soda_cans/thirteenloko = 6,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/shamblers = 6) premium = list(/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola = 1,/obj/item/weapon/reagent_containers/food/drinks/soda_cans/air = 1) refill_canister = /obj/item/weapon/vending_refill/cola @@ -874,6 +879,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C premium = list(/obj/item/weapon/storage/box/hug/medical = 1,/obj/item/weapon/reagent_containers/hypospray/medipen = 3, /obj/item/weapon/storage/belt/medical = 3, /obj/item/weapon/wrench/medical = 1) armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) resistance_flags = FIRE_PROOF + refill_canister = /obj/item/weapon/vending_refill/medical //This one's from bay12 /obj/machinery/vending/plasmaresearch @@ -896,6 +902,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C contraband = list(/obj/item/weapon/reagent_containers/pill/tox = 2,/obj/item/weapon/reagent_containers/pill/morphine = 2) armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) resistance_flags = FIRE_PROOF + refill_canister = /obj/item/weapon/vending_refill/medical + refill_count = 1 /obj/machinery/vending/security name = "\improper SecTech" @@ -1120,7 +1128,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C /obj/item/clothing/head/beanie=1, /obj/item/clothing/head/beanie/black=1, /obj/item/clothing/head/beanie/red=1, /obj/item/clothing/head/beanie/green=1, /obj/item/clothing/head/beanie/darkblue=1, /obj/item/clothing/head/beanie/purple=1, /obj/item/clothing/head/beanie/yellow=1, /obj/item/clothing/head/beanie/orange=1, /obj/item/clothing/head/beanie/cyan=1, /obj/item/clothing/head/beanie/christmas=1, /obj/item/clothing/head/beanie/striped=1, /obj/item/clothing/head/beanie/stripedred=1, /obj/item/clothing/head/beanie/stripedblue=1, /obj/item/clothing/head/beanie/stripedgreen=1, - /obj/item/clothing/suit/jacket/letterman_red=1) + /obj/item/clothing/suit/jacket/letterman_red=1, /obj/item/clothing/head/hunter=2) contraband = list(/obj/item/clothing/under/syndicate/tacticool=1,/obj/item/clothing/mask/balaclava=1,/obj/item/clothing/head/ushanka=1,/obj/item/clothing/under/soviet=1,/obj/item/weapon/storage/belt/fannypack/black=2,/obj/item/clothing/suit/jacket/letterman_syndie=1,/obj/item/clothing/under/jabroni=1, /obj/item/clothing/suit/vapeshirt=1, /obj/item/clothing/under/geisha=1) premium = list(/obj/item/clothing/under/suit_jacket/checkered=1,/obj/item/clothing/head/mailman=1,/obj/item/clothing/under/rank/mailman=1,/obj/item/clothing/suit/jacket/leather=1,/obj/item/clothing/suit/jacket/leather/overcoat=1,/obj/item/clothing/under/pants/mustangjeans=1,/obj/item/clothing/neck/necklace/dope=3,/obj/item/clothing/suit/jacket/letterman_nanotrasen=1) refill_canister = /obj/item/weapon/vending_refill/clothing diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index 7a9d01bb7f..bf90f0a569 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -107,7 +107,7 @@ icon_state = "mecha_ion" origin_tech = "materials=4;engineering=4;combat=6;magnets=6" energy_drain = 500 - projectile = /obj/item/projectile/energy/tesla_cannon + projectile = /obj/item/projectile/energy/tesla/cannon fire_sound = 'sound/magic/lightningbolt.ogg' @@ -337,8 +337,8 @@ /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/proj_init(var/obj/item/weapon/grenade/flashbang/F) var/turf/T = get_turf(src) - message_admins("[key_name(chassis.occupant, chassis.occupant.client)](?) fired a [src] in ([T.x],[T.y],[T.z] - JMP)",0,1) - log_game("[key_name(chassis.occupant)] fired a [src] ([T.x],[T.y],[T.z])") + message_admins("[ADMIN_LOOKUPFLW(chassis.occupant)] fired a [src] in [ADMIN_COORDJMP(T)]",0,1) + log_game("[key_name(chassis.occupant)] fired a [src] [COORD(T)]") addtimer(CALLBACK(F, /obj/item/weapon/grenade/flashbang.proc/prime), det_time) /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/flashbang/clusterbang //Because I am a heartless bastard -Sieve //Heartless? for making the poor man's honkblast? - Kaze diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm index 7727b4d9e9..a39c4fbe93 100644 --- a/code/game/objects/effects/decals/cleanable/humans.dm +++ b/code/game/objects/effects/decals/cleanable/humans.dm @@ -129,7 +129,7 @@ name = "footprints" icon = 'icons/effects/footprints.dmi' icon_state = "nothingwhatsoever" - desc = "where might they lead?" + desc = "WHOSE FOOTPRINTS ARE THESE?" random_icon_states = null var/entered_dirs = 0 var/exited_dirs = 0 diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index a34e30e689..9324c6edb7 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -74,7 +74,7 @@ /obj/effect/particle_effect/smoke/proc/spread_smoke() var/turf/t_loc = get_turf(src) if(!t_loc) - return + return var/list/newsmokes = list() for(var/turf/T in t_loc.GetAtmosAdjacentTurfs()) var/obj/effect/particle_effect/smoke/foundsmoke = locate() in T //Don't spread smoke where there's already smoke! diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 4194d9b76e..86d62eacea 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -94,7 +94,7 @@ name = "Head of Personnel" /obj/effect/landmark/start/librarian - name = "Librarian" + name = "Curator" /obj/effect/landmark/start/lawyer name = "Lawyer" diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index 3935b86c92..12225321d7 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -230,7 +230,15 @@ name = "blood sparks" icon_state = "bloodsparkles" -/obj/effect/overlay/temp/dir_setting/cult/phase +/obj/effect/overlay/temp/cult/blood // The traditional teleport + name = "blood jaunt" + duration = 12 + icon_state = "bloodin" + +/obj/effect/overlay/temp/cult/blood/out + icon_state = "bloodout" + +/obj/effect/overlay/temp/dir_setting/cult/phase // The veil shifter teleport name = "phase glow" duration = 7 icon_state = "cultin" @@ -323,11 +331,30 @@ /obj/effect/overlay/temp/ratvar/grille/broken icon_state = "ratvarbrokengrilleglow" +/obj/effect/overlay/temp/ratvar/mending_mantra + layer = ABOVE_MOB_LAYER + duration = 20 + alpha = 200 + icon_state = "mending_mantra" + light_range = 1.5 + light_color = "#1E8CE1" + +/obj/effect/overlay/temp/ratvar/mending_mantra/Initialize(mapload) + . = ..() + transform = matrix()*2 + var/matrix/M = transform + M.Turn(90) + animate(src, alpha = 20, time = duration, easing = BOUNCE_EASING, flags = ANIMATION_PARALLEL) + animate(src, transform = M, time = duration, flags = ANIMATION_PARALLEL) + /obj/effect/overlay/temp/ratvar/volt_hit name = "volt blast" layer = ABOVE_MOB_LAYER duration = 5 icon_state = "volt_hit" + light_range = 1.5 + light_power = 2 + light_color = LIGHT_COLOR_ORANGE var/mob/user var/damage = 20 @@ -336,7 +363,6 @@ damage *= multiplier duration = max(round(damage * 0.2), 1) . = ..() - set_light(1.5, 2, LIGHT_COLOR_ORANGE) /obj/effect/overlay/temp/ratvar/volt_hit/true/Initialize(mapload, caster, multiplier) . = ..() @@ -593,6 +619,18 @@ icon_state = "shieldsparkles" duration = 6 +/obj/effect/overlay/temp/heart + name = "heart" + icon = 'icons/mob/animal.dmi' + icon_state = "heart" + duration = 25 + +/obj/effect/overlay/temp/heart/Initialize(mapload) + . = ..() + pixel_x = rand(-4,4) + pixel_y = rand(-4,4) + + animate(src, pixel_y = pixel_y + 32, alpha = 0, time = 25) /obj/effect/overlay/palmtree_r name = "Palm tree" diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index e8c86390ea..2290456d78 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -63,7 +63,7 @@ return if (istype(M, /atom/movable)) if(ismegafauna(M)) - message_admins("[M] (FLW) has teleported through [src].") + message_admins("[M] [ADMIN_FLW(M)] has teleported through [src].") do_teleport(M, target, precision) ///You will appear adjacent to the beacon diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 07ffe61689..11079bf847 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -1,10 +1,15 @@ -/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0 ,silent = 0, smoke = 1) +/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range, silent = 0, smoke = 1) set waitfor = 0 src = null //so we don't abort once src is deleted epicenter = get_turf(epicenter) if(!epicenter) return + if(isnull(flame_range)) + flame_range = light_impact_range + if(isnull(flash_range)) + flash_range = devastation_range + // Archive the uncapped explosion for the doppler array var/orig_dev_range = devastation_range var/orig_heavy_range = heavy_impact_range diff --git a/code/game/objects/items/charter.dm b/code/game/objects/items/charter.dm index 0cf73fd9ff..36efee0092 100644 --- a/code/game/objects/items/charter.dm +++ b/code/game/objects/items/charter.dm @@ -7,6 +7,7 @@ desc = "An official document entrusting the governance of the station \ and surrounding space to the Captain. " var/used = FALSE + var/name_type = "station" var/unlimited_uses = FALSE var/ignores_timeout = FALSE @@ -33,10 +34,10 @@ /obj/item/station_charter/attack_self(mob/living/user) if(used) - to_chat(user, "This charter has already been used to name the station.") + to_chat(user, "The [name_type] has already been named.") return if(!ignores_timeout && (world.time-SSticker.round_start_time > STATION_RENAME_TIME_LIMIT)) //5 minutes - to_chat(user, "The crew has already settled into the shift. It probably wouldn't be good to rename the station right now.") + to_chat(user, "The crew has already settled into the shift. It probably wouldn't be good to rename the [name_type] right now.") return if(response_timer_id) to_chat(user, "You're still waiting for approval from your employers about your proposed name change, it'd be best to wait for now.") @@ -60,7 +61,7 @@ to_chat(user, "Your name has been sent to your employers for approval.") // Autoapproves after a certain time response_timer_id = addtimer(CALLBACK(src, .proc/rename_station, new_name, user.name, user.real_name, key_name(user)), approval_time, TIMER_STOPPABLE) - to_chat(GLOB.admins, "CUSTOM STATION RENAME:[key_name_admin(user)] (?) proposes to rename the station to [new_name] (will autoapprove in [approval_time / 10] seconds). [ADMIN_SMITE(user)] (REJECT) (RPLY)") + to_chat(GLOB.admins, "CUSTOM STATION RENAME:[ADMIN_LOOKUPFLW(user)] proposes to rename the [name_type] to [new_name] (will autoapprove in [approval_time / 10] seconds). [ADMIN_SMITE(user)] (REJECT) [ADMIN_CENTCOM_REPLY(user)]") /obj/item/station_charter/proc/reject_proposed(user) if(!user) @@ -94,4 +95,27 @@ unlimited_uses = TRUE ignores_timeout = TRUE + +/obj/item/weapon/station_charter/flag + name = "nanotrasen banner" + icon = 'icons/obj/items.dmi' + var/name_type = "planet" + icon_state = "banner" + item_state = "banner" + desc = "A cunning device used to claim ownership of planets." + w_class = 5 + force = 15 + +/obj/item/station_charter/flag/rename_station(designation, uname, ureal_name, ukey) + set_station_name(designation) + minor_announce("[ureal_name] has designated the planet as [station_name()]", "Captain's Banner", 0) + log_game("[ukey] has renamed the planet as [station_name()].") + name = "banner of [station_name()]" + desc = "The banner bears the official coat of arms of Nanotrasen, signifying that [station_name()] has been claimed by Captain [uname] in the name of the company." + SSblackbox.set_details("station_renames","[station_name()]") + if(!unlimited_uses) + used = TRUE + + + #undef STATION_RENAME_TIME_LIMIT diff --git a/code/game/objects/items/devices/PDA/PDA_types.dm b/code/game/objects/items/devices/PDA/PDA_types.dm index 4d46635847..6adc4efe22 100644 --- a/code/game/objects/items/devices/PDA/PDA_types.dm +++ b/code/game/objects/items/devices/PDA/PDA_types.dm @@ -161,11 +161,11 @@ icon_state = "pda-roboticist" default_cartridge = /obj/item/weapon/cartridge/roboticist -/obj/item/device/pda/librarian - name = "librarian PDA" +/obj/item/device/pda/curator + name = "curator PDA" icon_state = "pda-library" icon_alert = "pda-r-library" - default_cartridge = /obj/item/weapon/cartridge/librarian + default_cartridge = /obj/item/weapon/cartridge/curator desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a WGW-11 series e-reader." note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant!" silent = 1 //Quiet in the library! diff --git a/code/game/objects/items/devices/PDA/cart.dm b/code/game/objects/items/devices/PDA/cart.dm index 1fd52cf5d9..6f3491ac9c 100644 --- a/code/game/objects/items/devices/PDA/cart.dm +++ b/code/game/objects/items/devices/PDA/cart.dm @@ -108,7 +108,7 @@ access_mime = 1 var/mime_charges = 5 -/obj/item/weapon/cartridge/librarian +/obj/item/weapon/cartridge/curator name = "\improper Lib-Tweet cartridge" icon_state = "cart-s" access_newscaster = 1 diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index 6955872c27..9131c02240 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -37,9 +37,9 @@ return 1 -/obj/item/device/flashlight/attack(mob/living/carbon/human/M, mob/living/carbon/human/user) +/obj/item/device/flashlight/attack(mob/living/carbon/M, mob/living/carbon/human/user) add_fingerprint(user) - if(on && user.zone_selected == "eyes") + if(istype(M) && on && user.zone_selected in list("eyes", "mouth")) if((user.disabilities & CLUMSY || user.getBrainLoss() >= 60) && prob(50)) //too dumb to use flashlight properly return ..() //just hit them in the head @@ -48,28 +48,101 @@ to_chat(user, "You don't have the dexterity to do this!") return - var/mob/living/carbon/human/H = M //mob has protective eyewear - if(ishuman(M) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES))) - to_chat(user, "You're going to need to remove that [(H.head && H.head.flags_cover & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) ? "mask": "glasses"] first.") + if(!M.get_bodypart("head")) + to_chat(user, "[M] doesn't have a head!") return - if(M == user) //they're using it on themselves - if(M.flash_act(visual = 1)) - M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "You wave the light in front of your eyes! Trippy!") - else - M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "You wave the light in front of your eyes.") - else - user.visible_message("[user] directs [src] to [M]'s eyes.", \ - "You direct [src] to [M]'s eyes.") - var/mob/living/carbon/C = M - if(istype(C)) - if(C.stat == DEAD || (C.disabilities & BLIND)) //mob is dead or fully blind - to_chat(user, "[C] pupils don't react to the light!") - else if(C.dna.check_mutation(XRAY)) //mob has X-RAY vision - to_chat(user, "[C] pupils give an eerie glow!") - else //they're okay! - if(C.flash_act(visual = 1)) - to_chat(user, "[C]'s pupils narrow.") + switch(user.zone_selected) + if("eyes") + if((M.head && M.head.flags_cover & HEADCOVERSEYES) || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSEYES) || (M.glasses && M.glasses.flags_cover & GLASSESCOVERSEYES)) + to_chat(user, "You're going to need to remove that [(M.head && M.head.flags_cover & HEADCOVERSEYES) ? "helmet" : (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSEYES) ? "mask": "glasses"] first.") + return + + var/obj/item/organ/eyes/E = M.getorganslot("eye_sight") + if(!E) + to_chat(user, "[M] doesn't have any eyes!") + return + + if(M == user) //they're using it on themselves + if(M.flash_act(visual = 1)) + M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "You wave the light in front of your eyes! Trippy!") + else + M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "You wave the light in front of your eyes.") + else + user.visible_message("[user] directs [src] to [M]'s eyes.", \ + "You direct [src] to [M]'s eyes.") + if(M.stat == DEAD || (M.disabilities & BLIND) || !M.flash_act(visual = 1)) //mob is dead or fully blind + to_chat(user, "[M]'s pupils don't react to the light!") + else if(M.dna && M.dna.check_mutation(XRAY)) //mob has X-RAY vision + to_chat(user, "[M]'s pupils give an eerie glow!") + else //they're okay! + to_chat(user, "[M]'s pupils narrow.") + + if("mouth") + + if((M.head && M.head.flags_cover & HEADCOVERSMOUTH) || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH)) + to_chat(user, "You're going to need to remove that [(M.head && M.head.flags_cover & HEADCOVERSMOUTH) ? "helmet" : "mask"] first.") + return + + var/their = M.p_their() + + var/list/mouth_organs = new + for(var/obj/item/organ/O in M.internal_organs) + if(O.zone == "mouth") + mouth_organs.Add(O) + var/organ_list = "" + var/organ_count = LAZYLEN(mouth_organs) + if(organ_count) + for(var/I in 1 to organ_count) + if(I > 1) + if(I == mouth_organs.len) + organ_list += ", and " + else + organ_list += ", " + var/obj/item/organ/O = mouth_organs[I] + organ_list += (O.gender == "plural" ? O.name : "\an [O.name]") + + var/pill_count = 0 + for(var/datum/action/item_action/hands_free/activate_pill/AP in M.actions) + pill_count++ + + if(M == user) + var/can_use_mirror = FALSE + if(isturf(user.loc)) + var/obj/structure/mirror/mirror = locate(/obj/structure/mirror, user.loc) + if(mirror) + switch(user.dir) + if(NORTH) + can_use_mirror = mirror.pixel_y > 0 + if(SOUTH) + can_use_mirror = mirror.pixel_y < 0 + if(EAST) + can_use_mirror = mirror.pixel_x > 0 + if(WEST) + can_use_mirror = mirror.pixel_x < 0 + + M.visible_message("[M] directs [src] to [their] mouth.", \ + "You point [src] into your mouth.") + if(!can_use_mirror) + to_chat(user, "You can't see anything without a mirror.") + return + if(organ_count) + to_chat(user, "Inside your mouth [organ_count > 1 ? "are" : "is"] [organ_list].") + else + to_chat(user, "There's nothing inside your mouth.") + if(pill_count) + to_chat(user, "You have [pill_count] implanted pill[pill_count > 1 ? "s" : ""].") + + else + user.visible_message("[user] directs [src] to [M]'s mouth.",\ + "You direct [src] to [M]'s mouth.") + if(organ_count) + to_chat(user, "Inside [their] mouth [organ_count > 1 ? "are" : "is"] [organ_list].") + else + to_chat(user, "[M] doesn't have any organs in [their] mouth.") + if(pill_count) + to_chat(user, "[M] has [pill_count] pill[pill_count > 1 ? "s" : ""] implanted in [their] teeth.") + else return ..() @@ -280,7 +353,7 @@ return TRUE /obj/item/device/flashlight/emp/attack(mob/living/M, mob/living/user) - if(on && user.zone_selected == "eyes") // call original attack proc only if aiming at the eyes + if(on && user.zone_selected in list("eyes", "mouth")) // call original attack when examining organs ..() return diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm index 00e221918c..e1cf6bb8c8 100644 --- a/code/game/objects/items/devices/gps.dm +++ b/code/game/objects/items/devices/gps.dm @@ -7,10 +7,14 @@ GLOBAL_LIST_EMPTY(GPS_list) w_class = WEIGHT_CLASS_SMALL slot_flags = SLOT_BELT origin_tech = "materials=2;magnets=1;bluespace=2" + unique_rename = TRUE var/gpstag = "COM0" var/emped = FALSE var/turf/locked_location var/tracking = TRUE + var/updating = TRUE //Automatic updating of GPS list. Can be set to manual by user. + var/global_mode = TRUE //If disabled, only GPS signals of the same Z level are shown + /obj/item/device/gps/Initialize() ..() @@ -27,6 +31,7 @@ GLOBAL_LIST_EMPTY(GPS_list) cut_overlay("working") add_overlay("emp") addtimer(CALLBACK(src, .proc/reboot), 300, TIMER_OVERRIDE) //if a new EMP happens, remove the old timer so it doesn't reactivate early + SStgui.close_uis(src) //Close the UI control if it is open. /obj/item/device/gps/proc/reboot() emped = FALSE @@ -34,6 +39,9 @@ GLOBAL_LIST_EMPTY(GPS_list) add_overlay("working") /obj/item/device/gps/AltClick(mob/user) + toggletracking(user) + +/obj/item/device/gps/proc/toggletracking(mob/user) if(!user.canUseTopic(src, be_close=TRUE)) return //user not valid to use gps if(emped) @@ -48,45 +56,89 @@ GLOBAL_LIST_EMPTY(GPS_list) to_chat(user, "[src] is now tracking, and visible to other GPS devices.") tracking = TRUE -/obj/item/device/gps/attack_self(mob/user) - if(!tracking) - to_chat(user, "[src] is turned off. Use alt+click to toggle it back on.") - return - var/obj/item/device/gps/t = "" - var/gps_window_height = 110 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show +/obj/item/device/gps/ui_interact(mob/user, ui_key = "gps", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state. if(emped) - t += "ERROR" - else - t += "
Set Tag " - t += "
Tag: [gpstag]" - if(locked_location && locked_location.loc) - t += "
Bluespace coordinates saved: [locked_location.loc]" - gps_window_height += 20 - - for(var/obj/item/device/gps/G in GLOB.GPS_list) - var/turf/pos = get_turf(G) - var/area/gps_area = get_area(G) - var/tracked_gpstag = G.gpstag - if(G.emped == 1) - t += "
[tracked_gpstag]: ERROR" - else if(G.tracking) - t += "
[tracked_gpstag]: [format_text(gps_area.name)] ([pos.x], [pos.y], [pos.z])" - else - continue - var/datum/browser/popup = new(user, "GPS", name, 360, min(gps_window_height, 800)) - popup.set_content(t) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() + to_chat(user, "[src] fizzles weakly.") + return + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + if(!ui) + var/gps_window_height = 300 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show + ui = new(user, src, ui_key, "gps", "Global Positioning System", 600, gps_window_height, master_ui, state) //width, height + ui.open() + + ui.set_autoupdate(state = updating) + + +/obj/item/device/gps/ui_data(mob/user) + var/list/data = list() + data["power"] = tracking + data["tag"] = gpstag + data["updating"] = updating + data["globalmode"] = global_mode + if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed + return data + + var/turf/curr = get_turf(src) + data["current"] = "[get_area_name(curr)] ([curr.x], [curr.y], [curr.z])" + + var/list/signals = list() + data["signals"] = list() + + for(var/gps in GLOB.GPS_list) + var/obj/item/device/gps/G = gps + if(G.emped || !G.tracking || G == src) + continue + var/turf/pos = get_turf(G) + if(!global_mode && pos.z != curr.z) + continue + var/area/gps_area = get_area_name(G) + var/list/signal = list() + signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS + signal["area"] = format_text(gps_area) + signal["coord"] = "[pos.x], [pos.y], [pos.z]" + if(pos.z == curr.z) //Distance/Direction calculations for same z-level only + signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs + signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision. + var/direction = uppertext(dir2text(get_dir(curr, pos))) //Direction text (East, etc). Not as precise, but still helpful. + if(!direction) + direction = "CENTER" + signal["degrees"] = "N/A" + signal["direction"] = direction + + signals += list(signal) //Add this signal to the list of signals + data["signals"] = signals + return data + + + +/obj/item/device/gps/ui_act(action, params) + if(..()) + return + switch(action) + if("rename") + var/a = input("Please enter desired tag.", name, gpstag) as text + a = uppertext(copytext(sanitize(a), 1, 5)) + gpstag = a + name = "global positioning system ([gpstag])" + . = TRUE + if("power") + toggletracking(usr) + . = TRUE + if("updating") + updating = !updating + . = TRUE + if("globalmode") + global_mode = !global_mode + . = TRUE /obj/item/device/gps/Topic(href, href_list) ..() if(href_list["tag"] ) var/a = input("Please enter desired tag.", name, gpstag) as text - a = uppertext(copytext(sanitize(a), 1, 5)) + a = copytext(sanitize(a), 1, 20) if(in_range(src, usr)) gpstag = a - name = "global positioning system ([gpstag])" attack_self(usr) /obj/item/device/gps/science @@ -157,4 +209,4 @@ GLOBAL_LIST_EMPTY(GPS_list) clear() tagged = null STOP_PROCESSING(SSfastprocess, src) - . = ..() + . = ..() \ No newline at end of file diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 18658ceeb3..f7d11d2f47 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -95,8 +95,8 @@ "[user] activates \the [src]!", \ "You activate \the [src].", "You hear a click.") - message_admins("Power sink activated by [key_name_admin(user)](?) (FLW) at ([x],[y],[z] - JMP)") - log_game("Power sink activated by [key_name(user)] at ([x],[y],[z])") + message_admins("Power sink activated by [ADMIN_LOOKUPFLW(user)] at [ADMIN_COORDJMP(src)]") + log_game("Power sink activated by [key_name(user)] at [COORD(src)]") set_mode(OPERATING) if(OPERATING) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 1f2f86e42a..de0692d8e7 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -296,6 +296,7 @@ // --- Cold, emotionless machines. --- else if(isobj(M)) jobname = "Machine" + voice = capitalize(voice) // --- Unidentifiable mob --- else diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 257418eaa7..8d37640b6d 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -178,21 +178,21 @@ var/log_attacher = "" if(attacher) - log_attacher = "(?) (FLW)" + log_attacher = "[ADMIN_QUE(attacher)] [ADMIN_FLW(attacher)]" var/mob/mob = get_mob_by_key(src.fingerprintslast) var/last_touch_info = "" if(mob) - last_touch_info = "(?) (FLW)" + last_touch_info = "[ADMIN_QUE(mob)] [ADMIN_FLW(mob)]" var/log_str3 = " Last touched by: [key_name_admin(mob)]" - var/bomb_message = "[log_str1] [A.name] [log_str2][log_attacher] [log_str3][last_touch_info]" + var/bomb_message = "[log_str1] [A.name][ADMIN_JMP(bombturf)] [log_str2][log_attacher] [log_str3][last_touch_info]" GLOB.bombers += bomb_message message_admins(bomb_message, 0, 1) - log_game("[log_str1] [A.name]([A.x],[A.y],[A.z]) [log_str2] [log_str3]") + log_game("[log_str1] [A.name][COORD(bombturf)] [log_str2] [log_str3]") merge_gases() spawn(20) // In case one tank bursts for (var/i=0,i<5,i++) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 2aee5acdd9..29463b5a5c 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -237,6 +237,7 @@ /obj/item/borg/upgrade/selfrepair/proc/check_dropped() if(loc != cyborg) toggle_action.Remove(cyborg) + QDEL_NULL(toggle_action) cyborg = null deactivate() @@ -399,4 +400,4 @@ return R.make_shell(src) - return TRUE \ No newline at end of file + return TRUE diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index 611ef76eb4..436bc5ff59 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -29,6 +29,7 @@ Mineral Sheets GLOBAL_LIST_INIT(sandstone_recipes, list ( \ new/datum/stack_recipe("pile of dirt", /obj/machinery/hydroponics/soil, 3, time = 10, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("sandstone door", /obj/structure/mineral_door/sandstone, 10, one_per_turf = 1, on_floor = 1), \ + new/datum/stack_recipe("aesthetic volcanic floor tile", /obj/item/stack/tile/basalt, 2, 2, 4, 20), \ new/datum/stack_recipe("Assistant Statue", /obj/structure/statue/sandstone/assistant, 5, one_per_turf = 1, on_floor = 1), \ new/datum/stack_recipe("Breakdown into sand", /obj/item/weapon/ore/glass, 1, one_per_turf = 0, on_floor = 1), \ /* new/datum/stack_recipe("sandstone wall", ???), \ @@ -154,8 +155,9 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \ /obj/item/stack/sheet/mineral/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite - message_admins("Plasma sheets ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("Plasma sheets ignited by [key_name(user)] in ([x],[y],[z])") + var/turf/T = get_turf(src) + message_admins("Plasma sheets ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1) + log_game("Plasma sheets ignited by [key_name(user)] in [COORD(T)]") fire_act() else return ..() @@ -334,12 +336,20 @@ GLOBAL_LIST_INIT(snow_recipes, list ( \ /* * Adamantine */ +GLOBAL_LIST_INIT(adamantine_recipes, list( + new /datum/stack_recipe("artificial golem shell", /obj/item/golem_shell/artificial, req_amount=1, res_amount=1), + )) + /obj/item/stack/sheet/mineral/adamantine name = "adamantine" icon_state = "sheet-adamantine" singular_name = "adamantine sheet" origin_tech = "materials=4" +/obj/item/stack/sheet/mineral/adamantine/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.adamantine_recipes + ..() + /* * Mythril */ diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index a007dd4545..4700f81d82 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -328,7 +328,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \ /obj/item/stack/tile/brass/Initialize(mapload, new_amount, merge = TRUE) recipes = GLOB.brass_recipes - ..() + . = ..() pixel_x = 0 pixel_y = 0 diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index f2432cee3d..ef123030f5 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -13,8 +13,8 @@ var/turf_type = null var/mineralType = null -/obj/item/stack/tile/New(loc, amount) - ..() +/obj/item/stack/tile/Initialize(mapload, amount) + . = ..() pixel_x = rand(-3, 3) pixel_y = rand(-3, 3) //randomize a little @@ -88,6 +88,14 @@ turf_type = /turf/open/floor/wood resistance_flags = FLAMMABLE +//Basalt +/obj/item/stack/tile/basalt + name = "basalt tile" + singular_name = "basalt floor tile" + desc = "Artificially made ashy soil themed on a hostile enviroment." + icon_state = "tile_basalt" + origin_tech = "materials=1" + turf_type = /turf/open/floor/grass/fakebasalt //Carpets /obj/item/stack/tile/carpet diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index f332422578..0979a65981 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -1218,9 +1218,9 @@ icon_state = "lawyer" toysay = "My client is a dirty traitor!" -/obj/item/toy/figure/librarian - name = "Librarian action figure" - icon_state = "librarian" +/obj/item/toy/figure/curator + name = "Curator action figure" + icon_state = "curator" toysay = "One day while..." /obj/item/toy/figure/md diff --git a/code/game/objects/items/weapons/clown.dm b/code/game/objects/items/weapons/clown.dm new file mode 100644 index 0000000000..a01a0f18b6 --- /dev/null +++ b/code/game/objects/items/weapons/clown.dm @@ -0,0 +1,46 @@ + +/obj/item/weapon/pie_cannon + name = "pie cannon" + desc = "Load cream pie for optimal results" + force = 10 + icon_state = "piecannon" + item_state = "powerfist" + var/obj/item/weapon/reagent_containers/food/snacks/pie/loaded = null + +/obj/item/weapon/pie_cannon/attackby(obj/item/I, mob/living/L) + if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/pie)) + if(!loaded) + L.transferItemToLoc(I, src) + loaded = I + to_chat(L, "You load the [I] into the [src]!") + return + return ..() + +/obj/item/weapon/pie_cannon/afterattack(atom/target, mob/living/user, flag, params) + if(!loaded) + return ..() + var/obj/item/projectile/pie/launched = new /obj/item/projectile/pie(src) + launched.P = loaded + loaded.forceMove(launched) + launched.appearance = loaded.appearance + loaded = null + launched.preparePixelProjectile(target, get_turf(target), user, params, 0) + launched.forceMove(get_turf(src)) + launched.fire() + user.visible_message("[user] fires the [src] at [target]!") + +/obj/item/projectile/pie + name = "pie" + desc = "Think fast!" + var/obj/item/weapon/reagent_containers/food/snacks/pie/P = null + +/obj/item/projectile/pie/on_hit(atom/A) + . = ..() + if(P) + A.visible_message("[P] smashes into [A] at high velocity!") + P.forceMove(get_turf(A)) + P.throw_impact(A) + if(ismovableatom(A)) + var/atom/movable/AM = A + if(!AM.anchored) + AM.throw_at(get_edge_target_turf(get_dir(src, AM), 3, 2)) diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 756512dff1..2ae93fa774 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -81,7 +81,7 @@ to_chat(user, "You start planting the bomb...") - if(do_after(user, 50, target = AM)) + if(do_after(user, 50, target = AM)) if(!user.temporarilyRemoveItemFromInventory(src)) return src.target = AM diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index ac53eb25ff..aab6c9db48 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -158,7 +158,7 @@ if(lit) START_PROCESSING(SSobj, src) if(!warned_admins) - message_admins("[key_name_admin(usr)]? (FLW) has lit a flamethrower.") + message_admins("[ADMIN_LOOKUPFLW(usr)] has lit a flamethrower.") warned_admins = 1 if(href_list["amount"]) throw_amount = throw_amount + text2num(href_list["amount"]) diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 1ef83f3ac1..42362c1e55 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -36,8 +36,8 @@ else if(clown_check(user)) var/turf/bombturf = get_turf(src) var/area/A = get_area(bombturf) - message_admins("[key_name_admin(usr)]? (FLW) has primed a [name] for detonation at [A.name] (JMP).") - log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).") + message_admins("[ADMIN_LOOKUPFLW(usr)] has primed a [name] for detonation at [A.name][ADMIN_JMP(bombturf)].") + log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].") to_chat(user, "You prime the [name]! [det_time / 10] second\s!") playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1) active = 1 @@ -177,12 +177,12 @@ var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast) var/turf/T = get_turf(src) var/area/A = get_area(T) - message_admins("grenade primed by an assembly, attached by [key_name_admin(M)](?) (FLW) and last touched by [key_name_admin(last)](?) (FLW) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).") - log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])") + message_admins("grenade primed by an assembly, attached by [ADMIN_LOOKUPFLW(M)] and last touched by [ADMIN_LOOKUPFLW(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] [ADMIN_JMP(T)].") + log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] [COORD(T)]") var/turf/DT = get_turf(src) var/area/DA = get_area(DT) - log_game("A grenade detonated at [DA.name] ([DT.x], [DT.y], [DT.z])") + log_game("A grenade detonated at [DA.name] [COORD(DT)]") update_mob() diff --git a/code/game/objects/items/weapons/grenades/plastic.dm b/code/game/objects/items/weapons/grenades/plastic.dm index aedf0954c2..09b9d6aa33 100644 --- a/code/game/objects/items/weapons/grenades/plastic.dm +++ b/code/game/objects/items/weapons/grenades/plastic.dm @@ -96,7 +96,7 @@ to_chat(user, "You start planting the [src]. The timer is set to [det_time]...") - if(do_after(user, 50, target = AM)) + if(do_after(user, 30, target = AM)) if(!user.temporarilyRemoveItemFromInventory(src)) return src.target = AM @@ -119,8 +119,8 @@ qdel(src) //How? /obj/item/weapon/grenade/plastic/suicide_act(mob/user) - message_admins("[key_name_admin(user)](?) (FLW) suicided with [src] at ([user.x],[user.y],[user.z] - JMP)",0,1) - message_admins("[key_name(user)] suicided with [src] at ([user.x],[user.y],[user.z])") + message_admins("[ADMIN_LOOKUPFLW(user)] suicided with [src] at [ADMIN_COORDJMP(user)]",0,1) + log_game("[key_name(user)] suicided with [src] at [COORD(user)]") user.visible_message("[user] activates the [src] and holds it above [user.p_their()] head! It looks like [user.p_theyre()] going out with a bang!") var/message_say = "FOR NO RAISIN!" if(user.mind) @@ -165,4 +165,4 @@ icon_state = "plasticx40" item_state = "plasticx4" directional = TRUE - boom_sizes = list(0, 2, 5) \ No newline at end of file + boom_sizes = list(0, 2, 5) diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade.dm b/code/game/objects/items/weapons/grenades/spawnergrenade.dm index 2d5c4707a6..86c01d745e 100644 --- a/code/game/objects/items/weapons/grenades/spawnergrenade.dm +++ b/code/game/objects/items/weapons/grenades/spawnergrenade.dm @@ -1,5 +1,5 @@ /obj/item/weapon/grenade/spawnergrenade - desc = "It will unleash unleash an unspecified anomaly into the vicinity." + desc = "It will unleash an unspecified anomaly into the vicinity." name = "delivery grenade" icon = 'icons/obj/grenade.dmi' icon_state = "delivery" diff --git a/code/game/objects/items/weapons/his_grace.dm b/code/game/objects/items/weapons/his_grace.dm index be269d583d..d8e7dabdf9 100644 --- a/code/game/objects/items/weapons/his_grace.dm +++ b/code/game/objects/items/weapons/his_grace.dm @@ -41,7 +41,7 @@ ..() /obj/item/weapon/his_grace/CtrlClick(mob/user) //you can't pull his grace - attack_hand(user) + return /obj/item/weapon/his_grace/examine(mob/user) ..() diff --git a/code/game/objects/items/weapons/holy_weapons.dm b/code/game/objects/items/weapons/holy_weapons.dm index aa720f1979..4b5acd949d 100644 --- a/code/game/objects/items/weapons/holy_weapons.dm +++ b/code/game/objects/items/weapons/holy_weapons.dm @@ -214,7 +214,7 @@ possessed = TRUE - var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE) + var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the spirit of [user.real_name]'s blade?", ROLE_PAI, null, FALSE, 100, POLL_IGNORE_POSSESSED_BLADE) var/mob/dead/observer/theghost = null if(LAZYLEN(candidates)) diff --git a/code/game/objects/items/weapons/implants/implant_explosive.dm b/code/game/objects/items/weapons/implants/implant_explosive.dm index 369effbe7c..009aae3b54 100644 --- a/code/game/objects/items/weapons/implants/implant_explosive.dm +++ b/code/game/objects/items/weapons/implants/implant_explosive.dm @@ -44,7 +44,7 @@ active = TRUE var/turf/boomturf = get_turf(imp_in) var/area/A = get_area(boomturf) - message_admins("[key_name_admin(imp_in)]? (FLW) has activated their [name] at [A.name] (JMP).") + message_admins("[ADMIN_LOOKUPFLW(imp_in)] has activated their [name] at [A.name] [ADMIN_JMP(boomturf)].") //If the delay is short, just blow up already jeez if(delay <= 7) explosion(src,heavy,medium,weak,weak, flame_range = weak) diff --git a/code/game/objects/items/weapons/implants/implantchair.dm b/code/game/objects/items/weapons/implants/implantchair.dm index 6f1a43a93a..a3b72d55bd 100644 --- a/code/game/objects/items/weapons/implants/implantchair.dm +++ b/code/game/objects/items/weapons/implants/implantchair.dm @@ -41,9 +41,10 @@ data["open"] = state_open data["occupant"] = list() - if(occupant) - data["occupant"]["name"] = occupant.name - data["occupant"]["stat"] = occupant.stat + if(occupant) + var/mob/living/mob_occupant = occupant + data["occupant"]["name"] = mob_occupant.name + data["occupant"]["stat"] = mob_occupant.stat data["special_name"] = special ? special_name : null data["ready_implants"] = ready_implants diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm index 56c53e9cd8..fd8c5483a2 100644 --- a/code/game/objects/items/weapons/melee/energy.dm +++ b/code/game/objects/items/weapons/melee/energy.dm @@ -16,7 +16,7 @@ var/brightness_on = 3 /obj/item/weapon/melee/energy/Initialize() - ..() + . = ..() if(LAZYLEN(possible_colors)) item_color = pick(possible_colors) switch(item_color)//Only run this check if the color was picked randomly, so that colors can be manually set for non-random colored energy weapons. @@ -183,8 +183,8 @@ light_color = "#40ceff" possible_colors = null -/obj/item/weapon/melee/energy/sword/cyborg/saw/New() - ..() +/obj/item/weapon/melee/energy/sword/cyborg/saw/Initialize() + . = ..() icon_state = "esaw_0" item_color = null @@ -207,19 +207,9 @@ /obj/item/weapon/melee/energy/sword/saber/attackby(obj/item/weapon/W, mob/living/user, params) - if(istype(W, /obj/item/weapon/melee/energy/sword/saber)) - to_chat(user, "You attach the ends of the two energy swords, making a single double-bladed weapon! You're cool.") - var/obj/item/weapon/melee/energy/sword/saber/other_esword = W - var/obj/item/weapon/twohanded/dualsaber/newSaber = new(user.loc) - if(hacked || other_esword.hacked) - newSaber.hacked = TRUE - newSaber.item_color = "rainbow" - qdel(W) - qdel(src) - user.put_in_hands(newSaber) - else if(istype(W, /obj/item/device/multitool)) - if(hacked == 0) - hacked = 1 + if(istype(W, /obj/item/device/multitool)) + if(!hacked) + hacked = TRUE item_color = "rainbow" to_chat(user, "RNBW_ENGAGE") @@ -253,14 +243,12 @@ sharpness = IS_SHARP //Most of the other special functions are handled in their own files. aka special snowflake code so kewl -/obj/item/weapon/melee/energy/blade/New() +/obj/item/weapon/melee/energy/blade/Initialize() + . = ..() spark_system = new /datum/effect_system/spark_spread() spark_system.set_up(5, 0, src) spark_system.attach(src) -/obj/item/weapon/melee/energy/blade/dropped() - ..() - /obj/item/weapon/melee/energy/blade/attack_self(mob/user) return diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm index 61e68934b9..86c517aa99 100644 --- a/code/game/objects/items/weapons/pneumaticCannon.dm +++ b/code/game/objects/items/weapons/pneumaticCannon.dm @@ -1,3 +1,7 @@ + +#define PCANNON_FIREALL 1 +#define PCANNON_FILO 2 +#define PCANNON_FIFO 3 /obj/item/weapon/pneumatic_cannon name = "pneumatic cannon" desc = "A gas-powered cannon that can fire any object loaded into it." @@ -16,7 +20,15 @@ var/gasPerThrow = 3 //How much gas is drawn from a tank's pressure to fire var/list/loadedItems = list() //The items loaded into the cannon that will be fired out var/pressureSetting = 1 //How powerful the cannon is - higher pressure = more gas but more powerful throws + var/checktank = TRUE + var/range_multiplier = 1 + var/throw_amount = 20 //How many items to throw per fire + var/fire_mode = PCANNON_FIREALL + var/automatic = FALSE + var/clumsyCheck = TRUE +/obj/item/weapon/pneumatic_cannon/CanItemAutoclick() + return automatic /obj/item/weapon/pneumatic_cannon/examine(mob/user) ..() @@ -30,6 +42,8 @@ /obj/item/weapon/pneumatic_cannon/attackby(obj/item/weapon/W, mob/user, params) + if(user.a_intent == INTENT_HARM) + return ..() if(istype(W, /obj/item/weapon/tank/internals)) if(!tank) var/obj/item/weapon/tank/internals/IT = W @@ -55,19 +69,31 @@ to_chat(user, "\The [src] can't hold any more items!") else if(istype(W, /obj/item)) var/obj/item/IW = W - if((loadedWeightClass + IW.w_class) > maxWeightClass) - to_chat(user, "\The [IW] won't fit into \the [src]!") - return - if(IW.w_class > src.w_class) - to_chat(user, "\The [IW] is too large to fit into \the [src]!") - return - if(!user.transferItemToLoc(W, src)) - return - to_chat(user, "You load \the [IW] into \the [src].") - loadedItems.Add(IW) - loadedWeightClass += IW.w_class + load_item(IW, user) +/obj/item/weapon/pneumatic_cannon/proc/can_load_item(obj/item/I, mob/user) + if((loadedWeightClass + I.w_class) > maxWeightClass) //Only make messages if there's a user + if(user) + to_chat(user, "\The [I] won't fit into \the [src]!") + return FALSE + if(I.w_class > w_class) + if(user) + to_chat(user, "\The [I] is too large to fit into \the [src]!") + return FALSE + return TRUE +/obj/item/weapon/pneumatic_cannon/proc/load_item(obj/item/I, mob/user) + if(!can_load_item(I, user)) + return FALSE + if(user) //Only use transfer proc if there's a user, otherwise just set loc. + if(!user.transferItemToLoc(I, src)) + return FALSE + to_chat(user, "You load \the [I] into \the [src].") + else + I.forceMove(src) + loadedItems += I + loadedWeightClass += I.w_class + return TRUE /obj/item/weapon/pneumatic_cannon/afterattack(atom/target, mob/living/carbon/human/user, flag, params) if(flag && user.a_intent == INTENT_HARM) //melee attack @@ -76,7 +102,6 @@ return Fire(user, target) - /obj/item/weapon/pneumatic_cannon/proc/Fire(mob/living/carbon/human/user, var/atom/target) if(!istype(user) && !target) return @@ -90,13 +115,13 @@ if(!loadedItems || !loadedWeightClass) to_chat(user, "\The [src] has nothing loaded.") return - if(!tank) + if(!tank && checktank) to_chat(user, "\The [src] can't fire without a source of gas.") return if(tank && !tank.air_contents.remove(gasPerThrow * pressureSetting)) to_chat(user, "\The [src] lets out a weak hiss and doesn't react!") return - if(user.disabilities & CLUMSY && prob(75)) + if(user.disabilities & CLUMSY && prob(75) && clumsyCheck) user.visible_message("[user] loses their grip on [src], causing it to go off!", "[src] slips out of your hands and goes off!") user.drop_item() if(prob(10)) @@ -109,17 +134,48 @@ user.visible_message("[user] fires \the [src]!", \ "You fire \the [src]!") add_logs(user, target, "fired at", src) + var/turf/T = get_target(target, get_turf(src)) playsound(src.loc, 'sound/weapons/sonic_jackhammer.ogg', 50, 1) - for(var/obj/item/ITD in loadedItems) //Item To Discharge - loadedItems.Remove(ITD) - loadedWeightClass -= ITD.w_class - ITD.throw_speed = pressureSetting * 2 - ITD.loc = get_turf(src) - ITD.throw_at(target, pressureSetting * 5, pressureSetting * 2,user) + fire_items(T, user) if(pressureSetting >= 3 && user) user.visible_message("[user] is thrown down by the force of the cannon!", "[src] slams into your shoulder, knocking you down!") user.Weaken(3) +/obj/item/weapon/pneumatic_cannon/proc/fire_items(turf/target, mob/user) + if(fire_mode == PCANNON_FIREALL) + for(var/obj/item/ITD in loadedItems) //Item To Discharge + if(!throw_item(target, ITD, user)) + break + else + for(var/i in 1 to throw_amount) + if(!loadedItems.len) + break + var/obj/item/I + if(fire_mode == PCANNON_FILO) + I = loadedItems[loadedItems.len] + else + I = loadedItems[1] + if(!throw_item(target, I, user)) + break + +/obj/item/weapon/pneumatic_cannon/proc/throw_item(turf/target, obj/item/I, mob/user) + if(!istype(I)) + return FALSE + loadedItems -= I + loadedWeightClass -= I.w_class + I.forceMove(get_turf(src)) + I.throw_at(target, pressureSetting * 10 * range_multiplier, pressureSetting * 2, user) + return TRUE + +/obj/item/weapon/pneumatic_cannon/proc/get_target(turf/target, turf/starting) + if(range_multiplier == 1) + return target + var/x_o = (target.x - starting.x) + var/y_o = (target.y - starting.y) + var/new_x = Clamp((starting.x + (x_o * range_multiplier)), 0, world.maxx) + var/new_y = Clamp((starting.y + (y_o * range_multiplier)), 0, world.maxy) + var/turf/newtarget = locate(new_x, new_y, starting.z) + return newtarget /obj/item/weapon/pneumatic_cannon/ghetto //Obtainable by improvised methods; more gas per use, less capacity, but smaller name = "improvised pneumatic cannon" @@ -164,3 +220,35 @@ return add_overlay(tank.icon_state) src.update_icon() + +/obj/item/weapon/pneumatic_cannon/proc/fill_with_type(type, amount) + if(!ispath(type, /obj/item)) + return FALSE + var/loaded = 0 + for(var/i in 1 to amount) + var/obj/item/I = new type + if(!load_item(I, null)) + qdel(I) + return loaded + loaded++ + CHECK_TICK + return loaded + +/obj/item/weapon/pneumatic_cannon/pie + name = "pie cannon" + desc = "Load cream pie for optimal results" + force = 10 + icon_state = "piecannon" + gasPerThrow = 0 + checktank = FALSE + range_multiplier = 3 + fire_mode = PCANNON_FIFO + throw_amount = 1 + maxWeightClass = 100 //50 pies. :^) + clumsyCheck = FALSE + +/obj/item/weapon/pneumatic_cannon/pie/can_load_item(obj/item/I, mob/user) + if(istype(I, /obj/item/weapon/reagent_containers/food/snacks/pie)) + return ..() + to_chat(user, "[src] only accepts pies!") + return FALSE diff --git a/code/game/objects/items/weapons/storage/dakis.dm b/code/game/objects/items/weapons/storage/dakis.dm new file mode 100644 index 0000000000..a238304cac --- /dev/null +++ b/code/game/objects/items/weapons/storage/dakis.dm @@ -0,0 +1,48 @@ +////////////////////////////////// +//dakimakuras +////////////////////////////////// + +/obj/item/weapon/storage/daki + name = "dakimakura" + desc = "A large pillow depicting a girl in a compromising position. Featuring as many dimensions as you." + icon = 'icons/obj/daki.dmi' + icon_state = "daki_base" + slot_flags = SLOT_BACK + storage_slots = 3 + w_class = 4 + max_w_class = 3 + max_combined_w_class = 21 + var/cooldowntime = 20 + var/static/list/dakimakura_options = list("Callie","Casca","Chaika","Elisabeth","Foxy Grandpa","Haruko","Holo","Ian","Jolyne","Kurisu","Marie","Mugi","Nar'Sie","Patchouli","Plutia","Rei","Reisen","Naga","Squid","Squigly","Tomoko","Toriel","Umaru","Yaranaika","Yoko") //Kurisu is the ideal girl." - Me, Logos. + +/obj/item/weapon/storage/daki/attack_self(mob/living/user) + var/body_choice + var/custom_name + + if(icon_state == "daki_base") + body_choice = input("Pick a body.") in dakimakura_options + icon_state = "daki_[body_choice]" + custom_name = stripped_input(user, "What's her name?") + if(length(custom_name) > MAX_NAME_LEN) + to_chat(user,"Name is too long!") + return FALSE + if(custom_name) + name = custom_name + desc = "A large pillow depicting [custom_name] in a compromising position. Featuring as many dimensions as you." + else + switch(user.a_intent) + if(INTENT_HELP) + user.visible_message("[user] hugs the [name].") + playsound(src, "rustle", 50, 1, -5) + if(INTENT_DISARM) + user.visible_message("[user] kisses the [name].") + playsound(src, "rustle", 50, 1, -5) + if(INTENT_GRAB) + user.visible_message("[user] holds the [name]!") + playsound(src, 'sound/items/bikehorn.ogg', 50, 1) + if(INTENT_HARM) + user.visible_message("[user] punches the [name]!") + playsound(src, 'sound/effects/shieldbash.ogg', 50, 1) + user.changeNext_move(CLICK_CD_MELEE) + +//////////////////////////// diff --git a/code/game/objects/items/weapons/storage/internal.dm b/code/game/objects/items/weapons/storage/internal.dm index 8c7b7df04c..cfdc6cc354 100644 --- a/code/game/objects/items/weapons/storage/internal.dm +++ b/code/game/objects/items/weapons/storage/internal.dm @@ -5,10 +5,6 @@ w_class = WEIGHT_CLASS_BULKY rustle_jimmies = FALSE -/obj/item/weapon/storage/internal/ClickAccessible(mob/user, depth=1) - if(loc) - return loc.ClickAccessible(user, depth) - /obj/item/weapon/storage/internal/Adjacent(A) if(loc) return loc.Adjacent(A) @@ -53,7 +49,7 @@ /obj/item/weapon/implanter, /obj/item/weapon/screwdriver, /obj/item/weapon/weldingtool/mini, /obj/item/device/firing_pin ) - //can hold both regular pens and energy daggers. made for your every-day tactical librarians/murderers. + //can hold both regular pens and energy daggers. made for your every-day tactical curators/murderers. priority = FALSE quickdraw = TRUE silent = TRUE diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 08e947c45d..b1378617b8 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -38,7 +38,7 @@ return // this must come before the screen objects only block, dunno why it wasn't before - if(over_object == M && (src.ClickAccessible(M, depth=STORAGE_VIEW_DEPTH) || Adjacent(M))) + if(over_object == M && M.CanReach(src,view_only = TRUE)) orient2hud(M) if(M.s_active) M.s_active.close(M) diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 335545e8c9..1962fbd818 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -92,8 +92,7 @@ new /obj/item/pizzabox/bomb if("darklord") //20 tc + tk + summon item close enough for now - new /obj/item/weapon/melee/energy/sword/saber(src) - new /obj/item/weapon/melee/energy/sword/saber(src) + new /obj/item/weapon/twohanded/dualsaber(src) new /obj/item/weapon/dnainjector/telemut/darkbundle(src) new /obj/item/clothing/suit/hooded/chaplain_hoodie(src) new /obj/item/weapon/card/id/syndicate(src) @@ -220,6 +219,7 @@ new /obj/item/weapon/reagent_containers/glass/bottle/venom(src) new /obj/item/weapon/reagent_containers/glass/bottle/neurotoxin2(src) new /obj/item/weapon/reagent_containers/glass/bottle/formaldehyde(src) + new /obj/item/weapon/reagent_containers/glass/bottle/spewium(src) new /obj/item/weapon/reagent_containers/glass/bottle/cyanide(src) new /obj/item/weapon/reagent_containers/glass/bottle/histamine(src) new /obj/item/weapon/reagent_containers/glass/bottle/initropidril(src) @@ -296,3 +296,10 @@ /obj/item/weapon/storage/box/syndie_kit/mimery/PopulateContents() new /obj/item/weapon/spellbook/oneuse/mimery_blockade(src) new /obj/item/weapon/spellbook/oneuse/mimery_guns(src) + +/obj/item/weapon/storage/box/syndie_kit/holoparasite + name = "box" + +/obj/item/weapon/storage/box/syndie_kit/holoparasite/PopulateContents() + new /obj/item/weapon/guardiancreator/tech/choose/traitor(src) + new /obj/item/weapon/paper/guardian(src) \ No newline at end of file diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm index 002c7773b4..daa86eb833 100644 --- a/code/game/objects/items/weapons/twohanded.dm +++ b/code/game/objects/items/weapons/twohanded.dm @@ -262,11 +262,11 @@ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70) resistance_flags = FIRE_PROOF var/hacked = 0 - var/brightness_on = 6//TWICE AS BRIGHT AS A REGULAR ESWORD + var/brightness_on = 6 //TWICE AS BRIGHT AS A REGULAR ESWORD var/list/possible_colors = list("red", "blue", "green", "purple") /obj/item/weapon/twohanded/dualsaber/Initialize() - ..() + . = ..() if(LAZYLEN(possible_colors)) item_color = pick(possible_colors) switch(item_color) diff --git a/code/game/objects/items/weapons/vending_items.dm b/code/game/objects/items/weapons/vending_items.dm index 74ab7be4b6..c93dcaca3b 100644 --- a/code/game/objects/items/weapons/vending_items.dm +++ b/code/game/objects/items/weapons/vending_items.dm @@ -71,3 +71,9 @@ icon_state = "refill_clothes" charges = list(31, 4, 4)// of 101 standard, 12 contraband, 10 premium(?) init_charges = list(31, 4, 4) + +/obj/item/weapon/vending_refill/medical + machine_name = "NanoMed" + icon_state = "refill_medical" + charges = list(26, 5, 3)// of 76 standard, 13 contraband, 8 premium + init_charges = list(26, 5, 3) \ No newline at end of file diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index a0de9b5f76..e28c916ae4 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -390,7 +390,7 @@ desc = "A chainsaw that has replaced your arm." icon_state = "chainsaw_on" item_state = "mounted_chainsaw" - flags = NODROP | ABSTRACT + flags = NODROP | ABSTRACT | DROPDEL w_class = WEIGHT_CLASS_HUGE force = 21 throwforce = 0 @@ -400,10 +400,17 @@ attack_verb = list("sawed", "torn", "cut", "chopped", "diced") hitsound = 'sound/weapons/chainsawhit.ogg' -/obj/item/weapon/mounted_chainsaw/dropped() - ..() +/obj/item/weapon/mounted_chainsaw/Destroy() + var/obj/item/bodypart/part new /obj/item/weapon/twohanded/required/chainsaw(get_turf(src)) - qdel(src) + if(iscarbon(loc)) + var/mob/living/carbon/holder = loc + var/index = holder.get_held_index_of_item(src) + if(index) + part = holder.hand_bodyparts[index] + . = ..() + if(part) + part.drop_limb() /obj/item/weapon/statuebust name = "bust" diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index d46136a9ae..6212133b12 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -298,7 +298,7 @@ else for(var/mob/M in range(1,src)) if(CanHug(M)) - child.Attach(M) + child.Leap(M) break /obj/structure/alien/egg/obj_break(damage_flag) diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index 6813706ed6..89c815692d 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -106,6 +106,11 @@ LINEN BINS icon_state = "sheetrd" item_color = "director" +// for Free Golems. +/obj/item/weapon/bedsheet/rd/royal_cape + name = "Royal Cape of the Liberator" + desc = "Majestic." + /obj/item/weapon/bedsheet/medical name = "medical blanket" desc = "It's a sterilized* blanket commonly used in the Medbay. *Sterilization is voided if a virologist is present onboard the station." 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 67989257f2..5e1ea02509 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -11,6 +11,7 @@ else new /obj/item/weapon/storage/backpack/satchel/cap(src) new /obj/item/clothing/neck/cloak/cap(src) + new /obj/item/weapon/storage/daki(src) new /obj/item/weapon/storage/backpack/dufflebag/captain(src) new /obj/item/clothing/head/crown/fancy(src) new /obj/item/clothing/suit/captunic(src) diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 3817a16685..43fbdde5ee 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -11,30 +11,31 @@ max_integrity = 200 integrity_failure = 50 var/obj/item/showpiece = null - var/alert = 0 - var/open = 0 + var/alert = TRUE + var/open = FALSE + var/openable = TRUE var/obj/item/weapon/electronics/airlock/electronics var/start_showpiece_type = null //add type for items on display -/obj/structure/displaycase/Initialize() - . = ..() +/obj/structure/displaycase/Initialize() + . = ..() if(start_showpiece_type) showpiece = new start_showpiece_type (src) update_icon() /obj/structure/displaycase/Destroy() if(electronics) - QDEL_NULL(electronics) + QDEL_NULL(electronics) if(showpiece) - QDEL_NULL(showpiece) + QDEL_NULL(showpiece) return ..() /obj/structure/displaycase/examine(mob/user) ..() if(alert) to_chat(user, "Hooked up with an anti-theft system.") - if(showpiece) - to_chat(user, "There's [showpiece] inside.") + if(showpiece) + to_chat(user, "There's [showpiece] inside.") /obj/structure/displaycase/proc/dump() @@ -81,8 +82,8 @@ try getFlatIcon(A,defdir=4) catch - return 0 - return 1 + return FALSE + return TRUE /obj/structure/displaycase/proc/get_flat_icon_directional(atom/A) //Get flatIcon even if dir is mismatched for directionless icons @@ -113,7 +114,7 @@ return /obj/structure/displaycase/attackby(obj/item/weapon/W, mob/user, params) - if(W.GetID() && !broken) + if(W.GetID() && !broken && openable) if(allowed(user)) to_chat(user, "You [open ? "close":"open"] the [src]") toggle_lock(user) @@ -132,7 +133,7 @@ else to_chat(user, "[src] is already in good condition!") return - else if(!alert && istype(W,/obj/item/weapon/crowbar)) //Only applies to the lab cage and player made display cases + else if(!alert && istype(W,/obj/item/weapon/crowbar) && openable) //Only applies to the lab cage and player made display cases if(broken) if(showpiece) to_chat(user, "Remove the displayed object first.") @@ -145,8 +146,7 @@ to_chat(user, "You [open ? "close":"open"] the [src]") toggle_lock(user) else if(open && !showpiece) - if(user.drop_item()) - W.loc = src + if(user.transferItemToLoc(W, src)) showpiece = W to_chat(user, "You put [W] on display") update_icon() @@ -175,7 +175,7 @@ user.changeNext_move(CLICK_CD_MELEE) if (showpiece && (broken || open)) to_chat(user, "You deactivate the hover field built into the case.") - dump() + dump() src.add_fingerprint(user) update_icon() return @@ -247,96 +247,115 @@ desc = "A glass lab container for storing interesting creatures." start_showpiece_type = /obj/item/clothing/mask/facehugger/lamarr req_access = list(GLOB.access_rd) - - - -/obj/structure/displaycase/trophy - name = "trophy display case" - desc = "Store your trophies of accomplishment in here, and they will stay forever." - var/trophy_message = "" - var/placer_key = "" - var/added_roundstart = TRUE - alert = TRUE - integrity_failure = 0 - -/obj/structure/displaycase/trophy/Initialize() - . = ..() - GLOB.trophy_cases += src - -/obj/structure/displaycase/trophy/Destroy() - GLOB.trophy_cases -= src - return ..() - -/obj/structure/displaycase/trophy/examine(mob/user) - ..() - if(trophy_message) - to_chat(user, "The plaque reads:") - to_chat(user, trophy_message) - -/obj/structure/displaycase/trophy/attackby(obj/item/weapon/W, mob/user, params) - - if(!user.Adjacent(src)) //no TK museology - return - - if(!added_roundstart) - to_chat(user, "You've already put something new in this case.") - return - - if(is_type_in_typecache(W, GLOB.blacklisted_cargo_types)) - to_chat(user, "The case rejects the [W].") - return - - for(var/a in W.GetAllContents()) - if(is_type_in_typecache(a, GLOB.blacklisted_cargo_types)) - to_chat(user, "The case rejects the [W].") - return - - if(user.drop_item()) - - if(showpiece) - to_chat(user, "You press a button, and [showpiece] descends into the floor of the case.") - QDEL_NULL(showpiece) - - to_chat(user, "You insert [W] into the case.") - W.forceMove(src) - showpiece = W - added_roundstart = FALSE - update_icon() - - placer_key = user.ckey - - trophy_message = W.desc //default value - - var/chosen_plaque = stripped_input(user, "What would you like the plaque to say? Default value is item's description.", "Trophy Plaque") - if(chosen_plaque) - if(user.Adjacent(src)) - trophy_message = chosen_plaque - to_chat(user, "You set the plaque's text.") - else - to_chat(user, "You are too far to set the plaque's text.") - - SSpersistence.SaveTrophy(src) - - else - to_chat(user, "\The [W] is stuck to your hand, you can't put it in the [src.name]!") - - return - -/obj/structure/displaycase/trophy/dump() - if (showpiece) - if(added_roundstart) - visible_message("The [showpiece] crumbles to dust!") - new /obj/effect/decal/cleanable/ash(loc) - QDEL_NULL(showpiece) - else - ..() - -/obj/item/showpiece_dummy - name = "Cheap replica" - -/obj/item/showpiece_dummy/Initialize(mapload, path) - . = ..() - var/obj/item/I = path - name = initial(I.name) - icon = initial(I.icon) - icon_state = initial(I.icon_state) + +/obj/structure/displaycase/trophy + name = "trophy display case" + desc = "Store your trophies of accomplishment in here, and they will stay forever." + var/trophy_message = "" + var/placer_key = "" + var/added_roundstart = TRUE + var/is_locked = TRUE + + alert = TRUE + integrity_failure = 0 + openable = FALSE + +/obj/structure/displaycase/trophy/Initialize() + . = ..() + GLOB.trophy_cases += src + +/obj/structure/displaycase/trophy/Destroy() + GLOB.trophy_cases -= src + return ..() + +/obj/structure/displaycase/trophy/examine(mob/user) + ..() + if(trophy_message) + to_chat(user, "The plaque reads:") + to_chat(user, trophy_message) + +/obj/structure/displaycase/trophy/attackby(obj/item/weapon/W, mob/user, params) + + if(!user.Adjacent(src)) //no TK museology + return + if(user.a_intent == INTENT_HARM) + return ..() + + if(user.is_holding_item_of_type(/obj/item/key/displaycase)) + if(added_roundstart) + is_locked = !is_locked + to_chat(user, "You [!is_locked ? "un" : ""]lock the case.") + else + to_chat(user, "The lock is stuck shut!") + return + + if(is_locked) + to_chat(user, "The case is shut tight with an old fashioned physical lock. Maybe you should ask the curator for the key?") + return + + if(!added_roundstart) + to_chat(user, "You've already put something new in this case.") + return + + if(is_type_in_typecache(W, GLOB.blacklisted_cargo_types)) + to_chat(user, "The case rejects the [W].") + return + + for(var/a in W.GetAllContents()) + if(is_type_in_typecache(a, GLOB.blacklisted_cargo_types)) + to_chat(user, "The case rejects the [W].") + return + + if(user.transferItemToLoc(W, src)) + + if(showpiece) + to_chat(user, "You press a button, and [showpiece] descends into the floor of the case.") + QDEL_NULL(showpiece) + + to_chat(user, "You insert [W] into the case.") + showpiece = W + added_roundstart = FALSE + update_icon() + + placer_key = user.ckey + + trophy_message = W.desc //default value + + var/chosen_plaque = stripped_input(user, "What would you like the plaque to say? Default value is item's description.", "Trophy Plaque") + if(chosen_plaque) + if(user.Adjacent(src)) + trophy_message = chosen_plaque + to_chat(user, "You set the plaque's text.") + else + to_chat(user, "You are too far to set the plaque's text.") + + SSpersistence.SaveTrophy(src) + return TRUE + + else + to_chat(user, "\The [W] is stuck to your hand, you can't put it in the [src.name]!") + + return + +/obj/structure/displaycase/trophy/dump() + if (showpiece) + if(added_roundstart) + visible_message("The [showpiece] crumbles to dust!") + new /obj/effect/decal/cleanable/ash(loc) + QDEL_NULL(showpiece) + else + ..() + +/obj/item/key/displaycase + name = "display case key" + desc = "The key to the curator's display cases." + +/obj/item/showpiece_dummy + name = "Cheap replica" + +/obj/item/showpiece_dummy/Initialize(mapload, path) + . = ..() + var/obj/item/I = path + name = initial(I.name) + icon = initial(I.icon) + icon_state = initial(I.icon_state) diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm index 466be07c50..389ae40e88 100644 --- a/code/game/objects/structures/false_walls.dm +++ b/code/game/objects/structures/false_walls.dm @@ -234,8 +234,9 @@ /obj/structure/falsewall/plasma/attackby(obj/item/weapon/W, mob/user, params) if(W.is_hot() > 300) - message_admins("Plasma falsewall ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("Plasma falsewall ignited by [key_name(user)] in ([x],[y],[z])") + var/turf/T = get_turf(src) + message_admins("Plasma falsewall ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1) + log_game("Plasma falsewall ignited by [key_name(user)] in [COORD(T)]") burnbabyburn() else return ..() diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index cdd706e5df..c00348a2c6 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -88,7 +88,7 @@ pixel_y = -20 /obj/structure/flora/tree/jungle/Initialize() - icon_state = "[icon_state][rand(1, 3)]" + icon_state = "[icon_state][rand(1, 6)]" ..() //grass diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index d087b14390..bb55084dd9 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -155,8 +155,6 @@ name = "dust-caked golem shell" desc = "A humanoid shape, empty, lifeless, and full of potential." mob_name = "a free golem" - anchored = 1 - density = 1 can_transfer = FALSE mob_species = /datum/species/golem/adamantine diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm index 129862dd62..039f3da5d7 100644 --- a/code/game/objects/structures/mineral_doors.dm +++ b/code/game/objects/structures/mineral_doors.dm @@ -188,8 +188,9 @@ /obj/structure/mineral_door/transparent/plasma/attackby(obj/item/weapon/W, mob/user, params) if(W.is_hot()) - message_admins("Plasma mineral door ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("Plasma mineral door ignited by [key_name(user)] in ([x],[y],[z])") + var/turf/T = get_turf(src) + message_admins("Plasma mineral door ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1) + log_game("Plasma mineral door ignited by [key_name(user)] in [COORD(T)]") TemperatureAct() else return ..() diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index f5defdab50..6909965614 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -163,18 +163,20 @@ PlasmaBurn(500) burn = TRUE if(burn) + var/turf/T = get_turf(src) if(Proj.firer) - message_admins("Plasma statue ignited by [key_name_admin(Proj.firer)](?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("Plasma statue ignited by [key_name(Proj.firer)] in ([x],[y],[z])") + message_admins("Plasma statue ignited by [ADMIN_LOOKUPFLW(Proj.firer)] in [ADMIN_COORDJMP(T)]",0,1) + log_game("Plasma statue ignited by [key_name(Proj.firer)] in [COORD(T)]") else - message_admins("Plasma statue ignited by [Proj]. No known firer.(?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("Plasma statue ignited by [Proj] in ([x],[y],[z]). No known firer.") + message_admins("Plasma statue ignited by [Proj]. No known firer, in [ADMIN_COORDJMP(T)]",0,1) + log_game("Plasma statue ignited by [Proj] in [COORD(T)]. No known firer.") ..() /obj/structure/statue/plasma/attackby(obj/item/weapon/W, mob/user, params) if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite - message_admins("Plasma statue ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("Plasma statue ignited by [key_name(user)] in ([x],[y],[z])") + var/turf/T = get_turf(src) + message_admins("Plasma statue ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1) + log_game("Plasma statue ignited by [key_name(user)] in [COORD(T)]") ignite(W.is_hot()) else return ..() diff --git a/code/game/turfs/simulated/chasm.dm b/code/game/turfs/simulated/chasm.dm index 8890c50129..8b24a4c816 100644 --- a/code/game/turfs/simulated/chasm.dm +++ b/code/game/turfs/simulated/chasm.dm @@ -143,14 +143,14 @@ qdel(S.mmi) qdel(AM) - + if(AM && !QDELETED(AM)) //It's indestructible visible_message("[src] spits out the [AM]!") AM.alpha = oldalpha AM.color = oldcolor AM.transform = oldtransform AM.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1, 10),rand(1, 10)) - + /turf/open/chasm/straight_down/lava_land_surface/normal_air initial_gas_mix = "o2=22;n2=82;TEMP=293.15" @@ -158,3 +158,17 @@ /turf/open/chasm/CanPass(atom/movable/mover, turf/target, height=0) return 1 + + + +//Jungle + +/turf/open/chasm/jungle + icon = 'icons/turf/floors/junglechasm.dmi' + planetary_atmos = TRUE + initial_gas_mix = "o2=14;n2=23;TEMP=300" + +/turf/open/chasm/straight_down/jungle + icon = 'icons/turf/floors/junglechasm.dmi' + planetary_atmos = TRUE + initial_gas_mix = "o2=14;n2=23;TEMP=300" \ No newline at end of file diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm index eaba3d50eb..cce7756892 100644 --- a/code/game/turfs/simulated/floor/fancy_floor.dm +++ b/code/game/turfs/simulated/floor/fancy_floor.dm @@ -1,6 +1,7 @@ /* In this file: * Wood floor * Grass floor + * Fake Basalt * Carpet floor * Fake pits * Fake space @@ -67,6 +68,7 @@ broken_states = list("sand") flags = NONE var/ore_type = /obj/item/weapon/ore/glass + var/turfverb = "uproot" /turf/open/floor/grass/Initialize() ..() @@ -76,7 +78,7 @@ if(istype(C, /obj/item/weapon/shovel) && params) new ore_type(src) new ore_type(src) //Make some sand if you shovel grass - user.visible_message("[user] digs up [src].", "You uproot [src].") + user.visible_message("[user] digs up [src].", "You [src.turfverb] [src].") playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) make_plating() if(..()) @@ -93,7 +95,6 @@ initial_gas_mix = "o2=22;n2=82;TEMP=180" slowdown = 2 - /turf/open/floor/grass/snow/attackby(obj/item/W, mob/user, params) if(istype(W, /obj/item/weapon/crowbar))//You need to dig this turf out instead of crowbarring it return @@ -113,6 +114,24 @@ icon_state = "basalt[rand(0, 12)]" set_basalt_light(src) + +/turf/open/floor/grass/fakebasalt //Heart is not a real planeteer power + name = "aesthetic volcanic flooring" + desc = "Safely recreated turf for your hellplanet-scaping" + icon = 'icons/turf/floors.dmi' + icon_state = "basalt" + floor_tile = /obj/item/stack/tile/basalt + ore_type = /obj/item/weapon/ore/glass/basalt + turfverb = "dig up" + slowdown = 0 + +/turf/open/floor/grass/fakebasalt/Initialize() + ..() + if(prob(15)) + icon_state = "basalt[rand(0, 12)]" + set_basalt_light(src) + + /turf/open/floor/carpet name = "carpet" desc = "Soft velvet carpeting. Feels good between your toes." diff --git a/code/game/turfs/simulated/floor/mineral_floor.dm b/code/game/turfs/simulated/floor/mineral_floor.dm index 3e58e62854..5024dfea90 100644 --- a/code/game/turfs/simulated/floor/mineral_floor.dm +++ b/code/game/turfs/simulated/floor/mineral_floor.dm @@ -44,8 +44,8 @@ /turf/open/floor/mineral/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params) if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite - message_admins("Plasma flooring was ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("Plasma flooring was ignited by [key_name(user)] in ([x],[y],[z])") + message_admins("Plasma flooring was ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(src)]",0,1) + log_game("Plasma flooring was ignited by [key_name(user)] in [COORD(src)]") ignite(W.is_hot()) return ..() diff --git a/code/game/turfs/simulated/floor/plating/dirt.dm b/code/game/turfs/simulated/floor/plating/dirt.dm index 580aadc85f..0d13b93432 100644 --- a/code/game/turfs/simulated/floor/plating/dirt.dm +++ b/code/game/turfs/simulated/floor/plating/dirt.dm @@ -3,19 +3,9 @@ desc = "Upon closer examination, it's still dirt." icon = 'icons/turf/floors.dmi' icon_state = "dirt" - var/smooth_icon = 'icons/turf/floors/dirt.dmi' - canSmoothWith = list(/turf/closed, /turf/open/floor/plating/dirt) - smooth = SMOOTH_MORE|SMOOTH_BORDER - baseturf = /turf/open/chasm/straight_down/lava_land_surface + baseturf = /turf/open/chasm/straight_down/jungle initial_gas_mix = "o2=14;n2=23;TEMP=300" planetary_atmos = TRUE -/turf/open/floor/plating/dirt/Initialize() - pixel_y = -2 - pixel_x = -2 - icon = smooth_icon - ..() - /turf/open/floor/plating/dirt/dark - icon_state = "darkdirt" - smooth_icon = 'icons/turf/floors/darkdirt.dmi' + icon_state = "greenerdirt" diff --git a/code/game/turfs/simulated/minerals.dm b/code/game/turfs/simulated/minerals.dm index 398ff190f2..54f3ad5ad5 100644 --- a/code/game/turfs/simulated/minerals.dm +++ b/code/game/turfs/simulated/minerals.dm @@ -407,14 +407,14 @@ if(z != 5) notify_admins = 1 if(!triggered_by_explosion) - message_admins("[key_name_admin(user)]? (FLW) has triggered a gibtonite deposit reaction at [A.name] (JMP).") + message_admins("[ADMIN_LOOKUPFLW(user)] has triggered a gibtonite deposit reaction at [A.name] [ADMIN_JMP(bombturf)].") else - message_admins("An explosion has triggered a gibtonite deposit reaction at [A.name] (JMP).") + message_admins("An explosion has triggered a gibtonite deposit reaction at [A.name] [ADMIN_JMP(bombturf)].") if(!triggered_by_explosion) - log_game("[key_name(user)] has triggered a gibtonite deposit reaction at [A.name] ([A.x], [A.y], [A.z]).") + log_game("[key_name(user)] has triggered a gibtonite deposit reaction at [A.name] [ADMIN_JMP(bombturf)].") else - log_game("An explosion has triggered a gibtonite deposit reaction at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])") + log_game("An explosion has triggered a gibtonite deposit reaction at [A.name] [COORD(bombturf)]") countdown(notify_admins) diff --git a/code/game/turfs/simulated/wall/mineral_walls.dm b/code/game/turfs/simulated/wall/mineral_walls.dm index 355ba66a62..61a26954d3 100644 --- a/code/game/turfs/simulated/wall/mineral_walls.dm +++ b/code/game/turfs/simulated/wall/mineral_walls.dm @@ -101,8 +101,8 @@ /turf/closed/wall/mineral/plasma/attackby(obj/item/weapon/W, mob/user, params) if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite - message_admins("Plasma wall ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("Plasma wall ignited by [key_name(user)] in ([x],[y],[z])") + message_admins("Plasma wall ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(src)]",0,1) + log_game("Plasma wall ignited by [key_name(user)] in [COORD(src)]") ignite(W.is_hot()) return ..() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 4c29d87dfa..618894f207 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -455,6 +455,8 @@ O = new() O.underlays.Add(T) T.ChangeTurf(type) + for(var/group in decals) + T.add_decal(decals[group],group) if(underlays.len) T.underlays = O.underlays if(T.icon_state != icon_state) diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm index 9411917c39..bba253a9da 100644 --- a/code/modules/VR/vr_sleeper.dm +++ b/code/modules/VR/vr_sleeper.dm @@ -9,6 +9,7 @@ icon_state = "sleeper" state_open = TRUE anchored = TRUE + occupant_typecache = list(/mob/living/carbon/human) // turned into typecache in Initialize var/you_die_in_the_game_you_die_for_real = FALSE var/datum/effect_system/spark_spread/sparks var/mob/living/carbon/human/virtual_reality/vr_human @@ -92,11 +93,12 @@ return switch(action) if("vr_connect") - if(ishuman(occupant) && occupant.mind) + var/mob/living/carbon/human/human_occupant = occupant + if(human_occupant && human_occupant.mind) to_chat(occupant, "Transfering to virtual reality...") if(vr_human) vr_human.revert_to_reality(FALSE, FALSE) - occupant.mind.transfer_to(vr_human) + human_occupant.mind.transfer_to(vr_human) vr_human.real_me = occupant to_chat(vr_human, "Transfer successful! you are now playing as [vr_human] in VR!") SStgui.close_user_uis(vr_human, src) diff --git a/code/modules/admin/DB_ban/functions.dm b/code/modules/admin/DB_ban/functions.dm index 12517eb385..67d3b394c6 100644 --- a/code/modules/admin/DB_ban/functions.dm +++ b/code/modules/admin/DB_ban/functions.dm @@ -71,16 +71,13 @@ computerid = bancid ip = banip - var/datum/DBQuery/query_add_ban_get_id = SSdbcore.NewQuery("SELECT id FROM [format_table_name("player")] WHERE ckey = '[ckey]'") - if(!query_add_ban_get_id.warn_execute()) + var/datum/DBQuery/query_add_ban_get_ckey = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[ckey]'") + if(!query_add_ban_get_ckey.warn_execute()) return - var/validckey = 0 - if(query_add_ban_get_id.NextRow()) - validckey = 1 - if(!validckey) + if(!query_add_ban_get_ckey.NextRow()) if(!banned_mob || (banned_mob && !IsGuestKey(banned_mob.key))) - message_admins("[key_name_admin(usr)] attempted to ban [ckey], but [ckey] has not been seen yet. Please only ban actual players.",1) - return + if(alert(usr, "[ckey] has not been seen before, are you sure you want to create a ban for them?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes") + return var/a_ckey var/a_computerid diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 09e3629533..d4fa2e6177 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -63,7 +63,7 @@ if(!SSdbcore.Connect()) log_world("Ban database connection failure. Key [ckeytext] not checked") - GLOB.diary << "Ban database connection failure. Key [ckeytext] not checked" + GLOB.world_game_log << "Ban database connection failure. Key [ckeytext] not checked" return var/ipquery = "" diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 0e7986ec18..7196319568 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -37,6 +37,11 @@ else body += " \[Heal\] " + if(M.client) + body += "
\[First Seen: [M.client.player_join_date]\]\[Byond account registered on: [M.client.account_join_date]\]" + + + body += "

\[ " body += "VV - " body += "TP - " @@ -804,7 +809,7 @@ return 1 /client/proc/adminGreet(logout) - if(SSticker.HasRoundStarted()) + if(SSticker.HasRoundStarted()) var/string if(logout && config && config.announce_admin_logout) string = pick( diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index 53fefc30bc..7aca1ececb 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -1,50 +1,21 @@ -//By Carnwennan - -//This system was made as an alternative to all the in-game lists and variables used to log stuff in-game. -//lists and variables are great. However, they have several major flaws: -//Firstly, they use memory. TGstation has one of the highest memory usage of all the ss13 branches. -//Secondly, they are usually stored in an object. This means that they aren't centralised. It also means that -//the data is lost when the object is deleted! This is especially annoying for things like the singulo engine! -#define INVESTIGATE_DIR "data/investigate/" - -//SYSTEM -/proc/investigate_subject2file(subject) - return file("[INVESTIGATE_DIR][subject].html") - -/proc/investigate_reset() - if(fdel(INVESTIGATE_DIR)) - return 1 - return 0 - -/atom/proc/investigate_log(message, subject) - if(!message) - return - var/F = investigate_subject2file(subject) - if(!F) +atom/proc/investigate_log(message, subject) + if(!message || !subject) return + var/F = file("[GLOB.log_directory]/[subject].html") F << "[time_stamp()] \ref[src] ([x],[y],[z]) || [src] [message]
" -//ADMINVERBS -/client/proc/investigate_show( subject in list("hrefs","notes, memos, watchlist","singulo","wires","telesci", "gravity", "records", "cargo", "supermatter", "atmos", "experimentor", "botany") ) + +/client/proc/investigate_show( subject in list("hrefs","notes, memos, watchlist","singulo","wires","telesci", "gravity", "records", "cargo", "supermatter", "atmos", "experimentor", "botany") ) set name = "Investigate" set category = "Admin" if(!holder) return switch(subject) - if("singulo", "wires", "telesci", "gravity", "records", "cargo", "supermatter", "atmos", "botany") //general one-round-only stuff - var/F = investigate_subject2file(subject) - if(!F) - to_chat(src, "Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed.") - return - src << browse(F,"window=investigate[subject];size=800x300") - if("hrefs") //persistent logs and stuff - if(GLOB.href_logfile) - src << browse(GLOB.href_logfile,"window=investigate[subject];size=800x300") - else if(!config.log_hrefs) - to_chat(src, "Href logging is off and no logfile was found.") - return - else - to_chat(src, "No href logfile was found.") - return if("notes, memos, watchlist") browse_messages() + else + var/F = file("[GLOB.log_directory]/[subject].html") + if(!fexists(F)) + to_chat(src, "No [subject] logfile was found.") + return + src << browse(F,"window=investigate[subject];size=800x300") \ No newline at end of file diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index b38cc4e289..d4fbd1a030 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -127,7 +127,7 @@ GLOBAL_PROTECT(admin_ranks) else if(!SSdbcore.Connect()) log_world("Failed to connect to database in load_admin_ranks(). Reverting to legacy system.") - GLOB.diary << "Failed to connect to database in load_admin_ranks(). Reverting to legacy system." + GLOB.world_game_log << "Failed to connect to database in load_admin_ranks(). Reverting to legacy system." config.admin_legacy_system = 1 load_admin_ranks() return @@ -202,7 +202,7 @@ GLOBAL_PROTECT(admin_ranks) else if(!SSdbcore.Connect()) log_world("Failed to connect to database in load_admins(). Reverting to legacy system.") - GLOB.diary << "Failed to connect to database in load_admins(). Reverting to legacy system." + GLOB.world_game_log << "Failed to connect to database in load_admins(). Reverting to legacy system." config.admin_legacy_system = 1 load_admins() return diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index d4ba53c6af..e5f8360527 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -4,18 +4,12 @@ GLOBAL_PROTECT(admin_verbs_default) GLOBAL_LIST_INIT(admin_verbs_default, world.AVerbsDefault()) /world/proc/AVerbsDefault() return list( - /client/proc/toggleadminhelpsound, /*toggles whether we hear a sound when adminhelps/PMs are used*/ - /client/proc/toggleannouncelogin, /*toggles if an admin's login is announced during a round*/ /client/proc/deadmin, /*destroys our own admin datum so we can play as a regular player*/ /client/proc/cmd_admin_say, /*admin-only ooc chat*/ /client/proc/hide_verbs, /*hides all our adminverbs*/ /client/proc/hide_most_verbs, /*hides all our hideable adminverbs*/ /client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/ - /client/proc/deadchat, /*toggles deadchat on/off*/ /client/proc/dsay, /*talk in deadchat using our ckey/fakekey*/ - /client/proc/toggleprayers, /*toggles prayers on/off*/ - /client/verb/toggleprayersounds, /*Toggles prayer sounds (HALLELUJAH!)*/ - /client/proc/toggle_hear_radio, /*toggles whether we hear the radio*/ /client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/ /client/proc/secrets, /client/proc/restart_controller, @@ -32,7 +26,6 @@ GLOBAL_PROTECT(admin_verbs_admin) GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin()) /world/proc/AVerbsAdmin() return list( - /client/proc/player_panel_new, /*shows an interface for all players, with links to various panels*/ /client/proc/invisimin, /*allows our mob to go invisible/visible*/ // /datum/admins/proc/show_traitor_panel, /*interface which shows a mob's mind*/ -Removed due to rare practical use. Moved to debug verbs ~Errorage /datum/admins/proc/show_player_panel, /*shows an interface for individual players, with various links (links require additional flags*/ @@ -46,16 +39,14 @@ GLOBAL_LIST_INIT(admin_verbs_admin, world.AVerbsAdmin()) /datum/admins/proc/set_admin_notice,/*announcement all clients see when joining the server.*/ /client/proc/admin_ghost, /*allows us to ghost/reenter body at will*/ /client/proc/toggle_view_range, /*changes how far we can see*/ - /datum/admins/proc/view_txt_log, /*shows the server log (diary) for today*/ + /datum/admins/proc/view_txt_log, /*shows the server log (world_game_log) for today*/ /datum/admins/proc/view_atk_log, /*shows the server combat-log, doesn't do anything presently*/ /client/proc/cmd_admin_subtle_message, /*send an message to somebody as a 'voice in their head'*/ /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ /client/proc/cmd_admin_check_contents, /*displays the contents of an instance*/ /client/proc/check_antagonists, /*shows all antags*/ /datum/admins/proc/access_news_network, /*allows access of newscasters*/ - /client/proc/giveruntimelog, /*allows us to give access to runtime logs to somebody*/ - /client/proc/getruntimelog, /*allows us to access runtime logs to somebody*/ - /client/proc/getserverlog, /*allows us to fetch server logs (diary) for other days*/ + /client/proc/getserverlog, /*allows us to fetch server logs (world_game_log) for other days*/ /client/proc/jumptocoord, /*we ghost and jump to a coordinate*/ /client/proc/Getmob, /*teleports a mob to our location*/ /client/proc/Getkey, /*teleports a mob with a certain ckey to our location*/ @@ -116,7 +107,6 @@ GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer()) /datum/admins/proc/end_round, /datum/admins/proc/delay, /datum/admins/proc/toggleaban, - /client/proc/toggle_log_hrefs, /client/proc/everyone_random, /datum/admins/proc/toggleAI, /client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/ @@ -182,9 +172,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( /client/proc/set_ooc, /client/proc/reset_ooc, /client/proc/deadmin, - /client/proc/deadchat, - /client/proc/toggleprayers, - /client/proc/toggle_hear_radio, /datum/admins/proc/show_traitor_panel, /datum/admins/proc/toggleenter, /datum/admins/proc/toggleguests, @@ -223,7 +210,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( /datum/admins/proc/restart, /datum/admins/proc/delay, /datum/admins/proc/toggleaban, - /client/proc/toggle_log_hrefs, /client/proc/everyone_random, /datum/admins/proc/toggleAI, /client/proc/restart_controller, @@ -398,13 +384,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( mob.invisibility = INVISIBILITY_OBSERVER to_chat(mob, "Invisimin on. You are now as invisible as a ghost.") -/client/proc/player_panel_new() - set name = "Player Panel" - set category = "Admin" - if(holder) - holder.player_panel_new() - SSblackbox.add_details("admin_verb","Player Panel New") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - /client/proc/check_antagonists() set name = "Check Antagonists" set category = "Admin" @@ -638,19 +617,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( togglebuildmode(src.mob) SSblackbox.add_details("admin_verb","Toggle Build Mode") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/proc/toggle_log_hrefs() - set name = "Toggle href logging" - set category = "Server" - if(!holder) - return - if(config) - if(config.log_hrefs) - config.log_hrefs = 0 - to_chat(src, "Stopped logging hrefs") - else - config.log_hrefs = 1 - to_chat(src, "Started logging hrefs") - /client/proc/check_ai_laws() set name = "Check AI Laws" set category = "Admin" diff --git a/code/modules/admin/adminmenu.dm b/code/modules/admin/adminmenu.dm new file mode 100644 index 0000000000..fc7a57e212 --- /dev/null +++ b/code/modules/admin/adminmenu.dm @@ -0,0 +1,11 @@ +/datum/menu/Admin/Generate_list(client/C) + if (C.holder) + . = ..() + +/datum/menu/Admin/verb/playerpanel() + set name = "Player Panel" + set desc = "Player Panel" + set category = "Admin" + usr.client.holder.player_panel_new() + SSblackbox.add_details("admin_verb","Player Panel New") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + return \ No newline at end of file diff --git a/code/modules/admin/topic.dm.rej b/code/modules/admin/topic.dm.rej deleted file mode 100644 index 041ae92107..0000000000 --- a/code/modules/admin/topic.dm.rej +++ /dev/null @@ -1,10 +0,0 @@ -diff a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm (rejected hunks) -@@ -8,7 +8,7 @@ - if(href_list["ahelp"]) - if(!check_rights(R_ADMIN)) - return -- -+ - var/ahelp_ref = href_list["ahelp"] - var/datum/admin_help/AH = locate(ahelp_ref) - if(AH) diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index a59f40e35a..70ef44576c 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -71,7 +71,7 @@ if("select", "delete", "update") select_types = query_tree[query_tree[1]] - from_objs = SDQL_from_objs(query_tree["from"]) + from_objs = world.SDQL_from_objs(query_tree["from"]) var/list/objs = list() @@ -101,7 +101,7 @@ if("call") for(var/datum/d in objs) try - SDQL_var(d, query_tree["call"][1], source = d) + world.SDQL_var(d, query_tree["call"][1], source = d) catch(var/exception/e) runtime_tracker += SDQL_parse_exception(e) runtimes++ @@ -177,15 +177,6 @@ returning += "Description: [E.desc]
" return returning -/proc/SDQL_callproc_global(procname,args_list) - set waitfor = FALSE - WrapAdminProcCall(GLOBAL_PROC, procname, args_list) - -/proc/SDQL_callproc(thing, procname, args_list) - set waitfor = FALSE - if(hascall(thing, procname)) - WrapAdminProcCall(thing, procname, args_list) - /proc/SDQL_parse(list/query_list) var/datum/SDQL_parser/parser = new() var/list/querys = list() @@ -249,15 +240,10 @@ -/proc/SDQL_from_objs(list/tree) +/world/proc/SDQL_from_objs(list/tree) if("world" in tree) - if(IsAdminAdvancedProcCall()) - var/msg = "WARNING: Attempt to retrieve world reference made by [usr]!" - log_admin(msg) - message_admins(msg) - return - return world - return SDQL_expression(world, tree) + return src + return SDQL_expression(src, tree) /proc/SDQL_get_all(type, location) var/list/out = list() @@ -417,12 +403,12 @@ result = dummy val += result else - val = SDQL_var(object, expression, i, object) + val = world.SDQL_var(object, expression, i, object) i = expression.len return list("val" = val, "i" = i) -/proc/SDQL_var(datum/object, list/expression, start = 1, source) +/world/proc/SDQL_var(datum/object, list/expression, start = 1, source) var/v var/long = start < expression.len if(object == world && long && expression[start + 1] == ".") @@ -456,11 +442,6 @@ else return null if("world") - if(IsAdminAdvancedProcCall()) - var/msg = "WARNING: Attempt to retrieve world reference made by [usr]!" - log_admin(msg) - message_admins(msg) - return v = world if("global") v = GLOB diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm index 6b642d4fdd..db9eaa6458 100644 --- a/code/modules/admin/verbs/adminhelp.dm +++ b/code/modules/admin/verbs/adminhelp.dm @@ -479,7 +479,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new) current_ticket.MessageNoRecipient(msg) current_ticket.TimeoutVerb() return - else + else to_chat(usr, "Ticket not found, creating new one...") else current_ticket.AddInteraction("[key_name_admin(usr)] opened a new ticket.") diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index df59c1a7bb..eb3e24265c 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -103,6 +103,7 @@ if(!recipient) if(holder) to_chat(src, "Error: Admin-PM: Client not found.") + to_chat(src, msg) else current_ticket.MessageNoRecipient(msg) return diff --git a/code/modules/admin/verbs/deadsay.dm b/code/modules/admin/verbs/deadsay.dm index 37af9e8601..500edfe665 100644 --- a/code/modules/admin/verbs/deadsay.dm +++ b/code/modules/admin/verbs/deadsay.dm @@ -19,7 +19,7 @@ if (!msg) return - var/nicknames = world.file2list("config/admin_nicknames.txt") + var/static/nicknames = world.file2list("config/admin_nicknames.txt") var/rendered = "DEAD: ADMIN([src.holder.fakekey ? pick(nicknames) : src.key]) says, \"[msg]\"" diff --git a/code/modules/admin/verbs/getlogs.dm b/code/modules/admin/verbs/getlogs.dm index 7624a9443e..24cb4275b8 100644 --- a/code/modules/admin/verbs/getlogs.dm +++ b/code/modules/admin/verbs/getlogs.dm @@ -1,62 +1,3 @@ -/* - HOW DO I LOG RUNTIMES? - Firstly, start dreamdeamon if it isn't already running. Then select "world>Log Session" (or press the F3 key) - navigate the popup window to the data/logs/runtimes/ folder from where your tgstation .dmb is located. - (you may have to make this folder yourself) - - OPTIONAL: you can select the little checkbox down the bottom to make dreamdeamon save the log everytime you - start a world. Just remember to repeat these steps with a new name when you update to a new revision! - - Save it with the name of the revision your server uses (e.g. r3459.txt). - Game Masters will now be able to grant access any runtime logs you have archived this way! - This will allow us to gather information on bugs across multiple servers and make maintaining the TG - codebase for the entire /TG/station commuity a TONNE easier :3 Thanks for your help! -*/ - - -//This proc allows Game Masters to grant a client access to the .getruntimelog verb -//Permissions expire at the end of each round. -//Runtimes can be used to meta or spot game-crashing exploits so it's advised to only grant coders that -//you trust access. Also, it may be wise to ensure that they are not going to play in the current round. -/client/proc/giveruntimelog() - set name = ".giveruntimelog" - set desc = "Give somebody access to any session logfiles saved to the /log/runtime/ folder." - set category = null - - if(!src.holder) - to_chat(src, "Only Admins may use this command.") - return - - var/client/target = input(src,"Choose somebody to grant access to the server's runtime logs (permissions expire at the end of each round):","Grant Permissions",null) as null|anything in GLOB.clients - if(!istype(target,/client)) - to_chat(src, "Error: giveruntimelog(): Client not found.") - return - - target.verbs |= /client/proc/getruntimelog - to_chat(target, "You have been granted access to runtime logs. Please use them responsibly or risk being banned.") - return - - -//This proc allows download of runtime logs saved within the data/logs/ folder by dreamdeamon. -//It works similarly to show-server-log. -/client/proc/getruntimelog() - set name = ".getruntimelog" - set desc = "Retrieve any session logfiles saved by dreamdeamon." - set category = null - - var/path = browse_files("data/logs/runtimes/") - if(!path) - return - - if(file_spam_check()) - return - - message_admins("[key_name_admin(src)] accessed file: [path]") - src << ftp(file(path)) - to_chat(src, "Attempting to send file, this may take a fair few minutes if the file is very large.") - return - - //This proc allows download of past server logs saved within the data/logs/ folder. //It works similarly to show-server-log. /client/proc/getserverlog() @@ -83,10 +24,10 @@ /datum/admins/proc/view_txt_log() set category = "Admin" set name = "Show Server Log" - set desc = "Shows today's server log." + set desc = "Shows server log for this round." - if(fexists("[GLOB.diary]")) - src << ftp(GLOB.diary) + if(fexists("[GLOB.world_game_log]")) + src << ftp(GLOB.world_game_log) else to_chat(src, "Server log not found, try using .getserverlog.") return @@ -97,10 +38,10 @@ /datum/admins/proc/view_atk_log() set category = "Admin" set name = "Show Server Attack Log" - set desc = "Shows today's server attack log." + set desc = "Shows server attack log for this round." - if(fexists("[GLOB.diaryofmeanpeople]")) - src << ftp(GLOB.diaryofmeanpeople) + if(fexists("[GLOB.world_attack_log]")) + src << ftp(GLOB.world_attack_log) else to_chat(src, "Server attack log not found, try using .getserverlog.") return diff --git a/code/modules/admin/verbs/map_template_loadverb.dm b/code/modules/admin/verbs/map_template_loadverb.dm index 9fdb316971..ba50ecae32 100644 --- a/code/modules/admin/verbs/map_template_loadverb.dm +++ b/code/modules/admin/verbs/map_template_loadverb.dm @@ -19,7 +19,7 @@ usr.client.images += preview if(alert(usr,"Confirm location.","Template Confirm","Yes","No") == "Yes") if(template.load(T, centered = TRUE)) - message_admins("[key_name_admin(usr)] has placed a map template ([template.name]) at (JMP)") + message_admins("[key_name_admin(usr)] has placed a map template ([template.name]) at [ADMIN_COORDJMP(T)]") else to_chat(usr, "Failed to place map") usr.client.images -= preview diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm index d7b06ee9c8..87a9e5a040 100644 --- a/code/modules/admin/verbs/one_click_antag.dm +++ b/code/modules/admin/verbs/one_click_antag.dm @@ -132,7 +132,7 @@ /datum/admins/proc/makeWizard() - var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for the position of a Wizard Foundation 'diplomat'?", "wizard", null) + var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for the position of a Wizard Foundation 'diplomat'?", "wizard", null) var/mob/dead/observer/selected = pick_n_take(candidates) @@ -215,7 +215,7 @@ /datum/admins/proc/makeNukeTeam() var/datum/game_mode/nuclear/temp = new - var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for a nuke team being sent in?", "operative", temp) + var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for a nuke team being sent in?", "operative", temp) var/list/mob/dead/observer/chosen = list() var/mob/dead/observer/theghost = null @@ -288,7 +288,7 @@ // DEATH SQUADS /datum/admins/proc/makeDeathsquad() var/mission = input("Assign a mission to the deathsquad", "Assign Mission", "Leave no witnesses.") - var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for an elite Nanotrasen Strike Team?", "deathsquad", null) + var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for an elite Nanotrasen Strike Team?", "deathsquad", null) var/squadSpawned = 0 if(candidates.len >= 2) //Minimum 2 to be considered a squad @@ -396,7 +396,7 @@ /datum/admins/proc/makeOfficial() var/mission = input("Assign a task for the official", "Assign Task", "Conduct a routine preformance review of [station_name()] and its Captain.") - var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered to be a Centcom Official?", "deathsquad") + var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered to be a Centcom Official?", "deathsquad") if(candidates.len) var/mob/dead/observer/chosen_candidate = pick(candidates) @@ -457,7 +457,7 @@ var/mission = input("Assign a mission to the Emergency Response Team", "Assign Mission", "Assist the station.") as null|text if(!mission) return - var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for a Code [alert] Nanotrasen Emergency Response Team?", "deathsquad", null) + var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you wish to be considered for a Code [alert] Nanotrasen Emergency Response Team?", "deathsquad", null) var/teamSpawned = 0 if(candidates.len > 0) diff --git a/code/modules/admin/verbs/playsound.dm b/code/modules/admin/verbs/playsound.dm index f417dfbad3..2397f6c4a5 100644 --- a/code/modules/admin/verbs/playsound.dm +++ b/code/modules/admin/verbs/playsound.dm @@ -21,7 +21,7 @@ var/res = alert(usr, "Show the title of this song to the players?",, "No", "Yes", "Cancel") switch(res) if("Yes") - to_chat(world, "An admin played: [S]") + to_chat(world, "An admin played: [S]") if("Cancel") return diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 547e8e1d03..288027454a 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -112,6 +112,7 @@ message_admins(" LocalNarrate: [key_name_admin(usr)] at [get_area(A)][ADMIN_JMP(A)]: [msg]
") SSblackbox.add_details("admin_verb","Local Narrate") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + /client/proc/cmd_admin_godmode(mob/M in GLOB.mob_list) set category = "Special Verbs" set name = "Godmode" @@ -350,7 +351,6 @@ Traitors and the like can also be revived with the previous role mostly intact. if(G_found.mind && !G_found.mind.active) G_found.mind.transfer_to(new_character) //be careful when doing stuff like this! I've already checked the mind isn't in use - new_character.mind.special_verbs = list() else new_character.mind_initialize() if(!new_character.mind.assigned_role) @@ -701,7 +701,7 @@ Traitors and the like can also be revived with the previous role mostly intact. set name = "Make Everyone Random" set desc = "Make everyone have a random appearance. You can only use this before rounds!" - if(SSticker.HasRoundStarted()) + if(SSticker.HasRoundStarted()) to_chat(usr, "Nope you can't do this, the game's already started. This only works before rounds!") return diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 897812db5c..c1fd6de4a5 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -93,10 +93,10 @@ if(href_list["time"]) timing = text2num(href_list["time"]) if(timing && istype(holder, /obj/item/device/transfer_valve)) - var/timer_message = "[key_name_admin(usr)](?) (FLW) activated [src] attachment on [holder]." + var/timer_message = "[ADMIN_LOOKUPFLW(usr)] activated [src] attachment on [holder]." message_admins(timer_message) GLOB.bombers += timer_message - log_game("[key_name(usr)] activated [src] attachment for [loc]") + log_game("[key_name(usr)] activated [src] attachment on [holder]") update_icon() if(href_list["repeat"]) loop = text2num(href_list["repeat"]) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 2a67b5fe13..99db88dfe3 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -153,30 +153,31 @@ return var/datum/gas_mixture/air1 = AIR1 var/turf/T = get_turf(src) - if(occupant) - if(occupant.health >= 100) // Don't bother with fully healed people. + if(isliving(occupant)) + var/mob/living/mob_occupant + if(mob_occupant.health >= 100) // Don't bother with fully healed people. on = FALSE update_icon() - playsound(T, 'sound/machines/cryo_warning.ogg', volume, 1) // Bug the doctors. - radio.talk_into(src, "Patient fully restored", radio_channel) + playsound(T, 'sound/machines/cryo_warning.ogg', volume) // Bug the doctors. + radio.talk_into(src, "Patient fully restored", radio_channel, get_spans(), get_default_language()) if(autoeject) // Eject if configured. - radio.talk_into(src, "Auto ejecting patient now", radio_channel,get_spans(), get_default_language()) + radio.talk_into(src, "Auto ejecting patient now", radio_channel, get_spans(), get_default_language()) open_machine() return - else if(occupant.stat == DEAD) // We don't bother with dead people. + else if(mob_occupant.stat == DEAD) // We don't bother with dead people. return if(autoeject) // Eject if configured. open_machine() return if(air1.gases.len) - if(occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic. - occupant.Sleeping((occupant.bodytemperature / sleep_factor) * 100) - occupant.Paralyse((occupant.bodytemperature / paralyze_factor) * 100) + if(mob_occupant.bodytemperature < T0C) // Sleepytime. Why? More cryo magic. + mob_occupant.Sleeping((mob_occupant.bodytemperature / sleep_factor) * 100) + mob_occupant.Paralyse((mob_occupant.bodytemperature / paralyze_factor) * 100) if(beaker) if(reagent_transfer == 0) // Magically transfer reagents. Because cryo magic. - beaker.reagents.trans_to(occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic. - beaker.reagents.reaction(occupant, VAPOR) + beaker.reagents.trans_to(mob_occupant, 1, 10 * efficiency) // Transfer reagents, multiplied because cryo magic. + beaker.reagents.reaction(mob_occupant, VAPOR) air1.gases["o2"][MOLES] -= 2 / efficiency // Lets use gas for this. if(++reagent_transfer >= 10 * efficiency) // Throttle reagent transfer (higher efficiency will transfer the same amount but consume less from the beaker). reagent_transfer = 0 @@ -191,20 +192,21 @@ on = FALSE update_icon() return - if(occupant) + if(isliving(occupant)) + var/mob/living/mob_occupant = occupant var/cold_protection = 0 var/mob/living/carbon/human/H = occupant if(istype(H)) cold_protection = H.get_cold_protection(air1.temperature) - var/temperature_delta = air1.temperature - occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant. + var/temperature_delta = air1.temperature - mob_occupant.bodytemperature // The only semi-realistic thing here: share temperature between the cell and the occupant. if(abs(temperature_delta) > 1) var/air_heat_capacity = air1.heat_capacity() var/heat = ((1 - cold_protection) / 10 + conduction_coefficient) \ * temperature_delta * \ (air_heat_capacity * heat_capacity / (air_heat_capacity + heat_capacity)) air1.temperature = max(air1.temperature - heat / air_heat_capacity, TCMB) - occupant.bodytemperature = max(occupant.bodytemperature + heat / heat_capacity, TCMB) + mob_occupant.bodytemperature = max(mob_occupant.bodytemperature + heat / heat_capacity, TCMB) air1.gases["o2"][MOLES] -= 0.5 / efficiency // Magically consume gas? Why not, we run on cryo magic. @@ -265,6 +267,9 @@ I.loc = src user.visible_message("[user] places [I] in [src].", \ "You place [I] in [src].") + var/reagentlist = pretty_string_from_reagent_list(I.reagents.reagent_list) + log_game("[key_name(user)] added an [I] to cyro containing [reagentlist]") + return if(!on && !occupant && !state_open) if(default_deconstruction_screwdriver(user, "pod0-o", "pod0", I)) @@ -294,17 +299,18 @@ data["autoEject"] = autoeject var/list/occupantData = list() - if(occupant) - occupantData["name"] = occupant.name - occupantData["stat"] = occupant.stat - occupantData["health"] = occupant.health - occupantData["maxHealth"] = occupant.maxHealth + if(isliving(occupant)) + var/mob/living/mob_occupant = occupant + occupantData["name"] = mob_occupant.name + occupantData["stat"] = mob_occupant.stat + occupantData["health"] = mob_occupant.health + occupantData["maxHealth"] = mob_occupant.maxHealth occupantData["minHealth"] = HEALTH_THRESHOLD_DEAD - occupantData["bruteLoss"] = occupant.getBruteLoss() - occupantData["oxyLoss"] = occupant.getOxyLoss() - occupantData["toxLoss"] = occupant.getToxLoss() - occupantData["fireLoss"] = occupant.getFireLoss() - occupantData["bodyTemperature"] = occupant.bodytemperature + occupantData["bruteLoss"] = mob_occupant.getBruteLoss() + occupantData["oxyLoss"] = mob_occupant.getOxyLoss() + occupantData["toxLoss"] = mob_occupant.getToxLoss() + occupantData["fireLoss"] = mob_occupant.getFireLoss() + occupantData["bodyTemperature"] = mob_occupant.bodytemperature data["occupant"] = occupantData @@ -355,4 +361,4 @@ return //can't ventcrawl in or out of cryo. /obj/machinery/atmospherics/components/unary/cryo_cell/can_see_pipes() - return 0 //you can't see the pipe network when inside a cryo cell. + return 0 //you can't see the pipe network when inside a cryo cell. \ No newline at end of file diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm index f9e3b79ed6..f5168db1c3 100644 --- a/code/modules/atmospherics/machinery/other/meter.dm +++ b/code/modules/atmospherics/machinery/other/meter.dm @@ -16,22 +16,17 @@ armor = list(melee = 0, bullet = 0, laser = 0, energy = 100, bomb = 0, bio = 100, rad = 100, fire = 40, acid = 0) -/obj/machinery/meter/New() - ..() +/obj/machinery/meter/Initialize(mapload) + . = ..() SSair.atmos_machinery += src - src.target = locate(/obj/machinery/atmospherics/pipe) in loc - return 1 + if (mapload && !target) + target = locate(/obj/machinery/atmospherics/pipe) in loc /obj/machinery/meter/Destroy() SSair.atmos_machinery -= src src.target = null return ..() -/obj/machinery/meter/Initialize(mapload) - ..() - if (mapload && !target) - src.target = locate(/obj/machinery/atmospherics/pipe) in loc - /obj/machinery/meter/process_atmos() if(!target) icon_state = "meterX" diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index f5613c0b7e..7c9989c15d 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -400,8 +400,8 @@ var/bz = air_contents.gases["bz"] var/freon = air_contents.gases["freon"] if(n2o || plasma || bz || freon) - message_admins("[key_name_admin(usr)] (?) (FLW) opened a canister that contains the following: (JMP)") - log_admin("[key_name(usr)] opened a canister that contains the following at [x], [y], [z]:") + message_admins("[ADMIN_LOOKUPFLW(usr)] opened a canister that contains the following: [ADMIN_JMP(src)]") + log_admin("[key_name(usr)] opened a canister that contains the following at [COORD(src)]:") if(plasma) log_admin("Plasma") message_admins("Plasma") diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index 40f88cbecb..63082d1988 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -103,8 +103,9 @@ var/plasma = air_contents.gases["plasma"] var/n2o = air_contents.gases["n2o"] if(n2o || plasma) - message_admins("[key_name_admin(usr)] (?) (FLW) turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""]! (JMP)") - log_admin("[key_name(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [x], [y], [z]") + var/area/A = get_area(src) + message_admins("[ADMIN_LOOKUPFLW(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [A][ADMIN_JMP(src)]") + log_admin("[key_name(usr)] turned on a pump that contains [n2o ? "N2O" : ""][n2o && plasma ? " & " : ""][plasma ? "Plasma" : ""] at [A][COORD(src)]") . = TRUE if("direction") if(direction == PUMP_OUT) diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 80d6d84a68..c46399fa29 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -227,7 +227,7 @@ GLOBAL_DATUM(the_gateway, /obj/machinery/gateway/centerstation) if(check_exile_implant(C)) say("Rejecting [AM]: Exile implant detected in contained lifeform.") return - if(AM.buckled_mobs.len) + if(AM.has_buckled_mobs()) for(var/mob/living/carbon/C in AM.buckled_mobs) if(check_exile_implant(C)) say("Rejecting [AM]: Exile implant detected in close proximity lifeform.") diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm index f24075702a..7a665b40f3 100644 --- a/code/modules/awaymissions/mission_code/Academy.dm +++ b/code/modules/awaymissions/mission_code/Academy.dm @@ -64,17 +64,18 @@ next_check = world.time + cooldown /obj/structure/academy_wizard_spawner/proc/give_control() + set waitfor = FALSE + if(!current_wizard) return - spawn(0) - var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as Wizard Academy Defender?", "wizard", null, ROLE_WIZARD, current_wizard) - var/mob/dead/observer/chosen = null - - if(candidates.len) - chosen = pick(candidates) - message_admins("[key_name_admin(chosen)] was spawned as Wizard Academy Defender") - current_wizard.ghostize() // on the off chance braindead defender gets back in - current_wizard.key = chosen.key + var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as Wizard Academy Defender?", "wizard", null, be_special_flag = ROLE_WIZARD, M = current_wizard) + var/mob/dead/observer/chosen = null + + if(candidates.len) + chosen = pick(candidates) + message_admins("[key_name_admin(chosen)] was spawned as Wizard Academy Defender") + current_wizard.ghostize() // on the off chance braindead defender gets back in + current_wizard.key = chosen.key /obj/structure/academy_wizard_spawner/proc/summon_wizard() var/turf/T = src.loc diff --git a/code/modules/cargo/exports/materials.dm b/code/modules/cargo/exports/materials.dm index c2a0734958..8f3292df3a 100644 --- a/code/modules/cargo/exports/materials.dm +++ b/code/modules/cargo/exports/materials.dm @@ -50,11 +50,6 @@ material_id = MAT_PLASMA message = "cm3 of plasma" -/datum/export/material/plasma/get_cost(obj/O, contr = 0, emag = 0) - . = ..() - if(emag) // Syndicate pays you more for the plasma. - . = round(. * 1.5) - // Uranium. Still useful for both power generation and nuclear annihilation. /datum/export/material/uranium cost = 400 @@ -98,4 +93,4 @@ message = "cm3 of glass" material_id = MAT_GLASS export_types = list(/obj/item/stack/sheet/glass, /obj/item/weapon/ore, - /obj/item/weapon/shard) \ No newline at end of file + /obj/item/weapon/shard) diff --git a/code/modules/cargo/exports/sheets.dm b/code/modules/cargo/exports/sheets.dm index 707dab703c..06f2d6d019 100644 --- a/code/modules/cargo/exports/sheets.dm +++ b/code/modules/cargo/exports/sheets.dm @@ -88,7 +88,7 @@ // Wood. Quite expensive in the grim and dark 26 century. /datum/export/stack/wood - cost = 25 + cost = 50 unit_name = "wood plank" export_types = list(/obj/item/stack/sheet/mineral/wood) diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm index b7c7a7e377..b88cfc0315 100644 --- a/code/modules/cargo/packs.dm +++ b/code/modules/cargo/packs.dm @@ -182,14 +182,14 @@ /datum/supply_pack/emergency/syndicate name = "NULL_ENTRY" hidden = TRUE - cost = 14000 + cost = 20000 contains = list() crate_name = "emergency crate" crate_type = /obj/structure/closet/crate/internals dangerous = TRUE /datum/supply_pack/emergency/syndicate/fill(obj/structure/closet/crate/C) - var/crate_value = 50 + var/crate_value = 30 var/list/uplink_items = get_uplink_items(SSticker.mode) while(crate_value) var/category = pick(uplink_items) @@ -828,6 +828,14 @@ /obj/item/weapon/defibrillator/loaded) crate_name = "defibrillator crate" +/datum/supply_pack/medical/vending + name = "Medical Vending Crate" + cost = 2000 + contains = list(/obj/item/weapon/vending_refill/medical, + /obj/item/weapon/vending_refill/medical, + /obj/item/weapon/vending_refill/medical) + crate_name = "medical vending crate" + ////////////////////////////////////////////////////////////////////////////// //////////////////////////// Science ///////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// @@ -1680,15 +1688,6 @@ /obj/item/toy/crayon/rainbow) crate_name = "art supply crate" -/datum/supply_pack/misc/soapstone - name = "Librarian Engraving/Scribbling Crate" - crate_name = "librarian engraving/scribbling crate" - cost = 3000 - contains = list(/obj/item/soapstone) - access = GLOB.access_library - crate_type = /obj/structure/closet/crate/secure - - /datum/supply_pack/misc/bsa name = "Bluespace Artillery Parts" cost = 15000 diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 739e0231ca..221043bd8a 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -39,9 +39,12 @@ //////////////////////////////////// //things that require the database// //////////////////////////////////// - var/player_age = "Requires database" //So admins know why it isn't working - Used to determine how old the account is - in days. + var/player_age = -1 //Used to determine how old the account is - in days. + var/player_join_date = null //Date that this account was first seen in the server var/related_accounts_ip = "Requires database" //So admins know why it isn't working - Used to determine what other accounts previously logged in from this ip var/related_accounts_cid = "Requires database" //So admins know why it isn't working - Used to determine what other accounts previously logged in from this computer id + var/account_join_date = null //Date of byond account creation in ISO 8601 format + var/account_age = -1 //Age of byond account in days preload_rsc = PRELOAD_RSC @@ -62,4 +65,4 @@ var/connection_timeofday //world.timeofday they connected var/inprefs = FALSE - var/list/topiclimiter \ No newline at end of file + var/list/topiclimiter diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 4f6642f051..0d5e93fba7 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -80,8 +80,7 @@ */ //Logs all hrefs - if(config && config.log_hrefs && GLOB.href_logfile) - GLOB.href_logfile << "[time_stamp(show_ds = TRUE)] [src] (usr:[usr]) || [hsrc ? "[hsrc] " : ""][href]
" + GLOB.world_href_log << "[time_stamp(show_ds = TRUE)] [src] (usr:[usr]) || [hsrc ? "[hsrc] " : ""][href]
" // Admin PM if(href_list["priv_msg"]) @@ -289,16 +288,11 @@ GLOBAL_LIST(external_rsc_urls) mentor_memo_output("Show") */ add_verbs_from_config() - set_client_age_from_db() + set_client_age_from_db(tdata) var/cached_player_age = player_age //we have to cache this because other shit may change it and we need it's current value now down below. if (isnum(cached_player_age) && cached_player_age == -1) //first connection - player_age = 0 - if(!IsGuestKey(key) && SSdbcore.IsConnected()) - findJoinDate() + player_age = 0 - sync_client_with_db(tdata) - - if (isnum(cached_player_age) && cached_player_age == -1) //first connection if (config.panic_bunker && !holder && !(ckey in GLOB.deadmins)) log_access("Failed Login: [key] - New account attempting to connect during panic bunker") @@ -311,20 +305,19 @@ GLOBAL_LIST(external_rsc_urls) qdel(src) return 0 + if (config.notify_new_player_age >= 0) message_admins("New user: [key_name_admin(src)] is connecting here for the first time.") if (config.irc_first_connection_alert) send2irc_adminless_only("New-user", "[key_name(src)] is connecting for the first time!") - - player_age = 0 // set it from -1 to 0 so the job selection code doesn't have a panic attack - - else if (isnum(player_age) && player_age < config.notify_new_player_age) - message_admins("New user: [key_name_admin(src)] just connected with an age of [player_age] day[(player_age==1?"":"s")]") - - if(!IsGuestKey(key) && SSdbcore.IsConnected()) - findJoinDate() - - sync_client_with_db(tdata) + else if (isnum(cached_player_age) && cached_player_age < config.notify_new_player_age) + message_admins("New user: [key_name_admin(src)] just connected with an age of [cached_player_age] day[(player_age==1?"":"s")]") + if(config.use_account_age_for_jobs && account_age >= 0) + player_age = account_age + if(account_age >= 0 && account_age < config.notify_new_player_account_age) + message_admins("[key_name_admin(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age==1?"":"s")] old, created on [account_join_date].") + if (config.irc_first_connection_alert) + send2irc_adminless_only("new_byond_user", "[key_name(src)] (IP: [address], ID: [computer_id]) is a new BYOND account [account_age] day[(account_age==1?"":"s")] old, created on [account_join_date].") get_message_output("watchlist entry", ckey) check_ip_intel() @@ -360,6 +353,27 @@ GLOBAL_LIST(external_rsc_urls) hook_vr("client_new",list(src)) + var/list/topmenus = GLOB.menulist[/datum/menu] + for (var/thing in topmenus) + var/datum/menu/topmenu = thing + var/topmenuname = "[topmenu]" + if (topmenuname == "[topmenu.type]") + var/list/tree = splittext(topmenuname, "/") + topmenuname = tree[tree.len] + winset(src, "[topmenu.type]", "parent=menu;name=[url_encode(topmenuname)]") + var/list/entries = topmenu.Generate_list(src) + for (var/child in entries) + winset(src, "[url_encode(child)]", "[entries[child]]") + if (!ispath(child, /datum/menu)) + var/atom/verb/verbpath = child + if (copytext(verbpath.name,1,2) != "@") + new child(src) + + for (var/thing in prefs.menuoptions) + var/datum/menu/menuitem = GLOB.menulist[thing] + if (menuitem) + menuitem.Load_checked(src) + ////////////// //DISCONNECT// ////////////// @@ -370,8 +384,8 @@ GLOBAL_LIST(external_rsc_urls) adminGreet(1) holder.owner = null GLOB.admins -= src - - if (!GLOB.admins.len && SSticker.current_state == GAME_STATE_PLAYING) //Only report this stuff if we are currently playing. + + if (!GLOB.admins.len && SSticker.IsRoundInProgress()) //Only report this stuff if we are currently playing. if(!GLOB.admins.len) //Apparently the admin logging out is no longer an admin at this point, so we have to check this towards 0 and not towards 1. Awell. var/cheesy_message = pick( "I have no admins online!",\ @@ -396,7 +410,7 @@ GLOBAL_LIST(external_rsc_urls) "Sometimes when I have sex, I think about putting an entire peanut butter and jelly sandwich in the VCR.",\ "Forever alone :("\ ) - + send2irc("Server", "[cheesy_message] (No admins online)") GLOB.ahelp_tickets.ClientLogout(src) @@ -410,70 +424,86 @@ GLOBAL_LIST(external_rsc_urls) /client/Destroy() return QDEL_HINT_HARDDEL_NOW -/client/proc/set_client_age_from_db() +/client/proc/set_client_age_from_db(connectiontopic) if (IsGuestKey(src.key)) return - if(!SSdbcore.Connect()) return - var/sql_ckey = sanitizeSQL(src.ckey) - - var/datum/DBQuery/query_get_client_age = SSdbcore.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'") - if(!query_get_client_age.Execute()) - return - - while(query_get_client_age.NextRow()) - player_age = text2num(query_get_client_age.item[2]) - return - - //no match mark it as a first connection for use in client/New() - player_age = -1 - - -/client/proc/sync_client_with_db(connectiontopic) - if (IsGuestKey(src.key)) - return - - if (!SSdbcore.Connect()) - return - - var/sql_ckey = sanitizeSQL(ckey) - - var/datum/DBQuery/query_get_ip = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ip = INET_ATON('[address]') AND ckey != '[sql_ckey]'") - query_get_ip.Execute() + var/datum/DBQuery/query_get_related_ip = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ip = INET_ATON('[address]') AND ckey != '[sql_ckey]'") + query_get_related_ip.Execute() related_accounts_ip = "" - while(query_get_ip.NextRow()) - related_accounts_ip += "[query_get_ip.item[1]], " - - var/datum/DBQuery/query_get_cid = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE computerid = '[computer_id]' AND ckey != '[sql_ckey]'") - if(!query_get_cid.Execute()) + while(query_get_related_ip.NextRow()) + related_accounts_ip += "[query_get_related_ip.item[1]], " + var/datum/DBQuery/query_get_related_cid = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE computerid = '[computer_id]' AND ckey != '[sql_ckey]'") + if(!query_get_related_cid.Execute()) return related_accounts_cid = "" - while (query_get_cid.NextRow()) - related_accounts_cid += "[query_get_cid.item[1]], " - + while (query_get_related_cid.NextRow()) + related_accounts_cid += "[query_get_related_cid.item[1]], " var/admin_rank = "Player" if (src.holder && src.holder.rank) admin_rank = src.holder.rank.name else if (check_randomizer(connectiontopic)) return - - var/sql_ip = sanitizeSQL(src.address) - var/sql_computerid = sanitizeSQL(src.computer_id) + var/sql_ip = sanitizeSQL(address) + var/sql_computerid = sanitizeSQL(computer_id) var/sql_admin_rank = sanitizeSQL(admin_rank) - - - var/datum/DBQuery/query_log_player = SSdbcore.NewQuery("INSERT INTO [format_table_name("player")] (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, '[sql_ckey]', Now(), Now(), INET_ATON('[sql_ip]'), '[sql_computerid]', '[sql_admin_rank]') ON DUPLICATE KEY UPDATE lastseen = VALUES(lastseen), ip = VALUES(ip), computerid = VALUES(computerid), lastadminrank = VALUES(lastadminrank)") - if(!query_log_player.Execute()) + var/new_player + var/datum/DBQuery/query_client_in_db = SSdbcore.NewQuery("SELECT 1 FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'") + if(!query_client_in_db.Execute()) return - - //Logging player access - + if(!query_client_in_db.NextRow()) + new_player = 1 + account_join_date = sanitizeSQL(findJoinDate()) + var/datum/DBQuery/query_add_player = SSdbcore.NewQuery("INSERT INTO [format_table_name("player")] (`ckey`, `firstseen`, `lastseen`, `ip`, `computerid`, `lastadminrank`, `accountjoindate`) VALUES ('[sql_ckey]', Now(), Now(), INET_ATON('[sql_ip]'), '[sql_computerid]', '[sql_admin_rank]', [account_join_date ? "'[account_join_date]'" : "NULL"])") + if(!query_add_player.Execute()) + return + if(!account_join_date) + account_join_date = "Error" + account_age = -1 + var/datum/DBQuery/query_get_client_age = SSdbcore.NewQuery("SELECT firstseen, DATEDIFF(Now(),firstseen), accountjoindate, DATEDIFF(Now(),accountjoindate) FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'") + if(!query_get_client_age.Execute()) + return + if(query_get_client_age.NextRow()) + player_join_date = query_get_client_age.item[1] + player_age = text2num(query_get_client_age.item[2]) + if(!account_join_date) + account_join_date = query_get_client_age.item[3] + account_age = text2num(query_get_client_age.item[4]) + if(!account_age) + account_join_date = sanitizeSQL(findJoinDate()) + if(!account_join_date) + account_age = -1 + else + var/datum/DBQuery/query_datediff = SSdbcore.NewQuery("SELECT DATEDIFF(Now(),[account_join_date])") + if(!query_datediff.Execute()) + return + if(query_datediff.NextRow()) + account_age = text2num(query_datediff.item[1]) + if(!new_player) + var/datum/DBQuery/query_log_player = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET lastseen = Now(), ip = INET_ATON('[sql_ip]'), computerid = '[sql_computerid]', lastadminrank = '[sql_admin_rank]', accountjoindate = [account_join_date ? "'[account_join_date]'" : "NULL"] WHERE ckey = '[sql_ckey]'") + if(!query_log_player.Execute()) + return + if(!account_join_date) + account_join_date = "Error" var/datum/DBQuery/query_log_connection = SSdbcore.NewQuery("INSERT INTO `[format_table_name("connection_log")]` (`id`,`datetime`,`server_ip`,`server_port`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),INET_ATON('[world.internet_address]'),'[world.port]','[sql_ckey]',INET_ATON('[sql_ip]'),'[sql_computerid]')") query_log_connection.Execute() +/client/proc/findJoinDate() + var/list/http = world.Export("http://byond.com/members/[ckey]?format=text") + if(!http) + log_world("Failed to connect to byond age check for [ckey]") + return + var/F = file2text(http["CONTENT"]) + if(F) + var/regex/R = regex("joined = \"(\\d{4}-\\d{2}-\\d{2})\"") + if(R.Find(F)) + . = R.group[1] + else + CRASH("Age check regex failed for [src.ckey]") + /client/proc/check_randomizer(topic) . = FALSE if (connection != "seeker") diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 631871288d..8d5bbde4b3 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -168,6 +168,8 @@ GLOBAL_LIST_EMPTY(preferences_datums) var/uplink_spawn_loc = UPLINK_PDA + var/list/menuoptions + //citadel code var/arousable = TRUE //Allows players to disable arousal from the character creation menu var/flavor_text = "" @@ -194,6 +196,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(!loaded_preferences_successfully) save_preferences() save_character() //let's save this new random character so it doesn't keep generating new ones. + menuoptions = list() return /datum/preferences/proc/ShowChoices(mob/user) @@ -790,7 +793,7 @@ GLOBAL_LIST_EMPTY(preferences_datums) if(href_list["jobbancheck"]) var/job = sanitizeSQL(href_list["jobbancheck"]) var/sql_ckey = sanitizeSQL(user.ckey) - var/datum/DBQuery/query_get_jobban = SSdbcore.NewQuery("SELECT reason, bantime, duration, expiration_time, a_ckey FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[job]'") + var/datum/DBQuery/query_get_jobban = SSdbcore.NewQuery("SELECT reason, bantime, duration, expiration_time, a_ckey FROM [format_table_name("ban")] WHERE ckey = '[sql_ckey]' AND (bantype = 'JOB_PERMABAN' OR (bantype = 'JOB_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned) AND job = '[job]'") if(!query_get_jobban.warn_execute()) return if(query_get_jobban.NextRow()) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 128a07ebd1..076761f93f 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -1,5 +1,5 @@ //This is the lowest supported version, anything below this is completely obsolete and the entire savefile will be wiped. -#define SAVEFILE_VERSION_MIN 10 +#define SAVEFILE_VERSION_MIN 15 //This is the current version, anything below this will attempt to update (if it's not obsolete) #define SAVEFILE_VERSION_MAX 20 @@ -88,15 +88,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car /datum/preferences/proc/update_preferences(current_version, savefile/S) - if(current_version < 10) - toggles |= MEMBER_PUBLIC - if(current_version < 11) - chat_toggles = TOGGLES_DEFAULT_CHAT - toggles = TOGGLES_DEFAULT - if(current_version < 12) - ignoring = list() - if(current_version < 15) - toggles |= SOUND_ANNOUNCEMENTS //should this proc get fairly long (say 3 versions long), @@ -106,16 +97,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car //It's only really meant to avoid annoying frequent players //if your savefile is 3 months out of date, then 'tough shit'. /datum/preferences/proc/update_character(current_version, savefile/S) - if(pref_species && !(pref_species.id in GLOB.roundstart_species)) - var/rando_race = pick(config.roundstart_races) - pref_species = new rando_race() - - if(current_version < 13 || !istext(backbag)) - switch(backbag) - if(2) - backbag = DSATCHEL - else - backbag = DBACKPACK if(current_version < 16) var/berandom S["userandomjob"] >> berandom @@ -186,12 +167,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["tgui_fancy"] >> tgui_fancy S["tgui_lock"] >> tgui_lock S["windowflash"] >> windowflashing + S["be_special"] >> be_special - if(islist(S["be_special"])) - S["be_special"] >> be_special - else //force update and store the old bitflag version of be_special - needs_update = 12 - S["be_special"] >> old_be_special S["default_slot"] >> default_slot S["chat_toggles"] >> chat_toggles @@ -207,6 +184,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["uses_glasses_colour"]>> uses_glasses_colour S["clientfps"] >> clientfps S["parallax"] >> parallax + S["menuoptions"] >> menuoptions //citadel code S["arousable"] >> arousable @@ -231,6 +209,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit)) ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION) ghost_others = sanitize_inlist(ghost_others, GLOB.ghost_others_options, GHOST_OTHERS_DEFAULT_OPTION) + menuoptions = SANITIZE_LIST(menuoptions) + be_special = SANITIZE_LIST(be_special) + return 1 @@ -267,6 +248,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["uses_glasses_colour"]<< uses_glasses_colour S["clientfps"] << clientfps S["parallax"] << parallax + S["menuoptions"] << menuoptions //citadel code S["arousable"] << arousable @@ -299,9 +281,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(config.mutant_races && species_id && (species_id in GLOB.roundstart_species)) var/newtype = GLOB.roundstart_species[species_id] pref_species = new newtype() - else + else if (config.roundstart_races.len) var/rando_race = pick(config.roundstart_races) - pref_species = new rando_race() + if (rando_race) + pref_species = new rando_race() if(!S["features["mcolor"]"] || S["features["mcolor"]"] == "#000") S["features["mcolor"]"] << "#FFF" @@ -565,7 +548,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car #undef SAVEFILE_VERSION_MAX #undef SAVEFILE_VERSION_MIN -/* + +#ifdef TESTING //DEBUG //Some crude tools for testing savefiles //path is the savefile path @@ -576,4 +560,5 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car /client/verb/savefile_import(path as text) var/savefile/S = new /savefile(path) S.ImportText("/",file("[path].txt")) -*/ + +#endif \ No newline at end of file diff --git a/code/modules/client/preferences_toggles.dm b/code/modules/client/preferences_toggles.dm index 74cbc70b87..eb244937e6 100644 --- a/code/modules/client/preferences_toggles.dm +++ b/code/modules/client/preferences_toggles.dm @@ -1,162 +1,249 @@ -//toggles -/client/verb/toggle_ghost_ears() - set name = "Show/Hide GhostEars" - set category = "Preferences" - set desc = ".Toggle Between seeing all mob speech, and only speech of nearby mobs" - prefs.chat_toggles ^= CHAT_GHOSTEARS - to_chat(src, "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"].") - prefs.save_preferences() - SSblackbox.add_details("preferences_verb","Toggle Ghost Ears|[prefs.chat_toggles & CHAT_GHOSTEARS]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +//this works as is to create a single checked item, but has no back end code for toggleing the check yet +#define TOGGLE_CHECKBOX(PARENT, CHILD) PARENT/CHILD/abstract = TRUE;PARENT/CHILD/checkbox = CHECKBOX_TOGGLE;PARENT/CHILD/verb/CHILD -/client/verb/toggle_ghost_sight() - set name = "Show/Hide GhostSight" - set category = "Preferences" - set desc = ".Toggle Between seeing all mob emotes, and only emotes of nearby mobs" - prefs.chat_toggles ^= CHAT_GHOSTSIGHT - to_chat(src, "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"].") - prefs.save_preferences() - SSblackbox.add_details("preferences_verb","Toggle Ghost Sight|[prefs.chat_toggles & CHAT_GHOSTSIGHT]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +//Example usage TOGGLE_CHECKBOX(datum/menu/Settings/Ghost/chatterbox, toggle_ghost_ears)() -/client/verb/toggle_ghost_whispers() - set name = "Show/Hide GhostWhispers" - set category = "Preferences" - set desc = ".Toggle between hearing all whispers, and only whispers of nearby mobs" - prefs.chat_toggles ^= CHAT_GHOSTWHISPER - to_chat(src, "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTWHISPER) ? "see all whispers in the world" : "only see whispers from nearby mobs"].") - prefs.save_preferences() - SSblackbox.add_details("preferences_verb","Toggle Ghost Whispers|[prefs.chat_toggles & CHAT_GHOSTWHISPER]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +//override because we don't want to save preferences twice. +/datum/menu/Settings/Set_checked(client/C, verbpath) + if (checkbox == CHECKBOX_GROUP) + C.prefs.menuoptions[type] = verbpath + else if (checkbox == CHECKBOX_TOGGLE) + var/checked = Get_checked(C) + C.prefs.menuoptions[type] = !checked + winset(C, "[verbpath]", "is-checked = [!checked]") -/client/verb/toggle_ghost_radio() - set name = "Show/Hide GhostRadio" +/datum/menu/Settings/verb/setup_character() + set name = "Game Preferences" set category = "Preferences" - set desc = ".Enable or disable hearing radio chatter as a ghost" - prefs.chat_toggles ^= CHAT_GHOSTRADIO - to_chat(src, "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTRADIO) ? "see radio chatter" : "not see radio chatter"].") - prefs.save_preferences() - SSblackbox.add_details("preferences_verb","Toggle Ghost Radio|[prefs.chat_toggles & CHAT_GHOSTRADIO]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! //social experiment, increase the generation whenever you copypaste this shamelessly GENERATION 1 + set desc = "Open Game Preferences Window" + usr.client.prefs.current_tab = 1 + usr.client.prefs.ShowChoices(usr) + +//toggles +/datum/menu/Settings/Ghost/chatterbox + name = "Chat Box Spam" -/client/verb/toggle_ghost_pda() +TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox, toggle_ghost_ears)() + set name = "Show/Hide GhostEars" + set category = "Preferences" + set desc = "See All Speech" + usr.client.prefs.chat_toggles ^= CHAT_GHOSTEARS + to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTEARS) ? "see all speech in the world" : "only see speech from nearby mobs"].") + usr.client.prefs.save_preferences() + SSblackbox.add_details("preferences_verb","Toggle Ghost Ears|[usr.client.prefs.chat_toggles & CHAT_GHOSTEARS]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/menu/Settings/Ghost/chatterbox/toggle_ghost_ears/Get_checked(client/C) + return C.prefs.chat_toggles & CHAT_GHOSTEARS + +TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox, toggle_ghost_sight)() + set name = "Show/Hide GhostSight" + set category = "Preferences" + set desc = "See All Emotes" + usr.client.prefs.chat_toggles ^= CHAT_GHOSTSIGHT + to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) ? "see all emotes in the world" : "only see emotes from nearby mobs"].") + usr.client.prefs.save_preferences() + SSblackbox.add_details("preferences_verb","Toggle Ghost Sight|[usr.client.prefs.chat_toggles & CHAT_GHOSTSIGHT]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/menu/Settings/Ghost/chatterbox/toggle_ghost_sight/Get_checked(client/C) + return C.prefs.chat_toggles & CHAT_GHOSTSIGHT + +TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox, toggle_ghost_whispers)() + set name = "Show/Hide GhostWhispers" + set category = "Preferences" + set desc = "See All Whispers" + usr.client.prefs.chat_toggles ^= CHAT_GHOSTWHISPER + to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTWHISPER) ? "see all whispers in the world" : "only see whispers from nearby mobs"].") + usr.client.prefs.save_preferences() + SSblackbox.add_details("preferences_verb","Toggle Ghost Whispers|[usr.client.prefs.chat_toggles & CHAT_GHOSTWHISPER]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/menu/Settings/Ghost/chatterbox/toggle_ghost_whispers/Get_checked(client/C) + return C.prefs.chat_toggles & CHAT_GHOSTWHISPER + +TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox, toggle_ghost_radio)() + set name = "Show/Hide GhostRadio" + set category = "Preferences" + set desc = "See All Radio Chatter" + usr.client.prefs.chat_toggles ^= CHAT_GHOSTRADIO + to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTRADIO) ? "see radio chatter" : "not see radio chatter"].") + usr.client.prefs.save_preferences() + SSblackbox.add_details("preferences_verb","Toggle Ghost Radio|[usr.client.prefs.chat_toggles & CHAT_GHOSTRADIO]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! //social experiment, increase the generation whenever you copypaste this shamelessly GENERATION 1 +/datum/menu/Settings/Ghost/chatterbox/toggle_ghost_radio/Get_checked(client/C) + return C.prefs.chat_toggles & CHAT_GHOSTRADIO + +TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox, toggle_ghost_pda)() set name = "Show/Hide GhostPDA" - set category = "Preferences" - set desc = ".Toggle Between seeing all mob pda messages, and only pda messages of nearby mobs" - prefs.chat_toggles ^= CHAT_GHOSTPDA - to_chat(src, "As a ghost, you will now [(prefs.chat_toggles & CHAT_GHOSTPDA) ? "see all pda messages in the world" : "only see pda messages from nearby mobs"].") - prefs.save_preferences() - SSblackbox.add_details("preferences_verb","Toggle Ghost PDA|[prefs.chat_toggles & CHAT_GHOSTPDA]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + set category = "Preferences" + set desc = "See All PDA Messages" + usr.client.prefs.chat_toggles ^= CHAT_GHOSTPDA + to_chat(usr, "As a ghost, you will now [(usr.client.prefs.chat_toggles & CHAT_GHOSTPDA) ? "see all pda messages in the world" : "only see pda messages from nearby mobs"].") + usr.client.prefs.save_preferences() + SSblackbox.add_details("preferences_verb","Toggle Ghost PDA|[usr.client.prefs.chat_toggles & CHAT_GHOSTPDA]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/menu/Settings/Ghost/chatterbox/toggle_ghost_pda/Get_checked(client/C) + return C.prefs.chat_toggles & CHAT_GHOSTPDA + +/datum/menu/Settings/Ghost/chatterbox/Events + name = "Events" //please be aware that the following two verbs have inverted stat output, so that "Toggle Deathrattle|1" still means you activated it -/client/verb/toggle_deathrattle() +TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox/Events, toggle_deathrattle)() set name = "Toggle Deathrattle" - set category = "Preferences" - set desc = "Toggle recieving a message in deadchat when sentient mobs die." - prefs.toggles ^= DISABLE_DEATHRATTLE - prefs.save_preferences() - to_chat(usr, "You will [(prefs.toggles & DISABLE_DEATHRATTLE) ? "no longer" : "now"] get messages when a sentient mob dies.") - SSblackbox.add_details("preferences_verb", "Toggle Deathrattle|[!(prefs.toggles & DISABLE_DEATHRATTLE)]") //If you are copy-pasting this, maybe you should spend some time reading the comments. - -/client/verb/toggle_arrivalrattle() + set category = "Preferences" + set desc = "Death" + usr.client.prefs.toggles ^= DISABLE_DEATHRATTLE + usr.client.prefs.save_preferences() + to_chat(usr, "You will [(usr.client.prefs.toggles & DISABLE_DEATHRATTLE) ? "no longer" : "now"] get messages when a sentient mob dies.") + SSblackbox.add_details("preferences_verb", "Toggle Deathrattle|[!(usr.client.prefs.toggles & DISABLE_DEATHRATTLE)]") //If you are copy-pasting this, maybe you should spend some time reading the comments. +/datum/menu/Settings/Ghost/chatterbox/Events/toggle_deathrattle/Get_checked(client/C) + return !(C.prefs.toggles & DISABLE_DEATHRATTLE) + +TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost/chatterbox/Events, toggle_arrivalrattle)() set name = "Toggle Arrivalrattle" - set category = "Preferences" - set desc = "Toggle recieving a message in deadchat when someone joins the station." - prefs.toggles ^= DISABLE_ARRIVALRATTLE - to_chat(usr, "You will [(prefs.toggles & DISABLE_ARRIVALRATTLE) ? "no longer" : "now"] get messages when someone joins the station.") - prefs.save_preferences() - SSblackbox.add_details("preferences_verb", "Toggle Arrivalrattle|[!(prefs.toggles & DISABLE_ARRIVALRATTLE)]") //If you are copy-pasting this, maybe you should rethink where your life went so wrong. - -/client/verb/togglemidroundantag() + set category = "Preferences" + set desc = "New Player Arrival" + usr.client.prefs.toggles ^= DISABLE_ARRIVALRATTLE + to_chat(usr, "You will [(usr.client.prefs.toggles & DISABLE_ARRIVALRATTLE) ? "no longer" : "now"] get messages when someone joins the station.") + usr.client.prefs.save_preferences() + SSblackbox.add_details("preferences_verb", "Toggle Arrivalrattle|[!(usr.client.prefs.toggles & DISABLE_ARRIVALRATTLE)]") //If you are copy-pasting this, maybe you should rethink where your life went so wrong. +/datum/menu/Settings/Ghost/chatterbox/Events/toggle_arrivalrattle/Get_checked(client/C) + return !(C.prefs.toggles & DISABLE_ARRIVALRATTLE) + +TOGGLE_CHECKBOX(/datum/menu/Settings/Ghost, togglemidroundantag)() set name = "Toggle Midround Antagonist" - set category = "Preferences" - set desc = "Toggles whether or not you will be considered for antagonist status given during a round." - prefs.toggles ^= MIDROUND_ANTAG - prefs.save_preferences() - to_chat(src, "You will [(prefs.toggles & MIDROUND_ANTAG) ? "now" : "no longer"] be considered for midround antagonist positions.") - SSblackbox.add_details("preferences_verb","Toggle Midround Antag|[prefs.toggles & MIDROUND_ANTAG]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/verb/toggletitlemusic() + set category = "Preferences" + set desc = "Midround Antagonist" + usr.client.prefs.toggles ^= MIDROUND_ANTAG + usr.client.prefs.save_preferences() + to_chat(usr, "You will [(usr.client.prefs.toggles & MIDROUND_ANTAG) ? "now" : "no longer"] be considered for midround antagonist positions.") + SSblackbox.add_details("preferences_verb","Toggle Midround Antag|[usr.client.prefs.toggles & MIDROUND_ANTAG]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/menu/Settings/Ghost/togglemidroundantag/Get_checked(client/C) + return C.prefs.toggles & MIDROUND_ANTAG + +TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, toggletitlemusic)() set name = "Hear/Silence LobbyMusic" set category = "Preferences" - set desc = "Toggles hearing the GameLobby music" - prefs.toggles ^= SOUND_LOBBY - prefs.save_preferences() - if(prefs.toggles & SOUND_LOBBY) - to_chat(src, "You will now hear music in the game lobby.") - if(isnewplayer(mob)) - playtitlemusic() + set desc = "Hear Music In Lobby" + usr.client.prefs.toggles ^= SOUND_LOBBY + usr.client.prefs.save_preferences() + if(usr.client.prefs.toggles & SOUND_LOBBY) + to_chat(usr, "You will now hear music in the game lobby.") + if(isnewplayer(usr)) + usr.client.playtitlemusic() else - to_chat(src, "You will no longer hear music in the game lobby.") - mob.stop_sound_channel(CHANNEL_LOBBYMUSIC) - SSblackbox.add_details("preferences_verb","Toggle Lobby Music|[prefs.toggles & SOUND_LOBBY]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + to_chat(usr, "You will no longer hear music in the game lobby.") + usr.stop_sound_channel(CHANNEL_LOBBYMUSIC) + SSblackbox.add_details("preferences_verb","Toggle Lobby Music|[usr.client.prefs.toggles & SOUND_LOBBY]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/menu/Settings/Sound/toggletitlemusic/Get_checked(client/C) + return C.prefs.toggles & SOUND_LOBBY + -/client/verb/togglemidis() +TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, togglemidis)() set name = "Hear/Silence Midis" set category = "Preferences" - set desc = "Toggles hearing sounds uploaded by admins" - prefs.toggles ^= SOUND_MIDI - prefs.save_preferences() - if(prefs.toggles & SOUND_MIDI) - to_chat(src, "You will now hear any sounds uploaded by admins.") + set desc = "Hear Admin Triggered Sounds (Midis)" + usr.client.prefs.toggles ^= SOUND_MIDI + usr.client.prefs.save_preferences() + if(usr.client.prefs.toggles & SOUND_MIDI) + to_chat(usr, "You will now hear any sounds uploaded by admins.") else - to_chat(src, "You will no longer hear sounds uploaded by admins") - mob.stop_sound_channel(CHANNEL_ADMIN) - SSblackbox.add_details("preferences_verb","Toggle Hearing Midis|[prefs.toggles & SOUND_MIDI]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + to_chat(usr, "You will no longer hear sounds uploaded by admins") + usr.stop_sound_channel(CHANNEL_ADMIN) + SSblackbox.add_details("preferences_verb","Toggle Hearing Midis|[usr.client.prefs.toggles & SOUND_MIDI]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/menu/Settings/Sound/togglemidis/Get_checked(client/C) + return C.prefs.toggles & SOUND_MIDI -/client/verb/stop_client_sounds() - set name = "Stop Sounds" + +TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, toggle_instruments)() + set name = "Hear/Silence Instruments" set category = "Preferences" - set desc = "Kills all currently playing sounds, use if admin taste in midis a shite" - src << sound(null) - SSblackbox.add_details("preferences_verb","Stop Self Sounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + set desc = "Hear In-game Instruments" + usr.client.prefs.toggles ^= SOUND_INSTRUMENTS + usr.client.prefs.save_preferences() + if(usr.client.prefs.toggles & SOUND_INSTRUMENTS) + to_chat(usr, "You will now hear people playing musical instruments.") + else + to_chat(usr, "You will no longer hear musical instruments.") + SSblackbox.add_details("preferences_verb","Toggle Instruments|[usr.client.prefs.toggles & SOUND_INSTRUMENTS]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/menu/Settings/Sound/toggle_instruments/Get_checked(client/C) + return C.prefs.toggles & SOUND_INSTRUMENTS + -/client/verb/listen_ooc() - set name = "Show/Hide OOC" - set category = "Preferences" - set desc = "Toggles seeing OutOfCharacter chat" - prefs.chat_toggles ^= CHAT_OOC - prefs.save_preferences() - to_chat(src, "You will [(prefs.chat_toggles & CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel.") - SSblackbox.add_details("preferences_verb","Toggle Seeing OOC|[prefs.chat_toggles & CHAT_OOC]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - -/client/verb/Toggle_Soundscape() //All new ambience should be added here so it works with this verb until someone better at things comes up with a fix that isn't awful +TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, Toggle_Soundscape)() set name = "Hear/Silence Ambience" set category = "Preferences" - set desc = "Toggles hearing ambient sound effects" - prefs.toggles ^= SOUND_AMBIENCE - prefs.save_preferences() - if(prefs.toggles & SOUND_AMBIENCE) - to_chat(src, "You will now hear ambient sounds.") + set desc = "Hear Ambient Sound Effects" + usr.client.prefs.toggles ^= SOUND_AMBIENCE + usr.client.prefs.save_preferences() + if(usr.client.prefs.toggles & SOUND_AMBIENCE) + to_chat(usr, "You will now hear ambient sounds.") else - to_chat(src, "You will no longer hear ambient sounds.") - src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 1) - src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2) - SSblackbox.add_details("preferences_verb","Toggle Ambience|[prefs.toggles & SOUND_AMBIENCE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + to_chat(usr, "You will no longer hear ambient sounds.") + usr << sound(null, repeat = 0, wait = 0, volume = 0, channel = 1) + usr << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2) + SSblackbox.add_details("preferences_verb","Toggle Ambience|[usr.client.prefs.toggles & SOUND_AMBIENCE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/menu/Settings/Sound/Toggle_Soundscape/Get_checked(client/C) + return C.prefs.toggles & SOUND_AMBIENCE -// This needs a toggle because you people are awful and spammed terrible music -/client/verb/toggle_instruments() - set name = "Hear/Silence Instruments" + +TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, toggle_ship_ambience)() + set name = "Hear/Silence Ship Ambience" set category = "Preferences" - set desc = "Toggles hearing musical instruments like the violin and piano" - prefs.toggles ^= SOUND_INSTRUMENTS - prefs.save_preferences() - if(prefs.toggles & SOUND_INSTRUMENTS) - to_chat(src, "You will now hear people playing musical instruments.") + set desc = "Hear Ship Ambience Roar" + usr.client.prefs.toggles ^= SOUND_SHIP_AMBIENCE + usr.client.prefs.save_preferences() + if(usr.client.prefs.toggles & SOUND_SHIP_AMBIENCE) + to_chat(usr, "You will now hear ship ambience.") else - to_chat(src, "You will no longer hear musical instruments.") - SSblackbox.add_details("preferences_verb","Toggle Instruments|[prefs.toggles & SOUND_INSTRUMENTS]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + to_chat(usr, "You will no longer hear ship ambience.") + usr << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2) + usr.client.ambience_playing = 0 + SSblackbox.add_details("preferences_verb", "Toggle Ship Ambience|[usr.client.prefs.toggles & SOUND_SHIP_AMBIENCE]") //If you are copy-pasting this, I bet you read this comment expecting to see the same thing :^) +/datum/menu/Settings/Sound/toggle_ship_ambience/Get_checked(client/C) + return C.prefs.toggles & SOUND_SHIP_AMBIENCE -//Lots of people get headaches from the normal ship ambience, this is to prevent that -/client/verb/toggle_ship_ambience() - set name = "Hear/Silence Ship Ambience" + +TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, toggle_announcement_sound)() + set name = "Hear/Silence Announcements" set category = "Preferences" - set desc = "Toggles hearing generalized ship ambience, no matter your area." - prefs.toggles ^= SOUND_SHIP_AMBIENCE - prefs.save_preferences() - if(prefs.toggles & SOUND_SHIP_AMBIENCE) - to_chat(src, "You will now hear ship ambience.") + set desc = "Hear Announcement Sound" + usr.client.prefs.toggles ^= SOUND_ANNOUNCEMENTS + to_chat(usr, "You will now [(usr.client.prefs.toggles & SOUND_ANNOUNCEMENTS) ? "hear announcement sounds" : "no longer hear announcements"].") + usr.client.prefs.save_preferences() + SSblackbox.add_details("preferences_verb","Toggle Announcement Sound|[usr.client.prefs.toggles & SOUND_ANNOUNCEMENTS]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/menu/Settings/Sound/toggle_announcement_sound/Get_checked(client/C) + return C.prefs.toggles & SOUND_ANNOUNCEMENTS + + +TOGGLE_CHECKBOX(/datum/menu/Settings/Sound, toggleprayersounds)() + set name = "Hear/Silence Prayer Sounds" + set category = "Preferences" + set desc = "Hear Prayer Sounds" + usr.client.prefs.toggles ^= SOUND_PRAYERS + usr.client.prefs.save_preferences() + if(usr.client.prefs.toggles & SOUND_PRAYERS) + to_chat(usr, "You will now hear prayer sounds.") else - to_chat(src, "You will no longer hear ship ambience.") - src << sound(null, repeat = 0, wait = 0, volume = 0, channel = 2) - src.ambience_playing = 0 - SSblackbox.add_details("preferences_verb", "Toggle Ship Ambience|[prefs.toggles & SOUND_SHIP_AMBIENCE]") //If you are copy-pasting this, I bet you read this comment expecting to see the same thing :^) + to_chat(usr, "You will no longer prayer sounds.") + SSblackbox.add_details("admin_toggle", "Toggle Prayer Sounds|[usr.client.prefs.toggles & SOUND_PRAYERS]") +/datum/menu/Settings/Sound/toggleprayersounds/Get_checked(client/C) + return C.prefs.toggles & SOUND_PRAYERS + + +/datum/menu/Settings/Sound/verb/stop_client_sounds() + set name = "Stop Sounds" + set category = "Preferences" + set desc = "Stop Current Sounds" + usr << sound(null) + SSblackbox.add_details("preferences_verb","Stop Self Sounds") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + +TOGGLE_CHECKBOX(/datum/menu/Settings, listen_ooc)() + set name = "Show/Hide OOC" + set category = "Preferences" + set desc = "Show OOC Chat" + usr.client.prefs.chat_toggles ^= CHAT_OOC + usr.client.prefs.save_preferences() + to_chat(usr, "You will [(usr.client.prefs.chat_toggles & CHAT_OOC) ? "now" : "no longer"] see messages on the OOC channel.") + SSblackbox.add_details("preferences_verb","Toggle Seeing OOC|[usr.client.prefs.chat_toggles & CHAT_OOC]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +/datum/menu/Settings/listen_ooc/Get_checked(client/C) + return C.prefs.chat_toggles & CHAT_OOC + GLOBAL_LIST_INIT(ghost_forms, list("ghost","ghostking","ghostian2","skeleghost","ghost_red","ghost_black", \ "ghost_blue","ghost_yellow","ghost_green","ghost_pink", \ @@ -246,13 +333,6 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS prefs.save_preferences() SSblackbox.add_details("preferences_verb","Toggle Intent Selection|[prefs.toggles & INTENT_STYLE]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/verb/setup_character() - set name = "Game Preferences" - set category = "Preferences" - set desc = "Allows you to access the Setup Character screen. Changes to your character won't take effect until next round, but other changes will." - prefs.current_tab = 1 - prefs.ShowChoices(usr) - /client/verb/toggle_ghost_hud_pref() set name = "Toggle Ghost HUD" set category = "Preferences" @@ -278,15 +358,6 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS to_chat(src, "You will no longer examine things you click on.") SSblackbox.add_details("preferences_verb","Toggle Ghost Inquisitiveness|[prefs.inquisitive_ghost]") -/client/verb/toggle_announcement_sound() - set name = "Hear/Silence Announcements" - set category = "Preferences" - set desc = ".Toggles hearing Central Command, Captain, VOX, and other announcement sounds" - prefs.toggles ^= SOUND_ANNOUNCEMENTS - to_chat(src, "You will now [(prefs.toggles & SOUND_ANNOUNCEMENTS) ? "hear announcement sounds" : "no longer hear announcements"].") - prefs.save_preferences() - SSblackbox.add_details("preferences_verb","Toggle Announcement Sound|[prefs.toggles & SOUND_ANNOUNCEMENTS]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - //Admin Preferences /client/proc/toggleadminhelpsound() set name = "Hear/Silence Adminhelps" @@ -338,14 +409,3 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS to_chat(src, "You will [(prefs.chat_toggles & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat.") SSblackbox.add_details("admin_toggle","Toggle Prayer Visibility|[prefs.chat_toggles & CHAT_PRAYER]") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -/client/verb/toggleprayersounds() - set name = "Hear/Silence Prayer Sounds" - set category = "Preferences" - set desc = "Toggles hearing pray sounds." - prefs.toggles ^= SOUND_PRAYERS - prefs.save_preferences() - if(prefs.toggles & SOUND_PRAYERS) - to_chat(src, "You will now hear prayer sounds.") - else - to_chat(src, "You will no longer prayer sounds.") - SSblackbox.add_details("admin_toggle", "Toggle Prayer Sounds|[prefs.toggles & SOUND_PRAYERS]") diff --git a/code/modules/client/verbs/suicide.dm b/code/modules/client/verbs/suicide.dm index 6847a7c1f4..1f50a697c2 100644 --- a/code/modules/client/verbs/suicide.dm +++ b/code/modules/client/verbs/suicide.dm @@ -13,8 +13,8 @@ return if(confirm == "Yes") suiciding = 1 - log_game("[key_name(src)] (job: [job ? "[job]" : "None"]) commited suicide at [get_area(src)].") - message_admins("[key_name(src)] (job: [job ? "[job]" : "None"]) commited suicide at [get_area(src)].") + log_game("[key_name(src)] (job: [job ? "[job]" : "None"]) committed suicide at [get_area(src)].") + message_admins("[key_name(src)] (job: [job ? "[job]" : "None"]) committed suicide at [get_area(src)].") var/obj/item/held_item = get_active_held_item() if(held_item) var/damagetype = held_item.suicide_act(src) diff --git a/code/modules/client/verbs/who.dm b/code/modules/client/verbs/who.dm index a7b1a9ac53..1614966726 100644 --- a/code/modules/client/verbs/who.dm +++ b/code/modules/client/verbs/who.dm @@ -33,7 +33,7 @@ entry += " - DEAD" if(is_special_character(C.mob)) entry += " - Antagonist" - entry += " (?)" + entry += " [ADMIN_QUE(C.mob)]" entry += " ([round(C.avgping, 1)]ms)" Lines += entry else//If they don't have +ADMIN, only show hidden admins diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 20f59d0435..80547c4db9 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -161,7 +161,9 @@ /obj/item/clothing/obj_break(damage_flag) if(!damaged_clothes) update_clothes_damaged_state(TRUE) - to_chat(usr, "Your [src] starts to fall apart!") + if(ismob(loc)) //It's not important enough to warrant a message if nobody's wearing it + var/mob/M = loc + M.visible_message("[M]'s [name] starts to fall apart!", "Your [name] starts to fall apart!") /obj/item/clothing/proc/update_clothes_damaged_state(damaging = TRUE) var/index = "\ref[initial(icon)]-[initial(icon_state)]" diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm index 6720663fb7..6a9ac41a0d 100644 --- a/code/modules/clothing/glasses/engine_goggles.dm +++ b/code/modules/clothing/glasses/engine_goggles.dm @@ -18,6 +18,7 @@ vision_flags = 0 darkness_view = 2 invis_view = SEE_INVISIBLE_LIVING + lighting_alpha = null to_chat(user, "You toggle the goggles' scanning mode to \[T-Ray].") else STOP_PROCESSING(SSobj, src) diff --git a/code/modules/clothing/head/cit_hats.dm b/code/modules/clothing/head/cit_hats.dm new file mode 100644 index 0000000000..d562802db1 --- /dev/null +++ b/code/modules/clothing/head/cit_hats.dm @@ -0,0 +1,5 @@ +/obj/item/clothing/head/hunter + name = "hunter hat" + desc = "It's a flimsy looking hat." + icon_state = "hunter" + icon = 'icons/obj/clothing/cit_hats.dmi' \ No newline at end of file diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm index 61171ccf59..b55d826547 100644 --- a/code/modules/clothing/head/collectable.dm +++ b/code/modules/clothing/head/collectable.dm @@ -30,7 +30,7 @@ /obj/item/clothing/head/collectable/paper name = "collectable paper hat" - desc = "What looks like an ordinary paper hat is actually a rare and valuable collector's edition paper hat. Keep away from water, fire, and Librarians." + desc = "What looks like an ordinary paper hat is actually a rare and valuable collector's edition paper hat. Keep away from water, fire, and Curators." icon_state = "paper" dog_fashion = /datum/dog_fashion/head diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm index 6f8e365bd9..65920a06d0 100644 --- a/code/modules/clothing/head/jobs.dm +++ b/code/modules/clothing/head/jobs.dm @@ -158,4 +158,5 @@ name = "treasure hunter's fedora" desc = "You got red text today kid, but it doesn't mean you have to like it." icon_state = "curator" - armor = list(melee = 25, bullet = 5, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0, fire = 30, acid = 50) \ No newline at end of file + armor = list(melee = 25, bullet = 5, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0, fire = 30, acid = 50) + pockets = /obj/item/weapon/storage/internal/pocket/small \ No newline at end of file diff --git a/code/modules/clothing/spacesuits/flightsuit.dm b/code/modules/clothing/spacesuits/flightsuit.dm index 275ad542b5..b1c0bb325d 100644 --- a/code/modules/clothing/spacesuits/flightsuit.dm +++ b/code/modules/clothing/spacesuits/flightsuit.dm @@ -326,9 +326,6 @@ disable_flight(1) if(!suit) disable_flight(1) - if(!resync) - addtimer(CALLBACK(src, .proc/resync), 600) - resync = 1 if(!wearer) //Oh god our user fell off! disable_flight(1) if(!pressure && brake) @@ -340,12 +337,6 @@ stabilizer = FALSE usermessage("Warning: Sensor data is not being recieved from flight shoes. Stabilizers and airbrake modules OFFLINE!", 2) -//Resync the suit -/obj/item/device/flightpack/proc/resync() - resync = FALSE - suit.resync() - -//How fast should the wearer be? /obj/item/device/flightpack/proc/update_slowdown() if(!flight) suit.slowdown = slowdown_ground @@ -356,20 +347,11 @@ /obj/item/device/flightpack/process() if(!suit || (processing_mode == FLIGHTSUIT_PROCESSING_NONE)) return FALSE - update_slowdown() - update_icon() check_conditions() calculate_momentum_speed() momentum_drift() handle_boost() handle_damage() - handle_flight() - -/obj/item/device/flightpack/proc/handle_flight() - if(!flight) - return FALSE - if(wearer) - wearer.float(TRUE) /obj/item/device/flightpack/proc/handle_damage() if(crash_damage) @@ -424,7 +406,6 @@ if(boost_charge < boost_maxcharge) boost_charge = Clamp(boost_charge+boost_chargerate, 0, boost_maxcharge) - /obj/item/device/flightpack/proc/cycle_power() if(powersetting < powersetting_high) powersetting++ @@ -654,6 +635,8 @@ wearer.movement_type |= FLYING wearer.pass_flags |= flight_passflags usermessage("ENGAGING FLIGHT ENGINES.") + update_slowdown() + wearer.floating = TRUE wearer.visible_message("[wearer]'s flight engines activate as they lift into the air!") //I DONT HAVE SOUND EFFECTS YET playsound( flight = TRUE @@ -670,6 +653,8 @@ momentum_x = 0 momentum_y = 0 usermessage("DISENGAGING FLIGHT ENGINES.") + update_slowdown() + wearer.floating = FALSE wearer.visible_message("[wearer] drops to the ground as their flight engines cut out!") //NO SOUND YET playsound( ion_trail.stop() @@ -678,6 +663,9 @@ flight = FALSE if(suit.shoes) suit.shoes.toggle(FALSE) + if(isturf(wearer.loc)) + var/turf/T = wearer.loc + T.Entered(src) else if(override_safe) disable_flight(TRUE) @@ -749,11 +737,13 @@ wearer.visible_message("[wearer.name]'s flightpack engines flare in intensity as they are rocketed forward by the immense thrust!") boost = TRUE update_slowdown() + update_icon() /obj/item/device/flightpack/proc/deactivate_booster() usermessage("Boosters disengaged!") boost = FALSE update_slowdown() + update_icon() /obj/item/device/flightpack/proc/enable_airbrake() if(wearer) diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm index 22741f18f3..526a15e7f5 100644 --- a/code/modules/clothing/suits/jobs.dm +++ b/code/modules/clothing/suits/jobs.dm @@ -182,7 +182,7 @@ item_state = "curator" blood_overlay_type = "coat" body_parts_covered = CHEST|ARMS - allowed = list(/obj/item/weapon/tank/internals/emergency_oxygen, /obj/item/weapon/melee/curator_whip) + allowed = list(/obj/item/weapon/tank/internals, /obj/item/weapon/melee/curator_whip) armor = list(melee = 25, bullet = 10, laser = 25, energy = 10, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 45) cold_protection = CHEST|ARMS heat_protection = CHEST|ARMS diff --git a/code/modules/clothing/under/jobs/civilian.dm b/code/modules/clothing/under/jobs/civilian.dm index 8c30774c02..eaa80d823c 100644 --- a/code/modules/clothing/under/jobs/civilian.dm +++ b/code/modules/clothing/under/jobs/civilian.dm @@ -137,7 +137,7 @@ can_adjust = 1 alt_covers_chest = 1 -/obj/item/clothing/under/rank/librarian +/obj/item/clothing/under/rank/curator name = "sensible suit" desc = "It's very... sensible." icon_state = "red_suit" @@ -145,7 +145,7 @@ item_color = "red_suit" can_adjust = 0 -/obj/item/clothing/under/rank/librarian/curator +/obj/item/clothing/under/rank/curator/treasure_hunter name = "treasure hunter uniform" desc = "A rugged uniform suitable for treasure hunting." icon_state = "curator" diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm index 92437a34c1..562f59290a 100644 --- a/code/modules/detectivework/scanner.dm +++ b/code/modules/detectivework/scanner.dm @@ -13,6 +13,8 @@ var/scanning = 0 var/list/log = list() origin_tech = "engineering=4;biotech=2;programming=5" + var/range = 8 + var/view_check = TRUE /obj/item/device/detective_scanner/attack_self(mob/user) if(log.len && !scanning) @@ -43,7 +45,7 @@ log = list() scanning = 0 -/obj/item/device/detective_scanner/pre_attackby(atom/A, mob/user, params) +/obj/item/device/detective_scanner/afterattack(atom/A, mob/user, params) scan(A, user) return FALSE @@ -51,9 +53,7 @@ set waitfor = 0 if(!scanning) // Can remotely scan objects and mobs. - if(!in_range(A, user) && !(A in view(world.view, user))) - return - if(loc != user) + if((get_dist(A, user) > range) || (!(A in view(range, user)) && view_check) || (loc != user)) return scanning = 1 diff --git a/code/modules/error_handler/error_handler.dm b/code/modules/error_handler/error_handler.dm index b48dd40e09..e2cce14db3 100644 --- a/code/modules/error_handler/error_handler.dm +++ b/code/modules/error_handler/error_handler.dm @@ -6,7 +6,7 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) if(!istype(E)) //Something threw an unusual exception log_world("\[[time_stamp()]] Uncaught exception: [E]") return ..() - + var/static/list/error_last_seen = list() var/static/list/error_cooldown = list() /* Error_cooldown items will either be positive(cooldown time) or negative(silenced error) If negative, starts at -1, and goes down by 1 each time that error gets skipped*/ @@ -107,9 +107,8 @@ GLOBAL_VAR_INIT(total_runtimes_skipped, 0) if (split[i] != "") split[i] = "\[[time2text(world.timeofday,"hh:mm:ss")]\][split[i]]" E.desc = jointext(split, "\n") - if(config && config.log_runtimes) - world.log = GLOB.runtime_diary - ..(E) + world.log = GLOB.world_runtime_log + ..(E) world.log = null diff --git a/code/modules/events/ghost_role.dm b/code/modules/events/ghost_role.dm index 93eff54b27..2468ddb5c6 100644 --- a/code/modules/events/ghost_role.dm +++ b/code/modules/events/ghost_role.dm @@ -59,7 +59,7 @@ var/list/mob/dead/observer/regular_candidates // don't get their hopes up if(priority_candidates.len < minimum_required) - regular_candidates = pollCandidates("Do you wish to be considered for the special role of '[role_name]'?", jobban, gametypecheck, be_special) + regular_candidates = pollGhostCandidates("Do you wish to be considered for the special role of '[role_name]'?", jobban, gametypecheck, be_special) else regular_candidates = list() diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index bbeedee68f..b43bf3fe3a 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -362,8 +362,6 @@ for(var/datum/spacevine_mutation/SM in mutations) override += SM.on_eat(src, eater) if(!override) - if(prob(10)) - eater.say("Nom") qdel(src) /obj/structure/spacevine/attackby(obj/item/weapon/W, mob/user, params) diff --git a/code/modules/food_and_drinks/food/condiment.dm b/code/modules/food_and_drinks/food/condiment.dm index e1c463becc..baa804a4de 100644 --- a/code/modules/food_and_drinks/food/condiment.dm +++ b/code/modules/food_and_drinks/food/condiment.dm @@ -23,7 +23,8 @@ "sodiumchloride" = list("saltshakersmall", "salt shaker", "Salt. From space oceans, presumably"), "blackpepper" = list("peppermillsmall", "pepper mill", "Often used to flavor food or make people sneeze"), "cornoil" = list("oliveoil", "corn oil bottle", "A delicious oil used in cooking. Made from corn"), - "sugar" = list("emptycondiment", "sugar bottle", "Tasty spacey sugar!")) + "sugar" = list("emptycondiment", "sugar bottle", "Tasty spacey sugar!"), + "mayonnaise" = list("mayonnaise", "mayonnaise jar", "An oily condiment made from egg yolks.")) var/originalname = "condiment" //Can't use initial(name) for this. This stores the name set by condimasters. /obj/item/weapon/reagent_containers/food/condiment/attack(mob/M, mob/user, def_zone) @@ -207,6 +208,13 @@ list_reagents = list("soysauce" = 50) possible_states = list() +/obj/item/weapon/reagent_containers/food/condiment/mayonnaise + name = "mayonnaise" + desc = "An oily condiment made from egg yolks." + icon_state = "mayonnaise" + list_reagents = list("mayonnaise" = 50) + possible_states = list() + //Food packs. To easily apply deadly toxi... delicious sauces to your food! diff --git a/code/modules/food_and_drinks/food/snacks_bread.dm b/code/modules/food_and_drinks/food/snacks_bread.dm index b2664e5b5a..b76b896803 100644 --- a/code/modules/food_and_drinks/food/snacks_bread.dm +++ b/code/modules/food_and_drinks/food/snacks_bread.dm @@ -164,3 +164,24 @@ icon = 'icons/obj/food/food.dmi' icon_state = "" bitesize = 2 + +/obj/item/weapon/reagent_containers/food/snacks/butteredtoast + name = "buttered toast" + desc = "Butter lightly spread over a piece of toast." + icon = 'icons/obj/food/food.dmi' + icon_state = "butteredtoast" + bitesize = 3 + filling_color = "#FFA500" + list_reagents = list("nutriment" = 4) + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) + tastes = list("butter" = 1, "toast" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/butterbiscuit + name = "butter biscuit" + desc = "Well butter my biscuit!" + icon = 'icons/obj/food/food.dmi' + icon_state = "butterbiscuit" + filling_color = "#F0E68C" + list_reagents = list("nutriment" = 5) + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) + tastes = list("butter" = 1, "biscuit" = 1) \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/snacks_meat.dm b/code/modules/food_and_drinks/food/snacks_meat.dm index d7ebd364a3..e050ecd72b 100644 --- a/code/modules/food_and_drinks/food/snacks_meat.dm +++ b/code/modules/food_and_drinks/food/snacks_meat.dm @@ -236,3 +236,12 @@ var/shape = pick("lump", "star", "lizard", "corgi") desc = "A 'chicken' nugget vaguely shaped like a [shape]." icon_state = "nugget_[shape]" + +/obj/item/weapon/reagent_containers/food/snacks/pigblanket + name = "pig in a blanket" + desc = "A tiny sausage wrapped in a flakey, buttery roll. Free this pig from its blanket prison by eating it." + icon_state = "pigblanket" + list_reagents = list("nutriment" = 6, "vitamin" = 1) + bonus_reagents = list("nutriment" = 1, "vitamin" = 1) + filling_color = "#800000" + tastes = list("meat" = 1, "butter" = 1) diff --git a/code/modules/food_and_drinks/food/snacks_other.dm b/code/modules/food_and_drinks/food/snacks_other.dm index 6ec7fd9a1e..7cfce5419d 100644 --- a/code/modules/food_and_drinks/food/snacks_other.dm +++ b/code/modules/food_and_drinks/food/snacks_other.dm @@ -468,3 +468,11 @@ list_reagents = list("nutriment" = 3, "vitamin" = 2, "sodiumchloride" = 5) bonus_reagents = list("sodiumchloride" = 10) tastes = list("bran" = 4, "raisins" = 3, "salt" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/butter + name = "stick of butter" + desc = "A stick of delicious, golden, fatty goodness." + icon_state = "butter" + list_reagents = list("nutriment" = 5) + filling_color = "#FFD700" + tastes = list("butter" = 1) \ No newline at end of file diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm index 76ef327bb6..6081838669 100644 --- a/code/modules/food_and_drinks/food/snacks_pastry.dm +++ b/code/modules/food_and_drinks/food/snacks_pastry.dm @@ -13,8 +13,8 @@ filling_color = "#D2691E" tastes = list("donut" = 1) -/obj/item/weapon/reagent_containers/food/snacks/donut/New() - ..() +/obj/item/weapon/reagent_containers/food/snacks/donut/Initialize() + . = ..() if(prob(30)) icon_state = "donut2" name = "frosted donut" @@ -28,8 +28,8 @@ bitesize = 10 tastes = list("donut" = 3, "chaos" = 1) -/obj/item/weapon/reagent_containers/food/snacks/donut/chaos/New() - ..() +/obj/item/weapon/reagent_containers/food/snacks/donut/chaos/Initialize() + . = ..() extra_reagent = pick("nutriment", "capsaicin", "frostoil", "krokodil", "plasma", "cocoa", "slimejelly", "banana", "berryjuice", "omnizine") reagents.add_reagent("[extra_reagent]", 3) bonus_reagents = list("[extra_reagent]" = 3, "sugar" = 1) @@ -48,8 +48,8 @@ extra_reagent = "berryjuice" tastes = list("jelly" = 1, "donut" = 3) -/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/New() - ..() +/obj/item/weapon/reagent_containers/food/snacks/donut/jelly/Initialize() + . = ..() if(extra_reagent) reagents.add_reagent("[extra_reagent]", 3) if(prob(30)) @@ -210,13 +210,13 @@ filling_color = "#F0E68C" tastes = list("mushroom" = 1, "biscuit" = 1) -/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit/New() +/obj/item/weapon/reagent_containers/food/snacks/plumphelmetbiscuit/Initialize() var/fey = prob(10) if(fey) name = "exceptional plump helmet biscuit" desc = "Microwave is taken by a fey mood! It has cooked an exceptional plump helmet biscuit!" bonus_reagents = list("omnizine" = 5, "nutriment" = 1, "vitamin" = 1) - ..() + . = ..() if(fey) reagents.add_reagent("omnizine", 5) diff --git a/code/modules/food_and_drinks/food/snacks_spaghetti.dm b/code/modules/food_and_drinks/food/snacks_spaghetti.dm index dc3aa60115..8cd4665918 100644 --- a/code/modules/food_and_drinks/food/snacks_spaghetti.dm +++ b/code/modules/food_and_drinks/food/snacks_spaghetti.dm @@ -85,3 +85,12 @@ trash = /obj/item/weapon/reagent_containers/glass/bowl bonus_reagents = list("nutriment" = 5, "vitamin" = 6, "liquidgibs" = 3) tastes = list("noodle" = 1, "meat" = 1) + +/obj/item/weapon/reagent_containers/food/snacks/butternoodles + name = "butter noodles" + desc = "Noodles covered in savory butter. Simple and slippery, but delicious." + icon = 'icons/obj/food/pizzaspaghetti.dmi' + icon_state = "butternoodles" + trash = /obj/item/trash/plate + bonus_reagents = list("nutriment" = 8, "vitamin" = 1) + tastes = list("noodle" = 1, "butter" = 1) diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm index a4d9a32d3d..43cf70bbe2 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm @@ -31,7 +31,7 @@ break if(!input_plate) - GLOB.diary << "a [src] didn't find an input plate." + GLOB.world_game_log << "a [src] didn't find an input plate." return /obj/machinery/gibber/autogibber/Bumped(atom/A) @@ -168,13 +168,14 @@ var/offset = prob(50) ? -2 : 2 animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking - var/sourcename = src.occupant.real_name + var/mob/living/mob_occupant = occupant + var/sourcename = mob_occupant.real_name var/sourcejob if(ishuman(occupant)) var/mob/living/carbon/human/gibee = occupant sourcejob = gibee.job - var/sourcenutriment = src.occupant.nutrition / 15 - var/sourcetotalreagents = src.occupant.reagents.total_volume + var/sourcenutriment = mob_occupant.nutrition / 15 + var/sourcetotalreagents = mob_occupant.reagents.total_volume var/gibtype = /obj/effect/decal/cleanable/blood/gibs var/typeofmeat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human var/typeofskin = /obj/item/stack/sheet/animalhide/human @@ -212,8 +213,8 @@ allskin = newskin add_logs(user, occupant, "gibbed") - src.occupant.death(1) - src.occupant.ghostize() + mob_occupant.death(1) + mob_occupant.ghostize() qdel(src.occupant) spawn(src.gibtime) playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) diff --git a/code/modules/food_and_drinks/pizzabox.dm b/code/modules/food_and_drinks/pizzabox.dm index d6f6c0f32e..7bdd62211b 100644 --- a/code/modules/food_and_drinks/pizzabox.dm +++ b/code/modules/food_and_drinks/pizzabox.dm @@ -67,6 +67,7 @@ var/mutable_appearance/bomb_overlay = mutable_appearance(bomb.icon, bomb.icon_state) bomb_overlay.pixel_y = 5 add_overlay(bomb_overlay) + else icon_state = "pizzabox[boxes.len + 1]" var/obj/item/pizzabox/box = boxes.len ? boxes[boxes.len] : src if(box.boxtag != "") diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm index e35d5c89e6..d0682ced1e 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_bread.dm @@ -74,3 +74,22 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/store/bread/mimana category = CAT_BREAD + +/datum/crafting_recipe/food/butteredtoast + name = "Buttered Toast" + reqs = list( + /obj/item/weapon/reagent_containers/food/snacks/breadslice/plain = 1, + /obj/item/weapon/reagent_containers/food/snacks/butter = 1 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/butteredtoast + category = CAT_BREAD + +/datum/crafting_recipe/food/butterbiscuit + name = "Butter Biscuit" + reqs = list( + /obj/item/weapon/reagent_containers/food/snacks/bun = 1, + /obj/item/weapon/reagent_containers/food/snacks/butter = 1 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/butterbiscuit + category = CAT_BREAD + diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm index d2245a0ecd..878dda1804 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_meat.dm @@ -160,3 +160,13 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/rawkhinkali category = CAT_MEAT + +/datum/crafting_recipe/food/pigblanket + name = "Pig in a Blanket" + reqs = list( + /obj/item/weapon/reagent_containers/food/snacks/bun = 1, + /obj/item/weapon/reagent_containers/food/snacks/butter = 1, + /obj/item/weapon/reagent_containers/food/snacks/meat/cutlet = 1 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/pigblanket + category = CAT_MEAT diff --git a/code/modules/food_and_drinks/recipes/tablecraft/recipes_spaghetti.dm b/code/modules/food_and_drinks/recipes/tablecraft/recipes_spaghetti.dm index 85d2ee6d65..412157033b 100644 --- a/code/modules/food_and_drinks/recipes/tablecraft/recipes_spaghetti.dm +++ b/code/modules/food_and_drinks/recipes/tablecraft/recipes_spaghetti.dm @@ -59,3 +59,12 @@ ) result = /obj/item/weapon/reagent_containers/food/snacks/chowmein category = CAT_SPAGHETTI + +/datum/crafting_recipe/food/butternoodles + name = "Butter Noodles" + reqs = list( + /obj/item/weapon/reagent_containers/food/snacks/boiledspaghetti = 1, + /obj/item/weapon/reagent_containers/food/snacks/butter = 1 + ) + result = /obj/item/weapon/reagent_containers/food/snacks/butternoodles + category = CAT_SPAGHETTI \ No newline at end of file diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 555df764b8..5104ab333a 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -111,6 +111,7 @@ for(var/datum/plant_gene/trait/trait in seed.genes) trait.on_squash(src, target) + reagents.reaction(T) for(var/A in T) reagents.reaction(A) diff --git a/code/modules/hydroponics/grown/ambrosia.dm b/code/modules/hydroponics/grown/ambrosia.dm index 554cba9f47..51b8f3c43e 100644 --- a/code/modules/hydroponics/grown/ambrosia.dm +++ b/code/modules/hydroponics/grown/ambrosia.dm @@ -59,7 +59,7 @@ species = "ambrosia_gaia" plantname = "Ambrosia Gaia" product = /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/gaia - mutatelist = list() + mutatelist = list(/obj/item/seeds/ambrosia/deus) reagents_add = list("earthsblood" = 0.05, "nutriment" = 0.06, "vitamin" = 0.05) rarity = 30 //These are some pretty good plants right here genes = list() diff --git a/code/modules/hydroponics/grown/misc.dm b/code/modules/hydroponics/grown/misc.dm index 71e6debf25..a67fef2473 100644 --- a/code/modules/hydroponics/grown/misc.dm +++ b/code/modules/hydroponics/grown/misc.dm @@ -123,8 +123,8 @@ /obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/attack_self(mob/living/user) var/area/A = get_area(user) user.visible_message("[user] plucks the stem from [src]!", "You pluck the stem from [src], which begins to hiss loudly!") - message_admins("[user] ([user.key ? user.key : "no key"]) primed a cherry bomb for detonation at [A] ([user.x], [user.y], [user.z]) (JMP)") - log_game("[user] ([user.key ? user.key : "no key"]) primed a cherry bomb for detonation at [A] ([user.x],[user.y],[user.z]).") + message_admins("[ADMIN_LOOKUPFLW(user)] primed a cherry bomb for detonation at [A] [ADMIN_COORDJMP(user)]") + log_game("[key_name(user)] primed a cherry bomb for detonation at [A] [COORD(user)].") prime() /obj/item/weapon/reagent_containers/food/snacks/grown/cherry_bomb/deconstruct(disassembled = TRUE) diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index 264261dd69..82cc192344 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -50,17 +50,22 @@ /obj/item/weapon/grown/nettle/pickup(mob/living/user) ..() if(!iscarbon(user)) - return 0 + return FALSE var/mob/living/carbon/C = user if(C.gloves) - return 0 + return FALSE + if(ishuman(C)) + var/mob/living/carbon/human/H = C + if(H.dna && H.dna.species) + if(PIERCEIMMUNE in H.dna.species.species_traits) + return FALSE var/hit_zone = (C.held_index_to_dir(C.active_hand_index) == "l" ? "l_":"r_") + "arm" var/obj/item/bodypart/affecting = C.get_bodypart(hit_zone) if(affecting) if(affecting.receive_damage(0, force)) C.update_damage_overlays() to_chat(C, "The nettle burns your bare hand!") - return 1 + return TRUE /obj/item/weapon/grown/nettle/afterattack(atom/A as mob|obj, mob/user,proximity) if(!proximity) return diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index b26a911b3a..317b954c91 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -27,6 +27,8 @@ var/unwrenchable = 1 var/recent_bee_visit = FALSE //Have we been visited by a bee recently, so bees dont overpollinate one plant var/using_irrigation = FALSE //If the tray is connected to other trays via irrigation hoses + var/self_sufficiency_req = 20 //Required total dose to make a self-sufficient hydro tray. 1:1 with earthsblood. + var/self_sufficiency_progress = 0 var/self_sustaining = FALSE //If the tray generates nutrients and water on its own @@ -329,6 +331,9 @@ if(!self_sustaining) to_chat(user, "Water: [waterlevel]/[maxwater]") to_chat(user, "Nutrient: [nutrilevel]/[maxnutri]") + if(self_sufficiency_progress > 0) + var/percent_progress = round(self_sufficiency_progress * 100 / self_sufficiency_req) + to_chat(user, "Treatment for self-sustenance are [percent_progress]% complete.") else to_chat(user, "It doesn't require any water or nutrients.") @@ -504,6 +509,14 @@ yieldmod = 1.3 mutmod = 0 adjustNutri(round(S.get_reagent_amount("robustharvestnutriment") *1 )) + + // Ambrosia Gaia produces earthsblood. + if(S.has_reagent("earthsblood")) + self_sufficiency_progress += S.get_reagent_amount("earthsblood") + if(self_sufficiency_progress >= self_sufficiency_req) + become_self_sufficient() + else if(!self_sustaining) + to_chat(user, "[src] warms as it might on a spring day under a genuine Sun.") // Antitoxin binds shit pretty well. So the tox goes significantly down if(S.has_reagent("charcoal", 1)) @@ -675,33 +688,7 @@ /obj/machinery/hydroponics/attackby(obj/item/O, mob/user, params) //Called when mob user "attacks" it with object O - if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/gaia)) //Checked early on so it doesn't have to deal with composting checks - if(self_sustaining) - to_chat(user, "This [name] is already self-sustaining!") - return - if(myseed || weedlevel) - to_chat(user, "[src] needs to be clear of plants and weeds!") - return - if(alert(user, "This will make [src] self-sustaining but consume [O] forever. Are you sure?", "[name]", "I'm Sure", "Abort") == "Abort" || !user) - return - if(!O || QDELETED(O)) - return - if(!Adjacent(user)) - return - if(self_sustaining) - to_chat(user, "This [name] is already self-sustaining!") - return - if(myseed || weedlevel) - to_chat(user, "[src] needs to be clear of plants and weeds!") - return - user.visible_message("[user] gently pulls open the soil for [O] and places it inside.", "You tenderly root [O] into [src].") - user.drop_item() - qdel(O) - visible_message("[src] begins to glow with a beautiful light!") - self_sustaining = TRUE - update_icon() - - else if(istype(O, /obj/item/weapon/reagent_containers) ) // Syringe stuff (and other reagent containers now too) + if(istype(O, /obj/item/weapon/reagent_containers) ) // Syringe stuff (and other reagent containers now too) var/obj/item/weapon/reagent_containers/reagent_source = O if(istype(reagent_source, /obj/item/weapon/reagent_containers/syringe)) @@ -930,6 +917,10 @@ var/mob/living/simple_animal/hostile/C = new chosen C.faction = list("plants") +/obj/machinery/hydroponics/proc/become_self_sufficient() // Ambrosia Gaia effect + visible_message("[src] begins to glow with a beautiful light!") + self_sustaining = TRUE + update_icon() /////////////////////////////////////////////////////////////////////////////// /obj/machinery/hydroponics/soil //Not actually hydroponics at all! Honk! diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm index 31bb564a06..5f4a79b661 100644 --- a/code/modules/hydroponics/plant_genes.dm +++ b/code/modules/hydroponics/plant_genes.dm @@ -268,7 +268,7 @@ rate = 0.03 examine_line = "It emits a soft glow." trait_id = "glow" - var/glow_color = "#AAD84B" + var/glow_color = "#C3E381" /datum/plant_gene/trait/glow/proc/glow_range(obj/item/seeds/S) return 1.4 + S.potency*rate @@ -285,6 +285,7 @@ //adds -potency*(rate*0.05) light power to products name = "Shadow Emission" rate = 0.04 + glow_color = "#AAD84B" /datum/plant_gene/trait/glow/shadow/glow_power(obj/item/seeds/S) return -max(S.potency*(rate*0.05), 0.075) diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm index 0ab974126e..85923811f9 100644 --- a/code/modules/jobs/access.dm +++ b/code/modules/jobs/access.dm @@ -459,7 +459,7 @@ GLOBAL_VAR_CONST(access_away_generic4, 208) /proc/get_all_jobs() return list("Assistant", "Captain", "Head of Personnel", "Bartender", "Cook", "Botanist", "Quartermaster", "Cargo Technician", - "Shaft Miner", "Clown", "Mime", "Janitor", "Librarian", "Lawyer", "Chaplain", "Chief Engineer", "Station Engineer", + "Shaft Miner", "Clown", "Mime", "Janitor", "Curator", "Lawyer", "Chaplain", "Chief Engineer", "Station Engineer", "Atmospheric Technician", "Chief Medical Officer", "Medical Doctor", "Chemist", "Geneticist", "Virologist", "Research Director", "Scientist", "Roboticist", "Head of Security", "Warden", "Detective", "Security Officer") diff --git a/code/modules/jobs/job_types/cargo_service.dm b/code/modules/jobs/job_types/cargo_service.dm index a863f983cf..b606000ef4 100644 --- a/code/modules/jobs/job_types/cargo_service.dm +++ b/code/modules/jobs/job_types/cargo_service.dm @@ -277,4 +277,4 @@ Janitor belt = /obj/item/device/pda/janitor ears = /obj/item/device/radio/headset/headset_srv uniform = /obj/item/clothing/under/rank/janitor - backpack_contents = list(/obj/item/device/modular_computer/tablet/preset/advanced=1, /obj/item/soapstone/empty=1) + backpack_contents = list(/obj/item/device/modular_computer/tablet/preset/advanced=1) diff --git a/code/modules/jobs/job_types/civilian.dm b/code/modules/jobs/job_types/civilian.dm index 86185e2848..7d983e5519 100644 --- a/code/modules/jobs/job_types/civilian.dm +++ b/code/modules/jobs/job_types/civilian.dm @@ -35,7 +35,8 @@ Clown /obj/item/weapon/reagent_containers/spray/waterflower = 1, /obj/item/weapon/reagent_containers/food/snacks/grown/banana = 1, /obj/item/device/megaphone/clown = 1, - /obj/item/weapon/reagent_containers/food/drinks/soda_cans/canned_laughter = 1 + /obj/item/weapon/reagent_containers/food/drinks/soda_cans/canned_laughter = 1, + /obj/item/weapon/pneumatic_cannon/pie = 1 ) implants = list(/obj/item/weapon/implant/sad_trombone) @@ -112,11 +113,11 @@ Mime H.mind.miming = 1 /* -Librarian +Curator */ -/datum/job/librarian - title = "Librarian" - flag = LIBRARIAN +/datum/job/curator + title = "Curator" + flag = CURATOR department_head = list("Head of Personnel") department_flag = CIVILIAN faction = "Station" @@ -125,33 +126,35 @@ Librarian supervisors = "the head of personnel" selection_color = "#dddddd" - outfit = /datum/outfit/job/librarian + outfit = /datum/outfit/job/curator access = list(GLOB.access_library) - minimal_access = list(GLOB.access_library) + minimal_access = list(GLOB.access_library, GLOB.access_construction,GLOB.access_mining_station) -/datum/outfit/job/librarian - name = "Librarian" - jobtype = /datum/job/librarian +/datum/outfit/job/curator + name = "Curator" + jobtype = /datum/job/curator - belt = /obj/item/device/pda/librarian - uniform = /obj/item/clothing/under/rank/librarian + belt = /obj/item/device/pda/curator + uniform = /obj/item/clothing/under/rank/curator l_hand = /obj/item/weapon/storage/bag/books - r_pocket = /obj/item/weapon/barcodescanner + r_pocket = /obj/item/key/displaycase l_pocket = /obj/item/device/laser_pointer backpack_contents = list( - /obj/item/soapstone = 1 + /obj/item/weapon/melee/curator_whip = 1, + /obj/item/soapstone = 1, + /obj/item/weapon/barcodescanner = 1 ) - -/datum/outfit/job/librarian/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) - ..() - - if(visualsOnly) - return - - H.grant_all_languages(omnitongue=TRUE) - + +/datum/outfit/job/curator/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE) + ..() + + if(visualsOnly) + return + + H.grant_all_languages(omnitongue=TRUE) + /* Lawyer */ diff --git a/code/modules/jobs/jobs.dm b/code/modules/jobs/jobs.dm index eff50f07ff..9b226e70f5 100644 --- a/code/modules/jobs/jobs.dm +++ b/code/modules/jobs/jobs.dm @@ -39,7 +39,7 @@ GLOBAL_LIST_INIT(civilian_positions, list( "Botanist", "Cook", "Janitor", - "Librarian", + "Curator", "Lawyer", "Chaplain", "Clown", diff --git a/code/modules/library/lib_codex_gigas.dm b/code/modules/library/lib_codex_gigas.dm index 4fcd00c5c0..35cb988083 100644 --- a/code/modules/library/lib_codex_gigas.dm +++ b/code/modules/library/lib_codex_gigas.dm @@ -32,7 +32,7 @@ var/speed = 300 var/correctness = 85 var/willpower = 98 - if(U.job in list("Librarian")) // the librarian is both faster, and more accurate than normal crew members at research + if(U.job in list("Curator")) // the curator is both faster, and more accurate than normal crew members at research speed = 45 correctness = 100 willpower = 100 diff --git a/code/modules/library/lib_readme.dm b/code/modules/library/lib_readme.dm index b8a0a42ed6..7b59bb5dfb 100644 --- a/code/modules/library/lib_readme.dm +++ b/code/modules/library/lib_readme.dm @@ -22,7 +22,7 @@ ------------ A place for the crew to go, relax, and enjoy a good book. Aspiring authors can even self publish and, if they're lucky - convince the on-staff Librarian to submit it to the Archives + convince the on-staff Curator to submit it to the Archives to be chronicled in history forever - some say even persisting through alternate dimensions. @@ -49,12 +49,12 @@ // Ideas for the future // --------------------- -// - Visitor's computer should be able to search the current in-round library inventory (that the Librarian has stocked and checked in) +// - Visitor's computer should be able to search the current in-round library inventory (that the Curator has stocked and checked in) // -- Give computer other features like an Instant Messenger application, or the ability to edit, save, and print documents. // - Admin interface directly tied to the Archive DB. Right now there's no way to delete uploaded books in-game. -// -- If this gets implemented, allow Librarians to "tag" or "suggest" books to be deleted. The DB ID of the tagged books gets saved to a text file (or another table in the DB maybe?). +// -- If this gets implemented, allow Curators to "tag" or "suggest" books to be deleted. The DB ID of the tagged books gets saved to a text file (or another table in the DB maybe?). // The admin interface would automatically take these IDs and SELECT them all from the DB to be displayed along with a Delete link to drop the row from the table. -// - When the game sets up and the round begins, have it automatically pick random books from the DB to populate the library with. Even if the Librarian is a useless fuck there are at least a few books around. +// - When the game sets up and the round begins, have it automatically pick random books from the DB to populate the library with. Even if the Curator is a useless fuck there are at least a few books around. // - Allow books to be "hollowed out" like the Chaplain's Bible, allowing you to store one pocket-sized item inside. // - Make books/book cases burn when exposed to flame. // - Make book binder hackable. diff --git a/code/modules/library/soapstone.dm b/code/modules/library/soapstone.dm index 231f5417ab..5efc9c1dd3 100644 --- a/code/modules/library/soapstone.dm +++ b/code/modules/library/soapstone.dm @@ -1,5 +1,5 @@ /obj/item/soapstone - name = "chisel" + name = "soapstone" desc = "Leave informative messages for the crew, including the crew of future shifts!\nEven if out of uses, it can still be used to remove messages.\n(Not suitable for engraving on shuttles, off station or on cats. Side effects may include beatings, bannings and orbital bombardment.)" icon = 'icons/obj/items.dmi' icon_state = "soapstone" @@ -9,36 +9,9 @@ var/tool_speed = 50 var/remaining_uses = 3 - var/non_dull_name - var/w_engrave = "engrave" - var/w_engraving = "engraving" - var/w_chipping = "chipping" - var/w_dull = "dull" - -/obj/item/soapstone/New() +/obj/item/soapstone/Initialize(mapload) . = ..() - random_name() - check_name() // could start empty - -/obj/item/soapstone/proc/random_name() - name = pick("soapstone", "chisel", "chalk", "magic marker") - non_dull_name = name - if(name == "chalk" || name == "magic marker") - desc = replacetext(desc, "engraving", "scribbling") - w_engrave = "scribble" - w_engraving = "scribbling" - w_chipping = "sketching" - if(name == "chalk") - w_dull = "used" - if(name == "magic marker") - w_dull = "empty" - - if(name == "soapstone" || name == "chisel") - desc = replacetext(desc, "scribbling", "engraving") - w_engrave = initial(w_engrave) - w_engraving = initial(w_engraving) - w_chipping = initial(w_chipping) - w_dull = "dull" + check_name() /obj/item/soapstone/examine(mob/user) . = ..() @@ -57,11 +30,11 @@ return if(!good_chisel_message_location(T)) - to_chat(user, "It's not appropriate to [w_engrave] on [T].") + to_chat(user, "It's not appropriate to engrave on [T].") return if(existing_message) - user.visible_message("[user] starts erasing [existing_message].", "You start erasing [existing_message].", "You hear a [w_chipping] sound.") + user.visible_message("[user] starts erasing [existing_message].", "You start erasing [existing_message].", "You hear a chipping sound.") playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1) if(do_after(user, tool_speed, target = existing_message)) user.visible_message("[user] erases [existing_message].", "You erase [existing_message][existing_message.creator_key == user.ckey ? ", refunding a use" : ""].") @@ -72,19 +45,19 @@ refund_use() return - var/message = stripped_input(user, "What would you like to [w_engrave]?", "Leave a message") + var/message = stripped_input(user, "What would you like to engrave?", "Leave a message") if(!message) - to_chat(user, "You decide not to [w_engrave] anything.") + to_chat(user, "You decide not to engrave anything.") return if(!target.Adjacent(user) && locate(/obj/structure/chisel_message) in T) to_chat(user, "Someone wrote here before you chose! Find another spot.") return playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1) - user.visible_message("[user] starts [w_engraving] a message into [T]...", "You start [w_engraving] a message into [T]...", "You hear a [w_chipping] sound.") + user.visible_message("[user] starts engraving a message into [T]...", "You start engraving a message into [T]...", "You hear a chipping sound.") if(can_use() && do_after(user, tool_speed, target = T) && can_use()) //This looks messy but it's actually really clever! if(!locate(/obj/structure/chisel_message in T)) - user.visible_message("[user] leaves a message for future spacemen!", "You [w_engrave] a message into [T]!", "You hear a [w_chipping] sound.") + user.visible_message("[user] leaves a message for future spacemen!", "You engrave a message into [T]!", "You hear a chipping sound.") playsound(loc, 'sound/items/gavel.ogg', 50, 1, -1) var/obj/structure/chisel_message/M = new(T) M.register(user, message) @@ -107,15 +80,16 @@ /obj/item/soapstone/proc/check_name() if(remaining_uses) - name = non_dull_name + // This will mess up RPG loot names, but w/e + name = initial(name) else - name = "[w_dull] [name]" + name = "dull [initial(name)]" /* Persistent engraved messages, etched onto the station turfs to serve as instructions and/or memes for the next generation of spessmen. Limited in location to station_z only. Can be smashed out or exploded, - but only permamently removed with the librarian's soapstone. + but only permamently removed with the curator's soapstone. */ /obj/item/soapstone/infinite @@ -127,10 +101,6 @@ /proc/good_chisel_message_location(turf/T) if(!T) . = FALSE - else if(T.z != ZLEVEL_STATION) - . = FALSE - else if(istype(get_area(T), /area/shuttle)) - . = FALSE else if(!(isfloorturf(T) || iswallturf(T))) . = FALSE else @@ -142,9 +112,8 @@ icon = 'icons/obj/stationobjs.dmi' icon_state = "soapstone_message" layer = HIGH_OBJ_LAYER - density = 0 - anchored = 1 - luminosity = 1 + density = FALSE + anchored = TRUE obj_integrity = 30 max_integrity = 30 @@ -157,17 +126,18 @@ var/list/like_keys = list() var/list/dislike_keys = list() -/obj/structure/chisel_message/New(newloc) - ..() + var/turf/original_turf + +/obj/structure/chisel_message/Initialize(mapload) + . = ..() SSpersistence.chisel_messages += src var/turf/T = get_turf(src) + original_turf = T + if(!good_chisel_message_location(T)) persists = FALSE qdel(src) -/obj/structure/chisel_message/singularity_pull() - return - /obj/structure/chisel_message/proc/register(mob/user, newmessage) hidden_message = newmessage creator_name = user.real_name @@ -181,6 +151,8 @@ var/hash = md5(hidden_message) var/newcolor = copytext(hash, 1, 7) add_atom_colour("#[newcolor]", FIXED_COLOUR_PRIORITY) + light_color = "#[newcolor]" + set_light(1) /obj/structure/chisel_message/proc/pack() var/list/data = list() @@ -189,12 +161,12 @@ data["creator_key"] = creator_key data["realdate"] = realdate data["map"] = SSmapping.config.map_name - var/turf/T = get_turf(src) - data["x"] = T.x - data["y"] = T.y - data["z"] = T.z + data["x"] = original_turf.x + data["y"] = original_turf.y + data["z"] = original_turf.z data["like_keys"] = like_keys data["dislike_keys"] = dislike_keys + return data /obj/structure/chisel_message/proc/unpack(list/data) if(!islist(data)) diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm index 2f431e884a..c51e7feb7a 100644 --- a/code/modules/lighting/lighting_corner.dm +++ b/code/modules/lighting/lighting_corner.dm @@ -6,8 +6,8 @@ GLOBAL_LIST_INIT(LIGHTING_CORNER_DIAGONAL, list(NORTHEAST, SOUTHEAST, SOUTHWEST, NORTHWEST)) /datum/lighting_corner - var/list/turf/masters = list() - var/list/datum/light_source/affecting = list() // Light sources affecting us. + var/list/turf/masters + var/list/datum/light_source/affecting // Light sources affecting us. var/active = FALSE // TRUE if one of our masters has dynamic lighting. var/x = 0 @@ -25,11 +25,9 @@ GLOBAL_LIST_INIT(LIGHTING_CORNER_DIAGONAL, list(NORTHEAST, SOUTHEAST, SOUTHWEST, var/cache_b = LIGHTING_SOFT_THRESHOLD var/cache_mx = 0 - var/update_gen = 0 - /datum/lighting_corner/New(var/turf/new_turf, var/diagonal) . = ..() - + masters = list() masters[new_turf] = turn(diagonal, 180) z = new_turf.z diff --git a/code/modules/lighting/lighting_object.dm b/code/modules/lighting/lighting_object.dm index 369129fc57..b0b0b32285 100644 --- a/code/modules/lighting/lighting_object.dm +++ b/code/modules/lighting/lighting_object.dm @@ -6,6 +6,7 @@ GLOBAL_LIST_EMPTY(all_lighting_objects) // Global list of lighting objects. anchored = TRUE icon = LIGHTING_ICON + icon_state = "transparent" color = LIGHTING_BASE_MATRIX plane = LIGHTING_PLANE mouse_opacity = 0 @@ -16,7 +17,7 @@ GLOBAL_LIST_EMPTY(all_lighting_objects) // Global list of lighting objects. var/needs_update = FALSE -/atom/movable/lighting_object/Initialize(mapload, var/no_update = FALSE) +/atom/movable/lighting_object/Initialize(mapload) . = ..() verbs.Cut() GLOB.all_lighting_objects += src @@ -28,10 +29,8 @@ GLOBAL_LIST_EMPTY(all_lighting_objects) // Global list of lighting objects. for(var/turf/open/space/S in RANGE_TURFS(1, src)) //RANGE_TURFS is in code\__HELPERS\game.dm S.update_starlight() - if (no_update) - return - - update() + needs_update = TRUE + GLOB.lighting_update_objects += src /atom/movable/lighting_object/Destroy(var/force) if (force) @@ -69,10 +68,17 @@ GLOBAL_LIST_EMPTY(all_lighting_objects) // Global list of lighting objects. // See LIGHTING_CORNER_DIAGONAL in lighting_corner.dm for why these values are what they are. var/static/datum/lighting_corner/dummy/dummy_lighting_corner = new - var/datum/lighting_corner/cr = T.corners[3] || dummy_lighting_corner - var/datum/lighting_corner/cg = T.corners[2] || dummy_lighting_corner - var/datum/lighting_corner/cb = T.corners[4] || dummy_lighting_corner - var/datum/lighting_corner/ca = T.corners[1] || dummy_lighting_corner + + var/list/corners = T.corners + var/datum/lighting_corner/cr = dummy_lighting_corner + var/datum/lighting_corner/cg = dummy_lighting_corner + var/datum/lighting_corner/cb = dummy_lighting_corner + var/datum/lighting_corner/ca = dummy_lighting_corner + if (corners) //done this way for speed + cr = corners[3] || dummy_lighting_corner + cg = corners[2] || dummy_lighting_corner + cb = corners[4] || dummy_lighting_corner + ca = corners[1] || dummy_lighting_corner var/max = max(cr.cache_mx, cg.cache_mx, cb.cache_mx, ca.cache_mx) diff --git a/code/modules/lighting/lighting_setup.dm b/code/modules/lighting/lighting_setup.dm index fe9bdb5609..5086b0c9d2 100644 --- a/code/modules/lighting/lighting_setup.dm +++ b/code/modules/lighting/lighting_setup.dm @@ -8,6 +8,6 @@ if(!IS_DYNAMIC_LIGHTING(T)) continue - new/atom/movable/lighting_object(T, TRUE) + new/atom/movable/lighting_object(T) CHECK_TICK CHECK_TICK diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm index 1cf14c3c47..63457a1ce9 100644 --- a/code/modules/lighting/lighting_source.dm +++ b/code/modules/lighting/lighting_source.dm @@ -26,22 +26,15 @@ var/applied = FALSE // Whether we have applied our light yet or not. - var/vis_update // Whether we should smartly recalculate visibility. and then only update tiles that became (in)visible to us. - var/needs_update // Whether we are queued for an update. - var/force_update + var/needs_update = LIGHTING_NO_UPDATE // Whether we are queued for an update. + /datum/light_source/New(var/atom/owner, var/atom/top) source_atom = owner // Set our new owner. - if (!source_atom.light_sources) - source_atom.light_sources = list() - - source_atom.light_sources += src // Add us to the lights of our owner. + LAZYADD(source_atom.light_sources, src) top_atom = top if (top_atom != source_atom) - if (!top.light_sources) - top.light_sources = list() - - top_atom.light_sources += src + LAZYADD(top_atom.light_sources, src) source_turf = top_atom pixel_turf = get_turf_pixel(top_atom) || source_turf @@ -52,20 +45,18 @@ parse_light_color() - effect_str = list() - affecting_turfs = list() - update() return ..() /datum/light_source/Destroy(force) - force_update() + remove_lum() if (source_atom) - source_atom.light_sources -= src + LAZYREMOVE(source_atom.light_sources, src) if (top_atom) - top_atom.light_sources -= src + LAZYREMOVE(top_atom.light_sources, src) + . = ..() if(!force) return QDEL_HINT_IWILLGC @@ -73,79 +64,34 @@ // Yes this doesn't align correctly on anything other than 4 width tabs. // If you want it to go switch everybody to elastic tab stops. // Actually that'd be great if you could! -#define EFFECT_UPDATE \ - if (!needs_update) \ - { \ - GLOB.lighting_update_lights += src; \ - needs_update = TRUE; \ - } +#define EFFECT_UPDATE(level) \ + if (needs_update == LIGHTING_NO_UPDATE) \ + GLOB.lighting_update_lights += src; \ + if (needs_update < level) \ + needs_update = level; \ + // This proc will cause the light source to update the top atom, and add itself to the update queue. /datum/light_source/proc/update(var/atom/new_top_atom) // This top atom is different. if (new_top_atom && new_top_atom != top_atom) if(top_atom != source_atom && top_atom.light_sources) // Remove ourselves from the light sources of that top atom. - top_atom.light_sources -= src + LAZYREMOVE(top_atom.light_sources, src) top_atom = new_top_atom if (top_atom != source_atom) LAZYADD(top_atom.light_sources, src) // Add ourselves to the light sources of our new top atom. - EFFECT_UPDATE + EFFECT_UPDATE(LIGHTING_CHECK_UPDATE) // Will force an update without checking if it's actually needed. /datum/light_source/proc/force_update() - force_update = 1 - - EFFECT_UPDATE + EFFECT_UPDATE(LIGHTING_FORCE_UPDATE) // Will cause the light source to recalculate turfs that were removed or added to visibility only. /datum/light_source/proc/vis_update() - vis_update = 1 - - EFFECT_UPDATE - -// Will check if we actually need to update, and update any variables that may need to be updated. -/datum/light_source/proc/check() - if (!source_atom || !light_range || !light_power) - qdel(src) - return 1 - - if (!top_atom) - top_atom = source_atom - . = 1 - - if (isturf(top_atom)) - if (source_turf != top_atom) - source_turf = top_atom - pixel_turf = source_turf - . = 1 - else if (top_atom.loc != source_turf) - source_turf = top_atom.loc - pixel_turf = get_turf_pixel(top_atom) - . = 1 - else - var/P = get_turf_pixel(top_atom) - if (P != pixel_turf) - . = 1 - pixel_turf = get_turf_pixel(top_atom) - - if (source_atom.light_power != light_power) - light_power = source_atom.light_power - . = 1 - - if (source_atom.light_range != light_range) - light_range = source_atom.light_range - . = 1 - - if (light_range && light_power && !applied) - . = 1 - - if (source_atom.light_color != light_color) - light_color = source_atom.light_color - parse_light_color() - . = 1 + EFFECT_UPDATE(LIGHTING_VIS_UPDATE) // Decompile the hexadecimal colour into lumcounts of each perspective. /datum/light_source/proc/parse_light_color() @@ -164,48 +110,47 @@ // As such this all gets counted as a single line. // The braces and semicolons are there to be able to do this on a single line. #define LUM_FALLOFF(C, T) (1 - CLAMP01(sqrt((C.x - T.x) ** 2 + (C.y - T.y) ** 2 + LIGHTING_HEIGHT) / max(1, light_range))) -#define APPLY_CORNER(C) \ - . = LUM_FALLOFF(C, pixel_turf); \ - \ - . *= light_power; \ - \ - effect_str[C] = .; \ - \ - C.update_lumcount \ - ( \ - . * applied_lum_r, \ - . * applied_lum_g, \ - . * applied_lum_b \ + +#define APPLY_CORNER(C) \ + . = LUM_FALLOFF(C, pixel_turf); \ + . *= light_power; \ + var/OLD = effect_str[C]; \ + \ + effect_str[C] = .; \ + \ + C.update_lumcount \ + ( \ + (. * lum_r) - (OLD * applied_lum_r), \ + (. * lum_g) - (OLD * applied_lum_g), \ + (. * lum_b) - (OLD * applied_lum_b) \ ); -// I don't need to explain what this does, do I? -#define REMOVE_CORNER(C) \ - . = -effect_str[C]; \ - C.update_lumcount \ - ( \ - . * applied_lum_r, \ - . * applied_lum_g, \ - . * applied_lum_b \ + +#define REMOVE_CORNER(C) \ + . = -effect_str[C]; \ + C.update_lumcount \ + ( \ + . * applied_lum_r, \ + . * applied_lum_g, \ + . * applied_lum_b \ ); // This is the define used to calculate falloff. - +/* /datum/light_source/proc/apply_lum() var/static/update_gen = 1 applied = 1 // Keep track of the last applied lum values so that the lighting can be reversed - applied_lum_r = lum_r - applied_lum_g = lum_g - applied_lum_b = lum_b var/thing var/datum/lighting_corner/C + var/corners = list() + LAZYINITLIST(effect_str) FOR_DVIEW(var/turf/T, light_range+1, source_turf, INVISIBILITY_LIGHTING) - if (!T.lighting_corners_initialised) - T.generate_missing_corners() + var/list/turf_corners = T.get_corners() - for (thing in T.get_corners()) + for (thing in turf_corners) C = thing if (C.update_gen == update_gen) continue @@ -220,9 +165,13 @@ APPLY_CORNER(C) LAZYADD(T.affecting_lights, src) - affecting_turfs += T + LAZYADD(affecting_turfs, T) FOR_DVIEW_END update_gen++ + applied_lum_r = lum_r + applied_lum_g = lum_g + applied_lum_b = lum_b +*/ /datum/light_source/proc/remove_lum() applied = FALSE @@ -231,7 +180,7 @@ var/turf/T = thing LAZYREMOVE(T.affecting_lights, src) - affecting_turfs.Cut() + affecting_turfs = null var/datum/lighting_corner/C for (thing in effect_str) @@ -240,30 +189,93 @@ LAZYREMOVE(C.affecting, src) - effect_str.Cut() + effect_str = null /datum/light_source/proc/recalc_corner(var/datum/lighting_corner/C) - if (effect_str.Find(C)) // Already have one. + LAZYINITLIST(effect_str) + if (effect_str[C]) // Already have one. REMOVE_CORNER(C) + effect_str[C] = 0 APPLY_CORNER(C) + UNSETEMPTY(effect_str) + +/datum/light_source/proc/update_corners() + var/update = FALSE + + if (!source_atom || QDELETED(source_atom)) + qdel(src) + return + + if (source_atom.light_power != light_power) + light_power = source_atom.light_power + update = TRUE + + if (source_atom.light_range != light_range) + light_range = source_atom.light_range + update = TRUE + + if (!top_atom) + top_atom = source_atom + update = TRUE + + if (!light_range || !light_power) + qdel(src) + return + + if (isturf(top_atom)) + if (source_turf != top_atom) + source_turf = top_atom + pixel_turf = source_turf + update = TRUE + else if (top_atom.loc != source_turf) + source_turf = top_atom.loc + pixel_turf = get_turf_pixel(top_atom) + update = TRUE + else + var/P = get_turf_pixel(top_atom) + if (P != pixel_turf) + pixel_turf = P + update = TRUE + + if (!isturf(source_turf)) + if (applied) + remove_lum() + return + + if (light_range && light_power && !applied) + update = TRUE + + if (source_atom.light_color != light_color) + light_color = source_atom.light_color + parse_light_color() + update = TRUE + + else if (applied_lum_r != lum_r || applied_lum_g != lum_g || applied_lum_b != lum_b) + update = TRUE + + if (update) + needs_update = LIGHTING_CHECK_UPDATE + applied = TRUE + else if (needs_update == LIGHTING_CHECK_UPDATE) + return //nothing's changed -/datum/light_source/proc/smart_vis_update() var/list/datum/lighting_corner/corners = list() var/list/turf/turfs = list() var/thing var/datum/lighting_corner/C var/turf/T + if (source_turf) + var/oldlum = source_turf.luminosity + source_turf.luminosity = Ceiling(light_range) + for(T in view(Ceiling(light_range), source_turf)) + for (thing in T.get_corners(source_turf)) + C = thing + corners[C] = 0 + turfs += T + source_turf.luminosity = oldlum - FOR_DVIEW(T, light_range+1, source_turf, 0) - if (!T.lighting_corners_initialised) - T.generate_missing_corners() - for (thing in T.get_corners(source_turf)) - C = thing - corners[C] = 0 - turfs += T - FOR_DVIEW_END - + LAZYINITLIST(affecting_turfs) var/list/L = turfs - affecting_turfs // New turfs, add us to the affecting lights of them. affecting_turfs += L for (thing in L) @@ -276,22 +288,45 @@ T = thing LAZYREMOVE(T.affecting_lights, src) + LAZYINITLIST(effect_str) + if (needs_update == LIGHTING_VIS_UPDATE) + for (thing in corners - effect_str) // New corners + C = thing + LAZYADD(C.affecting, src) + if (!C.active) + effect_str[C] = 0 + continue + APPLY_CORNER(C) + else + L = corners - effect_str + for (thing in L) // New corners + C = thing + LAZYADD(C.affecting, src) + if (!C.active) + effect_str[C] = 0 + continue + APPLY_CORNER(C) + for (thing in corners - L) // Existing corners + C = thing + if (!C.active) + effect_str[C] = 0 + continue + APPLY_CORNER(C) - for (thing in corners - effect_str) // New corners - C = thing - LAZYADD(C.affecting, src) - if (!C.active) - effect_str[C] = 0 - continue - - APPLY_CORNER(C) - - for (thing in effect_str - corners) // Old, now gone, corners. + L = effect_str - corners + for (thing in L) // Old, now gone, corners. C = thing REMOVE_CORNER(C) LAZYREMOVE(C.affecting, src) - effect_str -= C + effect_str -= L + + applied_lum_r = lum_r + applied_lum_g = lum_g + applied_lum_b = lum_b + + UNSETEMPTY(effect_str) + UNSETEMPTY(affecting_turfs) #undef EFFECT_UPDATE #undef LUM_FALLOFF diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index 65b1ec2615..ca6866c48e 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -33,7 +33,7 @@ return var/area/A = loc - if (!IS_DYNAMIC_LIGHTING(A)) + if (!IS_DYNAMIC_LIGHTING(A) && !light_sources) return if (!lighting_corners_initialised) @@ -113,12 +113,18 @@ lighting_clear_overlay() /turf/proc/get_corners() + if (!IS_DYNAMIC_LIGHTING(src) && !light_sources) + return null + if (!lighting_corners_initialised) + generate_missing_corners() if (has_opaque_atom) return null // Since this proc gets used in a for loop, null won't be looped though. return corners /turf/proc/generate_missing_corners() + if (!IS_DYNAMIC_LIGHTING(src) && !light_sources) + return lighting_corners_initialised = TRUE if (!corners) corners = list(null, null, null, null) diff --git a/code/modules/mapping/ruins.dm b/code/modules/mapping/ruins.dm index 81c0a7e54d..d08161916c 100644 --- a/code/modules/mapping/ruins.dm +++ b/code/modules/mapping/ruins.dm @@ -20,7 +20,7 @@ if(ruins && ruins.len) ruin = ruins[pick(ruins)] else - world.log << "Ruin loader had no ruins to pick from with [budget] left to spend." + log_world("Ruin loader had no ruins to pick from with [budget] left to spend.") break // Can we afford it if(ruin.cost > budget) @@ -47,7 +47,7 @@ if(!valid) continue - world.log << "Ruin \"[ruin.name]\" placed at ([T.x], [T.y], [T.z])" + log_world("Ruin \"[ruin.name]\" placed at ([T.x], [T.y], [T.z])") var/obj/effect/ruin_loader/R = new /obj/effect/ruin_loader(T) R.Load(ruins,ruin) @@ -57,7 +57,7 @@ break if(!overall_sanity) - world.log << "Ruin loader gave up with [budget] left to spend." + log_world("Ruin loader gave up with [budget] left to spend.") /obj/effect/ruin_loader diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index 6b1179a585..4999f796c5 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -10,7 +10,7 @@ desc = "It's watching you suspiciously." /obj/structure/closet/crate/necropolis/tendril/PopulateContents() - var/loot = rand(1,25) + var/loot = rand(1,26) switch(loot) if(1) new /obj/item/device/shared_storage/red(src) @@ -33,7 +33,7 @@ if(9) new /obj/item/organ/brain/alien(src) if(10) - new /obj/item/organ/heart/cursed(src) + new /obj/item/organ/heart/cursed/wizard(src) if(11) new /obj/item/ship_in_a_bottle(src) if(12) @@ -65,6 +65,8 @@ new /obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor(src) if(25) new /obj/item/weapon/spellbook/oneuse/summonitem(src) + if(26) + new /obj/item/book_of_babel(src) @@ -343,6 +345,24 @@ add_fingerprint(usr) + + +//Book of Babel + +/obj/item/book_of_babel + name = "Book of Babel" + desc = "An ancient tome written in countless tongues." + icon = 'icons/obj/library.dmi' + icon_state = "book1" + w_class = 2 + +/obj/item/book_of_babel/attack_self(mob/user) + to_chat(user, "You flip through the pages of the book, quickly and conveniently learning every language in existence. Somewhat less conveniently, the aging book crumbles to dust in the process. Whoops.") + user.grant_all_languages(omnitongue=TRUE) + new /obj/effect/decal/cleanable/ash(get_turf(user)) + qdel(src) + + //Boat /obj/vehicle/lavaboat diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index d93bcb5028..f3b66d9172 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -84,7 +84,7 @@ if(D.make_reagents.len) return 0 - var/build_amount = 1 + var/build_amount = 0 for(var/mat_id in D.materials) var/M = D.materials[mat_id] @@ -93,7 +93,15 @@ if(!M || !redemption_mat) return 0 - build_amount = min(build_amount, round(redemption_mat.amount / M)) + var/smeltable_sheets = round(redemption_mat.amount / M) + + if(!smeltable_sheets) + return 0 + + if(!build_amount) + build_amount = smeltable_sheets + + build_amount = min(build_amount, smeltable_sheets) return build_amount @@ -152,6 +160,7 @@ if(exchange_parts(user, W)) return if(default_pry_open(W)) + materials.retrieve_all() return if(default_unfasten_wrench(user, W)) return diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 0d651518b7..ae0ad90dfe 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -193,9 +193,7 @@ qdel(voucher) /obj/machinery/mineral/equipment_vendor/ex_act(severity, target) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() + do_sparks(5, TRUE, src) if(prob(50 / severity) && severity < 3) qdel(src) @@ -214,11 +212,10 @@ new /datum/data/mining_equipment("Monkey Cube", /obj/item/weapon/reagent_containers/food/snacks/monkeycube, 300), new /datum/data/mining_equipment("Toolbelt", /obj/item/weapon/storage/belt/utility, 350), new /datum/data/mining_equipment("Sulphuric Acid", /obj/item/weapon/reagent_containers/glass/beaker/sulphuric, 500), - new /datum/data/mining_equipment("Brute First-Aid Kit", /obj/item/weapon/storage/firstaid/brute, 600), new /datum/data/mining_equipment("Grey Slime Extract", /obj/item/slime_extract/grey, 1000), new /datum/data/mining_equipment("Modification Kit", /obj/item/borg/upgrade/modkit/trigger_guard, 1700), new /datum/data/mining_equipment("The Liberator's Legacy", /obj/item/weapon/storage/box/rndboards, 2000), - + new /datum/data/mining_equipment("Royal Cape of the Liberator", /obj/item/weapon/bedsheet/rd/royal_cape, 500) ) var/obj/item/weapon/circuitboard/machine/B = new /obj/item/weapon/circuitboard/machine/mining_equipment_vendor/golem(null) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 2bb438639b..d15896a8db 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -278,8 +278,8 @@ var/turf/T = deploy_location if(T.z != ZLEVEL_MINING && T.z != ZLEVEL_LAVALAND)//only report capsules away from the mining/lavaland level - message_admins("[key_name_admin(usr)] (?) (FLW) activated a bluespace capsule away from the mining level! (JMP)") - log_admin("[key_name(usr)] activated a bluespace capsule away from the mining level at [T.x], [T.y], [T.z]") + message_admins("[ADMIN_LOOKUPFLW(usr)] activated a bluespace capsule away from the mining level! [ADMIN_JMP(T)]") + log_admin("[key_name(usr)] activated a bluespace capsule away from the mining level at [get_area(T)][COORD(T)]") template.load(deploy_location, centered = TRUE) new /obj/effect/particle_effect/smoke(get_turf(src)) qdel(src) diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index 1e7f01d7a3..b1ba6680c2 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -248,18 +248,18 @@ if(notify_admins) if(triggered_by == 1) - message_admins("An explosion has triggered a [name] to detonate at [A.name] (JMP).") + message_admins("An explosion has triggered a [name] to detonate at [ADMIN_COORDJMP(bombturf)].") else if(triggered_by == 2) - message_admins("A signal has triggered a [name] to detonate at [A.name] (JMP). Igniter attacher: [key_name_admin(attacher)]? (FLW)") + message_admins("A signal has triggered a [name] to detonate at [ADMIN_COORDJMP(bombturf)]. Igniter attacher: [ADMIN_LOOKUPFLW(attacher)]") else - message_admins("[key_name_admin(user)]? (FLW) has triggered a [name] to detonate at [A.name] (JMP).") + message_admins("[ADMIN_LOOKUPFLW(attacher)] has triggered a [name] to detonate at [ADMIN_COORDJMP(bombturf)].") if(triggered_by == 1) - log_game("An explosion has primed a [name] for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])") + log_game("An explosion has primed a [name] for detonation at [A][COORD(bombturf)]") else if(triggered_by == 2) - log_game("A signal has primed a [name] for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z]). Igniter attacher: [key_name(attacher)].") + log_game("A signal has primed a [name] for detonation at [A][COORD(bombturf)]. Igniter attacher: [key_name(attacher)].") else user.visible_message("[user] strikes \the [src], causing a chain reaction!", "You strike \the [src], causing a chain reaction.") - log_game("[key_name(user)] has primed a [name] for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])") + log_game("[key_name(user)] has primed a [name] for detonation at [A][COORD(bombturf)]") spawn(det_time) if(primed) if(quality == 3) diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm index 666222aa27..45a64bbfde 100644 --- a/code/modules/mob/dead/dead.dm +++ b/code/modules/mob/dead/dead.dm @@ -1,42 +1,51 @@ //Dead mobs can exist whenever. This is needful -INITIALIZE_IMMEDIATE(/mob/dead) - -/mob/dead/Initialize() - . = ..() - if(config.cross_allowed) - verbs += /mob/dead/proc/server_hop + INITIALIZE_IMMEDIATE(/mob/dead) -/mob/dead/dust() //ghosts can't be vaporised. - return - -/mob/dead/gib() //ghosts can't be gibbed. - return + /mob/dead/Initialize() + if(initialized) + stack_trace("Warning: [src]([type]) initialized multiple times!") + initialized = TRUE + tag = "mob_[next_mob_id++]" + GLOB.mob_list += src -/mob/dead/ConveyorMove() //lol - return + prepare_huds() + + if(config.cross_allowed) + verbs += /mob/dead/proc/server_hop + return INITIALIZE_HINT_NORMAL + + /mob/dead/dust() //ghosts can't be vaporised. + return + + /mob/dead/gib() //ghosts can't be gibbed. + return + + /mob/dead/ConveyorMove() //lol + return -/mob/dead/proc/server_hop() - set category = "OOC" - set name = "Server Hop!" - set desc= "Jump to the other server" - if(notransform) - return - if(!config.cross_allowed) - verbs -= /mob/dead/proc/server_hop - to_chat(src, "Server Hop has been disabled.") - return - if (alert(src, "Jump to server running at [config.cross_address]?", "Server Hop", "Yes", "No") != "Yes") - return 0 - if (client && config.cross_allowed) - to_chat(src, "Sending you to [config.cross_address].") - new /obj/screen/splash(client) - notransform = TRUE - sleep(29) //let the animation play - notransform = FALSE - winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources - client << link(config.cross_address + "?server_hop=[key]") - else - to_chat(src, "There is no other server configured!") + /mob/dead/proc/server_hop() + set category = "OOC" + set name = "Server Hop!" + set desc= "Jump to the other server" + if(notransform) + return + if(!config.cross_allowed) + verbs -= /mob/dead/proc/server_hop + to_chat(src, "Server Hop has been disabled.") + return + if (alert(src, "Jump to server running at [config.cross_address]?", "Server Hop", "Yes", "No") != "Yes") + return 0 + if (client && config.cross_allowed) + to_chat(src, "Sending you to [config.cross_address].") + new /obj/screen/splash(client) + notransform = TRUE + sleep(29) //let the animation play + notransform = FALSE + winset(src, null, "command=.options") //other wise the user never knows if byond is downloading resources + client << link(config.cross_address + "?server_hop=[key]") + else + to_chat(src, "There is no other server configured!") + \ No newline at end of file diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm index bc00dc395a..e3943d07e6 100644 --- a/code/modules/mob/dead/new_player/new_player.dm +++ b/code/modules/mob/dead/new_player/new_player.dm @@ -16,12 +16,6 @@ var/mob/living/new_character //for instant transfer once the round is set up /mob/dead/new_player/Initialize() - if(initialized) - stack_trace("Warning: [src]([type]) initialized multiple times!") - initialized = TRUE - tag = "mob_[next_mob_id++]" - GLOB.mob_list += src - if(client && SSticker.state == GAME_STATE_STARTUP) var/obj/screen/splash/S = new(client, TRUE, TRUE) S.Fade(TRUE) @@ -30,7 +24,10 @@ loc = pick(GLOB.newplayer_start) else loc = locate(1,1,1) - return INITIALIZE_HINT_NORMAL + . = ..() + +/mob/dead/new_player/prepare_huds() + return /mob/dead/new_player/proc/new_player_panel() diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 395d7f0099..316a7a3b83 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -54,7 +54,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) var/deadchat_name /mob/dead/observer/Initialize() - invisibility = GLOB.observer_default_invisibility + set_invisibility(GLOB.observer_default_invisibility) verbs += /mob/dead/observer/proc/dead_tele @@ -117,6 +117,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) animate(src, pixel_y = 2, time = 10, loop = -1) + GLOB.dead_mob_list += src ..() @@ -786,13 +787,25 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(!invisibility) to_chat(user, "It seems extremely obvious.") +/mob/dead/observer/proc/set_invisibility(value) + invisibility = value + if(!value) + set_light(1, 2) + else + set_light(0, 0) + // Ghosts have no momentum, being massless ectoplasm /mob/dead/observer/Process_Spacemove(movement_dir) return 1 +/mob/dead/observer/vv_edit_var(var_name, var_value) + . = ..() + if(var_name == "invisibility") + set_invisibility(invisibility) // updates light + /proc/set_observer_default_invisibility(amount, message=null) for(var/mob/dead/observer/G in GLOB.player_list) - G.invisibility = amount + G.set_invisibility(amount) if(message) to_chat(G, message) GLOB.observer_default_invisibility = amount diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index ca380170f7..ca8b8f2d9d 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -35,22 +35,21 @@ blood_volume += 0.1 // regenerate blood VERY slowly //Effects of bloodloss + var/word = pick("dizzy","woozy","faint") switch(blood_volume) if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) if(prob(5)) - to_chat(src, "You feel [pick("dizzy","woozy","faint")].") + to_chat(src, "You feel [word].") adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.01, 1)) if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) adjustOxyLoss(round((BLOOD_VOLUME_NORMAL - blood_volume) * 0.02, 1)) if(prob(5)) blur_eyes(6) - var/word = pick("dizzy","woozy","faint") to_chat(src, "You feel very [word].") if(BLOOD_VOLUME_SURVIVE to BLOOD_VOLUME_BAD) adjustOxyLoss(5) if(prob(15)) Paralyse(rand(1,3)) - var/word = pick("dizzy","woozy","faint") to_chat(src, "You feel extremely [word].") if(0 to BLOOD_VOLUME_SURVIVE) death() @@ -70,7 +69,7 @@ bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases - if(bleed_rate && !bleedsuppress) + if(bleed_rate && !bleedsuppress && !(status_flags & FAKEDEATH)) bleed(bleed_rate) //Makes a blood drop, leaking amt units of blood from the mob diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm index 6247083747..9cad58c201 100644 --- a/code/modules/mob/living/brain/MMI.dm +++ b/code/modules/mob/living/brain/MMI.dm @@ -31,13 +31,10 @@ else icon_state = "mmi_empty" -/obj/item/device/mmi/New() - ..() +/obj/item/device/mmi/Initialize() + . = ..() radio = new(src) //Spawns a radio inside the MMI. radio.broadcasting = 0 //researching radio mmis turned the robofabs into radios because this didnt start as 0. - -/obj/item/device/mmi/Initialize() - ..() laws.set_laws_config() /obj/item/device/mmi/attackby(obj/item/O, mob/user, params) diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm index 8a9ee012d9..f9bd64153e 100644 --- a/code/modules/mob/living/carbon/alien/organs.dm +++ b/code/modules/mob/living/carbon/alien/organs.dm @@ -87,6 +87,8 @@ owner.adjustFireLoss(-heal_amt) owner.adjustOxyLoss(-heal_amt) owner.adjustCloneLoss(-heal_amt) + else + owner.adjustPlasma(plasma_rate * 0.1) /obj/item/organ/alien/plasmavessel/Insert(mob/living/carbon/M, special = 0) ..() diff --git a/code/modules/mob/living/carbon/alien/say.dm b/code/modules/mob/living/carbon/alien/say.dm index 72162387ee..12c131b3cc 100644 --- a/code/modules/mob/living/carbon/alien/say.dm +++ b/code/modules/mob/living/carbon/alien/say.dm @@ -1,4 +1,4 @@ -/mob/living/proc/alien_talk(message, shown_name = name) +/mob/living/proc/alien_talk(message, shown_name = real_name) log_say("[key_name(src)] : [message]") message = trim(message) if(!message) return 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 68d94b4c04..6e9bcc08cc 100644 --- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm +++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm @@ -69,7 +69,7 @@ bursting = TRUE - var/list/candidates = pollCandidates("Do you want to play as an alien larva that will burst out of [owner]?", ROLE_ALIEN, null, ROLE_ALIEN, 100, POLL_IGNORE_ALIEN_LARVA) + var/list/candidates = pollGhostCandidates("Do you want to play as an alien larva that will burst out of [owner]?", ROLE_ALIEN, null, ROLE_ALIEN, 100, POLL_IGNORE_ALIEN_LARVA) if(QDELETED(src) || QDELETED(owner)) return @@ -81,7 +81,7 @@ var/mob/dead/observer/ghost = pick(candidates) - var/mutable_appearance/overlay = mutable_appearance('icons/mob/alien.dmi', "burst_lie") + var/mutable_appearance/overlay = mutable_appearance('icons/mob/alien.dmi', "burst_lie") owner.add_overlay(overlay) var/atom/xeno_loc = get_turf(owner) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 87cf246717..06145235a0 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -484,7 +484,7 @@ adjustBruteLoss(3) else if(T) - T.add_vomit_floor(src, 0)//toxic barf looks different + T.add_vomit_floor(src, toxic)//toxic barf looks different nutrition -= lost_nutrition adjustToxLoss(-3) T = get_step(T, dir) @@ -492,6 +492,16 @@ break return 1 +/mob/living/carbon/proc/spew_organ(power = 5) + if(!internal_organs.len) + return //Guess we're out of organs + var/obj/item/organ/guts = pick(internal_organs) + var/turf/T = get_turf(src) + guts.Remove(src) + guts.forceMove(T) + var/atom/throw_target = get_edge_target_turf(guts, dir) + guts.throw_at(throw_target, power, 4, src) + /mob/living/carbon/fully_replace_character_name(oldname,newname) ..() diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 0d8cfeb98d..84cbc01a33 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -119,9 +119,7 @@ visible_message("The [M.name] has shocked [src]!", \ "The [M.name] has shocked [src]!") - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() + do_sparks(5, TRUE, src) var/power = M.powerlevel + rand(0,3) Weaken(power) if(stuttering < power) diff --git a/code/modules/mob/living/carbon/emote.dm b/code/modules/mob/living/carbon/emote.dm index 30fa676500..48ebd53435 100644 --- a/code/modules/mob/living/carbon/emote.dm +++ b/code/modules/mob/living/carbon/emote.dm @@ -68,6 +68,17 @@ if(!isnum(text2num(params))) return message +/datum/emote/sound/carbon/snap + key = "snap" + key_third_person = "snaps" + message = "snaps their fingers." + muzzle_ignore = TRUE + restraint_check = TRUE + emote_type = EMOTE_AUDIBLE + sound = 'sound/effects/snap01.ogg' + mob_type_allowed_typecache = list(/mob/living/carbon/) + + /datum/emote/living/carbon/sign/signal key = "signal" key_third_person = "signals" diff --git a/code/modules/mob/living/carbon/human/death.dm.rej b/code/modules/mob/living/carbon/human/death.dm.rej deleted file mode 100644 index a4a1fc5a7c..0000000000 --- a/code/modules/mob/living/carbon/human/death.dm.rej +++ /dev/null @@ -1,10 +0,0 @@ -diff a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm (rejected hunks) -@@ -32,7 +32,7 @@ - - dna.species.spec_death(gibbed, src) - -- if(SSticker && SSticker.mode) -+ if(SSticker.HasRoundStarted()) - SSblackbox.ReportDeath(src) - if(mind && mind.devilinfo) - INVOKE_ASYNC(mind.devilinfo, /datum/devilinfo.proc/beginResurrectionCheck, src) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index de4eecabff..b778279f42 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -171,5 +171,8 @@ dna.species.mutant_bodyparts -= "wingsopen" dna.species.mutant_bodyparts |= "wings" update_body() + if(isturf(loc)) + var/turf/T = loc + T.Entered(src) //Ayy lmao diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index 9081591395..a3bb2fefde 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -134,7 +134,7 @@ if(stat == DEAD || (status_flags & FAKEDEATH)) appears_dead = 1 if(suiciding) - msg += "[t_He] appear[p_s()] to have commited suicide... there is no hope of recovery.\n" + msg += "[t_He] appear[p_s()] to have committed suicide... there is no hope of recovery.\n" if(hellbound) msg += "[t_His] soul seems to have been ripped out of [t_his] body. Revival is impossible.\n" msg += "[t_He] [t_is] limp and unresponsive; there are no signs of life" diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index dec8692ef7..be7e851a8e 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1,929 +1,930 @@ -/mob/living/carbon/human - name = "Unknown" - real_name = "Unknown" - voice_name = "Unknown" - icon = 'icons/mob/human.dmi' - icon_state = "caucasian_m" - -/mob/living/carbon/human/dummy - real_name = "Test Dummy" - status_flags = GODMODE|CANPUSH - -/mob/living/carbon/human/dummy/New(loc) - ..() - if(!initialized) - args[1] = FALSE - Initialize(arglist(args)) - -/mob/living/carbon/human/dummy/Life() - return - -/mob/living/carbon/human/Initialize() - verbs += /mob/living/proc/mob_sleep - verbs += /mob/living/proc/lay_down - - //initialize limbs first - create_bodyparts() - - //initialize dna. for spawned humans; overwritten by other code - create_dna(src) - randomize_human(src) - dna.initialize_dna() - - if(dna.species) - set_species(dna.species.type) - - //initialise organs - create_internal_organs() - - martial_art = default_martial_art - - handcrafting = new() - - ..() - -/mob/living/carbon/human/create_internal_organs() - if(!(NOHUNGER in dna.species.species_traits)) - internal_organs += new /obj/item/organ/appendix - if(!(NOBREATH in dna.species.species_traits)) - if(dna.species.mutantlungs) - internal_organs += new dna.species.mutantlungs() - else - internal_organs += new /obj/item/organ/lungs() - if(!(NOBLOOD in dna.species.species_traits)) - internal_organs += new /obj/item/organ/heart - - internal_organs += new dna.species.mutanteyes() - internal_organs += new dna.species.mutantears - internal_organs += new /obj/item/organ/brain - give_genitals() - ..() - -/mob/living/carbon/human/OpenCraftingMenu() - handcrafting.ui_interact(src) - -/mob/living/carbon/human/prepare_data_huds() - //Update med hud images... - ..() - //...sec hud images... - sec_hud_set_ID() - sec_hud_set_implants() - sec_hud_set_security_status() - //...and display them. - add_to_all_human_data_huds() - -/mob/living/carbon/human/Stat() - ..() - - if(statpanel("Status")) - stat(null, "Intent: [a_intent]") - stat(null, "Move Mode: [m_intent]") - if (internal) - if (!internal.air_contents) - qdel(internal) - else - stat("Internal Atmosphere Info", internal.name) - stat("Tank Pressure", internal.air_contents.return_pressure()) - stat("Distribution Pressure", internal.distribute_pressure) - - var/mob/living/simple_animal/borer/B = has_brain_worms() - if(B && B.controlling) - stat("Chemicals", B.chemicals) - - if(mind) - if(mind.changeling) - stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]") - stat("Absorbed DNA", mind.changeling.absorbedcount) - - - //NINJACODE - if(istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)) //Only display if actually a ninja. - var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit - if(statpanel("SpiderOS")) - stat("SpiderOS Status:","[SN.s_initialized ? "Initialized" : "Disabled"]") - stat("Current Time:", "[worldtime2text()]") - if(SN.s_initialized) - //Suit gear - stat("Energy Charge:", "[round(SN.cell.charge/100)]%") - stat("Smoke Bombs:", "\Roman [SN.s_bombs]") - //Ninja status - stat("Fingerprints:", "[md5(dna.uni_identity)]") - stat("Unique Identity:", "[dna.unique_enzymes]") - stat("Overall Status:", "[stat > 1 ? "dead" : "[health]% healthy"]") - stat("Nutrition Status:", "[nutrition]") - stat("Oxygen Loss:", "[getOxyLoss()]") - stat("Toxin Levels:", "[getToxLoss()]") - stat("Burn Severity:", "[getFireLoss()]") - stat("Brute Trauma:", "[getBruteLoss()]") - stat("Radiation Levels:","[radiation] rad") - stat("Body Temperature:","[bodytemperature-T0C] degrees C ([bodytemperature*1.8-459.67] degrees F)") - - //Virsuses - if(viruses.len) - stat("Viruses:", null) - for(var/datum/disease/D in viruses) - stat("*", "[D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]") - - -/mob/living/carbon/human/show_inv(mob/user) - user.set_machine(src) - var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask) - var/list/obscured = check_obscured_slots() - var/list/dat = list() - - dat += "" - for(var/i in 1 to held_items.len) - var/obj/item/I = get_item_for_held_index(i) - dat += "" - dat += "" - - dat += "" - - dat += "" - - if(slot_wear_mask in obscured) - dat += "" - else - dat += "" - - if(slot_neck in obscured) - dat += "" - else - dat += "" - - if(slot_glasses in obscured) - dat += "" - else - dat += "" - - if(slot_ears in obscured) - dat += "" - else - dat += "" - - dat += "" - - dat += "" - if(wear_suit) - dat += "" - else - dat += "" - - if(slot_shoes in obscured) - dat += "" - else - dat += "" - - if(slot_gloves in obscured) - dat += "" - else - dat += "" - - if(slot_w_uniform in obscured) - dat += "" - else - dat += "" - - if((w_uniform == null && !(dna && dna.species.nojumpsuit)) || (slot_w_uniform in obscured)) - dat += "" - dat += "" - dat += "" - else - dat += "" - dat += "" - dat += "" - - if(handcuffed) - dat += "" - if(legcuffed) - dat += "" - - dat += {"
[get_held_index_name(i)]:[(I && !(I.flags & ABSTRACT)) ? I : "Empty"]
 
Back:[(back && !(back.flags&ABSTRACT)) ? back : "Empty"]" - if(has_breathable_mask && istype(back, /obj/item/weapon/tank)) - dat += " [internal ? "Disable Internals" : "Set Internals"]" - - dat += "
 
Head:[(head && !(head.flags&ABSTRACT)) ? head : "Empty"]
Mask:Obscured
Mask:[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "Empty"]
Neck:Obscured
Neck:[(wear_neck && !(wear_neck.flags&ABSTRACT)) ? wear_neck : "Empty"]
Eyes:Obscured
Eyes:[(glasses && !(glasses.flags&ABSTRACT)) ? glasses : "Empty"]
Ears:Obscured
Ears:[(ears && !(ears.flags&ABSTRACT)) ? ears : "Empty"]
 
Exosuit:[(wear_suit && !(wear_suit.flags&ABSTRACT)) ? wear_suit : "Empty"]
 ↳Suit Storage:[(s_store && !(s_store.flags&ABSTRACT)) ? s_store : "Empty"]" - if(has_breathable_mask && istype(s_store, /obj/item/weapon/tank)) - dat += " [internal ? "Disable Internals" : "Set Internals"]" - dat += "
 ↳Suit Storage:
Shoes:Obscured
Shoes:[(shoes && !(shoes.flags&ABSTRACT)) ? shoes : "Empty"]
Gloves:Obscured
Gloves:[(gloves && !(gloves.flags&ABSTRACT)) ? gloves : "Empty"]
Uniform:Obscured
Uniform:[(w_uniform && !(w_uniform.flags&ABSTRACT)) ? w_uniform : "Empty"]
 ↳Pockets:
 ↳ID:
 ↳Belt:
 ↳Belt:[(belt && !(belt.flags&ABSTRACT)) ? belt : "Empty"]" - if(has_breathable_mask && istype(belt, /obj/item/weapon/tank)) - dat += " [internal ? "Disable Internals" : "Set Internals"]" - dat += "
 ↳Pockets:[(l_store && !(l_store.flags&ABSTRACT)) ? "Left (Full)" : "Left (Empty)"]" - dat += " [(r_store && !(r_store.flags&ABSTRACT)) ? "Right (Full)" : "Right (Empty)"]
 ↳ID:[(wear_id && !(wear_id.flags&ABSTRACT)) ? wear_id : "Empty"]
Handcuffed: Remove
Legcuffed
- Close - "} - - var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 510) - popup.set_content(dat.Join()) - popup.open() - -// called when something steps onto a human -// this could be made more general, but for now just handle mulebot -/mob/living/carbon/human/Crossed(atom/movable/AM) - var/mob/living/simple_animal/bot/mulebot/MB = AM - if(istype(MB)) - MB.RunOver(src) - - spreadFire(AM) - - -/mob/living/carbon/human/Topic(href, href_list) - if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) - - if(href_list["embedded_object"]) - var/obj/item/bodypart/L = locate(href_list["embedded_limb"]) in bodyparts - if(!L) - return - var/obj/item/I = locate(href_list["embedded_object"]) in L.embedded_objects - if(!I || I.loc != src) //no item, no limb, or item is not in limb or in the person anymore - return - var/time_taken = I.embedded_unsafe_removal_time*I.w_class - usr.visible_message("[usr] attempts to remove [I] from their [L.name].","You attempt to remove [I] from your [L.name]... (It will take [time_taken/10] seconds.)") - if(do_after(usr, time_taken, needhand = 1, target = src)) - if(!I || !L || I.loc != src || !(I in L.embedded_objects)) - return - L.embedded_objects -= I - L.receive_damage(I.embedded_unsafe_removal_pain_multiplier*I.w_class)//It hurts to rip it out, get surgery you dingus. - I.forceMove(get_turf(src)) - usr.put_in_hands(I) - usr.emote("scream") - usr.visible_message("[usr] successfully rips [I] out of their [L.name]!","You successfully remove [I] from your [L.name].") - if(!has_embedded_objects()) - clear_alert("embeddedobject") - return - - if(href_list["item"]) - var/slot = text2num(href_list["item"]) - if(slot in check_obscured_slots()) - to_chat(usr, "You can't reach that! Something is covering it.") - return - - if(href_list["pockets"]) - var/pocket_side = href_list["pockets"] - var/pocket_id = (pocket_side == "right" ? slot_r_store : slot_l_store) - var/obj/item/pocket_item = (pocket_id == slot_r_store ? r_store : l_store) - var/obj/item/place_item = usr.get_active_held_item() // Item to place in the pocket, if it's empty - - var/delay_denominator = 1 - if(pocket_item && !(pocket_item.flags&ABSTRACT)) - if(pocket_item.flags & NODROP) - to_chat(usr, "You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!") - to_chat(usr, "You try to empty [src]'s [pocket_side] pocket.") - else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.flags&ABSTRACT)) - to_chat(usr, "You try to place [place_item] into [src]'s [pocket_side] pocket.") - delay_denominator = 4 - else - return - - if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator)) //placing an item into the pocket is 4 times faster - if(pocket_item) - if(pocket_item == (pocket_id == slot_r_store ? r_store : l_store)) //item still in the pocket we search - dropItemToGround(pocket_item) - else - if(place_item) - if(place_item.mob_can_equip(src, usr, pocket_id, FALSE, TRUE)) - usr.temporarilyRemoveItemFromInventory(place_item, TRUE) - equip_to_slot(place_item, pocket_id, TRUE) - //do nothing otherwise - - // Update strip window - if(usr.machine == src && in_range(src, usr)) - show_inv(usr) - else - // Display a warning if the user mocks up - to_chat(src, "You feel your [pocket_side] pocket being fumbled with!") - - ..() - - -///////HUDs/////// - if(href_list["hud"]) - if(ishuman(usr)) - var/mob/living/carbon/human/H = usr - var/perpname = get_face_name(get_id_name("")) - if(istype(H.glasses, /obj/item/clothing/glasses/hud) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud)) - var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.general) - if(href_list["photo_front"] || href_list["photo_side"]) - if(R) - if(!H.canUseHUD()) - return - else if(!istype(H.glasses, /obj/item/clothing/glasses/hud) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical)) - return - var/obj/item/weapon/photo/P = null - if(href_list["photo_front"]) - P = R.fields["photo_front"] - else if(href_list["photo_side"]) - P = R.fields["photo_side"] - if(P) - P.show(H) - - if(href_list["hud"] == "m") - if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical)) - if(href_list["p_stat"]) - var/health_status = input(usr, "Specify a new physical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("Active", "Physically Unfit", "*Unconscious*", "*Deceased*", "Cancel") - if(R) - if(!H.canUseHUD()) - return - else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical)) - return - if(health_status && health_status != "Cancel") - R.fields["p_stat"] = health_status - return - if(href_list["m_stat"]) - var/health_status = input(usr, "Specify a new mental status for this person.", "Medical HUD", R.fields["m_stat"]) in list("Stable", "*Watch*", "*Unstable*", "*Insane*", "Cancel") - if(R) - if(!H.canUseHUD()) - return - else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical)) - return - if(health_status && health_status != "Cancel") - R.fields["m_stat"] = health_status - return - if(href_list["evaluation"]) - if(!getBruteLoss() && !getFireLoss() && !getOxyLoss() && getToxLoss() < 20) - to_chat(usr, "No external injuries detected.
") - return - var/span = "notice" - var/status = "" - if(getBruteLoss()) - to_chat(usr, "Physical trauma analysis:") - for(var/X in bodyparts) - var/obj/item/bodypart/BP = X - var/brutedamage = BP.brute_dam - if(brutedamage > 0) - status = "received minor physical injuries." - span = "notice" - if(brutedamage > 20) - status = "been seriously damaged." - span = "danger" - if(brutedamage > 40) - status = "sustained major trauma!" - span = "userdanger" - if(brutedamage) - to_chat(usr, "[BP] appears to have [status]") - if(getFireLoss()) - to_chat(usr, "Analysis of skin burns:") - for(var/X in bodyparts) - var/obj/item/bodypart/BP = X - var/burndamage = BP.burn_dam - if(burndamage > 0) - status = "signs of minor burns." - span = "notice" - if(burndamage > 20) - status = "serious burns." - span = "danger" - if(burndamage > 40) - status = "major burns!" - span = "userdanger" - if(burndamage) - to_chat(usr, "[BP] appears to have [status]") - if(getOxyLoss()) - to_chat(usr, "Patient has signs of suffocation, emergency treatment may be required!") - if(getToxLoss() > 20) - to_chat(usr, "Gathered data is inconsistent with the analysis, possible cause: poisoning.") - - if(href_list["hud"] == "s") - if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) - if(usr.stat || usr == src) //|| !usr.canmove || usr.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at. - return //Non-fluff: This allows sec to set people to arrest as they get disarmed or beaten - // Checks the user has security clearence before allowing them to change arrest status via hud, comment out to enable all access - var/allowed_access = null - var/obj/item/clothing/glasses/G = H.glasses - if (!G.emagged) - if(H.wear_id) - var/list/access = H.wear_id.GetAccess() - if(GLOB.access_sec_doors in access) - allowed_access = H.get_authentification_name() - else - allowed_access = "@%&ERROR_%$*" - - - if(!allowed_access) - to_chat(H, "ERROR: Invalid Access") - return - - if(perpname) - R = find_record("name", perpname, GLOB.data_core.security) - if(R) - if(href_list["status"]) - var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Parolled", "Discharged", "Cancel") - if(setcriminal != "Cancel") - if(R) - if(H.canUseHUD()) - if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) - investigate_log("[src.key] has been set from [R.fields["criminal"]] to [setcriminal] by [usr.name] ([usr.key]).", "records") - R.fields["criminal"] = setcriminal - sec_hud_set_security_status() - return - - if(href_list["view"]) - if(R) - if(!H.canUseHUD()) - return - else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) - return - to_chat(usr, "Name: [R.fields["name"]] Criminal Status: [R.fields["criminal"]]") - to_chat(usr, "Minor Crimes:") - for(var/datum/data/crime/c in R.fields["mi_crim"]) - to_chat(usr, "Crime: [c.crimeName]") - to_chat(usr, "Details: [c.crimeDetails]") - to_chat(usr, "Added by [c.author] at [c.time]") - to_chat(usr, "----------") - to_chat(usr, "Major Crimes:") - for(var/datum/data/crime/c in R.fields["ma_crim"]) - to_chat(usr, "Crime: [c.crimeName]") - to_chat(usr, "Details: [c.crimeDetails]") - to_chat(usr, "Added by [c.author] at [c.time]") - to_chat(usr, "----------") - to_chat(usr, "Notes: [R.fields["notes"]]") - return - - if(href_list["add_crime"]) - switch(alert("What crime would you like to add?","Security HUD","Minor Crime","Major Crime","Cancel")) - if("Minor Crime") - if(R) - var/t1 = stripped_input("Please input minor crime names:", "Security HUD", "", null) - var/t2 = stripped_multiline_input("Please input minor crime details:", "Security HUD", "", null) - if(R) - if (!t1 || !t2 || !allowed_access) - return - else if(!H.canUseHUD()) - return - else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) - return - var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text()) - GLOB.data_core.addMinorCrime(R.fields["id"], crime) - to_chat(usr, "Successfully added a minor crime.") - return - if("Major Crime") - if(R) - var/t1 = stripped_input("Please input major crime names:", "Security HUD", "", null) - var/t2 = stripped_multiline_input("Please input major crime details:", "Security HUD", "", null) - if(R) - if (!t1 || !t2 || !allowed_access) - return - else if (!H.canUseHUD()) - return - else if (!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) - return - var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text()) - GLOB.data_core.addMajorCrime(R.fields["id"], crime) - to_chat(usr, "Successfully added a major crime.") - return - - if(href_list["view_comment"]) - if(R) - if(!H.canUseHUD()) - return - else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) - return - to_chat(usr, "Comments/Log:") - var/counter = 1 - while(R.fields[text("com_[]", counter)]) - to_chat(usr, R.fields[text("com_[]", counter)]) - to_chat(usr, "----------") - counter++ - return - - if(href_list["add_comment"]) - if(R) - var/t1 = stripped_multiline_input("Add Comment:", "Secure. records", null, null) - if(R) - if (!t1 || !allowed_access) - return - else if(!H.canUseHUD()) - return - else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) - return - var/counter = 1 - while(R.fields[text("com_[]", counter)]) - counter++ - R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []
[]", allowed_access, worldtime2text(), time2text(world.realtime, "MMM DD"), GLOB.year_integer+540, t1) - to_chat(usr, "Successfully added comment.") - return - to_chat(usr, "Unable to locate a data core entry for this person.") - -/mob/living/carbon/human/proc/canUseHUD() - return !(src.stat || src.weakened || src.stunned || src.restrained()) - -/mob/living/carbon/human/can_inject(mob/user, error_msg, target_zone, var/penetrate_thick = 0) - . = 1 // Default to returning true. - if(user && !target_zone) - target_zone = user.zone_selected - if(dna && (PIERCEIMMUNE in dna.species.species_traits)) - . = 0 - // If targeting the head, see if the head item is thin enough. - // If targeting anything else, see if the wear suit is thin enough. - if(above_neck(target_zone)) - if(head && head.flags & THICKMATERIAL && !penetrate_thick) - . = 0 - else - if(wear_suit && wear_suit.flags & THICKMATERIAL && !penetrate_thick) - . = 0 - if(!. && error_msg && user) - // Might need re-wording. - to_chat(user, "There is no exposed flesh or thin material [above_neck(target_zone) ? "on [p_their()] head" : "on [p_their()] body"].") - -/mob/living/carbon/human/proc/check_obscured_slots() - var/list/obscured = list() - - if(wear_suit) - if(wear_suit.flags_inv & HIDEGLOVES) - obscured |= slot_gloves - if(wear_suit.flags_inv & HIDEJUMPSUIT) - obscured |= slot_w_uniform - if(wear_suit.flags_inv & HIDESHOES) - obscured |= slot_shoes - - if(head) - if(head.flags_inv & HIDEMASK) - obscured |= slot_wear_mask - if(head.flags_inv & HIDEEYES) - obscured |= slot_glasses - if(head.flags_inv & HIDEEARS) - obscured |= slot_ears - - if(wear_mask) - if(wear_mask.flags_inv & HIDEEYES) - obscured |= slot_glasses - - if(obscured.len) - return obscured - else - return null - -/mob/living/carbon/human/assess_threat(mob/living/simple_animal/bot/secbot/judgebot, lasercolor) - if(judgebot.emagged == 2) - return 10 //Everyone is a criminal! - - var/threatcount = 0 - - //Lasertag bullshit - if(lasercolor) - if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve - if(istype(wear_suit, /obj/item/clothing/suit/redtag)) - threatcount += 4 - if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/redtag)) - threatcount += 4 - if(istype(belt, /obj/item/weapon/gun/energy/laser/redtag)) - threatcount += 2 - - if(lasercolor == "r") - if(istype(wear_suit, /obj/item/clothing/suit/bluetag)) - threatcount += 4 - if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/bluetag)) - threatcount += 4 - if(istype(belt, /obj/item/weapon/gun/energy/laser/bluetag)) - threatcount += 2 - - return threatcount - - //Check for ID - var/obj/item/weapon/card/id/idcard = get_idcard() - if(judgebot.idcheck && !idcard && name=="Unknown") - threatcount += 4 - - //Check for weapons - if(judgebot.weaponscheck) - if(!idcard || !(GLOB.access_weapons in idcard.access)) - for(var/obj/item/I in held_items) - if(judgebot.check_for_weapons(I)) - threatcount += 4 - if(judgebot.check_for_weapons(belt)) - threatcount += 2 - - //Check for arrest warrant - if(judgebot.check_records) - var/perpname = get_face_name(get_id_name()) - var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security) - if(R && R.fields["criminal"]) - switch(R.fields["criminal"]) - if("*Arrest*") - threatcount += 5 - if("Incarcerated") - threatcount += 2 - if("Parolled") - threatcount += 2 - - //Check for dresscode violations - if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/syndi) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi)) - threatcount += 5 - - //Check for nonhuman scum - if(dna && dna.species.id && dna.species.id != "human" || "lizard" || "mammal" || "avian" || "aquatic" || "insect") - threatcount += 1 - - //mindshield implants imply trustworthyness - if(isloyal()) - threatcount -= 1 - - //Agent cards lower threatlevel. - if(istype(idcard, /obj/item/weapon/card/id/syndicate)) - threatcount -= 2 - - return threatcount - - -//Used for new human mobs created by cloning/goleming/podding -/mob/living/carbon/human/proc/set_cloned_appearance() - if(gender == MALE) - facial_hair_style = "Full Beard" - else - facial_hair_style = "Shaved" - hair_style = pick("Bedhead", "Bedhead 2", "Bedhead 3") - underwear = "Nude" - update_body() - update_genitals() - update_hair() - -/mob/living/carbon/human/singularity_pull(S, current_size) - if(current_size >= STAGE_THREE) - for(var/obj/item/hand in held_items) - if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && dropItemToGround(hand)) - step_towards(hand, src) - to_chat(src, "\The [S] pulls \the [hand] from your grip!") - rad_act(current_size * 3) - if(mob_negates_gravity()) - return - ..() - -/mob/living/carbon/human/proc/do_cpr(mob/living/carbon/C) - CHECK_DNA_AND_SPECIES(C) - - if(C.stat == DEAD || (C.status_flags & FAKEDEATH)) - to_chat(src, "[C.name] is dead!") - return - if(is_mouth_covered()) - to_chat(src, "Remove your mask first!") - return 0 - if(C.is_mouth_covered()) - to_chat(src, "Remove [p_their()] mask first!") - return 0 - - if(C.cpr_time < world.time + 30) - visible_message("[src] is trying to perform CPR on [C.name]!", \ - "You try to perform CPR on [C.name]... Hold still!") - if(!do_mob(src, C)) - to_chat(src, "You fail to perform CPR on [C]!") - return 0 - - var/they_breathe = (!(NOBREATH in C.dna.species.species_traits)) - var/they_lung = C.getorganslot("lungs") - - if(C.health > HEALTH_THRESHOLD_CRIT) - return - - src.visible_message("[src] performs CPR on [C.name]!", "You perform CPR on [C.name].") - C.cpr_time = world.time - add_logs(src, C, "CPRed") - - if(they_breathe && they_lung) - var/suff = min(C.getOxyLoss(), 7) - C.adjustOxyLoss(-suff) - C.updatehealth() - to_chat(C, "You feel a breath of fresh air enter your lungs... It feels good...") - else if(they_breathe && !they_lung) - to_chat(C, "You feel a breath of fresh air... but you don't feel any better...") - else - to_chat(C, "You feel a breath of fresh air... which is a sensation you don't recognise...") - -/mob/living/carbon/human/generateStaticOverlay() - var/image/staticOverlay = image(icon('icons/effects/effects.dmi', "static"), loc = src) - staticOverlay.override = 1 - staticOverlays["static"] = staticOverlay - - staticOverlay = image(icon('icons/effects/effects.dmi', "blank"), loc = src) - staticOverlay.override = 1 - staticOverlays["blank"] = staticOverlay - - staticOverlay = getLetterImage(src, "H", 1) - staticOverlay.override = 1 - staticOverlays["letter"] = staticOverlay - - staticOverlay = getRandomAnimalImage(src) - staticOverlay.override = 1 - staticOverlays["animal"] = staticOverlay - -/mob/living/carbon/human/cuff_resist(obj/item/I) - if(dna && dna.check_mutation(HULK)) - say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) - if(..(I, cuff_break = FAST_CUFFBREAK)) - dropItemToGround(I) - else - if(..()) - dropItemToGround(I) - -/mob/living/carbon/human/clean_blood() - var/mob/living/carbon/human/H = src - if(H.gloves) - if(H.gloves.clean_blood()) - H.update_inv_gloves() - else - ..() // Clear the Blood_DNA list - if(H.bloody_hands) - H.bloody_hands = 0 - H.update_inv_gloves() - update_icons() //apply the now updated overlays to the mob - - -/mob/living/carbon/human/wash_cream() - //clean both to prevent a rare bug +/mob/living/carbon/human + name = "Unknown" + real_name = "Unknown" + voice_name = "Unknown" + icon = 'icons/mob/human.dmi' + icon_state = "caucasian_m" + +/mob/living/carbon/human/dummy + real_name = "Test Dummy" + status_flags = GODMODE|CANPUSH + +/mob/living/carbon/human/dummy/New(loc) + ..() + if(!initialized) + args[1] = FALSE + Initialize(arglist(args)) + +/mob/living/carbon/human/dummy/Life() + return + +/mob/living/carbon/human/Initialize() + verbs += /mob/living/proc/mob_sleep + verbs += /mob/living/proc/lay_down + + //initialize limbs first + create_bodyparts() + + //initialize dna. for spawned humans; overwritten by other code + create_dna(src) + randomize_human(src) + dna.initialize_dna() + + if(dna.species) + set_species(dna.species.type) + + //initialise organs + create_internal_organs() + + martial_art = default_martial_art + + handcrafting = new() + + ..() + +/mob/living/carbon/human/create_internal_organs() + if(!(NOHUNGER in dna.species.species_traits)) + internal_organs += new /obj/item/organ/appendix + if(!(NOBREATH in dna.species.species_traits)) + if(dna.species.mutantlungs) + internal_organs += new dna.species.mutantlungs() + else + internal_organs += new /obj/item/organ/lungs() + if(!(NOBLOOD in dna.species.species_traits)) + internal_organs += new /obj/item/organ/heart + + internal_organs += new dna.species.mutanteyes + internal_organs += new dna.species.mutantears + internal_organs += new /obj/item/organ/brain + internal_organs += new dna.species.mutanttongue + give_genitals() + ..() + +/mob/living/carbon/human/OpenCraftingMenu() + handcrafting.ui_interact(src) + +/mob/living/carbon/human/prepare_data_huds() + //Update med hud images... + ..() + //...sec hud images... + sec_hud_set_ID() + sec_hud_set_implants() + sec_hud_set_security_status() + //...and display them. + add_to_all_human_data_huds() + +/mob/living/carbon/human/Stat() + ..() + + if(statpanel("Status")) + stat(null, "Intent: [a_intent]") + stat(null, "Move Mode: [m_intent]") + if (internal) + if (!internal.air_contents) + qdel(internal) + else + stat("Internal Atmosphere Info", internal.name) + stat("Tank Pressure", internal.air_contents.return_pressure()) + stat("Distribution Pressure", internal.distribute_pressure) + + var/mob/living/simple_animal/borer/B = has_brain_worms() + if(B && B.controlling) + stat("Chemicals", B.chemicals) + + if(mind) + if(mind.changeling) + stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]") + stat("Absorbed DNA", mind.changeling.absorbedcount) + + + //NINJACODE + if(istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)) //Only display if actually a ninja. + var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit + if(statpanel("SpiderOS")) + stat("SpiderOS Status:","[SN.s_initialized ? "Initialized" : "Disabled"]") + stat("Current Time:", "[worldtime2text()]") + if(SN.s_initialized) + //Suit gear + stat("Energy Charge:", "[round(SN.cell.charge/100)]%") + stat("Smoke Bombs:", "\Roman [SN.s_bombs]") + //Ninja status + stat("Fingerprints:", "[md5(dna.uni_identity)]") + stat("Unique Identity:", "[dna.unique_enzymes]") + stat("Overall Status:", "[stat > 1 ? "dead" : "[health]% healthy"]") + stat("Nutrition Status:", "[nutrition]") + stat("Oxygen Loss:", "[getOxyLoss()]") + stat("Toxin Levels:", "[getToxLoss()]") + stat("Burn Severity:", "[getFireLoss()]") + stat("Brute Trauma:", "[getBruteLoss()]") + stat("Radiation Levels:","[radiation] rad") + stat("Body Temperature:","[bodytemperature-T0C] degrees C ([bodytemperature*1.8-459.67] degrees F)") + + //Virsuses + if(viruses.len) + stat("Viruses:", null) + for(var/datum/disease/D in viruses) + stat("*", "[D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]") + + +/mob/living/carbon/human/show_inv(mob/user) + user.set_machine(src) + var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask) + var/list/obscured = check_obscured_slots() + var/list/dat = list() + + dat += "" + for(var/i in 1 to held_items.len) + var/obj/item/I = get_item_for_held_index(i) + dat += "" + dat += "" + + dat += "" + + dat += "" + + if(slot_wear_mask in obscured) + dat += "" + else + dat += "" + + if(slot_neck in obscured) + dat += "" + else + dat += "" + + if(slot_glasses in obscured) + dat += "" + else + dat += "" + + if(slot_ears in obscured) + dat += "" + else + dat += "" + + dat += "" + + dat += "" + if(wear_suit) + dat += "" + else + dat += "" + + if(slot_shoes in obscured) + dat += "" + else + dat += "" + + if(slot_gloves in obscured) + dat += "" + else + dat += "" + + if(slot_w_uniform in obscured) + dat += "" + else + dat += "" + + if((w_uniform == null && !(dna && dna.species.nojumpsuit)) || (slot_w_uniform in obscured)) + dat += "" + dat += "" + dat += "" + else + dat += "" + dat += "" + dat += "" + + if(handcuffed) + dat += "" + if(legcuffed) + dat += "" + + dat += {"
[get_held_index_name(i)]:[(I && !(I.flags & ABSTRACT)) ? I : "Empty"]
 
Back:[(back && !(back.flags&ABSTRACT)) ? back : "Empty"]" + if(has_breathable_mask && istype(back, /obj/item/weapon/tank)) + dat += " [internal ? "Disable Internals" : "Set Internals"]" + + dat += "
 
Head:[(head && !(head.flags&ABSTRACT)) ? head : "Empty"]
Mask:Obscured
Mask:[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "Empty"]
Neck:Obscured
Neck:[(wear_neck && !(wear_neck.flags&ABSTRACT)) ? wear_neck : "Empty"]
Eyes:Obscured
Eyes:[(glasses && !(glasses.flags&ABSTRACT)) ? glasses : "Empty"]
Ears:Obscured
Ears:[(ears && !(ears.flags&ABSTRACT)) ? ears : "Empty"]
 
Exosuit:[(wear_suit && !(wear_suit.flags&ABSTRACT)) ? wear_suit : "Empty"]
 ↳Suit Storage:[(s_store && !(s_store.flags&ABSTRACT)) ? s_store : "Empty"]" + if(has_breathable_mask && istype(s_store, /obj/item/weapon/tank)) + dat += " [internal ? "Disable Internals" : "Set Internals"]" + dat += "
 ↳Suit Storage:
Shoes:Obscured
Shoes:[(shoes && !(shoes.flags&ABSTRACT)) ? shoes : "Empty"]
Gloves:Obscured
Gloves:[(gloves && !(gloves.flags&ABSTRACT)) ? gloves : "Empty"]
Uniform:Obscured
Uniform:[(w_uniform && !(w_uniform.flags&ABSTRACT)) ? w_uniform : "Empty"]
 ↳Pockets:
 ↳ID:
 ↳Belt:
 ↳Belt:[(belt && !(belt.flags&ABSTRACT)) ? belt : "Empty"]" + if(has_breathable_mask && istype(belt, /obj/item/weapon/tank)) + dat += " [internal ? "Disable Internals" : "Set Internals"]" + dat += "
 ↳Pockets:[(l_store && !(l_store.flags&ABSTRACT)) ? "Left (Full)" : "Left (Empty)"]" + dat += " [(r_store && !(r_store.flags&ABSTRACT)) ? "Right (Full)" : "Right (Empty)"]
 ↳ID:[(wear_id && !(wear_id.flags&ABSTRACT)) ? wear_id : "Empty"]
Handcuffed: Remove
Legcuffed
+ Close + "} + + var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 510) + popup.set_content(dat.Join()) + popup.open() + +// called when something steps onto a human +// this could be made more general, but for now just handle mulebot +/mob/living/carbon/human/Crossed(atom/movable/AM) + var/mob/living/simple_animal/bot/mulebot/MB = AM + if(istype(MB)) + MB.RunOver(src) + + spreadFire(AM) + + +/mob/living/carbon/human/Topic(href, href_list) + if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) + + if(href_list["embedded_object"]) + var/obj/item/bodypart/L = locate(href_list["embedded_limb"]) in bodyparts + if(!L) + return + var/obj/item/I = locate(href_list["embedded_object"]) in L.embedded_objects + if(!I || I.loc != src) //no item, no limb, or item is not in limb or in the person anymore + return + var/time_taken = I.embedded_unsafe_removal_time*I.w_class + usr.visible_message("[usr] attempts to remove [I] from their [L.name].","You attempt to remove [I] from your [L.name]... (It will take [time_taken/10] seconds.)") + if(do_after(usr, time_taken, needhand = 1, target = src)) + if(!I || !L || I.loc != src || !(I in L.embedded_objects)) + return + L.embedded_objects -= I + L.receive_damage(I.embedded_unsafe_removal_pain_multiplier*I.w_class)//It hurts to rip it out, get surgery you dingus. + I.forceMove(get_turf(src)) + usr.put_in_hands(I) + usr.emote("scream") + usr.visible_message("[usr] successfully rips [I] out of their [L.name]!","You successfully remove [I] from your [L.name].") + if(!has_embedded_objects()) + clear_alert("embeddedobject") + return + + if(href_list["item"]) + var/slot = text2num(href_list["item"]) + if(slot in check_obscured_slots()) + to_chat(usr, "You can't reach that! Something is covering it.") + return + + if(href_list["pockets"]) + var/pocket_side = href_list["pockets"] + var/pocket_id = (pocket_side == "right" ? slot_r_store : slot_l_store) + var/obj/item/pocket_item = (pocket_id == slot_r_store ? r_store : l_store) + var/obj/item/place_item = usr.get_active_held_item() // Item to place in the pocket, if it's empty + + var/delay_denominator = 1 + if(pocket_item && !(pocket_item.flags&ABSTRACT)) + if(pocket_item.flags & NODROP) + to_chat(usr, "You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!") + to_chat(usr, "You try to empty [src]'s [pocket_side] pocket.") + else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.flags&ABSTRACT)) + to_chat(usr, "You try to place [place_item] into [src]'s [pocket_side] pocket.") + delay_denominator = 4 + else + return + + if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator)) //placing an item into the pocket is 4 times faster + if(pocket_item) + if(pocket_item == (pocket_id == slot_r_store ? r_store : l_store)) //item still in the pocket we search + dropItemToGround(pocket_item) + else + if(place_item) + if(place_item.mob_can_equip(src, usr, pocket_id, FALSE, TRUE)) + usr.temporarilyRemoveItemFromInventory(place_item, TRUE) + equip_to_slot(place_item, pocket_id, TRUE) + //do nothing otherwise + + // Update strip window + if(usr.machine == src && in_range(src, usr)) + show_inv(usr) + else + // Display a warning if the user mocks up + to_chat(src, "You feel your [pocket_side] pocket being fumbled with!") + + ..() + + +///////HUDs/////// + if(href_list["hud"]) + if(ishuman(usr)) + var/mob/living/carbon/human/H = usr + var/perpname = get_face_name(get_id_name("")) + if(istype(H.glasses, /obj/item/clothing/glasses/hud) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud)) + var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.general) + if(href_list["photo_front"] || href_list["photo_side"]) + if(R) + if(!H.canUseHUD()) + return + else if(!istype(H.glasses, /obj/item/clothing/glasses/hud) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical)) + return + var/obj/item/weapon/photo/P = null + if(href_list["photo_front"]) + P = R.fields["photo_front"] + else if(href_list["photo_side"]) + P = R.fields["photo_side"] + if(P) + P.show(H) + + if(href_list["hud"] == "m") + if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical)) + if(href_list["p_stat"]) + var/health_status = input(usr, "Specify a new physical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("Active", "Physically Unfit", "*Unconscious*", "*Deceased*", "Cancel") + if(R) + if(!H.canUseHUD()) + return + else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical)) + return + if(health_status && health_status != "Cancel") + R.fields["p_stat"] = health_status + return + if(href_list["m_stat"]) + var/health_status = input(usr, "Specify a new mental status for this person.", "Medical HUD", R.fields["m_stat"]) in list("Stable", "*Watch*", "*Unstable*", "*Insane*", "Cancel") + if(R) + if(!H.canUseHUD()) + return + else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical)) + return + if(health_status && health_status != "Cancel") + R.fields["m_stat"] = health_status + return + if(href_list["evaluation"]) + if(!getBruteLoss() && !getFireLoss() && !getOxyLoss() && getToxLoss() < 20) + to_chat(usr, "No external injuries detected.
") + return + var/span = "notice" + var/status = "" + if(getBruteLoss()) + to_chat(usr, "Physical trauma analysis:") + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + var/brutedamage = BP.brute_dam + if(brutedamage > 0) + status = "received minor physical injuries." + span = "notice" + if(brutedamage > 20) + status = "been seriously damaged." + span = "danger" + if(brutedamage > 40) + status = "sustained major trauma!" + span = "userdanger" + if(brutedamage) + to_chat(usr, "[BP] appears to have [status]") + if(getFireLoss()) + to_chat(usr, "Analysis of skin burns:") + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + var/burndamage = BP.burn_dam + if(burndamage > 0) + status = "signs of minor burns." + span = "notice" + if(burndamage > 20) + status = "serious burns." + span = "danger" + if(burndamage > 40) + status = "major burns!" + span = "userdanger" + if(burndamage) + to_chat(usr, "[BP] appears to have [status]") + if(getOxyLoss()) + to_chat(usr, "Patient has signs of suffocation, emergency treatment may be required!") + if(getToxLoss() > 20) + to_chat(usr, "Gathered data is inconsistent with the analysis, possible cause: poisoning.") + + if(href_list["hud"] == "s") + if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) + if(usr.stat || usr == src) //|| !usr.canmove || usr.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at. + return //Non-fluff: This allows sec to set people to arrest as they get disarmed or beaten + // Checks the user has security clearence before allowing them to change arrest status via hud, comment out to enable all access + var/allowed_access = null + var/obj/item/clothing/glasses/G = H.glasses + if (!G.emagged) + if(H.wear_id) + var/list/access = H.wear_id.GetAccess() + if(GLOB.access_sec_doors in access) + allowed_access = H.get_authentification_name() + else + allowed_access = "@%&ERROR_%$*" + + + if(!allowed_access) + to_chat(H, "ERROR: Invalid Access") + return + + if(perpname) + R = find_record("name", perpname, GLOB.data_core.security) + if(R) + if(href_list["status"]) + var/setcriminal = input(usr, "Specify a new criminal status for this person.", "Security HUD", R.fields["criminal"]) in list("None", "*Arrest*", "Incarcerated", "Parolled", "Discharged", "Cancel") + if(setcriminal != "Cancel") + if(R) + if(H.canUseHUD()) + if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) + investigate_log("[src.key] has been set from [R.fields["criminal"]] to [setcriminal] by [usr.name] ([usr.key]).", "records") + R.fields["criminal"] = setcriminal + sec_hud_set_security_status() + return + + if(href_list["view"]) + if(R) + if(!H.canUseHUD()) + return + else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) + return + to_chat(usr, "Name: [R.fields["name"]] Criminal Status: [R.fields["criminal"]]") + to_chat(usr, "Minor Crimes:") + for(var/datum/data/crime/c in R.fields["mi_crim"]) + to_chat(usr, "Crime: [c.crimeName]") + to_chat(usr, "Details: [c.crimeDetails]") + to_chat(usr, "Added by [c.author] at [c.time]") + to_chat(usr, "----------") + to_chat(usr, "Major Crimes:") + for(var/datum/data/crime/c in R.fields["ma_crim"]) + to_chat(usr, "Crime: [c.crimeName]") + to_chat(usr, "Details: [c.crimeDetails]") + to_chat(usr, "Added by [c.author] at [c.time]") + to_chat(usr, "----------") + to_chat(usr, "Notes: [R.fields["notes"]]") + return + + if(href_list["add_crime"]) + switch(alert("What crime would you like to add?","Security HUD","Minor Crime","Major Crime","Cancel")) + if("Minor Crime") + if(R) + var/t1 = stripped_input("Please input minor crime names:", "Security HUD", "", null) + var/t2 = stripped_multiline_input("Please input minor crime details:", "Security HUD", "", null) + if(R) + if (!t1 || !t2 || !allowed_access) + return + else if(!H.canUseHUD()) + return + else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) + return + var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text()) + GLOB.data_core.addMinorCrime(R.fields["id"], crime) + to_chat(usr, "Successfully added a minor crime.") + return + if("Major Crime") + if(R) + var/t1 = stripped_input("Please input major crime names:", "Security HUD", "", null) + var/t2 = stripped_multiline_input("Please input major crime details:", "Security HUD", "", null) + if(R) + if (!t1 || !t2 || !allowed_access) + return + else if (!H.canUseHUD()) + return + else if (!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) + return + var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text()) + GLOB.data_core.addMajorCrime(R.fields["id"], crime) + to_chat(usr, "Successfully added a major crime.") + return + + if(href_list["view_comment"]) + if(R) + if(!H.canUseHUD()) + return + else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) + return + to_chat(usr, "Comments/Log:") + var/counter = 1 + while(R.fields[text("com_[]", counter)]) + to_chat(usr, R.fields[text("com_[]", counter)]) + to_chat(usr, "----------") + counter++ + return + + if(href_list["add_comment"]) + if(R) + var/t1 = stripped_multiline_input("Add Comment:", "Secure. records", null, null) + if(R) + if (!t1 || !allowed_access) + return + else if(!H.canUseHUD()) + return + else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security)) + return + var/counter = 1 + while(R.fields[text("com_[]", counter)]) + counter++ + R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []
[]", allowed_access, worldtime2text(), time2text(world.realtime, "MMM DD"), GLOB.year_integer+540, t1) + to_chat(usr, "Successfully added comment.") + return + to_chat(usr, "Unable to locate a data core entry for this person.") + +/mob/living/carbon/human/proc/canUseHUD() + return !(src.stat || src.weakened || src.stunned || src.restrained()) + +/mob/living/carbon/human/can_inject(mob/user, error_msg, target_zone, var/penetrate_thick = 0) + . = 1 // Default to returning true. + if(user && !target_zone) + target_zone = user.zone_selected + if(dna && (PIERCEIMMUNE in dna.species.species_traits)) + . = 0 + // If targeting the head, see if the head item is thin enough. + // If targeting anything else, see if the wear suit is thin enough. + if(above_neck(target_zone)) + if(head && head.flags & THICKMATERIAL && !penetrate_thick) + . = 0 + else + if(wear_suit && wear_suit.flags & THICKMATERIAL && !penetrate_thick) + . = 0 + if(!. && error_msg && user) + // Might need re-wording. + to_chat(user, "There is no exposed flesh or thin material [above_neck(target_zone) ? "on [p_their()] head" : "on [p_their()] body"].") + +/mob/living/carbon/human/proc/check_obscured_slots() + var/list/obscured = list() + + if(wear_suit) + if(wear_suit.flags_inv & HIDEGLOVES) + obscured |= slot_gloves + if(wear_suit.flags_inv & HIDEJUMPSUIT) + obscured |= slot_w_uniform + if(wear_suit.flags_inv & HIDESHOES) + obscured |= slot_shoes + + if(head) + if(head.flags_inv & HIDEMASK) + obscured |= slot_wear_mask + if(head.flags_inv & HIDEEYES) + obscured |= slot_glasses + if(head.flags_inv & HIDEEARS) + obscured |= slot_ears + + if(wear_mask) + if(wear_mask.flags_inv & HIDEEYES) + obscured |= slot_glasses + + if(obscured.len) + return obscured + else + return null + +/mob/living/carbon/human/assess_threat(mob/living/simple_animal/bot/secbot/judgebot, lasercolor) + if(judgebot.emagged == 2) + return 10 //Everyone is a criminal! + + var/threatcount = 0 + + //Lasertag bullshit + if(lasercolor) + if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve + if(istype(wear_suit, /obj/item/clothing/suit/redtag)) + threatcount += 4 + if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/redtag)) + threatcount += 4 + if(istype(belt, /obj/item/weapon/gun/energy/laser/redtag)) + threatcount += 2 + + if(lasercolor == "r") + if(istype(wear_suit, /obj/item/clothing/suit/bluetag)) + threatcount += 4 + if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/bluetag)) + threatcount += 4 + if(istype(belt, /obj/item/weapon/gun/energy/laser/bluetag)) + threatcount += 2 + + return threatcount + + //Check for ID + var/obj/item/weapon/card/id/idcard = get_idcard() + if(judgebot.idcheck && !idcard && name=="Unknown") + threatcount += 4 + + //Check for weapons + if(judgebot.weaponscheck) + if(!idcard || !(GLOB.access_weapons in idcard.access)) + for(var/obj/item/I in held_items) + if(judgebot.check_for_weapons(I)) + threatcount += 4 + if(judgebot.check_for_weapons(belt)) + threatcount += 2 + + //Check for arrest warrant + if(judgebot.check_records) + var/perpname = get_face_name(get_id_name()) + var/datum/data/record/R = find_record("name", perpname, GLOB.data_core.security) + if(R && R.fields["criminal"]) + switch(R.fields["criminal"]) + if("*Arrest*") + threatcount += 5 + if("Incarcerated") + threatcount += 2 + if("Parolled") + threatcount += 2 + + //Check for dresscode violations + if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/syndi) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/shielded/syndi)) + threatcount += 5 + + //Check for nonhuman scum + if(dna && dna.species.id && dna.species.id != "human" || "lizard" || "mammal" || "avian" || "aquatic" || "insect") + threatcount += 1 + + //mindshield implants imply trustworthyness + if(isloyal()) + threatcount -= 1 + + //Agent cards lower threatlevel. + if(istype(idcard, /obj/item/weapon/card/id/syndicate)) + threatcount -= 2 + + return threatcount + + +//Used for new human mobs created by cloning/goleming/podding +/mob/living/carbon/human/proc/set_cloned_appearance() + if(gender == MALE) + facial_hair_style = "Full Beard" + else + facial_hair_style = "Shaved" + hair_style = pick("Bedhead", "Bedhead 2", "Bedhead 3") + underwear = "Nude" + update_body() + update_genitals() + update_hair() + +/mob/living/carbon/human/singularity_pull(S, current_size) + if(current_size >= STAGE_THREE) + for(var/obj/item/hand in held_items) + if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && dropItemToGround(hand)) + step_towards(hand, src) + to_chat(src, "\The [S] pulls \the [hand] from your grip!") + rad_act(current_size * 3) + if(mob_negates_gravity()) + return + ..() + +/mob/living/carbon/human/proc/do_cpr(mob/living/carbon/C) + CHECK_DNA_AND_SPECIES(C) + + if(C.stat == DEAD || (C.status_flags & FAKEDEATH)) + to_chat(src, "[C.name] is dead!") + return + if(is_mouth_covered()) + to_chat(src, "Remove your mask first!") + return 0 + if(C.is_mouth_covered()) + to_chat(src, "Remove [p_their()] mask first!") + return 0 + + if(C.cpr_time < world.time + 30) + visible_message("[src] is trying to perform CPR on [C.name]!", \ + "You try to perform CPR on [C.name]... Hold still!") + if(!do_mob(src, C)) + to_chat(src, "You fail to perform CPR on [C]!") + return 0 + + var/they_breathe = (!(NOBREATH in C.dna.species.species_traits)) + var/they_lung = C.getorganslot("lungs") + + if(C.health > HEALTH_THRESHOLD_CRIT) + return + + src.visible_message("[src] performs CPR on [C.name]!", "You perform CPR on [C.name].") + C.cpr_time = world.time + add_logs(src, C, "CPRed") + + if(they_breathe && they_lung) + var/suff = min(C.getOxyLoss(), 7) + C.adjustOxyLoss(-suff) + C.updatehealth() + to_chat(C, "You feel a breath of fresh air enter your lungs... It feels good...") + else if(they_breathe && !they_lung) + to_chat(C, "You feel a breath of fresh air... but you don't feel any better...") + else + to_chat(C, "You feel a breath of fresh air... which is a sensation you don't recognise...") + +/mob/living/carbon/human/generateStaticOverlay() + var/image/staticOverlay = image(icon('icons/effects/effects.dmi', "static"), loc = src) + staticOverlay.override = 1 + staticOverlays["static"] = staticOverlay + + staticOverlay = image(icon('icons/effects/effects.dmi', "blank"), loc = src) + staticOverlay.override = 1 + staticOverlays["blank"] = staticOverlay + + staticOverlay = getLetterImage(src, "H", 1) + staticOverlay.override = 1 + staticOverlays["letter"] = staticOverlay + + staticOverlay = getRandomAnimalImage(src) + staticOverlay.override = 1 + staticOverlays["animal"] = staticOverlay + +/mob/living/carbon/human/cuff_resist(obj/item/I) + if(dna && dna.check_mutation(HULK)) + say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" )) + if(..(I, cuff_break = FAST_CUFFBREAK)) + dropItemToGround(I) + else + if(..()) + dropItemToGround(I) + +/mob/living/carbon/human/clean_blood() + var/mob/living/carbon/human/H = src + if(H.gloves) + if(H.gloves.clean_blood()) + H.update_inv_gloves() + else + ..() // Clear the Blood_DNA list + if(H.bloody_hands) + H.bloody_hands = 0 + H.update_inv_gloves() + update_icons() //apply the now updated overlays to the mob + + +/mob/living/carbon/human/wash_cream() + //clean both to prevent a rare bug cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_lizard")) cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_human")) - - -//Turns a mob black, flashes a skeleton overlay -//Just like a cartoon! -/mob/living/carbon/human/proc/electrocution_animation(anim_duration) - //Handle mutant parts if possible - if(dna && dna.species) - add_atom_colour("#000000", TEMPORARY_COLOUR_PRIORITY) + + +//Turns a mob black, flashes a skeleton overlay +//Just like a cartoon! +/mob/living/carbon/human/proc/electrocution_animation(anim_duration) + //Handle mutant parts if possible + if(dna && dna.species) + add_atom_colour("#000000", TEMPORARY_COLOUR_PRIORITY) var/static/mutable_appearance/electrocution_skeleton_anim if(!electrocution_skeleton_anim) electrocution_skeleton_anim = mutable_appearance(icon, "electrocuted_base") electrocution_skeleton_anim.appearance_flags |= RESET_COLOR - add_overlay(electrocution_skeleton_anim) - addtimer(CALLBACK(src, .proc/end_electrocution_animation, electrocution_skeleton_anim), anim_duration) - - else //or just do a generic animation - flick_overlay_view(image(icon,src,"electrocuted_generic",ABOVE_MOB_LAYER), src, anim_duration) - + add_overlay(electrocution_skeleton_anim) + addtimer(CALLBACK(src, .proc/end_electrocution_animation, electrocution_skeleton_anim), anim_duration) + + else //or just do a generic animation + flick_overlay_view(image(icon,src,"electrocuted_generic",ABOVE_MOB_LAYER), src, anim_duration) + /mob/living/carbon/human/proc/end_electrocution_animation(mutable_appearance/MA) - remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000") + remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000") cut_overlay(MA) - -/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close = 0) - if(incapacitated() || lying ) - return - if(!Adjacent(M) && (M.loc != src)) - if((be_close == 0) && (dna.check_mutation(TK))) - if(tkMaxRangeCheck(src, M)) - return 1 - return - return 1 - -/mob/living/carbon/human/resist_restraints() - if(wear_suit && wear_suit.breakouttime) - changeNext_move(CLICK_CD_BREAKOUT) - last_special = world.time + CLICK_CD_BREAKOUT - cuff_resist(wear_suit) - else - ..() - -/mob/living/carbon/human/replace_records_name(oldname,newname) // Only humans have records right now, move this up if changed. - for(var/list/L in list(GLOB.data_core.general,GLOB.data_core.medical,GLOB.data_core.security,GLOB.data_core.locked)) - var/datum/data/record/R = find_record("name", oldname, L) - if(R) - R.fields["name"] = newname - -/mob/living/carbon/human/get_total_tint() - . = ..() - if(glasses) - . += glasses.tint - -/mob/living/carbon/human/update_health_hud() - if(!client || !hud_used) - return - if(dna.species.update_health_hud()) - return - else - if(hud_used.healths) - var/health_amount = health - staminaloss - if(..(health_amount)) //not dead - switch(hal_screwyhud) - if(SCREWYHUD_CRIT) - hud_used.healths.icon_state = "health6" - if(SCREWYHUD_DEAD) - hud_used.healths.icon_state = "health7" - if(SCREWYHUD_HEALTHY) - hud_used.healths.icon_state = "health0" - if(hud_used.healthdoll) - hud_used.healthdoll.cut_overlays() - if(stat != DEAD) - hud_used.healthdoll.icon_state = "healthdoll_OVERLAY" - for(var/X in bodyparts) - var/obj/item/bodypart/BP = X - var/damage = BP.burn_dam + BP.brute_dam - var/comparison = (BP.max_damage/5) - var/icon_num = 0 - if(damage) - icon_num = 1 - if(damage > (comparison)) - icon_num = 2 - if(damage > (comparison*2)) - icon_num = 3 - if(damage > (comparison*3)) - icon_num = 4 - if(damage > (comparison*4)) - icon_num = 5 - if(hal_screwyhud == SCREWYHUD_HEALTHY) - icon_num = 0 - if(icon_num) + +/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close = 0) + if(incapacitated() || lying ) + return + if(!Adjacent(M) && (M.loc != src)) + if((be_close == 0) && (dna.check_mutation(TK))) + if(tkMaxRangeCheck(src, M)) + return 1 + return + return 1 + +/mob/living/carbon/human/resist_restraints() + if(wear_suit && wear_suit.breakouttime) + changeNext_move(CLICK_CD_BREAKOUT) + last_special = world.time + CLICK_CD_BREAKOUT + cuff_resist(wear_suit) + else + ..() + +/mob/living/carbon/human/replace_records_name(oldname,newname) // Only humans have records right now, move this up if changed. + for(var/list/L in list(GLOB.data_core.general,GLOB.data_core.medical,GLOB.data_core.security,GLOB.data_core.locked)) + var/datum/data/record/R = find_record("name", oldname, L) + if(R) + R.fields["name"] = newname + +/mob/living/carbon/human/get_total_tint() + . = ..() + if(glasses) + . += glasses.tint + +/mob/living/carbon/human/update_health_hud() + if(!client || !hud_used) + return + if(dna.species.update_health_hud()) + return + else + if(hud_used.healths) + var/health_amount = health - staminaloss + if(..(health_amount)) //not dead + switch(hal_screwyhud) + if(SCREWYHUD_CRIT) + hud_used.healths.icon_state = "health6" + if(SCREWYHUD_DEAD) + hud_used.healths.icon_state = "health7" + if(SCREWYHUD_HEALTHY) + hud_used.healths.icon_state = "health0" + if(hud_used.healthdoll) + hud_used.healthdoll.cut_overlays() + if(stat != DEAD) + hud_used.healthdoll.icon_state = "healthdoll_OVERLAY" + for(var/X in bodyparts) + var/obj/item/bodypart/BP = X + var/damage = BP.burn_dam + BP.brute_dam + var/comparison = (BP.max_damage/5) + var/icon_num = 0 + if(damage) + icon_num = 1 + if(damage > (comparison)) + icon_num = 2 + if(damage > (comparison*2)) + icon_num = 3 + if(damage > (comparison*3)) + icon_num = 4 + if(damage > (comparison*4)) + icon_num = 5 + if(hal_screwyhud == SCREWYHUD_HEALTHY) + icon_num = 0 + if(icon_num) hud_used.healthdoll.add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[BP.body_zone][icon_num]")) - for(var/t in get_missing_limbs()) //Missing limbs + for(var/t in get_missing_limbs()) //Missing limbs hud_used.healthdoll.add_overlay(mutable_appearance('icons/mob/screen_gen.dmi', "[t]6")) - else - hud_used.healthdoll.icon_state = "healthdoll_DEAD" - -/mob/living/carbon/human/fully_heal(admin_revive = 0) - if(admin_revive) - regenerate_limbs() - regenerate_organs() - remove_all_embedded_objects() - set_heartattack(FALSE) - drunkenness = 0 - for(var/datum/mutation/human/HM in dna.mutations) - if(HM.quality != POSITIVE) - dna.remove_mutation(HM.name) - ..() - -/mob/living/carbon/human/proc/influenceSin() - var/datum/objective/sintouched/O - switch(rand(1,7))//traditional seven deadly sins... except lust. - if(1) // acedia - log_game("[src] was influenced by the sin of Acedia.") - O = new /datum/objective/sintouched/acedia - if(2) // Gluttony - log_game("[src] was influenced by the sin of gluttony.") - O = new /datum/objective/sintouched/gluttony - if(3) // Greed - log_game("[src] was influenced by the sin of greed.") - O = new /datum/objective/sintouched/greed - if(4) // sloth - log_game("[src] was influenced by the sin of sloth.") - O = new /datum/objective/sintouched/sloth - if(5) // Wrath - log_game("[src] was influenced by the sin of wrath.") - O = new /datum/objective/sintouched/wrath - if(6) // Envy - log_game("[src] was influenced by the sin of envy.") - O = new /datum/objective/sintouched/envy - if(7) // Pride - log_game("[src] was influenced by the sin of pride.") - O = new /datum/objective/sintouched/pride - SSticker.mode.sintouched += src.mind - src.mind.objectives += O - src.mind.announce_objectives() - -/mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker) - . = ..() - if (dna && dna.species) - . += dna.species.check_weakness(weapon, attacker) - -/mob/living/carbon/human/is_literate() - return 1 - -/mob/living/carbon/human/can_hold_items() - return TRUE - -/mob/living/carbon/human/update_gravity(has_gravity,override = 0) - override = dna.species.override_float - ..() - -/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = 0, stun = 1, distance = 0, message = 1, toxic = 0) - if(blood && (NOBLOOD in dna.species.species_traits)) - if(message) - visible_message("[src] dry heaves!", \ - "You try to throw up, but there's nothing in your stomach!") - if(stun) - Weaken(10) - return 1 - ..() - -/mob/living/carbon/human/Bump(atom/A) - ..() - var/crashdir = get_dir(src, A) - var/obj/item/device/flightpack/FP = get_flightpack() - if(FP) - FP.flight_impact(A, crashdir) - -/mob/living/carbon/human/vv_get_dropdown() - . = ..() - . += "---" - .["Make monkey"] = "?_src_=vars;makemonkey=\ref[src]" - .["Set Species"] = "?_src_=vars;setspecies=\ref[src]" - .["Make cyborg"] = "?_src_=vars;makerobot=\ref[src]" - .["Make alien"] = "?_src_=vars;makealien=\ref[src]" - .["Make slime"] = "?_src_=vars;makeslime=\ref[src]" - .["Toggle Purrbation"] = "?_src_=vars;purrbation=\ref[src]" - -/mob/living/carbon/human/MouseDrop_T(mob/living/target, mob/living/user) - if((target != pulling) || (grab_state < GRAB_AGGRESSIVE) || (user != target) || !isliving(user) || stat || user.stat)//Get consent first :^) - . = ..() - return - buckle_mob(target, TRUE, TRUE) - . = ..() - -/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE) - if(!force)//humans are only meant to be ridden through piggybacking and special cases - return - if(!is_type_in_typecache(M, can_ride_typecache)) - M.visible_message("[M] really can't seem to mount [src]...") - return - if(!riding_datum) - riding_datum = new /datum/riding/human(src) - if(buckled_mobs && ((M in buckled_mobs) || (buckled_mobs.len >= max_buckled_mobs)) || buckled || (M.stat != CONSCIOUS)) - return + else + hud_used.healthdoll.icon_state = "healthdoll_DEAD" + +/mob/living/carbon/human/fully_heal(admin_revive = 0) + if(admin_revive) + regenerate_limbs() + regenerate_organs() + remove_all_embedded_objects() + set_heartattack(FALSE) + drunkenness = 0 + for(var/datum/mutation/human/HM in dna.mutations) + if(HM.quality != POSITIVE) + dna.remove_mutation(HM.name) + ..() + +/mob/living/carbon/human/proc/influenceSin() + var/datum/objective/sintouched/O + switch(rand(1,7))//traditional seven deadly sins... except lust. + if(1) // acedia + log_game("[src] was influenced by the sin of Acedia.") + O = new /datum/objective/sintouched/acedia + if(2) // Gluttony + log_game("[src] was influenced by the sin of gluttony.") + O = new /datum/objective/sintouched/gluttony + if(3) // Greed + log_game("[src] was influenced by the sin of greed.") + O = new /datum/objective/sintouched/greed + if(4) // sloth + log_game("[src] was influenced by the sin of sloth.") + O = new /datum/objective/sintouched/sloth + if(5) // Wrath + log_game("[src] was influenced by the sin of wrath.") + O = new /datum/objective/sintouched/wrath + if(6) // Envy + log_game("[src] was influenced by the sin of envy.") + O = new /datum/objective/sintouched/envy + if(7) // Pride + log_game("[src] was influenced by the sin of pride.") + O = new /datum/objective/sintouched/pride + SSticker.mode.sintouched += src.mind + src.mind.objectives += O + src.mind.announce_objectives() + +/mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker) + . = ..() + if (dna && dna.species) + . += dna.species.check_weakness(weapon, attacker) + +/mob/living/carbon/human/is_literate() + return 1 + +/mob/living/carbon/human/can_hold_items() + return TRUE + +/mob/living/carbon/human/update_gravity(has_gravity,override = 0) + override = dna.species.override_float + ..() + +/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = 0, stun = 1, distance = 0, message = 1, toxic = 0) + if(blood && (NOBLOOD in dna.species.species_traits)) + if(message) + visible_message("[src] dry heaves!", \ + "You try to throw up, but there's nothing in your stomach!") + if(stun) + Weaken(10) + return 1 + ..() + +/mob/living/carbon/human/Bump(atom/A) + ..() + var/crashdir = get_dir(src, A) + var/obj/item/device/flightpack/FP = get_flightpack() + if(FP) + FP.flight_impact(A, crashdir) + +/mob/living/carbon/human/vv_get_dropdown() + . = ..() + . += "---" + .["Make monkey"] = "?_src_=vars;makemonkey=\ref[src]" + .["Set Species"] = "?_src_=vars;setspecies=\ref[src]" + .["Make cyborg"] = "?_src_=vars;makerobot=\ref[src]" + .["Make alien"] = "?_src_=vars;makealien=\ref[src]" + .["Make slime"] = "?_src_=vars;makeslime=\ref[src]" + .["Toggle Purrbation"] = "?_src_=vars;purrbation=\ref[src]" + +/mob/living/carbon/human/MouseDrop_T(mob/living/target, mob/living/user) + if((target != pulling) || (grab_state < GRAB_AGGRESSIVE) || (user != target) || !isliving(user) || stat || user.stat)//Get consent first :^) + . = ..() + return + buckle_mob(target, TRUE, TRUE) + . = ..() + +/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE) + if(!force)//humans are only meant to be ridden through piggybacking and special cases + return + if(!is_type_in_typecache(M, can_ride_typecache)) + M.visible_message("[M] really can't seem to mount [src]...") + return + if(!riding_datum) + riding_datum = new /datum/riding/human(src) + if(buckled_mobs && ((M in buckled_mobs) || (buckled_mobs.len >= max_buckled_mobs)) || buckled || (M.stat != CONSCIOUS)) + return visible_message("[M] starts to climb onto [src]...") if(do_after(M, 15, target = src)) if(iscarbon(M)) @@ -937,10 +938,10 @@ stop_pulling() else visible_message("[M] fails to climb onto [src]!") - -/mob/living/carbon/human/unbuckle_mob(mob/living/M, force=FALSE) - if(iscarbon(M)) - if(riding_datum) - riding_datum.unequip_buckle_inhands(M) - riding_datum.restore_position(M) - . = ..(M, force) + +/mob/living/carbon/human/unbuckle_mob(mob/living/M, force=FALSE) + if(iscarbon(M)) + if(riding_datum) + riding_datum.unequip_buckle_inhands(M) + riding_datum.restore_position(M) + . = ..(M, force) diff --git a/code/modules/mob/living/carbon/human/human.dm.rej b/code/modules/mob/living/carbon/human/human.dm.rej new file mode 100644 index 0000000000..5866cddae0 --- /dev/null +++ b/code/modules/mob/living/carbon/human/human.dm.rej @@ -0,0 +1,12 @@ +diff a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm (rejected hunks) +@@ -58,8 +58,9 @@ + if(!(NOBLOOD in dna.species.species_traits)) + internal_organs += new /obj/item/organ/heart + +- internal_organs += new dna.species.mutanteyes() ++ internal_organs += new dna.species.mutanteyes + internal_organs += new dna.species.mutantears ++ internal_organs += new dna.species.mutanttongue + internal_organs += new /obj/item/organ/brain + ..() + diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 331fc5fc95..77ac31812a 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -142,10 +142,12 @@ return not_handled //For future deeper overrides /mob/living/carbon/human/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE) + var/index = get_held_index_of_item(I) . = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should. if(!. || !I) return - + if(index && dna.species.mutanthands) + put_in_hand(new dna.species.mutanthands(), index) if(I == wear_suit) if(s_store && invdrop) dropItemToGround(s_store, TRUE) //It makes no sense for your suit storage to stay on you if you drop your suit. diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index a48124e412..9be254e4bc 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -35,7 +35,7 @@ var/say_mod = "says" // affects the speech message var/list/default_features = list() // Default mutant bodyparts for this species. Don't forget to set one for every mutant bodypart you allow this species to have. var/list/mutant_bodyparts = list() // Parts of the body that are diferent enough from the standard human model that they cause clipping with some equipment - var/list/mutant_organs = list(/obj/item/organ/tongue) //Internal organs that are unique to this race. + var/list/mutant_organs = list() //Internal organs that are unique to this race. var/speedmod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster var/armor = 0 // overall defense for the race... or less defense, if it's negative. var/brutemod = 1 // multiplier for brute damage @@ -65,11 +65,12 @@ //Flight and floating var/override_float = 0 - //Eyes var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes - - //Ears var/obj/item/organ/ears/mutantears = /obj/item/organ/ears + var/obj/item/organ/tongue/mutanttongue = /obj/item/organ/tongue + + //Hands + var/obj/item/mutanthands = null //Citadel snowflake var/fixed_mut_color2 = "" @@ -119,6 +120,8 @@ var/obj/item/thing = C.get_item_by_slot(slot_id) if(thing && (!thing.species_exception || !is_type_in_list(src,thing.species_exception))) C.dropItemToGround(thing) + if(C.hud_used) + C.hud_used.update_locked_slots() // this needs to be FIRST because qdel calls update_body which checks if we have DIGITIGRADE legs or not and if not then removes DIGITIGRADE from species_traits if(("legs" in C.dna.species.mutant_bodyparts) && C.dna.features["legs"] == "Digitigrade Legs") @@ -131,6 +134,7 @@ var/obj/item/organ/appendix/appendix = C.getorganslot("appendix") var/obj/item/organ/eyes/eyes = C.getorganslot("eye_sight") var/obj/item/organ/ears/ears = C.getorganslot("ears") + var/obj/item/organ/tongue/tongue = C.getorganslot("tongue") if((NOBLOOD in species_traits) && heart) heart.Remove(C) @@ -143,15 +147,21 @@ qdel(lungs) lungs = null - if(eyes) - qdel(eyes) - eyes = new mutanteyes - eyes.Insert(C) + if(C.get_bodypart("head")) + if(eyes) + qdel(eyes) + eyes = new mutanteyes + eyes.Insert(C) - if(ears) - qdel(ears) - ears = new mutantears - ears.Insert(C) + if(ears) + qdel(ears) + ears = new mutantears + ears.Insert(C) + + if(tongue) + qdel(tongue) + tongue = new mutanttongue + tongue.Insert(C) if((!(NOBREATH in species_traits)) && !lungs) if(mutantlungs) @@ -173,6 +183,21 @@ if(exotic_bloodtype && C.dna.blood_type != exotic_bloodtype) C.dna.blood_type = exotic_bloodtype + if(old_species.mutanthands) + for(var/obj/item/I in C.held_items) + if(istype(I, old_species.mutanthands)) + qdel(I) + + if(mutanthands) + // Drop items in hands + // If you're lucky enough to have a NODROP item, then it stays. + for(var/V in C.held_items) + var/obj/item/I = V + if(istype(I)) + C.dropItemToGround(I) + else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand + C.put_in_hands(new mutanthands()) + if(NOAROUSAL in species_traits) C.canbearoused = FALSE else @@ -352,7 +377,7 @@ var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[H.undershirt] if(undershirt) if(H.dna.species.sexes && H.gender == FEMALE) - standing += wear_female_version(undershirt.icon_state, undershirt.icon, -BODY_LAYER) + standing += wear_female_version(undershirt.icon_state, undershirt.icon, BODY_LAYER) else standing += mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER) diff --git a/code/modules/mob/living/carbon/human/species.dm.rej b/code/modules/mob/living/carbon/human/species.dm.rej new file mode 100644 index 0000000000..1260400360 --- /dev/null +++ b/code/modules/mob/living/carbon/human/species.dm.rej @@ -0,0 +1,18 @@ +diff a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm (rejected hunks) +@@ -66,15 +66,10 @@ + //Flight and floating + var/override_float = 0 + +- +- //Eyes + var/obj/item/organ/eyes/mutanteyes = /obj/item/organ/eyes +- +- //Ears + var/obj/item/organ/ears/mutantears = /obj/item/organ/ears +- +- //Hands + var/obj/item/mutanthands = null ++ var/obj/item/organ/tongue/mutanttongue = /obj/item/organ/tongue + + /////////// + // PROCS // 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 85b36c90c0..b76536f5bf 100644 --- a/code/modules/mob/living/carbon/human/species_types/abductors.dm +++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm @@ -4,6 +4,6 @@ say_mod = "gibbers" sexes = 0 species_traits = list(NOBLOOD,NOBREATH,VIRUSIMMUNE,NOGUNS,NOHUNGER) - mutant_organs = list(/obj/item/organ/tongue/abductor) + mutanttongue = /obj/item/organ/tongue/abductor var/scientist = 0 // vars to not pollute spieces list with castes - var/team = 1 \ No newline at end of file + var/team = 1 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 0e63115652..1c7cc6806b 100644 --- a/code/modules/mob/living/carbon/human/species_types/android.dm +++ b/code/modules/mob/living/carbon/human/species_types/android.dm @@ -5,7 +5,7 @@ species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOBLOOD,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYLIMBATTACHMENT) meat = null damage_overlay_type = "synth" - mutant_organs = list(/obj/item/organ/tongue/robot) + mutanttongue = /obj/item/organ/tongue/robot limbs_id = "synth" /datum/species/android/on_species_gain(mob/living/carbon/C) @@ -18,4 +18,4 @@ . = ..() for(var/X in C.bodyparts) var/obj/item/bodypart/O = X - O.change_bodypart_status(BODYPART_ORGANIC,FALSE, TRUE) \ No newline at end of file + O.change_bodypart_status(BODYPART_ORGANIC,FALSE, TRUE) 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 65b3eb9a65..3d6a10aae9 100644 --- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm @@ -2,7 +2,7 @@ name = "Flyperson" id = "fly" say_mod = "buzzes" - mutant_organs = list(/obj/item/organ/tongue/fly) + mutanttongue = /obj/item/organ/tongue/fly meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/fly /datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) 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 0390661c78..e56b2221ba 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -9,7 +9,7 @@ punchdamagelow = 5 punchdamagehigh = 14 punchstunthreshold = 11 //about 40% chance to stun - no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform) + no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform, slot_s_store) nojumpsuit = 1 sexes = 1 damage_overlay_type = "" @@ -20,6 +20,7 @@ dangerous_existence = TRUE limbs_id = "golem" fixed_mut_color = "aaa" + mutant_organs = list(/obj/item/organ/adamantine_resonator) var/info_text = "As an Iron Golem, you don't have any special traits." var/prefix = "Iron" @@ -54,8 +55,9 @@ name = "Adamantine Golem" id = "adamantine golem" meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem/adamantine + mutant_organs = list(/obj/item/organ/adamantine_resonator, /obj/item/organ/vocal_cords/adamantine) fixed_mut_color = "4ed" - info_text = "As an Adamantine Golem, you don't have any special traits." + info_text = "As an Adamantine Golem, you possess special vocal cords allowing you to \"resonate\" messages to all golems." prefix = "Adamantine" //Explodes on death @@ -71,14 +73,14 @@ prefix = "Plasma" special_names = list("Flood","Fire","Bar","Man") -/datum/species/golem/plasma/spec_life(mob/living/carbon/human/H) - if(H.bodytemperature > 900 && H.on_fire) - explosion(get_turf(H),1,2,4,flame_range = 5) - if(H) - H.gib() - if(H.fire_stacks < 2) //flammable - H.adjust_fire_stacks(1) - ..() +/datum/species/golem/plasma/spec_life(mob/living/carbon/human/H) + if(H.bodytemperature > 900 && H.on_fire) + explosion(get_turf(H),1,2,4,flame_range = 5) + if(H) + H.gib() + if(H.fire_stacks < 2) //flammable + H.adjust_fire_stacks(1) + ..() //Harder to hurt /datum/species/golem/diamond @@ -505,7 +507,7 @@ sexes = FALSE info_text = "As a Runic Golem, you possess eldritch powers granted by the Elder God Nar'Sie." species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER) //no mutcolors - prefix = "Runic" + prefix = "Runic" var/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/golem/phase_shift var/obj/effect/proc_holder/spell/targeted/abyssal_gaze/abyssal_gaze @@ -643,4 +645,19 @@ if(P.is_hot()) visible_message("[src] bursts into flames!") - fire_act() \ No newline at end of file + + fire_act() +/datum/species/golem/plastic + name = "Plastic" + id = "plastic golem" + prefix = "Plastic" + fixed_mut_color = "fff" + info_text = "As a Plastic Golem, you are capable of ventcrawling, and passing through plastic flaps." + +/datum/species/golem/plastic/on_species_gain(mob/living/carbon/C, datum/species/old_species) + . = ..() + C.ventcrawler = VENTCRAWLER_NUDE + +/datum/species/golem/plastic/on_species_loss(mob/living/carbon/C) + . = ..() + C.ventcrawler = initial(C.ventcrawler) 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 876d2f9e34..ca4deab288 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -6,7 +6,7 @@ default_color = "00FF00" species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,FACEHAIR) mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur") - mutant_organs = list(/obj/item/organ/tongue/lizard) + mutanttongue = /obj/item/organ/tongue/lizard coldmod = 1.5 heatmod = 0.67 default_features = list("mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0", "tail" = "Smooth", "snout" = "Round", "horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None", "legs" = "Normal Legs", "taur" = "None") @@ -17,6 +17,9 @@ skinned_type = /obj/item/stack/sheet/animalhide/lizard exotic_bloodtype = "L" +/datum/species/lizard/after_equip_job(datum/job/J, mob/living/carbon/human/H) + H.grant_language(/datum/language/draconic) + /datum/species/lizard/random_name(gender,unique,lastname) if(unique) return random_unique_lizard_name(gender) diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm.rej b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm.rej new file mode 100644 index 0000000000..1aab6d751d --- /dev/null +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm.rej @@ -0,0 +1,10 @@ +diff a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm (rejected hunks) +@@ -6,7 +6,7 @@ + default_color = "00FF00" + species_traits = list(MUTCOLORS,EYECOLOR,LIPS) + mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs") +- mutant_organs = list(/obj/item/organ/tongue/lizard) ++ mutanttongue = /obj/item/organ/tongue/lizard + coldmod = 1.5 + heatmod = 0.67 + default_features = list("mcolor" = "0F0", "tail" = "Smooth", "snout" = "Round", "horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None", "legs" = "Normal Legs") 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 6672c69b1e..f372968270 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -6,7 +6,7 @@ meat = /obj/item/stack/sheet/mineral/plasma species_traits = list(NOBLOOD,RESISTCOLD,RADIMMUNE,NOTRANSSTING,VIRUSIMMUNE,NOHUNGER) mutantlungs = /obj/item/organ/lungs/plasmaman - mutant_organs = list(/obj/item/organ/tongue/bone/plasmaman) + mutanttongue = /obj/item/organ/tongue/bone/plasmaman dangerous_existence = 1 //So so much blacklisted = 1 //See above burnmod = 1.5 @@ -66,4 +66,4 @@ if(lastname) randname += " [lastname]" - return randname \ No newline at end of file + return randname 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 573b58159a..6b56fa9ca4 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -13,9 +13,11 @@ name = "Infectious Zombie" id = "memezombies" limbs_id = "zombie" + mutanthands = /obj/item/zombie_hand no_equip = list(slot_wear_mask, slot_head) armor = 20 // 120 damage to KO a zombie, which kills it speedmod = 2 + mutanteyes = /obj/item/organ/eyes/night_vision/zombie /datum/species/zombie/infectious/spec_life(mob/living/carbon/C) . = ..() @@ -27,29 +29,15 @@ /datum/species/zombie/infectious/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() - // Drop items in hands - // If you're a zombie lucky enough to have a NODROP item, then it stays. - for(var/V in C.held_items) - var/obj/item/I = V - if(istype(I)) - if(C.dropItemToGround(I)) - var/obj/item/zombie_hand/zh = new /obj/item/zombie_hand() - C.put_in_hands(zh) - else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand - var/obj/item/zombie_hand/zh = new /obj/item/zombie_hand() - C.put_in_hands(zh) - // Next, deal with the source of this zombie corruption + // Deal with the source of this zombie corruption + // Infection organ needs to be handled separately from mutant_organs + // because it persists through species transitions var/obj/item/organ/zombie_infection/infection infection = C.getorganslot("zombie_infection") if(!infection) - infection = new(C) - -/datum/species/zombie/infectious/on_species_loss(mob/living/carbon/C) - . = ..() - for(var/obj/item/I in C.held_items) - if(istype(I, /obj/item/zombie_hand)) - qdel(I) + infection = new() + infection.Insert(C) // Your skin falls off diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm index 0734670468..d908ed547d 100644 --- a/code/modules/mob/living/death.dm +++ b/code/modules/mob/living/death.dm @@ -49,8 +49,8 @@ timeofdeath = world.time tod = worldtime2text() var/turf/T = get_turf(src) + var/area/A = get_area(T) if(mind && mind.name && mind.active && (!(T.flags & NO_DEATHRATTLE))) - var/area/A = get_area(T) var/rendered = "[mind.name] has died at [A.name]." deadchat_broadcast(rendered, follow_target = src, turf_target = T, message_type=DEADCHAT_DEATHRATTLE) if(mind) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 9c67b391d0..77dada5349 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -446,7 +446,7 @@ if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1)//separated from our puller and not in the middle of a diagonal move. pulledby.stop_pulling() - if (s_active && !(s_active.ClickAccessible(src, depth=STORAGE_VIEW_DEPTH) || s_active.Adjacent(src))) + if (s_active && !(CanReach(s_active,view_only = TRUE))) s_active.close(src) /mob/living/movement_delay(ignorewalk = 0) diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index dce38bd664..56c43211e4 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -28,7 +28,7 @@ //Holopad if(istype(ai.current, /obj/machinery/holopad)) var/obj/machinery/holopad/H = ai.current - H.move_hologram(ai) + H.move_hologram(ai, T) /mob/camera/aiEye/Move() return 0 diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 14b854d2a2..768ff69166 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1143,7 +1143,7 @@ M.visible_message("Unfortunately, [M] just can't seem to hold onto [src]!") return if(iscarbon(M) && (!riding_datum.equip_buckle_inhands(M, 1))) - M.visible_message("[M] can't climb onto [src] because his hands are full!") + M.visible_message("[M] can't climb onto [src] because [M.p_their()] hands are full!") return . = ..(M, force, check_loc) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 4eae96bf5d..ba4e3dc68c 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -287,17 +287,13 @@ to_chat(user, "The welder must be on for this task!") else if(W.force) //if force is non-zero - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() + do_sparks(5, TRUE, src) ..() /mob/living/simple_animal/bot/bullet_act(obj/item/projectile/Proj) if(Proj && (Proj.damage_type == BRUTE || Proj.damage_type == BURN)) if(prob(75) && Proj.damage > 0) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() + do_sparks(5, TRUE, src) return ..() /mob/living/simple_animal/bot/emp_act(severity) diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm index 4c5c2c14c5..190e6a7db4 100644 --- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm +++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm @@ -259,9 +259,7 @@ if(prob(50)) new /obj/item/bodypart/l_arm/robot(Tsec) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(3, 1, src) - s.start() + do_sparks(3, TRUE, src) ..() /obj/machinery/bot_core/cleanbot diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index e11711f2bd..32db638542 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -390,9 +390,7 @@ Auto Patrol[]"}, if(lasercolor == "r") new /obj/item/clothing/suit/redtag(Tsec) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(3, 1, src) - s.start() + do_sparks(3, TRUE, src) new /obj/effect/decal/cleanable/oil(loc) ..() diff --git a/code/modules/mob/living/simple_animal/bot/floorbot.dm b/code/modules/mob/living/simple_animal/bot/floorbot.dm index c8208e7a3b..fe2b08e777 100644 --- a/code/modules/mob/living/simple_animal/bot/floorbot.dm +++ b/code/modules/mob/living/simple_animal/bot/floorbot.dm @@ -381,9 +381,7 @@ var/obj/item/stack/tile/plasteel/T = new (Tsec) T.amount = 1 - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(3, 1, src) - s.start() + do_sparks(3, TRUE, src) ..() /obj/machinery/bot_core/floorbot diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm index bcf4b86191..5d3738108e 100644 --- a/code/modules/mob/living/simple_animal/bot/medbot.dm +++ b/code/modules/mob/living/simple_animal/bot/medbot.dm @@ -530,9 +530,7 @@ if(emagged && prob(25)) playsound(loc, 'sound/voice/minsult.ogg', 50, 0) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(3, 1, src) - s.start() + do_sparks(3, TRUE, src) ..() /mob/living/simple_animal/bot/medbot/proc/declare(crit_patient) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 30c2c4e9a9..bdf4277438 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -719,9 +719,7 @@ cell.update_icon() cell = null - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(3, 1, src) - s.start() + do_sparks(3, TRUE, src) new /obj/effect/decal/cleanable/oil(loc) ..() diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm index a57b9a9156..c30f52aa5c 100644 --- a/code/modules/mob/living/simple_animal/bot/secbot.dm +++ b/code/modules/mob/living/simple_animal/bot/secbot.dm @@ -397,9 +397,7 @@ Auto Patrol: []"}, if(prob(50)) new /obj/item/bodypart/l_arm/robot(Tsec) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(3, 1, src) - s.start() + do_sparks(3, TRUE, src) new /obj/effect/decal/cleanable/oil(loc) ..() diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index b879f1baf6..7285c2fa75 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -14,8 +14,8 @@ stop_automated_movement = 1 status_flags = CANPUSH attack_sound = 'sound/weapons/punch1.ogg' - see_in_dark = 7 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + see_in_dark = 7 + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE 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_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 @@ -31,12 +31,20 @@ deathmessage = "collapses in a shattered heap." var/list/construct_spells = list() var/playstyle_string = "You are a generic construct! Your job is to not exist, and you should probably adminhelp this." + var/master = null + var/seeking = FALSE /mob/living/simple_animal/hostile/construct/Initialize() - . = ..() + . = ..() for(var/spell in construct_spells) AddSpell(new spell(null)) +/mob/living/simple_animal/hostile/construct/Destroy() + for(var/X in actions) + var/datum/action/A = X + qdel(A) + ..() + /mob/living/simple_animal/hostile/construct/Login() ..() to_chat(src, playstyle_string) @@ -84,11 +92,11 @@ /mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE) return 0 - -/mob/living/simple_animal/hostile/construct/adjustHealth(amount, updating_health = TRUE, forced = FALSE) - . = ..() - if(updating_health) - update_health_hud() + +/mob/living/simple_animal/hostile/construct/adjustHealth(amount, updating_health = TRUE, forced = FALSE) + . = ..() + if(updating_health) + update_health_hud() /////////////////Juggernaut/////////////// /mob/living/simple_animal/hostile/construct/armored @@ -119,6 +127,38 @@ AIStatus = AI_ON environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP + +///////////////////////Master-Tracker/////////////////////// + +/datum/action/innate/seek_master + name = "Seek your Master" + desc = "You and your master share a soul-link that informs you of their location" + background_icon_state = "bg_demon" + buttontooltipstyle = "cult" + button_icon_state = "cult_mark" + var/tracking = FALSE + var/mob/living/simple_animal/hostile/construct/the_construct + +/datum/action/innate/seek_master/Grant(var/mob/living/C) + the_construct = C + ..() + +/datum/action/innate/seek_master/Activate() + if(!the_construct.master) + to_chat(the_construct, "You have no master to seek!") + the_construct.seeking = FALSE + return + if(tracking) + tracking = FALSE + the_construct.seeking = FALSE + to_chat(the_construct, "You are no longer tracking your master.") + return + else + tracking = TRUE + the_construct.seeking = TRUE + to_chat(the_construct, "You are now tracking your master.") + + /mob/living/simple_animal/hostile/construct/armored/bullet_act(obj/item/projectile/P) if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam)) var/reflectchance = 80 - round(P.damage/3) @@ -273,22 +313,22 @@ /mob/living/simple_animal/hostile/construct/harvester/hostile //actually hostile, will move around, hit things AIStatus = AI_ON environment_smash = 1 //only token destruction, don't smash the cult wall NO STOP - - - -/////////////////////////////ui stuff///////////////////////////// - -/mob/living/simple_animal/hostile/construct/update_health_hud() - if(hud_used) - if(health >= maxHealth) - hud_used.healths.icon_state = "[icon_state]_health0" - else if(health > maxHealth*0.8) - hud_used.healths.icon_state = "[icon_state]_health2" - else if(health > maxHealth*0.6) - hud_used.healths.icon_state = "[icon_state]_health3" - else if(health > maxHealth*0.4) - hud_used.healths.icon_state = "[icon_state]_health4" - else if(health > maxHealth*0.2) - hud_used.healths.icon_state = "[icon_state]_health5" - else + + + +/////////////////////////////ui stuff///////////////////////////// + +/mob/living/simple_animal/hostile/construct/update_health_hud() + if(hud_used) + if(health >= maxHealth) + hud_used.healths.icon_state = "[icon_state]_health0" + else if(health > maxHealth*0.8) + hud_used.healths.icon_state = "[icon_state]_health2" + else if(health > maxHealth*0.6) + hud_used.healths.icon_state = "[icon_state]_health3" + else if(health > maxHealth*0.4) + hud_used.healths.icon_state = "[icon_state]_health4" + else if(health > maxHealth*0.2) + hud_used.healths.icon_state = "[icon_state]_health5" + else hud_used.healths.icon_state = "[icon_state]_health6" \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 89dedede13..c08f291cee 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -216,7 +216,7 @@ if(change) if(change > 0) if(M && stat != DEAD) - flick_overlay(image('icons/mob/animal.dmi', src, "heart-ani2", ABOVE_MOB_LAYER), list(M.client), 20) + new /obj/effect/overlay/temp/heart(loc) emote("me", 1, "purrs!") else if(M && stat != DEAD) diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm index 8cad712bee..2cc4545faa 100644 --- a/code/modules/mob/living/simple_animal/friendly/crab.dm +++ b/code/modules/mob/living/simple_animal/friendly/crab.dm @@ -20,6 +20,7 @@ var/obj/item/inventory_head var/obj/item/inventory_mask gold_core_spawnable = 2 + devourable = TRUE /mob/living/simple_animal/crab/Life() ..() diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index c6aa754b6e..eb6feb00be 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -553,7 +553,7 @@ if(change) if(change > 0) if(M && stat != DEAD) // Added check to see if this mob (the dog) is dead to fix issue 2454 - flick_overlay(image('icons/mob/animal.dmi',src,"heart-ani2",ABOVE_MOB_LAYER), list(M.client), 20) + new /obj/effect/overlay/temp/heart(loc) emote("me", 1, "yaps happily!") else if(M && stat != DEAD) // Same check here, even though emote checks it as well (poor form to check it only in the help case) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 50711f25ea..427d9ddaa4 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -51,14 +51,12 @@ src.visible_message("[src] calms down.") if(stat == CONSCIOUS) udder.generateMilk() - var/obj/structure/spacevine/SV = locate(/obj/structure/spacevine) in loc - if(SV) - SV.eat(src) + eat_plants() if(!pulledby) for(var/direction in shuffle(list(1,2,4,8,5,6,9,10))) var/step = get_step(src, direction) if(step) - if(locate(/obj/structure/spacevine) in step) + if(locate(/obj/structure/spacevine) in step || locate(/obj/structure/glowshroom) in step) Move(step, get_dir(src, step)) /mob/living/simple_animal/hostile/retaliate/goat/Retaliate() @@ -68,9 +66,22 @@ /mob/living/simple_animal/hostile/retaliate/goat/Move() ..() if(!stat) - var/obj/structure/spacevine/SV = locate(/obj/structure/spacevine) in loc - if(SV) - SV.eat(src) + eat_plants() + +/mob/living/simple_animal/hostile/retaliate/goat/proc/eat_plants() + var/eaten = FALSE + var/obj/structure/spacevine/SV = locate(/obj/structure/spacevine) in loc + if(SV) + SV.eat(src) + eaten = TRUE + + var/obj/structure/glowshroom/GS = locate(/obj/structure/glowshroom) in loc + if(GS) + qdel(GS) + eaten = TRUE + + if(eaten && prob(10)) + say("Nom") /mob/living/simple_animal/hostile/retaliate/goat/attackby(obj/item/O, mob/user, params) if(stat == CONSCIOUS && istype(O, /obj/item/weapon/reagent_containers/glass)) @@ -300,8 +311,7 @@ name = "udder" /obj/item/udder/Initialize() - reagents = new(50) - reagents.my_atom = src + create_reagents(50) reagents.add_reagent("milk", 20) ..() diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index be889a4183..fe6e22bcab 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -414,7 +414,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians var/mob/living/simple_animal/hostile/guardian/G = input(src, "Pick the guardian you wish to reset", "Guardian Reset") as null|anything in guardians if(G) to_chat(src, "You attempt to reset [G.real_name]'s personality...") - var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", "pAI", null, FALSE, 100) + var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as [src.real_name]'s [G.real_name]?", "pAI", null, FALSE, 100) var/mob/dead/observer/new_stand = null if(candidates.len) new_stand = pick(candidates) @@ -489,7 +489,7 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians return used = TRUE to_chat(user, "[use_message]") - var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100) + var/list/mob/dead/observer/candidates = pollGhostCandidates("Do you want to play as the [mob_name] of [user.real_name]?", ROLE_PAI, null, FALSE, 100) var/mob/dead/observer/theghost = null if(candidates.len) diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index e7ab6e1b56..51e782b019 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -133,6 +133,7 @@ loc = BB target = null wanted_objects -= typecacheof(/obj/structure/beebox) //so we don't attack beeboxes when not going home + return //no don't attack the goddamm box else . = ..() if(. && beegent && isliving(target)) diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index 45f46b3828..fc2160399e 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -16,6 +16,7 @@ speed = 0 maxHealth = 25 health = 25 + devourable = TRUE harm_intent_damage = 8 obj_damage = 50 diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index e0eb8aad29..5454f3c553 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -53,7 +53,5 @@ ranged = 1 /mob/living/simple_animal/hostile/hivebot/death(gibbed) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(3, 1, src) - s.start() + do_sparks(3, TRUE, src) ..(1) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/jungle_mobs.dm b/code/modules/mob/living/simple_animal/hostile/jungle_mobs.dm new file mode 100644 index 0000000000..de1bf0b308 --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/jungle_mobs.dm @@ -0,0 +1,85 @@ +/mob/living/simple_animal/hostile/jungle + vision_range = 5 + atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) + faction = list("jungle") + weather_immunities = list("acid") + obj_damage = 30 + environment_smash = 2 + minbodytemp = 0 + maxbodytemp = 450 + response_help = "pokes" + response_disarm = "shoves" + response_harm = "strikes" + status_flags = 0 + a_intent = INTENT_HARM + see_in_dark = 4 + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + mob_size = MOB_SIZE_LARGE + + + +//Mega arachnid + +/mob/living/simple_animal/hostile/jungle/mega_arachnid + name = "mega arachnid" + desc = "Though physically imposing, it prefers to ambush its prey, and it will only engage with an already crippled opponent." + melee_damage_lower = 30 + melee_damage_upper = 30 + maxHealth = 300 + health = 300 + speed = 1 + ranged = 1 + pixel_x = -16 + move_to_delay = 10 + aggro_vision_range = 9 + speak_emote = list("chitters") + attack_sound = 'sound/weapons/bladeslice.ogg' + ranged_cooldown_time = 60 + projectiletype = /obj/item/projectile/mega_arachnid + projectilesound = 'sound/weapons/pierce.ogg' + icon = 'icons/mob/jungle/arachnid.dmi' + icon_state = "arachnid" + icon_living = "arachnid" + icon_dead = "dead_purple" + alpha = 50 + +/mob/living/simple_animal/hostile/jungle/mega_arachnid/Life() + ..() + if(target && ranged_cooldown > world.time && iscarbon(target)) + var/mob/living/carbon/C = target + if(!C.legcuffed && C.health < 50) + retreat_distance = 9 + minimum_distance = 9 + alpha = 125 + return + retreat_distance = 0 + minimum_distance = 0 + alpha = 255 + + +/mob/living/simple_animal/hostile/jungle/mega_arachnid/Aggro() + ..() + alpha = 255 + +/mob/living/simple_animal/hostile/jungle/mega_arachnid/LoseAggro() + ..() + alpha = 50 + +/obj/item/projectile/mega_arachnid + name = "flesh snare" + nodamage = 1 + damage = 0 + icon_state = "tentacle_end" + +/obj/item/projectile/mega_arachnid/on_hit(atom/target, blocked = 0) + if(iscarbon(target) && blocked < 100) + var/obj/item/weapon/restraints/legcuffs/beartrap/mega_arachnid/B = new /obj/item/weapon/restraints/legcuffs/beartrap/mega_arachnid(get_turf(target)) + B.Crossed(target) + ..() + +/obj/item/weapon/restraints/legcuffs/beartrap/mega_arachnid + name = "fleshy restraints" + desc = "Used by mega arachnids to immobilize their prey." + flags = DROPDEL + icon_state = "tentacle_end" + icon = 'icons/obj/projectiles.dmi' \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm index f3b5866ec6..b9731f7418 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/ghost.dm @@ -40,6 +40,7 @@ /mob/living/simple_animal/hostile/retaliate/ghost/Initialize() . = ..() + set_light(1, 2) if(!random) give_hair() else @@ -60,4 +61,4 @@ ghost_facial_hair = mutable_appearance('icons/mob/human_face.dmi', "facial_[ghost_facial_hair_style]", -HAIR_LAYER) ghost_facial_hair.alpha = 200 ghost_facial_hair.color = ghost_facial_hair_color - add_overlay(ghost_facial_hair) \ No newline at end of file + add_overlay(ghost_facial_hair) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index c14efe30c2..6eb688d38f 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -16,7 +16,7 @@ response_disarm = "shoos" response_harm = "stomps on" emote_see = list("jiggles", "bounces in place") - speak_emote = list("telepathically chirps") + speak_emote = list("blorbles") bubble_icon = "slime" initial_language_holder = /datum/language_holder/slime @@ -31,10 +31,10 @@ see_in_dark = 8 - verb_say = "telepathically chirps" - verb_ask = "telepathically asks" - verb_exclaim = "telepathically cries" - verb_yell = "telephatically cries" + verb_say = "blorbles" + verb_ask = "inquisitively blorbles" + verb_exclaim = "loudly blorbles" + verb_yell = "loudly blorbles" // canstun and canweaken don't affect slimes because they ignore stun and weakened variables // for the sake of cleanliness, though, here they are. diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index a4c85962c5..aab6e40c2d 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -351,6 +351,8 @@ /mob/proc/spin(spintime, speed) set waitfor = 0 var/D = dir + if((spintime < 1)||(speed < 1)||!spintime||!speed) + return while(spintime >= speed) sleep(speed) switch(D) @@ -576,6 +578,7 @@ var/datum/map_config/cached = SSmapping.next_map_config if(cached) stat(null, "Next Map: [cached.map_name]") + stat("Round ID:", "[GLOB.round_id ? GLOB.round_id : "NULL"]") stat(null, "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]") stat(null, "Station Time: [worldtime2text()]") stat(null, "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)") diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index 66fc0cf32a..de3d48f28b 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -12,16 +12,20 @@ slot_flags = SLOT_BELT resistance_flags = FLAMMABLE -/obj/item/weapon/clipboard/New() +/obj/item/weapon/clipboard/Initialize() update_icon() - ..() + . = ..() +/obj/item/weapon/clipboard/Destroy() + QDEL_NULL(haspen) + QDEL_NULL(toppaper) //let movable/Destroy handle the rest + return ..() /obj/item/weapon/clipboard/update_icon() cut_overlays() if(toppaper) add_overlay(toppaper.icon_state) - add_overlay(toppaper.overlays) + copy_overlays(toppaper) if(haspen) add_overlay("clipboard_pen") add_overlay("clipboard_over") @@ -115,4 +119,4 @@ //Update everything attack_self(usr) - update_icon() \ No newline at end of file + update_icon() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 4633285488..6c6a088644 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -497,9 +497,7 @@ var/turf/T = get_turf(src) var/obj/structure/cable/N = T.get_cable_node() if (prob(50) && electrocute_mob(usr, N, N, 1, TRUE)) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() + do_sparks(5, TRUE, src) return C.use(10) to_chat(user, "You add cables to the APC frame.") @@ -1181,9 +1179,7 @@ /obj/machinery/power/apc/proc/shock(mob/user, prb) if(!prob(prb)) return 0 - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() + do_sparks(5, TRUE, src) if(isalien(user)) return 0 if(electrocute_mob(user, src, src, 1, TRUE)) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 653e3296f4..48fc254a8e 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -156,9 +156,7 @@ By design, d1 is the smallest direction and d2 is the highest if(!prob(prb)) return 0 if (electrocute_mob(user, powernet, src, siemens_coeff)) - var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread - s.set_up(5, 1, src) - s.start() + do_sparks(5, TRUE, src) return 1 else return 0 diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index dfbf3fe50b..9fe043a4a0 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -28,11 +28,12 @@ /obj/machinery/power/generator/Initialize(mapload) - . = ..() + . = ..() var/obj/machinery/atmospherics/components/binary/circulator/circpath = /obj/machinery/atmospherics/components/binary/circulator cold_circ = locate(circpath) in get_step(src, cold_dir) hot_circ = locate(circpath) in get_step(src, hot_dir) connect_to_network() + SSair.atmos_machinery += src if(cold_circ) switch(cold_dir) @@ -55,6 +56,9 @@ update_icon() +/obj/machinery/power/generator/Destroy() + SSair.atmos_machinery -= src + return ..() /obj/machinery/power/generator/update_icon() @@ -63,21 +67,20 @@ else cut_overlays() - if(lastgenlev != 0) - add_overlay("teg-op[lastgenlev]") + var/L = min(round(lastgenlev/100000),11) + if(L != 0) + add_overlay(image('icons/obj/power.dmi', "teg-op[L]")) - add_overlay("teg-oc[lastcirc]") + add_overlay("teg-oc[lastcirc]") #define GENRATE 800 // generator output coefficient from Q -/obj/machinery/power/generator/process() +/obj/machinery/power/generator/process_atmos() if(!cold_circ || !hot_circ) return - lastgen = 0 - if(powernet) //to_chat(world, "cold_circ and hot_circ pass") @@ -104,7 +107,7 @@ var/energy_transfer = delta_temperature*hot_air_heat_capacity*cold_air_heat_capacity/(hot_air_heat_capacity+cold_air_heat_capacity) var/heat = energy_transfer*(1-efficiency) - lastgen = energy_transfer*efficiency + lastgen += energy_transfer*efficiency //to_chat(world, "lastgen = [lastgen]; heat = [heat]; delta_temperature = [delta_temperature]; hot_air_heat_capacity = [hot_air_heat_capacity]; cold_air_heat_capacity = [cold_air_heat_capacity];") @@ -113,7 +116,7 @@ //to_chat(world, "POWER: [lastgen] W generated at [efficiency*100]% efficiency and sinks sizes [cold_air_heat_capacity], [hot_air_heat_capacity]") - add_avail(lastgen) + //add_avail(lastgen) This is done in process now // update icon overlays only if displayed level has changed if(hot_air) @@ -124,15 +127,23 @@ var/datum/gas_mixture/cold_circ_air1 = cold_circ.AIR1 cold_circ_air1.merge(cold_air) - var/genlev = max(0, min( round(11*lastgen / 100000), 11)) + update_icon() + var/circ = "[cold_circ && cold_circ.last_pressure_delta > 0 ? "1" : "0"][hot_circ && hot_circ.last_pressure_delta > 0 ? "1" : "0"]" - if((genlev != lastgenlev) || (circ != lastcirc)) - lastgenlev = genlev + if(circ != lastcirc) lastcirc = circ update_icon() src.updateDialog() +/obj/machinery/power/generator/process() + //Setting this number higher just makes the change in power output slower, it doesnt actualy reduce power output cause **math** + var/power_output = round(lastgen / 10) + add_avail(power_output) + lastgenlev = power_output + lastgen -= power_output + ..() + /obj/machinery/power/generator/attack_hand(mob/user) if(..()) user << browse(null, "window=teg") @@ -151,7 +162,13 @@ t += "
" - t += "Output: [round(lastgen)] W" + var/displaygen = lastgenlev + if(displaygen < 1000000) //less than a MW + displaygen /= 1000 + t += "Output: [round(displaygen,0.01)] kW" + else + displaygen /= 1000000 + t += "Output: [round(displaygen,0.01)] MW" t += "
" diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index 6ca3c8f620..4bd8bb56b0 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -98,7 +98,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne // /obj/machinery/gravity_generator/main/station/Initialize() - . = ..() + . = ..() setup_parts() middle.add_overlay("activated") update_list() @@ -303,17 +303,17 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne use_power = on ? 2 : 1 // Sound the alert if gravity was just enabled or disabled. var/alert = 0 - var/area/area = get_area(src) - if(on && SSticker.IsRoundInProgress()) // If we turned on and the game is live. + var/area/A = get_area(src) + if(on && SSticker.IsRoundInProgress()) // If we turned on and the game is live. if(gravity_in_level() == 0) alert = 1 investigate_log("was brought online and is now producing gravity for this level.", "gravity") - message_admins("The gravity generator was brought online. ([area.name])") + message_admins("The gravity generator was brought online [A][ADMIN_COORDJMP(src)]") else if(gravity_in_level() == 1) alert = 1 investigate_log("was brought offline and there is now no gravity for this level.", "gravity") - message_admins("The gravity generator was brought offline with no backup generator. ([area.name])") + message_admins("The gravity generator was brought offline with no backup generator. [A][ADMIN_COORDJMP(src)]") update_icon() update_list() diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index cfe57d0607..b7a298d6b3 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -93,7 +93,7 @@ connect_to_network() sparks = new - sparks.attach(src) + sparks.attach(src) sparks.set_up(5, TRUE, src) /obj/machinery/power/emitter/Destroy() @@ -121,8 +121,8 @@ if(src.active==1) src.active = 0 to_chat(user, "You turn off \the [src].") - message_admins("Emitter turned off by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("Emitter turned off by [key_name(user)] in ([x],[y],[z])") + message_admins("Emitter turned off by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(src)]",0,1) + log_game("Emitter turned off by [key_name(user)] in [COORD(src)]") investigate_log("turned off by [key_name(user)] at [get_area(src)]","singulo") else src.active = 1 diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm index 9deebdfe10..fb2df4deeb 100644 --- a/code/modules/power/singularity/narsie.dm +++ b/code/modules/power/singularity/narsie.dm @@ -14,6 +14,7 @@ light_power = 0.7 light_range = 15 light_color = rgb(255, 0, 0) + gender = FEMALE var/clashing = FALSE //If Nar-Sie is fighting Ratvar /obj/singularity/narsie/large @@ -26,8 +27,8 @@ grav_pull = 10 consume_range = 12 //How many tiles out do we eat -/obj/singularity/narsie/large/New() - ..() +/obj/singularity/narsie/large/Initialize() + . = ..() send_to_playing_players("NAR-SIE HAS RISEN") send_to_playing_players(pick('sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg')) diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index 3b36e436ee..dc3da6db8d 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -117,8 +117,8 @@ strength++ strength_change() - message_admins("PA Control Computer increased to [strength] by [key_name_admin(usr)](?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("PA Control Computer increased to [strength] by [key_name(usr)] in ([x],[y],[z])") + message_admins("PA Control Computer increased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_COORDJMP(src)]",0,1) + log_game("PA Control Computer increased to [strength] by [key_name(usr)] in [COORD(src)]") investigate_log("increased to [strength] by [key_name(usr)]","singulo") @@ -127,8 +127,8 @@ strength-- strength_change() - message_admins("PA Control Computer decreased to [strength] by [key_name_admin(usr)](?) (FLW) in ([x],[y],[z] - JMP)",0,1) - log_game("PA Control Computer decreased to [strength] by [key_name(usr)] in ([x],[y],[z])") + message_admins("PA Control Computer decreased to [strength] by [ADMIN_LOOKUPFLW(usr)] in [ADMIN_COORDJMP(src)]",0,1) + log_game("PA Control Computer decreased to [strength] by [key_name(usr)] in [COORD(src)]") investigate_log("decreased to [strength] by [key_name(usr)]","singulo") diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 3b0bc3087b..1a308ed471 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -29,12 +29,12 @@ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF dangerous_possession = TRUE -/obj/singularity/New(loc, var/starting_energy = 50, var/temp = 0) +/obj/singularity/Initialize(mapload, starting_energy = 50) //CARN: admin-alert for chuckle-fuckery. admin_investigate_setup() src.energy = starting_energy - ..() + . = ..() START_PROCESSING(SSobj, src) GLOB.poi_list |= src GLOB.singularities |= src diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 1e1737661e..ea95b08269 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -170,7 +170,7 @@ //crowbarring it ! var/turf/T = get_turf(src) if(default_deconstruction_crowbar(I)) - message_admins("[src] has been deconstructed by [key_name_admin(user)](?) (FLW) in ([T.x],[T.y],[T.z] - JMP)",0,1) + message_admins("[src] has been deconstructed by [ADMIN_LOOKUPFLW(user)] in [ADMIN_COORDJMP(T)]",0,1) log_game("[src] has been deconstructed by [key_name(user)]") investigate_log("SMES deconstructed by [key_name(user)]","singulo") return @@ -256,9 +256,9 @@ input_available = terminal.surplus() if(inputting) - if(input_available > 0 && input_available >= input_level) // if there's power available, try to charge + if(input_available > 0) // if there's power available, try to charge - var/load = min((capacity-charge)/SMESRATE, input_level) // charge at set rate, limited to spare capacity + var/load = min(min((capacity-charge)/SMESRATE, input_level), input_available) // charge at set rate, limited to spare capacity charge += load * SMESRATE // increase the charge @@ -268,7 +268,7 @@ inputting = 0 // stop inputting else - if(input_attempt && input_available > 0 && input_available >= input_level) + if(input_attempt && input_available > 0) inputting = 1 else inputting = 0 diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 4b48d19857..712cd5cd41 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -129,6 +129,7 @@ /obj/machinery/power/supermatter_shard/Initialize() . = ..() + SSair.atmos_machinery += src countdown = new(src) countdown.start() GLOB.poi_list |= src @@ -139,6 +140,7 @@ /obj/machinery/power/supermatter_shard/Destroy() investigate_log("has been destroyed.", "supermatter") + SSair.atmos_machinery -= src QDEL_NULL(radio) GLOB.poi_list -= src QDEL_NULL(countdown) @@ -181,7 +183,7 @@ E.energy = power qdel(src) -/obj/machinery/power/supermatter_shard/process() +/obj/machinery/power/supermatter_shard/process_atmos() var/turf/T = loc if(isnull(T)) // We have a null turf...something is wrong, stop processing this entity. @@ -296,6 +298,7 @@ if(produces_gas) env.merge(removed) + air_update_turf() for(var/mob/living/carbon/human/l in view(src, HALLUCINATION_RANGE(power))) // If they can see it without mesons on. Bad on them. if(!istype(l.glasses, /obj/item/clothing/glasses/meson)) @@ -341,7 +344,7 @@ lastwarning = REALTIMEOFDAY if(!has_reached_emergency) investigate_log("has reached the emergency point for the first time.", "supermatter") - message_admins("[src] has reached the emergency point (JMP).") + message_admins("[src] has reached the emergency point [ADMIN_JMP(src)].") has_reached_emergency = 1 else if(damage >= damage_archived) // The damage is still going up SPEAK("[warning_alert] Instability: [stability]%") @@ -388,7 +391,7 @@ power += Proj.damage * config_bullet_energy if(!has_been_powered) investigate_log("has been powered for the first time.", "supermatter") - message_admins("[src] has been powered for the first time (JMP).") + message_admins("[src] has been powered for the first time [ADMIN_JMP(src)].") has_been_powered = 1 else if(takes_damage) damage += Proj.damage * config_bullet_energy @@ -487,7 +490,7 @@ /obj/machinery/power/supermatter_shard/proc/Consume(atom/movable/AM) if(isliving(AM)) var/mob/living/user = AM - message_admins("[src] has consumed [key_name_admin(user)]? (FLW) (JMP).") + message_admins("[src] has consumed [key_name_admin(user)] [ADMIN_JMP(src)].") investigate_log("has consumed [key_name(user)].", "supermatter") user.dust() matter_power += 200 diff --git a/code/modules/power/tesla/energy_ball.dm b/code/modules/power/tesla/energy_ball.dm index fbb82cb36a..df08899140 100644 --- a/code/modules/power/tesla/energy_ball.dm +++ b/code/modules/power/tesla/energy_ball.dm @@ -40,6 +40,11 @@ GLOBAL_LIST_INIT(blacklisted_tesla_types, typecacheof(list(/obj/machinery/atmosp var/energy_to_raise = 32 var/energy_to_lower = -20 +/obj/singularity/energy_ball/Initialize(mapload, starting_energy = 50, is_miniball = FALSE) + . = ..() + if(!is_miniball) + set_light(10, 7, "#EEEEFF") + /obj/singularity/energy_ball/ex_act(severity, target) return @@ -54,6 +59,11 @@ GLOBAL_LIST_INIT(blacklisted_tesla_types, typecacheof(list(/obj/machinery/atmosp . = ..() +/obj/singularity/energy_ball/admin_investigate_setup() + if(istype(loc, /obj/singularity/energy_ball)) + return + ..() + /obj/singularity/energy_ball/process() if(!orbiting) handle_energy() @@ -117,7 +127,7 @@ GLOBAL_LIST_INIT(blacklisted_tesla_types, typecacheof(list(/obj/machinery/atmosp /obj/singularity/energy_ball/proc/new_mini_ball() if(!loc) return - var/obj/singularity/energy_ball/EB = new(loc) + var/obj/singularity/energy_ball/EB = new(loc, 0, TRUE) EB.transform *= pick(0.3, 0.4, 0.5, 0.6, 0.7) var/icon/I = icon(icon,icon_state,dir) diff --git a/code/modules/projectiles/ammunition/energy.dm b/code/modules/projectiles/ammunition/energy.dm index a6440e32ed..b1fd49779f 100644 --- a/code/modules/projectiles/ammunition/energy.dm +++ b/code/modules/projectiles/ammunition/energy.dm @@ -191,7 +191,7 @@ fire_sound = 'sound/magic/lightningbolt.ogg' e_cost = 200 select_name = "stun" - projectile_type = /obj/item/projectile/energy/tesla_revolver + projectile_type = /obj/item/projectile/energy/tesla/revolver /obj/item/ammo_casing/energy/gravityrepulse projectile_type = /obj/item/projectile/gravityrepulse diff --git a/code/modules/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm index 69a9ca2a8a..8a94c2b849 100644 --- a/code/modules/projectiles/guns/energy/pulse.dm +++ b/code/modules/projectiles/guns/energy/pulse.dm @@ -19,15 +19,12 @@ /obj/item/weapon/gun/energy/pulse/prize/New() . = ..() GLOB.poi_list |= src - var/msg = "A pulse rifle prize has been created at ([x],[y],[z] - (\ - \ - JMP)" + var/msg = "A pulse rifle prize has been created at [ADMIN_COORDJMP(src)]" message_admins(msg) log_game(msg) - notify_ghosts("Someone won a pulse rifle as a prize!", source = src, - action = NOTIFY_ORBIT) + notify_ghosts("Someone won a pulse rifle as a prize!", source = src, action = NOTIFY_ORBIT) /obj/item/weapon/gun/energy/pulse/prize/Destroy() GLOB.poi_list -= src diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index dceed5b438..9835b1df21 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -179,6 +179,8 @@ return if(setAngle) Angle = setAngle + var/old_pixel_x = pixel_x + var/old_pixel_y = pixel_y if(!legacy) //new projectiles set waitfor = 0 var/next_run = world.time @@ -201,29 +203,30 @@ var/Pixel_x=round((sin(Angle)+16*sin(Angle)*2), 1) //round() is a floor operation when only one argument is supplied, we don't want that here var/Pixel_y=round((cos(Angle)+16*cos(Angle)*2), 1) - var/pixel_x_offset = pixel_x + Pixel_x - var/pixel_y_offset = pixel_y + Pixel_y + var/pixel_x_offset = old_pixel_x + Pixel_x + var/pixel_y_offset = old_pixel_y + Pixel_y var/new_x = x var/new_y = y while(pixel_x_offset > 16) pixel_x_offset -= 32 - pixel_x -= 32 + old_pixel_x -= 32 new_x++// x++ while(pixel_x_offset < -16) pixel_x_offset += 32 - pixel_x += 32 + old_pixel_x += 32 new_x-- - while(pixel_y_offset > 16) pixel_y_offset -= 32 - pixel_y -= 32 + old_pixel_y -= 32 new_y++ while(pixel_y_offset < -16) pixel_y_offset += 32 - pixel_y += 32 + old_pixel_y += 32 new_y-- - + + pixel_x = old_pixel_x + pixel_y = old_pixel_y step_towards(src, locate(new_x, new_y, z)) next_run += max(world.tick_lag, speed) var/delay = next_run - world.time @@ -232,7 +235,9 @@ pixel_y = pixel_y_offset else animate(src, pixel_x = pixel_x_offset, pixel_y = pixel_y_offset, time = max(1, (delay <= 3 ? delay - 1 : delay)), flags = ANIMATION_END_NOW) - + old_pixel_x = pixel_x_offset + old_pixel_y = pixel_y_offset + if(original && (original.layer>=2.75) || ismob(original)) if(loc == get_turf(original)) if(!(original in permutated)) diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm index c1a67f4c81..974ea935f2 100644 --- a/code/modules/projectiles/projectile/energy.dm +++ b/code/modules/projectiles/projectile/energy.dm @@ -159,44 +159,34 @@ /obj/item/projectile/energy/bolt/large damage = 20 -/obj/item/projectile/energy/tesla_revolver +/obj/item/projectile/energy/tesla name = "tesla bolt" icon_state = "tesla_projectile" impact_effect_type = /obj/effect/overlay/temp/impact_effect/blue_laser var/chain -/obj/item/projectile/energy/tesla_revolver/fire(setAngle) +/obj/item/projectile/energy/tesla/fire(setAngle) if(firer) chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY) ..() -/obj/item/projectile/energy/tesla_revolver/on_hit(atom/target) - . = ..() - if(isliving(target)) - tesla_zap(src, 3, 10000) - qdel(src) - -/obj/item/projectile/energy/tesla_revolver/Destroy() +/obj/item/projectile/energy/tesla/Destroy() qdel(chain) return ..() +/obj/item/projectile/energy/tesla/revolver + name = "energy orb" -/obj/item/projectile/energy/tesla_cannon - name = "tesla bolt" - icon_state = "tesla_projectile" - impact_effect_type = /obj/effect/overlay/temp/impact_effect/blue_laser - var/chain +/obj/item/projectile/energy/tesla/revolver/on_hit(atom/target) + . = ..() + if(isliving(target)) + tesla_zap(target, 3, 10000) + qdel(src) -/obj/item/projectile/energy/tesla_cannon/fire(setAngle) - if(firer) - chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY) - ..() +/obj/item/projectile/energy/tesla/cannon + name = "tesla orb" -/obj/item/projectile/energy/tesla_cannon/on_hit(atom/target) +/obj/item/projectile/energy/tesla/cannon/on_hit(atom/target) . = ..() - tesla_zap(src, 3, 10000, explosive = FALSE, stun_mobs = FALSE) + tesla_zap(target, 3, 10000, explosive = FALSE, stun_mobs = FALSE) qdel(src) - -/obj/item/projectile/energy/tesla_cannon/Destroy() - qdel(chain) - return ..() diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index da1eb90685..99056eb1dc 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -367,3 +367,9 @@ desc = "Creates and dispenses mutagen." dispensable_reagents = list("mutagen") emagged_reagents = list("plasma") + + +/obj/machinery/chem_dispenser/mutagensaltpeter + name = "mutagen and saltpeter dispenser" + desc = "Creates and dispenses mutagen and even saltpeter." + dispensable_reagents = list("mutagen", "saltpetre") diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index 2dbc0ff1c2..b929337a13 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -10,7 +10,7 @@ active_power_usage = 100 pass_flags = PASSTABLE resistance_flags = ACID_PROOF - var/operating = 0 + var/operating = FALSE var/obj/item/weapon/reagent_containers/beaker = null var/limit = 10 var/list/blend_items = list ( @@ -38,7 +38,7 @@ /obj/item/weapon/reagent_containers/food/snacks/grown/wheat = list("flour" = -5), /obj/item/weapon/reagent_containers/food/snacks/grown/oat = list("flour" = -5), /obj/item/weapon/reagent_containers/food/snacks/grown/rice = list("rice" = -5), - /obj/item/weapon/reagent_containers/food/snacks/donut/New = list("sprinkles" = -2, "sugar" = 1), + /obj/item/weapon/reagent_containers/food/snacks/donut = list("sprinkles" = -2, "sugar" = 1), /obj/item/weapon/reagent_containers/food/snacks/grown/cherries = list("cherryjelly" = 0), /obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries = list("bluecherryjelly" = 0), /obj/item/weapon/reagent_containers/food/snacks/egg = list("eggyolk" = -5), @@ -220,9 +220,12 @@ [processing_chamber]
[beaker_contents]
"} - if (is_beaker_ready && !is_chamber_empty && !(stat & (NOPOWER|BROKEN))) - dat += "Grind the reagents
" - dat += "Juice the reagents

" + if (is_beaker_ready) + if(!is_chamber_empty && !(stat & (NOPOWER|BROKEN))) + dat += "Grind the reagents
" + dat += "Juice the reagents

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

" if(holdingitems && holdingitems.len > 0) dat += "Eject the reagents
" if (beaker) @@ -248,6 +251,8 @@ grind() if("juice") juice() + if("mix") + mix() if("eject") eject() if ("detach") @@ -327,11 +332,11 @@ playsound(src.loc, 'sound/machines/juicer.ogg', 20, 1) var/offset = prob(50) ? -2 : 2 animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking - operating = 1 + operating = TRUE updateUsrDialog() spawn(50) pixel_x = initial(pixel_x) //return to its spot after shaking - operating = 0 + operating = FALSE updateUsrDialog() //Snacks @@ -365,11 +370,11 @@ playsound(src.loc, 'sound/machines/blender.ogg', 50, 1) var/offset = prob(50) ? -2 : 2 animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking - operating = 1 + operating = TRUE updateUsrDialog() spawn(60) pixel_x = initial(pixel_x) //return to its spot after shaking - operating = 0 + operating = FALSE updateUsrDialog() //Snacks and Plants @@ -467,3 +472,33 @@ break beaker.reagents.add_reagent(r_id, min(O.reagent_contents[r_id], space)) remove_object(O) + +/obj/machinery/reagentgrinder/proc/mix() + + //For butter and other things that would change upon shaking or mixing + power_change() + if(stat & (NOPOWER|BROKEN)) + return + if (!beaker) + return + playsound(src.loc, 'sound/machines/juicer.ogg', 20, 1) + var/offset = prob(50) ? -2 : 2 + animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 250) //start shaking + operating = TRUE + updateUsrDialog() + addtimer(CALLBACK(src, /obj/machinery/reagentgrinder/proc/mix_complete), 50) + +/obj/machinery/reagentgrinder/proc/mix_complete() + pixel_x = initial(pixel_x) //return to its spot after shaking + operating = FALSE + updateUsrDialog() + if (beaker.reagents.total_volume) + //Recipe to make Butter + while(beaker.reagents.get_reagent_amount("milk") >= 15) + beaker.reagents.remove_reagent("milk", 15) + new /obj/item/weapon/reagent_containers/food/snacks/butter(src.loc) + //Recipe to make Mayonnaise + if (beaker.reagents.has_reagent("eggyolk")) + var/amount = beaker.reagents.get_reagent_amount("eggyolk") + beaker.reagents.remove_reagent("eggyolk", amount) + beaker.reagents.add_reagent("mayonnaise", amount) \ No newline at end of file diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 23836e866d..31ec27fb79 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -966,7 +966,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Only for the experienced. You think you see sand floating in the glass." /datum/reagent/consumable/ethanol/bananahonk - name = "Banana Mama" + name = "Banana Honk" id = "bananahonk" description = "A drink from Clown Heaven." nutriment_factor = 1 * REAGENTS_METABOLISM diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm old mode 100644 new mode 100755 index 442772fea8..d2f78002a1 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -60,7 +60,10 @@ // data for nutriment is one or more (flavour -> ratio) // where all the ratio values adds up to 1 - var/list/taste_amounts = data.Copy() + var/list/taste_amounts = list() + if(data) + taste_amounts = data.Copy() + counterlist_scale(taste_amounts, volume) var/list/other_taste_amounts = newdata.Copy() @@ -513,17 +516,27 @@ /datum/reagent/consumable/honey name = "honey" id = "honey" - description = "Sweet sweet honey, decays into sugar." + description = "Sweet sweet honey, decays into sugar and has natural healing properties." color = "#d3a308" nutriment_factor = 15 * REAGENTS_METABOLISM + metabolization_rate = 1 * REAGENTS_METABOLISM taste_description = "sweetness" /datum/reagent/consumable/honey/on_mob_life(mob/living/M) M.reagents.add_reagent("sugar",3) - if(prob(20)) - M.heal_bodypart_damage(3,1) + if(prob(55)) + M.adjustBruteLoss(-1*REM, 0) + M.adjustFireLoss(-1*REM, 0) + M.adjustOxyLoss(-1*REM, 0) + M.adjustToxLoss(-1*REM, 0) ..() +/datum/reagent/consumable/mayonnaise + name = "Mayonnaise" + id = "mayonnaise" + description = "An white and oily mixture of mixed egg yolks." + color = "#DFDFDF" + taste_description = "mayonnaise" ////Lavaland Flora Reagents//// diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 500147d233..6d38e85ca8 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -347,10 +347,9 @@ /datum/reagent/medicine/mine_salve/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M) && M.stat != DEAD) if(method in list(INGEST, VAPOR, INJECT)) - M.Stun(4) - M.Weaken(4) + M.nutrition -= 5 if(show_message) - to_chat(M, "Your stomach agonizingly cramps!") + to_chat(M, "Your stomach feels empty and cramps!") else var/mob/living/carbon/C = M for(var/s in C.surgeries) @@ -962,8 +961,7 @@ /datum/reagent/medicine/antitoxin/on_mob_life(mob/living/M) M.adjustToxLoss(-2*REM, 0) for(var/datum/reagent/toxin/R in M.reagents.reagent_list) - if(R != src) - M.reagents.remove_reagent(R.id,1) + M.reagents.remove_reagent(R.id,1) ..() . = 1 diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index c25a1d050d..f359a1fc37 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -189,7 +189,7 @@ /datum/reagent/water/holywater/on_mob_life(mob/living/M) if(!data) data = 1 data++ - M.jitteriness = max(M.jitteriness-5,0) + M.jitteriness = min(M.jitteriness+4,10) if(data >= 30) // 12 units, 54 seconds @ metabolism 0.4 units & tick rate 1.8 sec if(!M.stuttering) M.stuttering = 1 @@ -212,9 +212,9 @@ SSticker.mode.remove_cultist(M.mind, 1, 1) else if(is_servant_of_ratvar(M)) remove_servant_of_ratvar(M) - holder.remove_reagent(id, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better?? M.jitteriness = 0 M.stuttering = 0 + holder.remove_reagent(id, volume) // maybe this is a little too perfect and a max() cap on the statuses would be better?? return holder.remove_reagent(id, 0.4) //fixed consumption to prevent balancing going out of whack @@ -658,7 +658,7 @@ taste_mult = 0 // apparently tasteless. /datum/reagent/mercury/on_mob_life(mob/living/M) - if(M.canmove && isspaceturf(M.loc)) + if(M.canmove && !isspaceturf(M.loc)) step(M, pick(GLOB.cardinal)) if(prob(5)) M.emote(pick("twitch","drool","moan")) @@ -738,7 +738,7 @@ taste_description = "metal" /datum/reagent/lithium/on_mob_life(mob/living/M) - if(M.canmove && isspaceturf(M.loc)) + if(M.canmove && !isspaceturf(M.loc)) step(M, pick(GLOB.cardinal)) if(prob(5)) M.emote(pick("twitch","drool","moan")) @@ -1110,8 +1110,9 @@ id = "nitrous_oxide" description = "A potent oxidizer used as fuel in rockets and as an anaesthetic during surgery." reagent_state = LIQUID + metabolization_rate = 1.5 * REAGENTS_METABOLISM color = "#808080" - taste_description = "numbness" + taste_description = "sweetness" /datum/reagent/nitrous_oxide/reaction_obj(obj/O, reac_volume) if((!O) || (!reac_volume)) @@ -1122,7 +1123,19 @@ if(istype(T)) T.atmos_spawn_air("n2o=[reac_volume/5];TEMP=[T20C]") - +/datum/reagent/nitrous_oxide/reaction_mob(mob/M, method=TOUCH, reac_volume) + if(method == VAPOR) + M.drowsyness += max(round(reac_volume, 1), 2) + +/datum/reagent/nitrous_oxide/on_mob_life(mob/living/M) + M.drowsyness += 2 + if(ishuman(M)) + var/mob/living/carbon/human/H = M + H.blood_volume = max(H.blood_volume - 2.5, 0) + if(prob(20)) + M.losebreath += 2 + M.confused = min(M.confused + 2, 5) + ..() /////////////////////////Coloured Crayon Powder//////////////////////////// //For colouring in /proc/mix_color_from_reagents @@ -1533,7 +1546,9 @@ /datum/reagent/romerol/on_mob_life(mob/living/carbon/human/H) // Silently add the zombie infection organ to be activated upon death - new /obj/item/organ/zombie_infection(H) + if(!H.getorganslot("zombie_infection")) + var/obj/item/organ/zombie_infection/ZI = new() + ZI.Insert(H) ..() /datum/reagent/growthserum @@ -1568,6 +1583,13 @@ M.update_transform() ..() +/datum/reagent/plastic_polymers + name = "plastic polymers" + id = "plastic_polymers" + description = "the petroleum based components of plastic." + color = "#f7eded" + taste_description = "plastic" + /datum/reagent/glitter name = "generic glitter" id = "glitter" diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 528124f84c..cedec9941b 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -648,6 +648,34 @@ M.losebreath += 5 return ..() +/datum/reagent/toxin/spewium + name = "Spewium" + id = "spewium" + description = "A powerful emetic, causes uncontrollable vomiting. May result in vomiting organs at high doses." + reagent_state = LIQUID + color = "#2f6617" //A sickly green color + metabolization_rate = REAGENTS_METABOLISM + overdose_threshold = 29 + toxpwr = 0 + taste_description = "vomit" + +/datum/reagent/toxin/spewium/on_mob_life(mob/living/M) + .=..() + if(current_cycle >=11 && prob(min(50,current_cycle)) && ishuman(M)) + var/mob/living/carbon/human/H = M + H.vomit(lost_nutrition = 10, blood = prob(10), stun = prob(50), distance = rand(0,4), message = TRUE, toxic = prob(30)) + for(var/datum/reagent/toxin/R in M.reagents.reagent_list) + if(R != src) + H.reagents.remove_reagent(R.id,1) + +/datum/reagent/toxin/spewium/overdose_process(mob/living/M) + . = ..() + if(current_cycle >=33 && prob(15) && ishuman(M)) + var/mob/living/carbon/human/H = M + H.spew_organ() + H.vomit(lost_nutrition = 0, blood = 1, stun = 1, distance = 4) + to_chat(H, "You feel something lumpy come up as you vomit.") + /datum/reagent/toxin/curare name = "Curare" id = "curare" diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm index 9e0bb2d0e4..c13ff096e4 100644 --- a/code/modules/reagents/chemistry/recipes.dm +++ b/code/modules/reagents/chemistry/recipes.dm @@ -36,12 +36,12 @@ var/atom/A = holder.my_atom var/turf/T = get_turf(A) var/area/my_area = get_area(T) - var/message = "A [reaction_name] reaction has occurred in [my_area.name]. (JMP)" + var/message = "A [reaction_name] reaction has occurred in [my_area.name] [ADMIN_COORDJMP(T)]" message += " (VV)" var/mob/M = get(A, /mob) if(M) - message += " - Carried By: [key_name_admin(M)](?) (FLW)" + message += " - Carried By: [ADMIN_LOOKUPFLW(M)]" else message += " - Last Fingerprint: [(A.fingerprintslast ? A.fingerprintslast : "N/A")]" diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm index 19bb28666d..0bc843a605 100644 --- a/code/modules/reagents/chemistry/recipes/others.dm +++ b/code/modules/reagents/chemistry/recipes/others.dm @@ -624,3 +624,14 @@ id = "laughter" results = list("laughter" = 10) // Fuck it. I'm not touching this one. required_reagents = list("sugar" = 1, "banana" = 1) + +/datum/chemical_reaction/plastic_polymers + name = "plastic polymers" + id = "plastic_polymers" + required_reagents = list("oil" = 5, "sodiumchloride" = 2, "ash" = 3) + required_temp = 374 //lazily consistent with soap & other crafted objects generically created with heat. + +/datum/chemical_reaction/plastic_polymers/on_reaction(datum/reagents/holder, created_volume) + var/location = get_turf(holder.my_atom) + for(var/i in 1 to 10) + new /obj/item/stack/sheet/plastic(location) diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 805aa936d4..6cfdd80cf5 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -6,6 +6,7 @@ /datum/chemical_reaction/reagent_explosion/on_reaction(datum/reagents/holder, created_volume) var/turf/T = get_turf(holder.my_atom) + var/area/A = get_area(T) var/inside_msg if(ismob(holder.my_atom)) var/mob/M = holder.my_atom @@ -14,9 +15,9 @@ var/touch_msg = "N/A" if(lastkey) var/mob/toucher = get_mob_by_key(lastkey) - touch_msg = "[key_name_admin(lastkey)]? (FLW)" - message_admins("Reagent explosion reaction occurred at [T.loc.name] (JMP)[inside_msg]. Last Fingerprint: [touch_msg].") - log_game("Reagent explosion reaction occurred at [T.loc.name] ([T.x],[T.y],[T.z]). Last Fingerprint: [lastkey ? lastkey : "N/A"]." ) + touch_msg = "[ADMIN_LOOKUPFLW(toucher)]" + message_admins("Reagent explosion reaction occurred at [A] [ADMIN_COORDJMP(T)][inside_msg]. Last Fingerprint: [touch_msg].") + log_game("Reagent explosion reaction occurred at [A] [COORD(T)]. Last Fingerprint: [lastkey ? lastkey : "N/A"]." ) var/datum/effect_system/reagents_explosion/e = new() e.set_up(modifier + round(created_volume/strengthdiv, 1), T, 0, 0) e.start() diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index a1c4a74795..f06dff50cf 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -437,13 +437,14 @@ /datum/chemical_reaction/slime/slimeexplosion/on_reaction(datum/reagents/holder) var/turf/T = get_turf(holder.my_atom) + var/area/A = get_area(T) var/lastkey = holder.my_atom.fingerprintslast var/touch_msg = "N/A" if(lastkey) var/mob/toucher = get_mob_by_key(lastkey) - touch_msg = "[key_name_admin(lastkey)]?(FLW)." - message_admins("Slime Explosion reaction started at [T.loc.name] (JMP). Last Fingerprint: [touch_msg]") - log_game("Slime Explosion reaction started at [T.loc.name] ([T.x],[T.y],[T.z]). Last Fingerprint: [lastkey ? lastkey : "N/A"].") + touch_msg = "[ADMIN_LOOKUPFLW(toucher)]." + message_admins("Slime Explosion reaction started at [A] [ADMIN_COORDJMP(T)]. Last Fingerprint: [touch_msg]") + log_game("Slime Explosion reaction started at [A] [COORD(T)]. Last Fingerprint: [lastkey ? lastkey : "N/A"].") T.visible_message("The slime extract begins to vibrate violently !") addtimer(CALLBACK(src, .proc/boom, holder), 50) var/obj/item/slime_extract/M = holder.my_atom @@ -477,26 +478,15 @@ ..() //Adamantine -/datum/chemical_reaction/slime/slimegolem - name = "Slime Golem" - id = "m_golem" +/datum/chemical_reaction/slime/adamantine + name = "Adamantine" + id = "adamantine" required_reagents = list("plasma" = 1) required_container = /obj/item/slime_extract/adamantine required_other = 1 -/datum/chemical_reaction/slime/slimegolem/on_reaction(datum/reagents/holder) - new /obj/effect/golemrune(get_turf(holder.my_atom)) - ..() - -/datum/chemical_reaction/slime/slimegolem2 - name = "Slime Golem 2" - id = "m_golem2" - required_reagents = list("iron" = 1) - required_container = /obj/item/slime_extract/adamantine - required_other = 1 - -/datum/chemical_reaction/slime/slimegolem2/on_reaction(datum/reagents/holder) - new /obj/item/golem_shell/artificial(get_turf(holder.my_atom)) +/datum/chemical_reaction/slime/adamantine/on_reaction(datum/reagents/holder) + new /obj/item/stack/sheet/mineral/adamantine(get_turf(holder.my_atom)) ..() //Bluespace diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm index a92c52abf4..37074b6d12 100644 --- a/code/modules/reagents/reagent_containers/bottle.dm +++ b/code/modules/reagents/reagent_containers/bottle.dm @@ -58,6 +58,12 @@ icon_state = "bottle12" list_reagents = list("cyanide" = 30) +/obj/item/weapon/reagent_containers/glass/bottle/spewium + name = "spewium bottle" + desc = "A small bottle of spewium." + icon_state = "bottle12" + list_reagents = list("spewium" = 30) + /obj/item/weapon/reagent_containers/glass/bottle/morphine name = "morphine bottle" desc = "A small bottle of morphine." diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm old mode 100644 new mode 100755 index 6ea2673004..d61217f006 --- a/code/modules/reagents/reagent_containers/glass.dm +++ b/code/modules/reagents/reagent_containers/glass.dm @@ -155,6 +155,12 @@ filling.color = mix_color_from_reagents(reagents.reagent_list) add_overlay(filling) +/obj/item/weapon/reagent_containers/glass/beaker/jar + name = "honey jar" + desc = "A jar for honey. It can hold up to 50 units of sweet delight." + icon = 'icons/obj/chemical.dmi' + icon_state = "vapour" + /obj/item/weapon/reagent_containers/glass/beaker/large name = "large beaker" desc = "A large beaker. Can hold up to 100 units." diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 34d422da92..92e01f4824 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -48,15 +48,16 @@ user.changeNext_move(CLICK_CD_RANGE*2) user.newtonian_move(get_dir(A, user)) var/turf/T = get_turf(src) + var/area/area = get_area(src) if(reagents.has_reagent("sacid")) - message_admins("[key_name_admin(user)] fired sulphuric acid from \a [src] at ([get_area(src)] ([T.x], [T.y], [T.z])).") - log_game("[key_name(user)] fired sulphuric acid from \a [src] at [get_area(src)] ([T.x], [T.y], [T.z]).") + message_admins("[ADMIN_LOOKUPFLW(user)] fired sulphuric acid from \a [src] at [area] [ADMIN_COORDJMP(T)].") + log_game("[key_name(user)] fired sulphuric acid from \a [src] at [area] ([T.x], [T.y], [T.z]).") if(reagents.has_reagent("facid")) - message_admins("[key_name_admin(user)] fired Fluacid from \a [src] at ([get_area(src)] ([T.x], [T.y], [T.z])).") - log_game("[key_name(user)] fired Fluacid from \a [src] at [get_area(src)] ([T.x], [T.y], [T.z]).") + message_admins("[ADMIN_LOOKUPFLW(user)] fired Fluacid from \a [src] at [area] [ADMIN_COORDJMP(T)].") + log_game("[key_name(user)] fired Fluacid from \a [src] at [area] [COORD(T)].") if(reagents.has_reagent("lube")) - message_admins("[key_name_admin(user)] fired Space lube from \a [src] at ([get_area(src)] ([T.x], [T.y], [T.z])).") - log_game("[key_name(user)] fired Space lube from \a [src] at [get_area(src)] ([T.x], [T.y], [T.z]).") + message_admins("[ADMIN_LOOKUPFLW(user)] fired Space lube from \a [src] at [area] [ADMIN_COORDJMP(T)].") + log_game("[key_name(user)] fired Space lube from \a [src] at [area] [COORD(T)].") return diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 15d8e5e80c..54984227ad 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -47,7 +47,7 @@ other types of metals and chemistry for reagents). //////////////////////////////////////// /obj/item/weapon/disk/design_disk - name = "component design disk" + name = "Component Design Disk" desc = "A disk for storing device design data for construction in lathes." icon_state = "datadisk1" materials = list(MAT_METAL=300, MAT_GLASS=100) @@ -62,7 +62,7 @@ other types of metals and chemistry for reagents). blueprints += null /obj/item/weapon/disk/design_disk/adv - name = "advanced component design disk" + name = "Advanced Component Design Disk" desc = "A disk for storing device design data for construction in lathes. This one has extra storage space." materials = list(MAT_METAL=300, MAT_GLASS=100, MAT_SILVER = 50) max_blueprints = 5 @@ -587,7 +587,7 @@ other types of metals and chemistry for reagents). category = list("Equipment") /datum/design/diskplantgene - name = "Plant data disk" + name = "Plant Data Disk" desc = "A disk for storing plant genetic data." id = "diskplantgene" req_tech = list("programming" = 4, "biotech" = 3) @@ -595,7 +595,7 @@ other types of metals and chemistry for reagents). materials = list(MAT_METAL=200, MAT_GLASS=100) build_path = /obj/item/weapon/disk/plantgene category = list("Electronics") - + ///////////////////////////////////////// ////////////Janitor Designs////////////// ///////////////////////////////////////// diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index 9f2fbda1f3..7fbc8309a8 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -11,7 +11,7 @@ category = list("initial","Tools") /datum/design/crowbar - name = "Pocket crowbar" + name = "Pocket Crowbar" id = "crowbar" build_type = AUTOLATHE materials = list(MAT_METAL = 50) @@ -27,7 +27,7 @@ category = list("initial","Tools") /datum/design/extinguisher - name = "Fire extinguisher" + name = "Fire Extinguisher" id = "extinguisher" build_type = AUTOLATHE materials = list(MAT_METAL = 90) @@ -51,7 +51,7 @@ category = list("initial","Tools") /datum/design/tscanner - name = "T-ray scanner" + name = "T-Ray Scanner" id = "tscanner" build_type = AUTOLATHE materials = list(MAT_METAL = 150) @@ -59,7 +59,7 @@ category = list("initial","Tools") /datum/design/weldingtool - name = "Welding tool" + name = "Welding Tool" id = "welding_tool" build_type = AUTOLATHE materials = list(MAT_METAL = 70, MAT_GLASS = 20) @@ -67,7 +67,7 @@ category = list("initial","Tools") /datum/design/mini_weldingtool - name = "Emergency welding tool" + name = "Emergency Welding Tool" id = "mini_welding_tool" build_type = AUTOLATHE materials = list(MAT_METAL = 30, MAT_GLASS = 10) @@ -99,7 +99,7 @@ category = list("initial","Tools") /datum/design/welding_helmet - name = "Welding helmet" + name = "Welding Helmet" id = "welding_helmet" build_type = AUTOLATHE materials = list(MAT_METAL = 1750, MAT_GLASS = 400) @@ -107,7 +107,7 @@ category = list("initial","Tools") /datum/design/cable_coil - name = "Cable coil" + name = "Cable Coil" id = "cable_coil" build_type = AUTOLATHE materials = list(MAT_METAL = 10, MAT_GLASS = 5) @@ -124,7 +124,7 @@ category = list("initial","Tools") /datum/design/console_screen - name = "Console screen" + name = "Console Screen" id = "console_screen" build_type = AUTOLATHE materials = list(MAT_GLASS = 200) @@ -132,7 +132,7 @@ category = list("initial", "Electronics") /datum/design/apc_board - name = "APC module" + name = "APC Module" id = "power control" build_type = AUTOLATHE materials = list(MAT_METAL = 100, MAT_GLASS = 100) @@ -140,7 +140,7 @@ category = list("initial", "Electronics") /datum/design/airlock_board - name = "Airlock electronics" + name = "Airlock Electronics" id = "airlock_board" build_type = AUTOLATHE materials = list(MAT_METAL = 50, MAT_GLASS = 50) @@ -148,7 +148,7 @@ category = list("initial", "Electronics") /datum/design/firelock_board - name = "Firelock circuitry" + name = "Firelock Circuitry" id = "firelock_board" build_type = AUTOLATHE materials = list(MAT_METAL = 50, MAT_GLASS = 50) @@ -156,7 +156,7 @@ category = list("initial", "Electronics") /datum/design/airalarm_electronics - name = "Air alarm electronics" + name = "Air Alarm Electronics" id = "airalarm_electronics" build_type = AUTOLATHE materials = list(MAT_METAL = 50, MAT_GLASS = 50) @@ -164,7 +164,7 @@ category = list("initial", "Electronics") /datum/design/firealarm_electronics - name = "Fire alarm electronics" + name = "Fire Alarm Electronics" id = "firealarm_electronics" build_type = AUTOLATHE materials = list(MAT_METAL = 50, MAT_GLASS = 50) @@ -180,7 +180,7 @@ category = list("initial", "Misc") /datum/design/pipe_painter - name = "Pipe painter" + name = "Pipe Painter" id = "pipe_painter" build_type = AUTOLATHE materials = list(MAT_METAL = 5000, MAT_GLASS = 2000) @@ -188,7 +188,7 @@ category = list("initial", "Misc") /datum/design/airlock_painter - name = "Airlock painter" + name = "Airlock Painter" id = "airlock_painter" build_type = AUTOLATHE materials = list(MAT_METAL = 50, MAT_GLASS = 50) @@ -214,7 +214,7 @@ maxstack = 50 /datum/design/rglass - name = "Reinforced glass" + name = "Reinforced Glass" id = "rglass" build_type = AUTOLATHE materials = list(MAT_METAL = 1000, MAT_GLASS = MINERAL_MATERIAL_AMOUNT) @@ -223,7 +223,7 @@ maxstack = 50 /datum/design/rods - name = "Metal rod" + name = "Metal Rod" id = "rods" build_type = AUTOLATHE materials = list(MAT_METAL = 1000) @@ -232,7 +232,7 @@ maxstack = 50 /datum/design/rcd_ammo - name = "Compressed matter cardridge" + name = "Compressed Matter Cartridge" id = "rcd_ammo" build_type = AUTOLATHE materials = list(MAT_METAL = 3000, MAT_GLASS=2000) @@ -240,7 +240,7 @@ category = list("initial","Construction") /datum/design/kitchen_knife - name = "Kitchen knife" + name = "Kitchen Knife" id = "kitchen_knife" build_type = AUTOLATHE materials = list(MAT_METAL = 12000) @@ -272,7 +272,7 @@ category = list("initial","Dinnerware") /datum/design/drinking_glass - name = "Drinking glass" + name = "Drinking Glass" id = "drinking_glass" build_type = AUTOLATHE materials = list(MAT_GLASS = 500) @@ -280,7 +280,7 @@ category = list("initial","Dinnerware") /datum/design/shot_glass - name = "Shot glass" + name = "Shot Glass" id = "shot_glass" build_type = AUTOLATHE materials = list(MAT_GLASS = 100) @@ -304,7 +304,7 @@ category = list("initial","Misc") /datum/design/plant_analyzer - name = "Plant analyzer" + name = "Plant Analyzer" id = "plant_analyzer" build_type = AUTOLATHE materials = list(MAT_METAL = 30, MAT_GLASS = 20) @@ -344,7 +344,7 @@ category = list("initial", "Medical") /datum/design/circular_saw - name = "Circular saw" + name = "Circular Saw" id = "circular_saw" build_type = AUTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 6000) @@ -352,7 +352,7 @@ category = list("initial", "Medical") /datum/design/surgicaldrill - name = "Surgical drill" + name = "Surgical Drill" id = "surgicaldrill" build_type = AUTOLATHE materials = list(MAT_METAL = 10000, MAT_GLASS = 6000) @@ -392,7 +392,7 @@ category = list("initial", "Medical") /datum/design/large_beaker - name = "Large beaker" + name = "Large Beaker" id = "large_beaker" build_type = AUTOLATHE materials = list(MAT_GLASS = 2500) @@ -408,7 +408,7 @@ category = list("initial", "Medical") /datum/design/beanbag_slug - name = "Beanbag slug" + name = "Beanbag Slug" id = "beanbag_slug" build_type = AUTOLATHE materials = list(MAT_METAL = 250) @@ -416,7 +416,7 @@ category = list("initial", "Security") /datum/design/rubbershot - name = "Rubber shot" + name = "Rubber Shot" id = "rubber_shot" build_type = AUTOLATHE materials = list(MAT_METAL = 4000) @@ -424,7 +424,7 @@ category = list("initial", "Security") /datum/design/c38 - name = "Speed loader (.38)" + name = "Speed Loader (.38)" id = "c38" build_type = AUTOLATHE materials = list(MAT_METAL = 30000) @@ -432,7 +432,7 @@ category = list("initial", "Security") /datum/design/recorder - name = "Universal recorder" + name = "Universal Recorder" id = "recorder" build_type = AUTOLATHE materials = list(MAT_METAL = 60, MAT_GLASS = 30) @@ -456,7 +456,7 @@ category = list("initial", "Misc") /datum/design/signaler - name = "Remote signaling device" + name = "Remote Signaling Device" id = "signaler" build_type = AUTOLATHE materials = list(MAT_METAL = 400, MAT_GLASS = 120) @@ -464,7 +464,7 @@ category = list("initial", "T-Comm") /datum/design/radio_headset - name = "Radio headset" + name = "Radio Headset" id = "radio_headset" build_type = AUTOLATHE materials = list(MAT_METAL = 75) @@ -472,7 +472,7 @@ category = list("initial", "T-Comm") /datum/design/bounced_radio - name = "Station bounced radio" + name = "Station Bounced Radio" id = "bounced_radio" build_type = AUTOLATHE materials = list(MAT_METAL = 75, MAT_GLASS = 25) @@ -480,7 +480,7 @@ category = list("initial", "T-Comm") /datum/design/infrared_emitter - name = "Infrared emitter" + name = "Infrared Emitter" id = "infrared_emitter" build_type = AUTOLATHE materials = list(MAT_METAL = 1000, MAT_GLASS = 500) @@ -488,7 +488,7 @@ category = list("initial", "Misc") /datum/design/health_sensor - name = "Health sensor" + name = "Health Sensor" id = "health_sensor" build_type = AUTOLATHE materials = list(MAT_METAL = 800, MAT_GLASS = 200) @@ -504,7 +504,7 @@ category = list("initial", "Misc") /datum/design/voice_analyser - name = "Voice analyser" + name = "Voice Analyser" id = "voice_analyser" build_type = AUTOLATHE materials = list(MAT_METAL = 500, MAT_GLASS = 50) @@ -512,7 +512,7 @@ category = list("initial", "Misc") /datum/design/light_tube - name = "Light tube" + name = "Light Tube" id = "light_tube" build_type = AUTOLATHE materials = list(MAT_GLASS = 100) @@ -520,7 +520,7 @@ category = list("initial", "Construction") /datum/design/light_bulb - name = "Light bulb" + name = "Light Bulb" id = "light_bulb" build_type = AUTOLATHE materials = list(MAT_GLASS = 100) @@ -528,7 +528,7 @@ category = list("initial", "Construction") /datum/design/camera_assembly - name = "Camera assembly" + name = "Camera Assembly" id = "camera_assembly" build_type = AUTOLATHE materials = list(MAT_METAL = 400, MAT_GLASS = 250) @@ -536,7 +536,7 @@ category = list("initial", "Construction") /datum/design/newscaster_frame - name = "Newscaster frame" + name = "Newscaster Frame" id = "newscaster_frame" build_type = AUTOLATHE materials = list(MAT_METAL = 14000, MAT_GLASS = 8000) @@ -552,7 +552,7 @@ category = list("initial", "Medical") /datum/design/prox_sensor - name = "Proximity sensor" + name = "Proximity Sensor" id = "prox_sensor" build_type = AUTOLATHE materials = list(MAT_METAL = 800, MAT_GLASS = 200) @@ -577,7 +577,7 @@ category = list("hacked", "Weapons and ammo") /datum/design/rcd - name = "Rapid construction device (RCD)" + name = "Rapid Construction Device (RCD)" id = "rcd" build_type = AUTOLATHE materials = list(MAT_METAL = 30000) @@ -585,7 +585,7 @@ category = list("hacked", "Construction") /datum/design/rpd - name = "Rapid pipe dispenser (RPD)" + name = "Rapid Pipe Dispenser (RPD)" id = "rpd" build_type = AUTOLATHE materials = list(MAT_METAL = 75000, MAT_GLASS = 37500) @@ -601,7 +601,7 @@ category = list("hacked", "Tools") /datum/design/large_welding_tool - name = "Industrial welding tool" + name = "Industrial Welding Tool" id = "large_welding_tool" build_type = AUTOLATHE materials = list(MAT_METAL = 70, MAT_GLASS = 60) @@ -625,7 +625,7 @@ category = list("hacked", "Security") /datum/design/shotgun_slug - name = "Shotgun slug" + name = "Shotgun Slug" id = "shotgun_slug" build_type = AUTOLATHE materials = list(MAT_METAL = 4000) @@ -633,7 +633,7 @@ category = list("hacked", "Security") /datum/design/buckshot_shell - name = "Buckshot shell" + name = "Buckshot Shell" id = "buckshot_shell" build_type = AUTOLATHE materials = list(MAT_METAL = 4000) @@ -641,7 +641,7 @@ category = list("hacked", "Security") /datum/design/shotgun_dart - name = "Shotgun dart" + name = "Shotgun Dart" id = "shotgun_dart" build_type = AUTOLATHE materials = list(MAT_METAL = 4000) @@ -649,7 +649,7 @@ category = list("hacked", "Security") /datum/design/incendiary_slug - name = "Incendiary slug" + name = "Incendiary Slug" id = "incendiary_slug" build_type = AUTOLATHE materials = list(MAT_METAL = 4000) @@ -657,7 +657,7 @@ category = list("hacked", "Security") /datum/design/riot_dart - name = "Foam riot dart" + name = "Foam Riot Dart" id = "riot_dart" build_type = AUTOLATHE materials = list(MAT_METAL = 1000) //Discount for making individually - no box = less metal! @@ -665,7 +665,7 @@ category = list("hacked", "Security") /datum/design/riot_darts - name = "Foam riot dart box" + name = "Foam Riot Dart Box" id = "riot_darts" build_type = AUTOLATHE materials = list(MAT_METAL = 50000) //Comes with 40 darts @@ -673,7 +673,7 @@ category = list("hacked", "Security") /datum/design/a357 - name = "Ammo box (.357)" + name = "Ammo Box (.357)" id = "a357" build_type = AUTOLATHE materials = list(MAT_METAL = 30000) @@ -681,7 +681,7 @@ category = list("hacked", "Security") /datum/design/c10mm - name = "Ammo box (10mm)" + name = "Ammo Box (10mm)" id = "c10mm" build_type = AUTOLATHE materials = list(MAT_METAL = 30000) @@ -689,7 +689,7 @@ category = list("hacked", "Security") /datum/design/c45 - name = "Ammo box (.45)" + name = "Ammo Box (.45)" id = "c45" build_type = AUTOLATHE materials = list(MAT_METAL = 30000) @@ -697,7 +697,7 @@ category = list("hacked", "Security") /datum/design/c9mm - name = "Ammo box (9mm)" + name = "Ammo Box (9mm)" id = "c9mm" build_type = AUTOLATHE materials = list(MAT_METAL = 30000) @@ -705,7 +705,7 @@ category = list("hacked", "Security") /datum/design/cleaver - name = "Butcher's cleaver" + name = "Butcher's Cleaver" id = "cleaver" build_type = AUTOLATHE materials = list(MAT_METAL = 18000) @@ -721,7 +721,7 @@ category = list("initial", "Tools") /datum/design/desttagger - name = "Destination tagger" + name = "Destination Tagger" id = "desttagger" build_type = AUTOLATHE materials = list(MAT_METAL = 250, MAT_GLASS = 125) @@ -729,7 +729,7 @@ category = list("initial", "Electronics") /datum/design/handlabeler - name = "Hand labeler" + name = "Hand Labeler" id = "handlabel" build_type = AUTOLATHE materials = list(MAT_METAL = 150, MAT_GLASS = 125) @@ -737,7 +737,7 @@ category = list("initial", "Electronics") /datum/design/geiger - name = "Geiger counter" + name = "Geiger Counter" id = "geigercounter" build_type = AUTOLATHE materials = list(MAT_METAL = 150, MAT_GLASS = 150) @@ -745,7 +745,7 @@ category = list("initial", "Tools") /datum/design/turret_control_frame - name = "Turret control frame" + name = "Turret Control Frame" id = "turret_control" build_type = AUTOLATHE materials = list(MAT_METAL = 12000) @@ -753,7 +753,7 @@ category = list("initial", "Construction") /datum/design/conveyor_belt - name = "Conveyor belt" + name = "Conveyor Belt" id = "conveyor_belt" build_type = AUTOLATHE materials = list(MAT_METAL = 5000) @@ -761,7 +761,7 @@ category = list("initial", "Construction") /datum/design/conveyor_switch - name = "Conveyor belt switch" + name = "Conveyor Belt Switch" id = "conveyor_switch" build_type = AUTOLATHE materials = list(MAT_METAL = 450, MAT_GLASS = 190) @@ -783,3 +783,12 @@ materials = list(MAT_METAL = 2000, MAT_GLASS = 1000) build_path = /obj/item/device/modular_computer/tablet category = list("initial","Misc") + +/datum/design/slime_scanner + name = "Slime Scanner" + id = "slime_scanner" + build_type = AUTOLATHE + materials = list(MAT_METAL = 300, MAT_GLASS = 200) + build_path = /obj/item/device/slime_scanner + category = list("initial", "Misc") + \ No newline at end of file diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm index d293101229..af1d942e90 100644 --- a/code/modules/research/designs/biogenerator_designs.dm +++ b/code/modules/research/designs/biogenerator_designs.dm @@ -3,7 +3,7 @@ /////////////////////////////////// /datum/design/milk - name = "10 milk" + name = "10 Milk" id = "milk" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 20) @@ -11,7 +11,7 @@ category = list("initial","Food") /datum/design/cream - name = "10 cream" + name = "10 Cream" id = "cream" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 30) @@ -19,7 +19,7 @@ category = list("initial","Food") /datum/design/milk_carton - name = "Milk carton" + name = "Milk Carton" id = "milk_carton" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 100) @@ -27,7 +27,7 @@ category = list("initial","Food") /datum/design/cream_carton - name = "Cream carton" + name = "Cream Carton" id = "cream_carton" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 300) @@ -35,7 +35,7 @@ category = list("initial","Food") /datum/design/black_pepper - name = "10u black pepper" + name = "10u Black Pepper" id = "black_pepper" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 25) @@ -43,7 +43,7 @@ category = list("initial","Food") /datum/design/pepper_mill - name = "Pepper mill" + name = "Pepper Mill" id = "pepper_mill" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 50) @@ -52,7 +52,7 @@ category = list("initial","Food") /datum/design/monkey_cube - name = "Monkey cube" + name = "Monkey Cube" id = "mcube" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 250) @@ -60,7 +60,7 @@ category = list("initial", "Food") /datum/design/ez_nut - name = "E-Z-Nutrient" + name = "E-Z Nutrient" id = "ez_nut" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 10) @@ -108,7 +108,7 @@ category = list("initial", "Botany Chemicals") /datum/design/cloth - name = "Roll of cloth" + name = "Roll of Cloth" id = "cloth" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 50) @@ -124,7 +124,7 @@ category = list("initial","Leather and Cloth") /datum/design/botany_gloves - name = "Botanical gloves" + name = "Botanical Gloves" id = "botany_gloves" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 150) @@ -140,7 +140,7 @@ category = list("initial","Leather and Cloth") /datum/design/secbelt - name = "Security belt" + name = "Security Belt" id = "secbelt" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 300) @@ -148,7 +148,7 @@ category = list("initial","Leather and Cloth") /datum/design/medbelt - name = "Medical belt" + name = "Medical Belt" id = "medbel" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 300) @@ -156,7 +156,7 @@ category = list("initial","Leather and Cloth") /datum/design/janibelt - name = "Janitorial belt" + name = "Janitorial Belt" id = "janibelt" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 300) @@ -164,7 +164,7 @@ category = list("initial","Leather and Cloth") /datum/design/bandolier - name = "Bandolier belt" + name = "Bandolier Belt" id = "bandolier" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 300) @@ -172,7 +172,7 @@ category = list("initial","Leather and Cloth") /datum/design/s_holster - name = "Shoulder holster" + name = "Shoulder Holster" id = "s_holster" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 400) @@ -180,7 +180,7 @@ category = list("initial","Leather and Cloth") /datum/design/leather_satchel - name = "Leather satchel" + name = "Leather Satchel" id = "leather_satchel" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 400) @@ -188,7 +188,7 @@ category = list("initial","Leather and Cloth") /datum/design/leather_jacket - name = "Leather jacket" + name = "Leather Jacket" id = "leather_jacket" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 500) @@ -196,7 +196,7 @@ category = list("initial","Leather and Cloth") /datum/design/leather_overcoat - name = "Leather overcoat" + name = "Leather Overcoat" id = "leather_overcoat" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 1000) @@ -204,7 +204,7 @@ category = list("initial","Leather and Cloth") /datum/design/rice_hat - name = "Rice hat" + name = "Rice Hat" id = "rice_hat" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 300) diff --git a/code/modules/research/designs/computer_part_designs.dm b/code/modules/research/designs/computer_part_designs.dm index cd75eada7a..dbdd15817c 100644 --- a/code/modules/research/designs/computer_part_designs.dm +++ b/code/modules/research/designs/computer_part_designs.dm @@ -3,7 +3,7 @@ //////////////////////////////////////// /datum/design/disk/normal - name = "hard disk drive" + name = "Hard Disk Drive" id = "hdd_basic" req_tech = list("programming" = 1, "engineering" = 1) build_type = PROTOLATHE @@ -12,7 +12,7 @@ category = list("Computer Parts") /datum/design/disk/advanced - name = "advanced hard disk drive" + name = "Advanced Hard Disk Drive" id = "hdd_advanced" req_tech = list("programming" = 2, "engineering" = 2) build_type = PROTOLATHE @@ -21,7 +21,7 @@ category = list("Computer Parts") /datum/design/disk/super - name = "super hard disk drive" + name = "Super Hard Disk Drive" id = "hdd_super" req_tech = list("programming" = 3, "engineering" = 3) build_type = PROTOLATHE @@ -30,7 +30,7 @@ category = list("Computer Parts") /datum/design/disk/cluster - name = "cluster hard disk drive" + name = "Cluster Hard Disk Drive" id = "hdd_cluster" req_tech = list("programming" = 4, "engineering" = 4) build_type = PROTOLATHE @@ -39,7 +39,7 @@ category = list("Computer Parts") /datum/design/disk/small - name = "solid state drive" + name = "Solid State Drive" id = "ssd_small" req_tech = list("programming" = 2, "engineering" = 2) build_type = PROTOLATHE @@ -48,7 +48,7 @@ category = list("Computer Parts") /datum/design/disk/micro - name = "micro solid state drive" + name = "Micro Solid State Drive" id = "ssd_micro" req_tech = list("programming" = 1, "engineering" = 1) build_type = PROTOLATHE @@ -59,7 +59,7 @@ // Network cards /datum/design/netcard/basic - name = "network card" + name = "Network Card" id = "netcard_basic" req_tech = list("programming" = 2, "engineering" = 1) build_type = IMPRINTER @@ -69,7 +69,7 @@ category = list("Computer Parts") /datum/design/netcard/advanced - name = "advanced network card" + name = "Advanced Network Card" id = "netcard_advanced" req_tech = list("programming" = 4, "engineering" = 2) build_type = IMPRINTER @@ -79,7 +79,7 @@ category = list("Computer Parts") /datum/design/netcard/wired - name = "wired network card" + name = "Wired Network Card" id = "netcard_wired" req_tech = list("programming" = 5, "engineering" = 3) build_type = IMPRINTER @@ -91,7 +91,7 @@ // Data disks /datum/design/portabledrive/basic - name = "data disk" + name = "Data Disk" id = "portadrive_basic" req_tech = list("programming" = 1) build_type = IMPRINTER @@ -101,7 +101,7 @@ category = list("Computer Parts") /datum/design/portabledrive/advanced - name = "advanced data disk" + name = "Advanced Data Disk" id = "portadrive_advanced" req_tech = list("programming" = 2) build_type = IMPRINTER @@ -111,7 +111,7 @@ category = list("Computer Parts") /datum/design/portabledrive/super - name = "super data disk" + name = "Super Data Disk" id = "portadrive_super" req_tech = list("programming" = 4) build_type = IMPRINTER @@ -123,7 +123,7 @@ // Card slot /datum/design/cardslot - name = "ID card slot" + name = "ID Card Slot" id = "cardslot" req_tech = list("programming" = 2) build_type = PROTOLATHE @@ -133,7 +133,7 @@ // Intellicard slot /datum/design/aislot - name = "Intellicard slot" + name = "Intellicard Slot" id = "aislot" req_tech = list("programming" = 2) build_type = PROTOLATHE @@ -143,7 +143,7 @@ // Mini printer /datum/design/miniprinter - name = "miniprinter" + name = "Miniprinter" id = "miniprinter" req_tech = list("programming" = 2, "engineering" = 2) build_type = PROTOLATHE @@ -154,7 +154,7 @@ // APC Link /datum/design/APClink - name = "area power connector" + name = "Area Power Connector" id = "APClink" req_tech = list("programming" = 2, "powerstorage" = 3, "engineering" = 2) build_type = PROTOLATHE @@ -165,7 +165,7 @@ // Batteries /datum/design/battery/controller - name = "power cell controller" + name = "Power Cell Controller" id = "bat_control" req_tech = list("powerstorage" = 1, "engineering" = 1) build_type = PROTOLATHE @@ -174,7 +174,7 @@ category = list("Computer Parts") /datum/design/battery/normal - name = "battery module" + name = "Battery Module" id = "bat_normal" req_tech = list("powerstorage" = 1, "engineering" = 1) build_type = PROTOLATHE @@ -183,7 +183,7 @@ category = list("Computer Parts") /datum/design/battery/advanced - name = "advanced battery module" + name = "Advanced Battery Module" id = "bat_advanced" req_tech = list("powerstorage" = 2, "engineering" = 2) build_type = PROTOLATHE @@ -192,7 +192,7 @@ category = list("Computer Parts") /datum/design/battery/super - name = "super battery module" + name = "Super Battery Module" id = "bat_super" req_tech = list("powerstorage" = 3, "engineering" = 3) build_type = PROTOLATHE @@ -201,7 +201,7 @@ category = list("Computer Parts") /datum/design/battery/nano - name = "nano battery module" + name = "Nano Battery Module" id = "bat_nano" req_tech = list("powerstorage" = 1, "engineering" = 1) build_type = PROTOLATHE @@ -210,7 +210,7 @@ category = list("Computer Parts") /datum/design/battery/micro - name = "micro battery module" + name = "Micro Battery Module" id = "bat_micro" req_tech = list("powerstorage" = 2, "engineering" = 2) build_type = PROTOLATHE @@ -221,7 +221,7 @@ // Processor unit /datum/design/cpu - name = "processor board" + name = "Processor Board" id = "cpu_normal" req_tech = list("programming" = 3, "engineering" = 2) build_type = IMPRINTER @@ -231,7 +231,7 @@ category = list("Computer Parts") /datum/design/cpu/small - name = "microprocessor" + name = "Microprocessor" id = "cpu_small" req_tech = list("programming" = 2, "engineering" = 2) build_type = IMPRINTER @@ -241,7 +241,7 @@ category = list("Computer Parts") /datum/design/cpu/photonic - name = "photonic processor board" + name = "Photonic Processor Board" id = "pcpu_normal" req_tech = list("programming" = 5, "engineering" = 4) build_type = IMPRINTER @@ -251,7 +251,7 @@ category = list("Computer Parts") /datum/design/cpu/photonic/small - name = "photonic microprocessor" + name = "Photonic Microprocessor" id = "pcpu_small" req_tech = list("programming" = 4, "engineering" = 3) build_type = IMPRINTER diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 002112b717..f72458af4e 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -96,7 +96,7 @@ category = list("Medical Designs") /datum/design/bluespacebodybag - name = "Bluespace body bag" + name = "Bluespace Body Bag" desc = "A bluespace body bag, powered by experimental bluespace technology. It can hold loads of bodies and the largest of creatures." id = "bluespacebodybag" req_tech = list("bluespace" = 5, "materials" = 4, "plasmatech" = 4) @@ -106,7 +106,7 @@ category = list("Medical Designs") /datum/design/plasmarefiller - name = "Plasma-man jumpsuit refill" + name = "Plasma-Man Jumpsuit Refill" desc = "A refill pack for the auto-extinguisher on Plasma-man suits." id = "plasmarefiller" req_tech = list("materials" = 2, "plasmatech" = 3) //Why did this have no plasmatech @@ -191,7 +191,7 @@ category = list("Misc", "Medical Designs") /datum/design/cyberimp_breather - name = "Breathing Tube implant" + name = "Breathing Tube Implant" desc = "This simple implant adds an internals connector to your back, allowing you to use internals without a mask and protecting you from being choked." id = "ci-breather" req_tech = list("materials" = 2, "biotech" = 3) @@ -202,7 +202,7 @@ category = list("Misc", "Medical Designs") /datum/design/cyberimp_toolset - name = "Toolset Arm implant" + name = "Toolset Arm Implant" desc = "A stripped-down version of engineering cyborg toolset, designed to be installed on subject's arm." id = "ci-toolset" req_tech = list("materials" = 3, "engineering" = 4, "biotech" = 4, "powerstorage" = 4) @@ -213,7 +213,7 @@ category = list("Misc", "Medical Designs") /datum/design/cyberimp_medical_hud - name = "Medical HUD implant" + name = "Medical HUD Implant" desc = "These cybernetic eyes will display a medical HUD over everything you see. Wiggle eyes to control." id = "ci-medhud" req_tech = list("materials" = 5, "programming" = 4, "biotech" = 4) @@ -224,7 +224,7 @@ category = list("Misc", "Medical Designs") /datum/design/cyberimp_security_hud - name = "Security HUD implant" + name = "Security HUD Implant" desc = "These cybernetic eyes will display a security HUD over everything you see. Wiggle eyes to control." id = "ci-sechud" req_tech = list("materials" = 5, "programming" = 4, "biotech" = 4, "combat" = 3) @@ -235,7 +235,7 @@ category = list("Misc", "Medical Designs") /datum/design/cyberimp_xray - name = "X-Ray eyes" + name = "X-Ray Eyes" desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile." id = "ci-xray" req_tech = list("materials" = 7, "programming" = 5, "biotech" = 7, "magnets" = 5,"plasmatech" = 6) @@ -246,7 +246,7 @@ category = list("Misc", "Medical Designs") /datum/design/cyberimp_thermals - name = "Thermal eyes" + name = "Thermal Eyes" desc = "These cybernetic eyes will give you Thermal vision. Vertical slit pupil included." id = "ci-thermals" req_tech = list("materials" = 6, "programming" = 4, "biotech" = 7, "magnets" = 5,"plasmatech" = 4) @@ -257,7 +257,7 @@ category = list("Misc", "Medical Designs") /datum/design/cyberimp_antidrop - name = "Anti-Drop implant" + name = "Anti-Drop Implant" desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping. Twitch ear to toggle." id = "ci-antidrop" req_tech = list("materials" = 5, "programming" = 6, "biotech" = 5) @@ -268,7 +268,7 @@ category = list("Misc", "Medical Designs") /datum/design/cyberimp_antistun - name = "CNS Rebooter implant" + name = "CNS Rebooter Implant" desc = "This implant will automatically give you back control over your central nervous system, reducing downtime when stunned." id = "ci-antistun" req_tech = list("materials" = 6, "programming" = 5, "biotech" = 6) @@ -279,7 +279,7 @@ category = list("Misc", "Medical Designs") /datum/design/cyberimp_nutriment - name = "Nutriment pump implant" + name = "Nutriment Pump Implant" desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving." id = "ci-nutriment" req_tech = list("materials" = 3, "powerstorage" = 4, "biotech" = 3) @@ -290,7 +290,7 @@ category = list("Misc", "Medical Designs") /datum/design/cyberimp_nutriment_plus - name = "Nutriment pump implant PLUS" + name = "Nutriment Pump Implant PLUS" desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are hungry." id = "ci-nutrimentplus" req_tech = list("materials" = 5, "powerstorage" = 4, "biotech" = 4) @@ -301,7 +301,7 @@ category = list("Misc", "Medical Designs") /datum/design/cyberimp_reviver - name = "Reviver implant" + name = "Reviver Implant" desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" id = "ci-reviver" req_tech = list("materials" = 5, "programming" = 4, "biotech" = 5) @@ -312,7 +312,7 @@ category = list("Misc", "Medical Designs") /datum/design/cyberimp_thrusters - name = "Thrusters set implant" + name = "Thrusters Set Implant" desc = "This implant will allow you to use gas from environment or your internals for propulsion in zero-gravity areas." id = "ci-thrusters" req_tech = list("materials" = 5, "biotech" = 5, "magnets" = 4, "engineering" = 7) diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm index 80863259e8..15704651f6 100644 --- a/code/modules/research/designs/weapon_designs.dm +++ b/code/modules/research/designs/weapon_designs.dm @@ -3,7 +3,7 @@ ///////////////////////////////////////// /datum/design/pin_testing - name = "test-range firing pin" + name = "Test-Range Firing Pin" desc = "This safety firing pin allows firearms to be operated within proximity to a firing range." id = "pin_testing" req_tech = list("combat" = 2, "materials" = 2) @@ -13,7 +13,7 @@ category = list("Firing Pins") /datum/design/pin_mindshield - name = "mindshield firing pin" + name = "Mindshield Firing Pin" desc = "This is a security firing pin which only authorizes users who are mindshield-implanted." id = "pin_loyalty" req_tech = list("combat" = 5, "materials" = 6) diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm index ecc1398137..b28d388b29 100644 --- a/code/modules/ruins/lavaland_ruin_code.dm +++ b/code/modules/ruins/lavaland_ruin_code.dm @@ -11,7 +11,7 @@ lootcount = 1 loot = list(/obj/item/seeds/gatfruit = 10, - /obj/item/seeds/cherry = 15, + /obj/item/seeds/cherry/bomb = 10, /obj/item/seeds/berry/glow = 10, /obj/item/seeds/sunflower/moonflower = 8 ) @@ -103,6 +103,12 @@ if(istype(O, /obj/item/stack/medical/gauze) || istype(O, /obj/item/stack/sheet/cloth)) species = /datum/species/golem/cloth + + if(istype(O, /obj/item/stack/sheet/plastic)) + species = /datum/species/golem/plastic + + if(istype(O, /obj/item/stack/sheet/mineral/adamantine)) + species = /datum/species/golem/adamantine if(species) if(O.use(10)) @@ -119,7 +125,6 @@ name = "incomplete artificial golem shell" has_owner = TRUE - ///Syndicate Listening Post /obj/effect/mob_spawn/human/lavaland_syndicate r_hand = /obj/item/weapon/gun/ballistic/automatic/sniper_rifle @@ -136,7 +141,7 @@ icon = 'icons/obj/Cryogenic2.dmi' icon_state = "sleeper" has_id = 1 - flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunatley, your hated enemy, Nanotrasen, has begun mining in this sector. Continue your research as best you can, and try to keep a low profile. Do not abandon the base without good cause. The base is rigged with explosives should the worst happen, do not let the base fall into enemy hands!
" + flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Continue your research as best you can, and try to keep a low profile. Do not abandon the base without good cause. The base is rigged with explosives should the worst happen, do not let the base fall into enemy hands!
" id_access_list = list(GLOB.access_syndicate) /obj/effect/mob_spawn/human/lavaland_syndicate/comms @@ -144,9 +149,6 @@ r_hand = /obj/item/weapon/melee/energy/sword/saber mask = /obj/item/clothing/mask/chameleon suit = /obj/item/clothing/suit/armor/vest - flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. \n +\ - Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Monitor enemy activity as best you can, and try to keep a low profile. Do not abandon the base, activate the self destruct device if you are compromised. \n +\ - Use the communication equipment to provide support to any field agents, and sow disinformation to throw Nanotrasen off your trail.\n +\ - Remember, an enemy of our enemy is a friend, so also provide support to those that hinder Nanotrasen unless commanded otherwise by HQ. \n +\ - Do not let the base fall into enemy hands!" + flavour_text = "You are a syndicate agent, employed in a top secret research facility developing biological weapons. Unfortunately, your hated enemy, Nanotrasen, has begun mining in this sector. Monitor enemy activity as best you can, and try to keep a low profile. Do not abandon the base without good cause. Use the communication equipment to provide support to any field agents, and sow disinformation to throw Nanotrasen off your trail. Do not let the base fall into enemy hands!" pocket2 = /obj/item/weapon/card/id/syndicate/anyone + diff --git a/code/modules/shuttle/elevator.dm b/code/modules/shuttle/elevator.dm new file mode 100644 index 0000000000..12f9c24f9a --- /dev/null +++ b/code/modules/shuttle/elevator.dm @@ -0,0 +1,10 @@ +/obj/docking_port/mobile/elevator + name = "elevator" + id = "elevator" + dwidth = 3 + width = 7 + height = 7 + knockdown = FALSE + +/obj/docking_port/mobile/elevator/request(obj/docking_port/stationary/S) //No transit, no ignition, just a simple up/down platform + dock(S, TRUE) \ No newline at end of file diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index b9d284b280..6344689f0b 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -104,12 +104,8 @@ authorized += ID - message_admins("[key_name_admin(user.client)] \ - (?) \ - (FLW) \ - has authorized early shuttle launch", 0, 1) - log_game("[key_name(user)] has authorized early shuttle launch in \ - ([x],[y],[z])") + message_admins("[ADMIN_LOOKUPFLW(user)] has authorized early shuttle launch", 0, 1) + log_game("[key_name(user)] has authorized early shuttle launch in [COORD(src)]") // Now check if we're on our way . = TRUE process() diff --git a/code/modules/shuttle/ferry.dm b/code/modules/shuttle/ferry.dm index 2e04fdd9af..b846098fc4 100644 --- a/code/modules/shuttle/ferry.dm +++ b/code/modules/shuttle/ferry.dm @@ -30,4 +30,4 @@ return last_request = world.time to_chat(usr, "Your request has been recieved by Centcom.") - to_chat(GLOB.admins, "FERRY: [key_name_admin(usr)] (?) (FLW) (Move Ferry) is requesting to move the transport ferry to Centcom.") + to_chat(GLOB.admins, "FERRY: [ADMIN_LOOKUPFLW(usr)] (Move Ferry) is requesting to move the transport ferry to Centcom.") diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 756fad25b3..b5571164ff 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -3,7 +3,7 @@ return // Called when shuttle attempts to move an atom. -/atom/movable/proc/onShuttleMove(turf/T1, rotation) +/atom/movable/proc/onShuttleMove(turf/T1, rotation, knockdown = TRUE) if(rotation) shuttleRotate(rotation) loc = T1 @@ -47,11 +47,11 @@ else shake_camera(src, 7, 1) -/mob/living/carbon/onShuttleMove() +/mob/living/carbon/onShuttleMove(turf/T1, rotation, knockdown = TRUE) . = ..() if(!.) return - if(!buckled) + if(!buckled && knockdown) Weaken(3) /obj/effect/abstract/proximity_checker/onShuttleMove() diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm index 00ddecb7f8..656ba24da6 100644 --- a/code/modules/shuttle/shuttle.dm +++ b/code/modules/shuttle/shuttle.dm @@ -217,6 +217,8 @@ var/launch_status = NOLAUNCH + var/knockdown = TRUE //Will it knock down mobs when it docks? + // A timid shuttle will not register itself with the shuttle subsystem // All shuttle templates are timid var/timid = FALSE @@ -517,7 +519,7 @@ //move mobile to new location for(var/atom/movable/AM in T0) - if(AM.onShuttleMove(T1, rotation)) + if(AM.onShuttleMove(T1, rotation, knockdown)) moved_atoms += AM if(rotation) @@ -578,10 +580,7 @@ if(M.pulledby) M.pulledby.stop_pulling() M.stop_pulling() - M.visible_message("[M] is hit by \ - a hyperspace ripple!", - "You feel an immense \ - crushing pressure as the space around you ripples.") + M.visible_message("[src] slams into [M]!") if(M.key || M.get_ghost(TRUE)) SSblackbox.add_details("shuttle_gib", "[type]") else diff --git a/code/modules/spells/spell_types/aimed.dm b/code/modules/spells/spell_types/aimed.dm index ef40210fd1..597f3185a4 100644 --- a/code/modules/spells/spell_types/aimed.dm +++ b/code/modules/spells/spell_types/aimed.dm @@ -36,7 +36,7 @@ /obj/effect/proc_holder/spell/aimed/InterceptClickOn(mob/living/caller, params, atom/target) if(..()) return FALSE - var/ignore = (current_amount <= 0) + var/ignore = (current_amount >= 1) if(!cast_check(ignore, ranged_ability_user)) remove_ranged_ability() return FALSE diff --git a/code/modules/spells/spell_types/mind_transfer.dm b/code/modules/spells/spell_types/mind_transfer.dm index 7ebafe6e24..052c1f1162 100644 --- a/code/modules/spells/spell_types/mind_transfer.dm +++ b/code/modules/spells/spell_types/mind_transfer.dm @@ -62,29 +62,14 @@ Also, you never added distance checking after target is selected. I've went ahea var/mob/caster = user//The wizard/whomever doing the body transferring. //MIND TRANSFER BEGIN - if(caster.mind.special_verbs.len)//If the caster had any special verbs, remove them from the mob verb list. - for(var/V in caster.mind.special_verbs)//Since the caster is using an object spell system, this is mostly moot. - caster.verbs -= V//But a safety nontheless. - - if(victim.mind.special_verbs.len)//Now remove all of the victim's verbs. - for(var/V in victim.mind.special_verbs) - victim.verbs -= V - var/mob/dead/observer/ghost = victim.ghostize(0) caster.mind.transfer_to(victim) - if(victim.mind.special_verbs.len)//To add all the special verbs for the original caster. - for(var/V in caster.mind.special_verbs)//Not too important but could come into play. - caster.verbs += V - ghost.mind.transfer_to(caster) if(ghost.key) caster.key = ghost.key //have to transfer the key since the mind was not active qdel(ghost) - if(caster.mind.special_verbs.len)//If they had any special verbs, we add them here. - for(var/V in caster.mind.special_verbs) - caster.verbs += V //MIND TRANSFER END //Here we paralyze both mobs and knock them out for a time. diff --git a/code/modules/spells/spell_types/wizard.dm b/code/modules/spells/spell_types/wizard.dm index 66bc198311..76f5b9b307 100644 --- a/code/modules/spells/spell_types/wizard.dm +++ b/code/modules/spells/spell_types/wizard.dm @@ -69,6 +69,24 @@ action_icon_state = "smoke" + +/obj/effect/proc_holder/spell/targeted/smoke/lesser //Chaplain smoke book + name = "Smoke" + desc = "This spell spawns a small cloud of choking smoke at your location." + + school = "conjuration" + charge_max = 360 + clothes_req = 0 + invocation = "none" + invocation_type = "none" + range = -1 + include_user = 1 + + smoke_spread = 1 + smoke_amt = 2 + + action_icon_state = "smoke" + /obj/effect/proc_holder/spell/targeted/emplosion/disable_tech name = "Disable Tech" desc = "This spell disables all weapons, cameras and most other technology in range." diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index de8c2b79ac..585f452de4 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -218,6 +218,14 @@ for(var/X in list(owner.glasses, owner.ears, owner.wear_mask, owner.head)) var/obj/item/I = X owner.dropItemToGround(I, TRUE) + + //Handle dental implants + for(var/datum/action/item_action/hands_free/activate_pill/AP in owner.actions) + AP.Remove(owner) + var/obj/pill = AP.target + if(pill) + pill.forceMove(src) + name = "[owner.real_name]'s head" ..() @@ -254,6 +262,8 @@ if(held_index > C.hand_bodyparts.len) C.hand_bodyparts.len = held_index C.hand_bodyparts[held_index] = src + if(C.dna.species.mutanthands && !is_pseudopart) + C.put_in_hand(new C.dna.species.mutanthands(), held_index) if(C.hud_used) var/obj/screen/inventory/hand/hand = C.hud_used.hand_slots["[held_index]"] if(hand) @@ -269,6 +279,9 @@ qdel(S) break + for(var/obj/item/organ/O in contents) + O.Insert(C) + update_bodypart_damage_state() C.updatehealth() @@ -300,6 +313,14 @@ C.real_name = real_name real_name = "" name = initial(name) + + //Handle dental implants + for(var/obj/item/weapon/reagent_containers/pill/P in src) + for(var/datum/action/item_action/hands_free/activate_pill/AP in P.actions) + P.forceMove(C) + AP.Grant(C) + break + ..() diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index 909f83e4d7..dd63506086 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -48,7 +48,10 @@ brain = null update_icon_dropped() else - I.loc = T + if(istype(I, /obj/item/weapon/reagent_containers/pill)) + for(var/datum/action/item_action/hands_free/activate_pill/AP in I.actions) + qdel(AP) + I.forceMove(T) /obj/item/bodypart/head/update_limb(dropping_limb, mob/living/carbon/source) var/mob/living/carbon/C diff --git a/code/modules/surgery/dental_implant.dm b/code/modules/surgery/dental_implant.dm index eef88e4a5f..c51a49081c 100644 --- a/code/modules/surgery/dental_implant.dm +++ b/code/modules/surgery/dental_implant.dm @@ -18,10 +18,10 @@ user.drop_item() tool.loc = target - var/datum/action/item_action/hands_free/activate_pill/P = new + var/datum/action/item_action/hands_free/activate_pill/P = new(tool) P.button.name = "Activate [tool.name]" P.target = tool - P.Grant(target) + P.Grant(target) //The pill never actually goes in an inventory slot, so the owner doesn't inherit actions from it user.visible_message("[user] wedges \the [tool] into [target]'s [parse_zone(target_zone)]!", "You wedge [tool] into [target]'s [parse_zone(target_zone)].") return 1 @@ -37,6 +37,5 @@ if(target.reagents.total_volume) target.reagents.reaction(owner, INGEST) target.reagents.trans_to(owner, target.reagents.total_volume) - Remove(owner) qdel(target) return 1 \ No newline at end of file diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm index 6e3c224924..9d88e491b2 100644 --- a/code/modules/surgery/organ_manipulation.dm +++ b/code/modules/surgery/organ_manipulation.dm @@ -106,7 +106,7 @@ "You begin to mend the incision in [target]'s [parse_zone(target_zone)]...") else if(istype(tool, /obj/item/weapon/reagent_containers/food/snacks/organ)) - to_chat(user, "[tool] was biten by someone! It's too damaged to use!") + to_chat(user, "[tool] was bitten by someone! It's too damaged to use!") return -1 /datum/surgery_step/manipulate_organs/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm index c91cb219af..e66346a2c8 100644 --- a/code/modules/surgery/organs/ears.dm +++ b/code/modules/surgery/organs/ears.dm @@ -4,6 +4,7 @@ desc = "There are three parts to the ear. Inner, middle and outer. Only one of these parts should be normally visible." zone = "head" slot = "ears" + gender = PLURAL // `deaf` measures "ticks" of deafness. While > 0, the person is unable // to hear anything. diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 672ac924ad..83b70d33d9 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -4,6 +4,7 @@ desc = "I see you!" zone = "eyes" slot = "eye_sight" + gender = PLURAL var/sight_flags = 0 var/see_in_dark = 2 @@ -63,6 +64,9 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE sight_flags = SEE_MOBS +/obj/item/organ/eyes/night_vision/zombie + name = "undead eyes" + desc = "Somewhat counterintuitively, these half rotten eyes actually have superior vision to those of a living human." ///Robotic diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm index 97e794b466..78adf8268c 100644 --- a/code/modules/surgery/organs/organ_internal.dm +++ b/code/modules/surgery/organs/organ_internal.dm @@ -125,16 +125,13 @@ if(!getorganslot("tongue")) var/obj/item/organ/tongue/T - if(dna && dna.species) - for(var/tongue_type in dna.species.mutant_organs) - if(ispath(tongue_type, /obj/item/organ/tongue)) - T = new tongue_type() - T.Insert(src) + if(dna && dna.species && dna.species.mutanttongue) + T = new dna.species.mutanttongue() + else + T = new() // if they have no mutant tongues, give them a regular one - if(!T) - T = new() - T.Insert(src) + T.Insert(src) if(!getorganslot("eye_sight")) var/obj/item/organ/eyes/E diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm index b6a62cacd2..575a634a11 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -10,9 +10,10 @@ var/taste_sensitivity = 15 // lower is more sensitive. /obj/item/organ/tongue/Initialize(mapload) - ..() + . = ..() languages_possible = typecacheof(list( /datum/language/common, + /datum/language/draconic, /datum/language/monkey, /datum/language/ratvar )) @@ -123,10 +124,11 @@ taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED /obj/item/organ/tongue/alien/Initialize(mapload) - ..() + . = ..() languages_possible = typecacheof(list( /datum/language/xenocommon, /datum/language/common, + /datum/language/draconic, /datum/language/ratvar, /datum/language/monkey)) @@ -175,7 +177,7 @@ /obj/item/organ/tongue/bone/plasmaman/get_spans() return - + /obj/item/organ/tongue/robot name = "robotic voicebox" desc = "A voice synthesizer that can interface with organic lifeforms." @@ -185,16 +187,8 @@ attack_verb = list("beeped", "booped") taste_sensitivity = 25 // not as good as an organic tongue -/obj/item/organ/tongue/robot/Initialize(mapload) - ..() - languages_possible = typecacheof(list( - /datum/language/xenocommon, - /datum/language/common, - /datum/language/ratvar, - /datum/language/monkey, - /datum/language/drone, - /datum/language/machine, - /datum/language/swarmer)) +/obj/item/organ/tongue/robot/can_speak_in_language(datum/language/dt) + . = TRUE // THE MAGIC OF ELECTRONICS /obj/item/organ/tongue/robot/get_spans() return ..() | SPAN_ROBOT diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm index a2048c2b71..e817557cc2 100644 --- a/code/modules/surgery/organs/vocal_cords.dm +++ b/code/modules/surgery/organs/vocal_cords.dm @@ -8,6 +8,7 @@ icon_state = "appendix" zone = "mouth" slot = "vocal_cords" + gender = PLURAL var/list/spans = null /obj/item/organ/vocal_cords/proc/can_speak_with() //if there is any limitation to speaking with these cords @@ -19,6 +20,40 @@ /obj/item/organ/vocal_cords/proc/handle_speech(message) //actually say the message owner.say(message, spans = spans, sanitize = FALSE) +/obj/item/organ/adamantine_resonator + name = "adamantine resonator" + desc = "Fragments of adamantine exists in all golems, stemming from their origins as purely magical constructs. These are used to \"hear\" messages from their leaders." + zone = "head" + slot = "adamantine_resonator" + icon_state = "adamantine_resonator" + +/obj/item/organ/vocal_cords/adamantine + name = "adamantine vocal cords" + desc = "When adamantine resonates, it causes all nearby pieces of adamantine to resonate as well. Adamantine golems use this to broadcast messages to nearby golems." + actions_types = list(/datum/action/item_action/organ_action/use/adamantine_vocal_cords) + zone = "mouth" + slot = "vocal_cords" + icon_state = "adamantine_cords" + +/datum/action/item_action/organ_action/use/adamantine_vocal_cords/Trigger() + if(!IsAvailable()) + return + var/message = input(owner, "Resonate a message to all nearby golems.", "Resonate") + if(QDELETED(src) || QDELETED(owner) || !message) + return + owner.say(".x[message]") + +/obj/item/organ/vocal_cords/adamantine/handle_speech(message) + var/msg = "[owner.real_name] resonates, \"[message]\"" + for(var/m in GLOB.player_list) + if(iscarbon(m)) + var/mob/living/carbon/C = m + if(C.getorganslot("adamantine_resonator")) + to_chat(C, msg) + if(isobserver(m)) + var/link = FOLLOW_LINK(m, src) + to_chat(m, "[link] [msg]") + //Colossus drop, forces the listeners to obey certain commands /obj/item/organ/vocal_cords/colossus name = "divine vocal cords" @@ -247,7 +282,7 @@ else if((findtext(message, silence_words))) cooldown = COOLDOWN_STUN for(var/mob/living/carbon/C in listeners) - if(user.mind && (user.mind.assigned_role == "Librarian" || user.mind.assigned_role == "Mime")) + if(user.mind && (user.mind.assigned_role == "Curator" || user.mind.assigned_role == "Mime")) power_multiplier *= 3 C.silent += (10 * power_multiplier) diff --git a/code/modules/surgery/prosthetic_replacement.dm b/code/modules/surgery/prosthetic_replacement.dm index 53520679c2..4be7b84a6c 100644 --- a/code/modules/surgery/prosthetic_replacement.dm +++ b/code/modules/surgery/prosthetic_replacement.dm @@ -72,9 +72,9 @@ user.visible_message("[user] successfully replaces [target]'s [parse_zone(target_zone)]!", "You succeed in replacing [target]'s [parse_zone(target_zone)].") return 1 else - target.regenerate_limb(target_zone) - var/obj/item/bodypart/L = target.get_bodypart(target_zone) + var/obj/item/bodypart/L = target.newBodyPart(target_zone, FALSE, FALSE) L.is_pseudopart = TRUE + L.attach_limb(target) user.visible_message("[user] finishes attaching [tool]!", "You attach [tool].") qdel(tool) if(istype(tool, /obj/item/weapon/twohanded/required/chainsaw)) diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 90cb344cf5..efd1ec64f2 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -111,17 +111,8 @@ if(contents.len) to_chat(user, "[src] already has something inside it.") return - if(isorgan(I)) - var/obj/item/organ/O = I - if(O.status != ORGAN_ORGANIC) - to_chat(user, "[src] can only hold organic body parts!") - return - else if(isbodypart(I)) - var/obj/item/bodypart/BP = I - if(BP.status != BODYPART_ORGANIC) - to_chat(user, "[src] can only hold organic body parts!") - return - else + if(!isorgan(I) && !isbodypart(I)) + to_chat(user, "[src] can only hold body parts!") return user.visible_message("[user] puts [I] into [src].", "You put [I] inside [src].") @@ -150,4 +141,4 @@ desc = "A container for holding body parts." else to_chat(user, "[src] is empty.") - return \ No newline at end of file + return diff --git a/code/modules/uplink/uplink_item.dm b/code/modules/uplink/uplink_item.dm index d80a8e21b3..98aa41e88f 100644 --- a/code/modules/uplink/uplink_item.dm +++ b/code/modules/uplink/uplink_item.dm @@ -44,7 +44,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. for(var/i in 1 to 3) var/datum/uplink_item/I = pick_n_take(sale_items) var/datum/uplink_item/A = new I.type - var/discount = pick(4;0.75,2;0.5,1;0.25) + var/discount = A.get_discount() var/list/disclaimer = list("Void where prohibited.", "Not recommended for children.", "Contains small parts.", "Check local laws for legality in region.", "Do not taunt.", "Not responsible for direct, indirect, incidental or consequential damages resulting from any defect, error or failure to perform.", "Keep away from fire or flames.", "Product is provided \"as is\" without any implied or expressed warranties.", "As seen on TV.", "For recreational use only.", "Use only as directed.", "16% sales tax will be charged for orders originating within Space Nebraska.") A.limited_stock = 1 I.refundable = FALSE //THIS MAN USES ONE WEIRD TRICK TO GAIN FREE TC, CODERS HATES HIM! @@ -86,6 +86,9 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. var/player_minimum //The minimum crew size needed for this item to be added to uplinks. var/purchase_log_vis = TRUE // Visible in the purchase log? +/datum/uplink_item/proc/get_discount() + return pick(4;0.75,2;0.5,1;0.25) + /datum/uplink_item/proc/spawn_item(turf/loc, obj/item/device/uplink/U) if(item) SSblackbox.add_details("traitor_uplink_items_bought", "[name]|[cost]") @@ -276,12 +279,21 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. /datum/uplink_item/dangerous/sword name = "Energy Sword" desc = "The energy sword is an edged weapon with a blade of pure energy. The sword is small enough to be \ - pocketed when inactive. Activating it produces a loud, distinctive noise. One can combine two \ - energy swords to create a double energy sword, which must be wielded in two hands but is more robust \ - and deflects all energy projectiles." + pocketed when inactive. Activating it produces a loud, distinctive noise." item = /obj/item/weapon/melee/energy/sword/saber cost = 8 +/datum/uplink_item/dangerous/doublesword + name = "Double-Bladed Energy Sword" + desc = "The double-bladed energy sword does slightly more damage than a standard energy sword and will deflect \ + all energy projectiles, but requires two hands to wield." + item = /obj/item/weapon/twohanded/dualsaber + player_minimum = 25 + cost = 16 + +/datum/uplink_item/dangerous/doublesword/get_discount() + return pick(4;0.8,2;0.65,1;0.5) + /datum/uplink_item/dangerous/powerfist name = "Power Fist" desc = "The power-fist is a metal gauntlet with a built-in piston-ram powered by an external gas supply.\ @@ -1250,7 +1262,7 @@ GLOBAL_LIST_EMPTY(uplink_items) // Global list so we only initialize this once. desc = "Most magic eightballs are toys with dice inside. Although identical in appearance to the harmless toys, this occult device reaches into the spirit world to find its answers. Be warned, that spirits are often capricious or just little assholes. To use, simply speak your question aloud, then begin shaking." item = /obj/item/toy/eightball/haunted cost = 2 - restricted_roles = list("Librarian") + restricted_roles = list("Curator") limited_stock = 1 // please don't spam deadchat // Pointless diff --git a/code/modules/uplink/uplink_item_cit.dm b/code/modules/uplink/uplink_item_cit.dm index c74ad3ba9c..b835a21a8c 100644 --- a/code/modules/uplink/uplink_item_cit.dm +++ b/code/modules/uplink/uplink_item_cit.dm @@ -7,4 +7,15 @@ refundable = TRUE cost = 10 surplus = 20 //Let's not have this be too common + exclude_modes = list(/datum/game_mode/nuclear) + +/datum/uplink_item/stealthy_tools/holoparasite + name="Holoparasite Injector" + desc="It contains an alien nanoswarm of unknown origin.\ + Though capable of near sorcerous feats via use of hardlight holograms and nanomachines.\ + It requires an organic host as a home base and source of fuel." //This is the description of the actual injector. Feel free to change this for uplink purposes// + item = /obj/item/weapon/storage/box/syndie_kit/holoparasite + refundable = TRUE + cost = 10 //I'm working off the borer. Price subject to change + surplus = 20 //Nobody needs a ton of parasites exclude_modes = list(/datum/game_mode/nuclear) \ No newline at end of file diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm index 1bdbd3fa45..1b93a4f685 100644 --- a/code/modules/zombie/items.dm +++ b/code/modules/zombie/items.dm @@ -46,7 +46,8 @@ var/obj/item/organ/zombie_infection/infection infection = target.getorganslot("zombie_infection") if(!infection) - infection = new(target) + infection = new() + infection.Insert(target) /obj/item/zombie_hand/proc/check_feast(mob/living/target, mob/living/user) if(target.stat == DEAD) diff --git a/code/modules/zombie/organs.dm b/code/modules/zombie/organs.dm index f254ef6337..3515da0dc6 100644 --- a/code/modules/zombie/organs.dm +++ b/code/modules/zombie/organs.dm @@ -5,7 +5,7 @@ slot = "zombie_infection" icon_state = "blacktumor" origin_tech = "biotech=5" - var/datum/species/old_species + var/datum/species/old_species = /datum/species/human var/living_transformation_time = 3 var/converts_living = FALSE @@ -63,6 +63,7 @@ if(!iszombie(owner)) old_species = owner.dna.species.type + owner.set_species(/datum/species/zombie/infectious) if(!converts_living && owner.stat != DEAD) return @@ -70,7 +71,6 @@ var/stand_up = (owner.stat == DEAD) || (owner.stat == UNCONSCIOUS) owner.grab_ghost() - owner.set_species(/datum/species/zombie/infectious) owner.revive(full_heal = TRUE) owner.visible_message("[owner] suddenly convulses, as [owner.p_they()][stand_up ? " stagger to [owner.p_their()] feet and" : ""] gain a ravenous hunger in [owner.p_their()] eyes!", "You HUNGER!") playsound(owner.loc, 'sound/hallucinations/far_noise.ogg', 50, 1) diff --git a/code/world.dm b/code/world.dm index 9023ac47f3..4489b9a1cb 100644 --- a/code/world.dm +++ b/code/world.dm @@ -25,37 +25,50 @@ else external_rsc_urls.Cut(i,i+1) #endif - //logs - var/date_string = time2text(world.realtime, "YYYY/MM-Month/DD-Day") - GLOB.href_logfile = file("data/logs/[date_string] hrefs.htm") - GLOB.diary = file("data/logs/[date_string].log") - GLOB.diaryofmeanpeople = file("data/logs/[date_string] Attack.log") - GLOB.diary << "\n\nStarting up. [time_stamp()]\n---------------------" - GLOB.diaryofmeanpeople << "\n\nStarting up. [time_stamp()]\n---------------------" - GLOB.changelog_hash = md5('html/changelog.html') //used for telling if the changelog has changed recently - + GLOB.config_error_log = file("data/logs/config_error.log") //temporary file used to record errors with loading config, moved to log directory once logging is set bl make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once) config = new + GLOB.log_directory = "data/logs/[time2text(world.realtime, "YYYY/MM/DD")]/round-" + if(config.sql_enabled) + if(SSdbcore.Connect()) + log_world("Database connection established.") + var/datum/DBQuery/query_feedback_create_round = SSdbcore.NewQuery("INSERT INTO [format_table_name("feedback")] SELECT null, Now(), MAX(round_id)+1, \"server_ip\", 0, \"[world.internet_address]:[world.port]\" FROM [format_table_name("feedback")]") + query_feedback_create_round.Execute() + var/datum/DBQuery/query_feedback_max_id = SSdbcore.NewQuery("SELECT MAX(round_id) FROM [format_table_name("feedback")]") + query_feedback_max_id.Execute() + if(query_feedback_max_id.NextRow()) + GLOB.round_id = query_feedback_max_id.item[1] + GLOB.log_directory += "[GLOB.round_id]" + else + log_world("Your server failed to establish a connection with the database.") + if(!GLOB.round_id) + GLOB.log_directory += "[replacetext(time_stamp(), ":", ".")]" + GLOB.world_game_log = file("[GLOB.log_directory]/game.log") + GLOB.world_attack_log = file("[GLOB.log_directory]/attack.log") + GLOB.world_runtime_log = file("[GLOB.log_directory]/runtime.log") + GLOB.world_href_log = file("[GLOB.log_directory]/hrefs.html") + GLOB.world_game_log << "\n\nStarting up round ID [GLOB.round_id]. [time_stamp()]\n---------------------" + GLOB.world_attack_log << "\n\nStarting up round ID [GLOB.round_id]. [time_stamp()]\n---------------------" + GLOB.world_runtime_log << "\n\nStarting up round ID [GLOB.round_id]. [time_stamp()]\n---------------------" + GLOB.changelog_hash = md5('html/changelog.html') //used for telling if the changelog has changed recently + if(fexists(GLOB.config_error_log)) + fcopy(GLOB.config_error_log, "[GLOB.log_directory]/config_error.log") + fdel(GLOB.config_error_log) + + GLOB.revdata.DownloadPRDetails() load_mode() load_motd() load_admins() + load_menu() //disabled to prevent runtimes until it's fixed // load_mentors() if(config.usewhitelist) load_whitelist() LoadBans() - investigate_reset() GLOB.timezoneOffset = text2num(time2text(0,"hh")) * 36000 - if(config.sql_enabled) - if(!SSdbcore.Connect()) - log_world("Your server failed to establish a connection with the database.") - else - log_world("Database connection established.") - - GLOB.data_core = new /datum/datacore() Master.Initialize(10, FALSE) @@ -63,7 +76,7 @@ #define IRC_STATUS_THROTTLE 50 /world/Topic(T, addr, master, key) if(config && config.log_world_topic) - GLOB.diary << "TOPIC: \"[T]\", from:[addr], master:[master], key:[key]" + GLOB.world_game_log << "TOPIC: \"[T]\", from:[addr], master:[master], key:[key]" var/list/input = params2list(T) var/key_valid = (global.comms_allowed && input["key"] == global.comms_key) @@ -136,11 +149,7 @@ if(!key_valid) return "Bad Key" else -#define CHAT_PULLR 64 //defined in preferences.dm, but not available here at compilation time - for(var/client/C in GLOB.clients) - if(C.prefs && (C.prefs.chat_toggles & CHAT_PULLR)) - to_chat(C, "PR: [input["announce"]]") -#undef CHAT_PULLR + AnnouncePR(input["announce"], json_decode(input["payload"])) else if("crossmessage" in input) if(!key_valid) @@ -176,6 +185,25 @@ else if("server_hop" in input) show_server_hop_transfer_screen(input["server_hop"]) +#define PR_ANNOUNCEMENTS_PER_ROUND 5 //The number of unique PR announcements allowed per round + //This makes sure that a single person can only spam 3 reopens and 3 closes before being ignored + +/world/proc/AnnouncePR(announcement, list/payload) + var/static/list/PRcounts = list() //PR id -> number of times announced this round + var/id = "[payload["pull_request"]["id"]]" + if(!PRcounts[id]) + PRcounts[id] = 1 + else + ++PRcounts[id] + if(PRcounts[id] > PR_ANNOUNCEMENTS_PER_ROUND) + return + +#define CHAT_PULLR 64 //defined in preferences.dm, but not available here at compilation time + for(var/client/C in GLOB.clients) + if(C.prefs && (C.prefs.chat_toggles & CHAT_PULLR)) + C << "PR: [announcement]" +#undef CHAT_PULLR + #define WORLD_REBOOT(X) log_world("World rebooted at [time_stamp()]"); ..(X); return; /world/Reboot(var/reason, var/feedback_c, var/feedback_r, var/time) if (reason == 1) //special reboot, do none of the normal stuff @@ -226,7 +254,7 @@ /world/proc/RoundEndAnimation(round_end_sound_sent) set waitfor = FALSE var/round_end_sound - if(!SSticker && SSticker.round_end_sound) + if(SSticker.round_end_sound) round_end_sound = SSticker.round_end_sound if (!round_end_sound_sent) for(var/thing in GLOB.clients) @@ -256,7 +284,7 @@ if(Lines.len) if(Lines[1]) GLOB.master_mode = Lines[1] - GLOB.diary << "Saved mode is '[GLOB.master_mode]'" + GLOB.world_game_log << "Saved mode is '[GLOB.master_mode]'" /world/proc/save_mode(the_mode) var/F = file("data/mode.txt") @@ -317,5 +345,6 @@ status = s + /world/proc/has_round_started() - return SSticker.HasRoundStarted() \ No newline at end of file + return SSticker.HasRoundStarted() diff --git a/config/config.txt b/config/config.txt index 524802219d..68df4c81cf 100644 --- a/config/config.txt +++ b/config/config.txt @@ -80,9 +80,6 @@ LOG_PRAYER ## log lawchanges LOG_LAW -## log all Topic() calls (for use by coders in tracking down Topic issues) -# LOG_HREFS - ## log all world.Topic() calls # LOG_WORLD_TOPIC @@ -263,6 +260,10 @@ EXTREME_POPCAP_MESSAGE The server is currently serving a high number of users, f ## Requres database NOTIFY_NEW_PLAYER_AGE 0 +## Notify admins when a player connects if their byond account was created in the last X days +## Requires database +NOTIFY_NEW_PLAYER_ACCOUNT_AGE 1 + ## Notify the irc channel when a new player makes their first connection ## Requres database #IRC_FIRST_CONNECTION_ALERT @@ -281,9 +282,6 @@ PANIC_SERVER_NAME [Put the name here] ## Uncomment to have the changelog file automatically open when a user connects and hasn't seen the latest changelog #AGGRESSIVE_CHANGELOG -## Uncomment to have the game log runtimes to the log folder. (Note: this disables normal output in dd/ds, so it should be left off for testing. -#LOG_RUNTIMES - ## Comment this out if you've used the mass conversion sql proc for notes or want to stop converting notes AUTOCONVERT_NOTES diff --git a/config/game_options.txt b/config/game_options.txt index 356dc1acab..dce0b57d42 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -166,7 +166,7 @@ MIDROUND_ANTAG ABDUCTION #MIN_POP GANG 20 #MAX_POP GANG -1 -#MIN_POP CULT 24 +#MIN_POP CULT 0 #MAX_POP CULT -1 #MIN_POP CLOCKWORK_CULT 24 diff --git a/config/jobs.txt b/config/jobs.txt index 3b65a6a9b8..a0c1ffa970 100644 --- a/config/jobs.txt +++ b/config/jobs.txt @@ -22,7 +22,7 @@ Janitor=2,1 Clown=1,1 Mime=1,1 -Librarian=1,1 +Curator=1,1 Lawyer=2,2 Chaplain=1,1 diff --git a/html/changelogs/AutoChangeLog-pr-608.yml b/html/changelogs/AutoChangeLog-pr-608.yml new file mode 100644 index 0000000000..2d23f1ab00 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-608.yml @@ -0,0 +1,5 @@ +author: "Gun Hog" +delete-after: True +changes: + - rscadd: "The GPS interface has been converted to tgui." + - experiment: "GPS now update automatically or manually, give distance and direction to a signal, and many other improvements!" diff --git a/html/changelogs/AutoChangeLog-pr-642.yml b/html/changelogs/AutoChangeLog-pr-642.yml new file mode 100644 index 0000000000..0d442e470d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-642.yml @@ -0,0 +1,5 @@ +author: "Cobby" +delete-after: True +changes: + - tweak: "The GPS set tag has gone from a limit of 5 characters to 20." + - rscadd: "The GPS can now be personalized in both name and description using a pen." diff --git a/html/changelogs/AutoChangeLog-pr-676.yml b/html/changelogs/AutoChangeLog-pr-676.yml new file mode 100644 index 0000000000..73c6fac766 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-676.yml @@ -0,0 +1,5 @@ +author: "Joan" +delete-after: True +changes: + - rscadd: "Proselytizers can now charge from Sigils of Transmission at a rate of 1000W per second." + - rscadd: "Sigils of Transmission can be charged with brass at a rate of 250W per sheet." diff --git a/html/changelogs/AutoChangeLog-pr-682.yml b/html/changelogs/AutoChangeLog-pr-682.yml new file mode 100644 index 0000000000..c55c645e6e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-682.yml @@ -0,0 +1,4 @@ +author: "Swindly" +delete-after: True +changes: + - tweak: "Mercury and Lithium make people move when not in space instead of when in space." diff --git a/html/changelogs/AutoChangeLog-pr-696.yml b/html/changelogs/AutoChangeLog-pr-696.yml new file mode 100644 index 0000000000..9f58df768f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-696.yml @@ -0,0 +1,5 @@ +author: "Joan" +delete-after: True +changes: + - rscadd: "Belligerent now prevents you from running for 7 seconds after every chant." + - rscdel: "However, you no longer remain walking after Belligerent's effect fades." diff --git a/html/changelogs/AutoChangeLog-pr-697.yml b/html/changelogs/AutoChangeLog-pr-697.yml new file mode 100644 index 0000000000..3967efa494 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-697.yml @@ -0,0 +1,4 @@ +author: "Joan" +delete-after: True +changes: + - rscadd: "Clockcult component generation will automatically focus on components needed to activate the Ark if it exists." diff --git a/html/changelogs/AutoChangeLog-pr-698.yml b/html/changelogs/AutoChangeLog-pr-698.yml new file mode 100644 index 0000000000..40e55644b5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-698.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "You can now make holocalls! Simply stand on a pad, bring up the menu, and select the holopad you wish to call. Remain still until someone answers. When they do, you'll be able to act just like an AI hologram until the call ends" diff --git a/html/changelogs/AutoChangeLog-pr-701.yml b/html/changelogs/AutoChangeLog-pr-701.yml new file mode 100644 index 0000000000..8848bcb450 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-701.yml @@ -0,0 +1,7 @@ +author: "ninjanomnom" +delete-after: True +changes: + - tweak: "TEG displays power in kw or MW now" + - tweak: "TEG power bar only maxes over 1MW now" + - experiment: "Moves TEG to SSair" + - experiment: "Moves SM to SSair" diff --git a/html/changelogs/AutoChangeLog-pr-708.yml b/html/changelogs/AutoChangeLog-pr-708.yml new file mode 100644 index 0000000000..6cb7c07312 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-708.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Squishy plants will now affect walls and other turfs they get squished on" diff --git a/html/changelogs/AutoChangeLog-pr-714.yml b/html/changelogs/AutoChangeLog-pr-714.yml new file mode 100644 index 0000000000..d5e4582f40 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-714.yml @@ -0,0 +1,4 @@ +author: "XDTM" +delete-after: True +changes: + - tweak: "Blood Cult's talisman of Horrors now works at range. It will still give no warning to the victim." diff --git a/html/changelogs/AutoChangeLog-pr-717.yml b/html/changelogs/AutoChangeLog-pr-717.yml new file mode 100644 index 0000000000..fbb98e0039 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-717.yml @@ -0,0 +1,5 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "When talking on the alien hivemind, a person will be identified by +their real name, rather than who they are disguised as." diff --git a/html/changelogs/AutoChangeLog-pr-722.yml b/html/changelogs/AutoChangeLog-pr-722.yml new file mode 100644 index 0000000000..6ade3cd92d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-722.yml @@ -0,0 +1,6 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Investigate logs are now persistent." + - tweak: "Game logs are now stored per-round; use .getserverlog to access previous rounds." + - rscdel: ".giveruntimelog and .getruntimelog removed." diff --git a/html/changelogs/AutoChangeLog-pr-733.yml b/html/changelogs/AutoChangeLog-pr-733.yml new file mode 100644 index 0000000000..ef779f70a1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-733.yml @@ -0,0 +1,4 @@ +author: "BeeSting12" +delete-after: True +changes: + - bugfix: "Omega shuttle now has lighting." diff --git a/html/changelogs/AutoChangeLog-pr-734.yml b/html/changelogs/AutoChangeLog-pr-734.yml new file mode 100644 index 0000000000..53785c45e6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-734.yml @@ -0,0 +1,6 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "Restrictions on Lizardpeople using their native language on the +station have been lifted by Centcom, in order to maximise worker +productivity. The language's key is \",o\"." diff --git a/html/changelogs/AutoChangeLog-pr-735.yml b/html/changelogs/AutoChangeLog-pr-735.yml new file mode 100644 index 0000000000..10d910d62b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-735.yml @@ -0,0 +1,7 @@ +author: "Kor, Profakos, Iamgoofball" +delete-after: True +changes: + - rscadd: "The Librarian has been replaced by the Curator." + - rscadd: "Persistent trophy cases have been added to the library on Meta, Delta, and Box. These are only usable by the Curator." + - rscadd: "The Curator now starts with his whip." + - rscadd: "The Curator now has access to his treasure hunter outfit, stashed in his private office." diff --git a/html/changelogs/AutoChangeLog-pr-739.yml b/html/changelogs/AutoChangeLog-pr-739.yml new file mode 100644 index 0000000000..7e7a8cd3a5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-739.yml @@ -0,0 +1,6 @@ +author: "Joan" +delete-after: True +changes: + - rscadd: "Mania Motors now do minor toxin damage over time and will convert those affected if the toxin damage is high enough. +balance: The effects of a Mania Motor continue to apply to targets after they leave its range, though they will fall off extremely quickly." + - rscdel: "Mania Motors no longer cause brain damage." diff --git a/html/changelogs/AutoChangeLog-pr-745.yml b/html/changelogs/AutoChangeLog-pr-745.yml new file mode 100644 index 0000000000..b9aa3fddd2 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-745.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "revenants now properly resurrect from ectoplasm, as opposed to ectoplasm merely spawning a new grief ghost" diff --git a/html/changelogs/AutoChangeLog-pr-746.yml b/html/changelogs/AutoChangeLog-pr-746.yml new file mode 100644 index 0000000000..ddeea1d732 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-746.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Turrets can no longer see invisible things, such as unrevealed revenants" diff --git a/html/changelogs/AutoChangeLog-pr-747.yml b/html/changelogs/AutoChangeLog-pr-747.yml new file mode 100644 index 0000000000..583f6b5e56 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-747.yml @@ -0,0 +1,4 @@ +author: "QualityVan" +delete-after: True +changes: + - rscadd: "Point flashlights at mouths to see what's inside them" diff --git a/html/changelogs/AutoChangeLog-pr-748.yml b/html/changelogs/AutoChangeLog-pr-748.yml new file mode 100644 index 0000000000..7ad62adec8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-748.yml @@ -0,0 +1,5 @@ +author: "Moonlighting Mac says" +delete-after: True +changes: + - rscadd: "Courtesy of the art & crafts division, imitation basalt tiles themed on the rough volcanic terrain of lavaland are now available to be made out of sandstone." + - experiment: "The manufacturer even managed to replicate the way that it lights up with volcanic energy, it is the perfect accompaniment to other fake (or real) lava-land tiles or a independent piece." diff --git a/html/changelogs/AutoChangeLog-pr-756.yml b/html/changelogs/AutoChangeLog-pr-756.yml new file mode 100644 index 0000000000..7ef015b31c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-756.yml @@ -0,0 +1,6 @@ +author: "lordpidey" +delete-after: True +changes: + - rscadd: "There is a new traitor poison, spewium. It will cause uncontrollable vomiting, which gets worse the longer it's in your system. An overdose can cause vomiting of organs." + - tweak: "Committing suicide with a gas pump can now shoot out random organs." + - bugfix: "Toxic vomit now shows up as intended." diff --git a/html/changelogs/AutoChangeLog-pr-758.yml b/html/changelogs/AutoChangeLog-pr-758.yml new file mode 100644 index 0000000000..fff062e111 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-758.yml @@ -0,0 +1,6 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Lesser smoke book to Delta and Metastation" + - rscdel: "Normal smoke book from Delta and Metastation" + - tweak: "Civilian smoke book now has a 360 max cooldown (from 120) and halved smoke output." diff --git a/html/changelogs/AutoChangeLog-pr-760.yml b/html/changelogs/AutoChangeLog-pr-760.yml new file mode 100644 index 0000000000..b0296b2330 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-760.yml @@ -0,0 +1,4 @@ +author: "bgobandit" +delete-after: True +changes: + - tweak: "The Syndicate has added basic functionality to their state-of-the-art equipment. Nuke ops can now donate all TCs at once." diff --git a/html/changelogs/AutoChangeLog-pr-763.yml b/html/changelogs/AutoChangeLog-pr-763.yml new file mode 100644 index 0000000000..12fa07ea48 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-763.yml @@ -0,0 +1,4 @@ +author: "Incoming" +delete-after: True +changes: + - tweak: "Display cases now require a key to open, which the curator spawns with" diff --git a/html/changelogs/AutoChangeLog-pr-764.yml b/html/changelogs/AutoChangeLog-pr-764.yml new file mode 100644 index 0000000000..87210fcb7a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-764.yml @@ -0,0 +1,4 @@ +author: "QualityVan" +delete-after: True +changes: + - bugfix: "Dental implants stay with the head they're in" diff --git a/html/changelogs/AutoChangeLog-pr-771.yml b/html/changelogs/AutoChangeLog-pr-771.yml new file mode 100644 index 0000000000..031ec64151 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-771.yml @@ -0,0 +1,4 @@ +author: "BeeSting12" +delete-after: True +changes: + - bugfix: "Pubbystation no longer has two airlocks stacked on top of each other leading into xenobiology's kill room." diff --git a/html/changelogs/AutoChangeLog-pr-781.yml b/html/changelogs/AutoChangeLog-pr-781.yml new file mode 100644 index 0000000000..08a5c148ff --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-781.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - tweak: "Teslas now give off light" diff --git a/html/changelogs/AutoChangeLog-pr-785.yml b/html/changelogs/AutoChangeLog-pr-785.yml new file mode 100644 index 0000000000..608a090249 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-785.yml @@ -0,0 +1,14 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "Adamantine golems have special vocal cords that allow them to send +one-way messages to all golems, due to fragments of resonating +adamantine in their heads. Both of these are organs, and can be removed +and put in other species." + - rscadd: "You can use adamantine vocal cords by prefixing your message with +\":x\"." + - rscdel: "Xenobiology is no longer capable of making golem runes with plasma. +Instead, inject plasma into the adamantine slime core to get bars of adamantine +which you can then craft into an incomplete golem shell. Add 10 sheets of +suitable material to finish the shell." + - experiment: "The metal adamantine is also quite valuable when sold via cargo." diff --git a/html/changelogs/AutoChangeLog-pr-792.yml b/html/changelogs/AutoChangeLog-pr-792.yml new file mode 100644 index 0000000000..9d2ccfebde --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-792.yml @@ -0,0 +1,6 @@ +author: "BeeSting12" +delete-after: True +changes: + - rscadd: "Deltastation's chemistry now has a screwdriver." + - bugfix: "Deltastation's morgue no longer has a blue tile." + - bugfix: "Deltastation's chemistry smart fridge is no longer blocked by a disposal unit." diff --git a/html/changelogs/AutoChangeLog-pr-800.yml b/html/changelogs/AutoChangeLog-pr-800.yml new file mode 100644 index 0000000000..798c98c64b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-800.yml @@ -0,0 +1,4 @@ +author: "coiax" +delete-after: True +changes: + - tweak: "The lavaland Seed Vault ruin can spawn only once." diff --git a/html/changelogs/AutoChangeLog-pr-801.yml b/html/changelogs/AutoChangeLog-pr-801.yml new file mode 100644 index 0000000000..756cf33927 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-801.yml @@ -0,0 +1,6 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Internal Affairs Agents now obtain the kill objectives of their targets when they die." + - rscadd: "Internal Affairs Agents now have an integrated nanotrasen pinpointer that tracks their target at distances further than ten squares." + - rscadd: "Internal Affairs Agents will now lose any restrictions on collateral damage and gain a \"Die a glorious death\" objective upon becoming the last man standing, and revert if any of their targets are cloned." diff --git a/html/changelogs/AutoChangeLog-pr-803.yml b/html/changelogs/AutoChangeLog-pr-803.yml new file mode 100644 index 0000000000..c3b54164a8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-803.yml @@ -0,0 +1,5 @@ +author: "Robustin" +delete-after: True +changes: + - tweak: "Gang Dominator max time is now 8 minutes down from 15m" + - tweak: "Gang Tagging now reduces the timer by 9 seconds per territory, down from 12 seconds." diff --git a/html/changelogs/AutoChangeLog-pr-805.yml b/html/changelogs/AutoChangeLog-pr-805.yml new file mode 100644 index 0000000000..be4a17ddf7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-805.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Reduction to nutrition when consuming Miner's salve." + - rscdel: "Stun/weaken that bypasses bugged chemical protection when consuming Miner's salve." diff --git a/html/changelogs/AutoChangeLog-pr-806.yml b/html/changelogs/AutoChangeLog-pr-806.yml new file mode 100644 index 0000000000..550cb8c880 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-806.yml @@ -0,0 +1,5 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "It is now possible to make plastic golems, who are made of a material +flexible enough to crawl through vents (while not carrying equipment). They also can pass through plastic flaps." diff --git a/html/changelogs/AutoChangeLog-pr-807.yml b/html/changelogs/AutoChangeLog-pr-807.yml new file mode 100644 index 0000000000..6ac3995026 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-807.yml @@ -0,0 +1,10 @@ +author: "Robustin" +delete-after: True +changes: + - rscadd: "Blood Cultists can now attempt to claim the position of Cult Master with the approval of a majority of their brethren." + - rscadd: "The Cult Master has access to unique blood magic that will aid them in leading the cult to victory:" + - rscadd: "The Cult Master can mark targets, allowing the entire cult to track them down." + - rscadd: "The Cult Master has single-use, noisy, and overt channeled spell that will summon the entire cult to their location." + - rscadd: "All cultists gain a HUD alert that will assist them in completing their objectives." + - rscadd: "Constructs created by soul shards will now be able to track their master." + - rscadd: "Cultists created outside of cult mode will now get a working sacrifice and summon objective and the summon rune will no longer fail outside of cult mode." diff --git a/html/changelogs/AutoChangeLog-pr-809.yml b/html/changelogs/AutoChangeLog-pr-809.yml new file mode 100644 index 0000000000..06fb6139cc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-809.yml @@ -0,0 +1,5 @@ +author: "QualityVan" +delete-after: True +changes: + - rscadd: "Cargo can order restocking units for NanoMed vending machines" + - rscadd: "NanoMed vending machines can be build and unbuilt" diff --git a/html/changelogs/AutoChangeLog-pr-815.yml b/html/changelogs/AutoChangeLog-pr-815.yml new file mode 100644 index 0000000000..6472c7a13d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-815.yml @@ -0,0 +1,4 @@ +author: "Penguaro" +delete-after: True +changes: + - bugfix: "Adjusted the Examine description of the right-most tiles of the Space Station 13 sign to be consistent with the rest of the tiles." diff --git a/html/changelogs/AutoChangeLog-pr-824.yml b/html/changelogs/AutoChangeLog-pr-824.yml new file mode 100644 index 0000000000..625034ab7c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-824.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Showers and sinks added to gulag and mining station for hygiene and fire safety." + - rscadd: "Watertanks added to mining station for convenient fire extinguisher refill." diff --git a/html/changelogs/AutoChangeLog-pr-825.yml b/html/changelogs/AutoChangeLog-pr-825.yml new file mode 100644 index 0000000000..ee3a963c30 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-825.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - tweak: "c4 planting is now 40% faster" diff --git a/html/changelogs/AutoChangeLog-pr-827.yml b/html/changelogs/AutoChangeLog-pr-827.yml new file mode 100644 index 0000000000..e16167448d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-827.yml @@ -0,0 +1,4 @@ +author: "Jay" +delete-after: True +changes: + - rscadd: "Adds finger snapping emote. Use say *snap" diff --git a/html/changelogs/AutoChangeLog-pr-829.yml b/html/changelogs/AutoChangeLog-pr-829.yml new file mode 100644 index 0000000000..619bc85876 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-829.yml @@ -0,0 +1,4 @@ +author: "Penguaro" +delete-after: True +changes: + - bugfix: "Anywhere there was lava below a tile on the station is now space." diff --git a/html/changelogs/AutoChangeLog-pr-832.yml b/html/changelogs/AutoChangeLog-pr-832.yml new file mode 100644 index 0000000000..bf686c0cef --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-832.yml @@ -0,0 +1,7 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Moved to a new system to make top menu items easier to edit." + - tweak: "Moved icon size stuff to a sub menu" + - rscadd: "Added option to change icon scaling mode." + - bugfix: "Byond added fancy shader supported scaling(Point Sampling), this sucks because it's blurry, the default for /tg/station has changed back to the old nearest neighbor scaling." diff --git a/html/changelogs/AutoChangeLog-pr-835.yml b/html/changelogs/AutoChangeLog-pr-835.yml new file mode 100644 index 0000000000..5392a02984 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-835.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - tweak: "Removes organic check from mediborg storage container" diff --git a/html/changelogs/AutoChangeLog-pr-841.yml b/html/changelogs/AutoChangeLog-pr-841.yml new file mode 100644 index 0000000000..3c27ac83c8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-841.yml @@ -0,0 +1,5 @@ +author: "Moonlighting Mac" +delete-after: True +changes: + - experiment: "Due to budget cuts and oil synthesis replacing expensive processes of digging up haunted primeval ashwalker burial grounds, Nanotransen has taught chemists how to make plastic from chemicals in the hopes that new plastic products can reduce expenditure on metal and glass." + - rscadd: "you can now make plastic sheets from chemistry out of heated up crude oil, ash & sodium chloride" diff --git a/html/changelogs/AutoChangeLog-pr-844.yml b/html/changelogs/AutoChangeLog-pr-844.yml new file mode 100644 index 0000000000..1bf63a4cef --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-844.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Fixed being unable to hit museum cases in melee" diff --git a/html/changelogs/AutoChangeLog-pr-848.yml b/html/changelogs/AutoChangeLog-pr-848.yml new file mode 100644 index 0000000000..0c1695adbc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-848.yml @@ -0,0 +1,4 @@ +author: "ninjanomnom" +delete-after: True +changes: + - tweak: "Highlander no longer breaks your speakers" diff --git a/html/changelogs/AutoChangeLog-pr-854.yml b/html/changelogs/AutoChangeLog-pr-854.yml new file mode 100644 index 0000000000..c253fbdedd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-854.yml @@ -0,0 +1,4 @@ +author: "Penguaro" +delete-after: True +changes: + - rscadd: "The Slime Scanner is available from the Autolathe." diff --git a/html/changelogs/AutoChangeLog-pr-860.yml b/html/changelogs/AutoChangeLog-pr-860.yml new file mode 100644 index 0000000000..5fbaa4435a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-860.yml @@ -0,0 +1,4 @@ +author: "Penguaro" +delete-after: True +changes: + - tweak: "The Design Names in the various machines are now capitalized consistently" diff --git a/html/changelogs/AutoChangeLog-pr-862.yml b/html/changelogs/AutoChangeLog-pr-862.yml new file mode 100644 index 0000000000..65ab5ed7f9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-862.yml @@ -0,0 +1,4 @@ +author: "Penguaro" +delete-after: True +changes: + - tweak: "Adjusts Meteor Shuttle Name" diff --git a/html/changelogs/AutoChangeLog-pr-877.yml b/html/changelogs/AutoChangeLog-pr-877.yml new file mode 100644 index 0000000000..436a3b32d0 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-877.yml @@ -0,0 +1,4 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "Visible ghosts emit light." diff --git a/html/changelogs/AutoChangeLog-pr-880.yml b/html/changelogs/AutoChangeLog-pr-880.yml new file mode 100644 index 0000000000..1b4ddc17a6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-880.yml @@ -0,0 +1,4 @@ +author: "Penguaro" +delete-after: True +changes: + - bugfix: "The Central Command Ferry will now dock at one of the ports in Arrivals" diff --git a/html/changelogs/AutoChangeLog-pr-882.yml b/html/changelogs/AutoChangeLog-pr-882.yml new file mode 100644 index 0000000000..74b564cb7d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-882.yml @@ -0,0 +1,6 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Curator's fedora has a pocket, like all the other fedoras." + - tweak: "Treasure hunter suits can now hold large internal tanks, to ease the exploration of lavaland." + - tweak: "The curator can now access the Auxillary Base and open doors on the mining station." diff --git a/html/changelogs/AutoChangeLog-pr-883.yml b/html/changelogs/AutoChangeLog-pr-883.yml new file mode 100644 index 0000000000..40d333fc28 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-883.yml @@ -0,0 +1,4 @@ +author: "Penguaro" +delete-after: True +changes: + - tweak: "[Meta] The Slime Control Console boundaries have been adjusted around the Kill Room" diff --git a/html/changelogs/AutoChangeLog-pr-884.yml b/html/changelogs/AutoChangeLog-pr-884.yml new file mode 100644 index 0000000000..e2ec253dac --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-884.yml @@ -0,0 +1,5 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - tweak: "Lighting now defaults to fully bright until the first update tick for that tile. This makes shuttle movements less immersion breaking." + - experiment: "Rather than remove the light source from the system and then re-adding it on light movements, the system now calculates and applies the difference to each tile. This should speed up lighting updates." diff --git a/html/changelogs/AutoChangeLog-pr-885.yml b/html/changelogs/AutoChangeLog-pr-885.yml new file mode 100644 index 0000000000..d92eda0b51 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-885.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - bugfix: "Fixes t-ray mode on engineering goggles not resetting the lighting override properly." diff --git a/html/changelogs/AutoChangeLog-pr-886.yml b/html/changelogs/AutoChangeLog-pr-886.yml new file mode 100644 index 0000000000..e87f6c5843 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-886.yml @@ -0,0 +1,4 @@ +author: "QualityVan" +delete-after: True +changes: + - tweak: "Machine names will be capitalized when they talk on radio" diff --git a/html/changelogs/AutoChangeLog-pr-890.yml b/html/changelogs/AutoChangeLog-pr-890.yml new file mode 100644 index 0000000000..c54b5312a5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-890.yml @@ -0,0 +1,5 @@ +author: "Kor" +delete-after: True +changes: + - rscadd: "a new mysterious book has been discovered in lavaland chests!" + - tweak: "weird purple hearts found in lavaland chests have started beating again! what could this mean?" diff --git a/html/changelogs/AutoChangeLog-pr-891.yml b/html/changelogs/AutoChangeLog-pr-891.yml new file mode 100644 index 0000000000..c623a1953f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-891.yml @@ -0,0 +1,5 @@ +author: "Joan" +delete-after: True +changes: + - rscadd: "You can now buy double eswords from the uplink for 16 telecrystals. They cannot be bought below 25 players." + - rscdel: "You can no longer use two eswords to construct a double esword." diff --git a/html/changelogs/AutoChangeLog-pr-895.yml b/html/changelogs/AutoChangeLog-pr-895.yml new file mode 100644 index 0000000000..a1aafb74af --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-895.yml @@ -0,0 +1,4 @@ +author: "Robustin" +delete-after: True +changes: + - tweak: "Dominators now require a significant amount of open (non-walled) space around them in order to operate." diff --git a/html/changelogs/AutoChangeLog-pr-896.yml b/html/changelogs/AutoChangeLog-pr-896.yml new file mode 100644 index 0000000000..f781a678ce --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-896.yml @@ -0,0 +1,4 @@ +author: "TehZombehz" +delete-after: True +changes: + - rscadd: "Sticks of butter and liquid mayonnaise can now be produced via a new 'mix' function on the grinder. Please eat responsibly." diff --git a/html/changelogs/AutoChangeLog-pr-897.yml b/html/changelogs/AutoChangeLog-pr-897.yml new file mode 100644 index 0000000000..d1df7340c6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-897.yml @@ -0,0 +1,4 @@ +author: "ma44" +delete-after: True +changes: + - tweak: "Doubles the amount of points wooden planks sell for (now 50 points)" diff --git a/html/changelogs/AutoChangeLog-pr-898.yml b/html/changelogs/AutoChangeLog-pr-898.yml new file mode 100644 index 0000000000..f744b5fe7b --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-898.yml @@ -0,0 +1,4 @@ +author: "Jay / Cecily" +delete-after: True +changes: + - rscadd: "added a hunter hat to the game. Purely cosmetic, can be found in clothesmate. Icon by Cecily Catherine." diff --git a/html/changelogs/AutoChangeLog-pr-900.yml b/html/changelogs/AutoChangeLog-pr-900.yml new file mode 100644 index 0000000000..e29ab96af8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-900.yml @@ -0,0 +1,4 @@ +author: "bandit" +delete-after: True +changes: + - tweak: "Nanotrasen has enhanced personality matchmaking for its personal AIs. pAI candidates will now see who is requesting a pAI personality." diff --git a/html/changelogs/AutoChangeLog-pr-913.yml b/html/changelogs/AutoChangeLog-pr-913.yml new file mode 100644 index 0000000000..dd72fe0130 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-913.yml @@ -0,0 +1,4 @@ +author: "Cebutris" +delete-after: True +changes: + - rscadd: "The Syndicate has found an abandoned storage facility filled with hundreds of holoparasite injectors. While they aren't giving them to their operatives, sleeper operatives can buy them with their uplinks! Get your holographic murder machine buddy today!" diff --git a/html/changelogs/AutoChangeLog-pr-927.yml b/html/changelogs/AutoChangeLog-pr-927.yml new file mode 100644 index 0000000000..bf908dd5b4 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-927.yml @@ -0,0 +1,4 @@ +author: "optional name here" +delete-after: True +changes: + - rscadd: "Zombies can now see in the dark. If you steal their eyes you'll be able to see in the dark as well!" diff --git a/html/changelogs/AutoChangeLog-pr-931.yml b/html/changelogs/AutoChangeLog-pr-931.yml new file mode 100644 index 0000000000..288b87f529 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-931.yml @@ -0,0 +1,5 @@ +author: "Kingofcarrotflowerspt1" +delete-after: True +changes: + - rscadd: "Adds Dakimakuras, more colloquially known as \"anime girl body pillows\"" + - rscadd: "They take up a hand slot and can hold a few items. Many different girls to choose from!" diff --git a/html/changelogs/AutoChangeLog-pr-937.yml b/html/changelogs/AutoChangeLog-pr-937.yml new file mode 100644 index 0000000000..239db4ced6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-937.yml @@ -0,0 +1,5 @@ +author: "Tacolizard Forever: It's hip to fuck bees" +delete-after: True +changes: + - rscadd: "Added a honey jar item. It's not implemented yet. +balance: Honey is now more robust at healing, but don't eat too much or you'll turn into a fatty landwhale." diff --git a/html/changelogs/AutoChangeLog-pr-938.yml b/html/changelogs/AutoChangeLog-pr-938.yml new file mode 100644 index 0000000000..b01da1649c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-938.yml @@ -0,0 +1,4 @@ +author: "TehZombehz" +delete-after: True +changes: + - rscadd: "Butter noodles, butter biscuits, buttered toast, and pigs in a blanket can now be crafted using sticks of butter and other ingredients." diff --git a/html/changelogs/AutoChangeLog-pr-940.yml b/html/changelogs/AutoChangeLog-pr-940.yml new file mode 100644 index 0000000000..eb86ebd439 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-940.yml @@ -0,0 +1,4 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Hermit ruin now includes a portable seed extractor." diff --git a/html/changelogs/AutoChangeLog-pr-944.yml b/html/changelogs/AutoChangeLog-pr-944.yml new file mode 100644 index 0000000000..8215cf0463 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-944.yml @@ -0,0 +1,4 @@ +author: "QualityVan" +delete-after: True +changes: + - bugfix: "Pizza boxes once again look different when open" diff --git a/html/changelogs/AutoChangeLog-pr-954.yml b/html/changelogs/AutoChangeLog-pr-954.yml new file mode 100644 index 0000000000..1c3a6cc9f8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-954.yml @@ -0,0 +1,5 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "Free Golems can purchase Royal Capes of the Liberator at their +mining equipment vendor." diff --git a/html/changelogs/AutoChangeLog-pr-958.yml b/html/changelogs/AutoChangeLog-pr-958.yml new file mode 100644 index 0000000000..c0825f367f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-958.yml @@ -0,0 +1,5 @@ +author: "coiax" +delete-after: True +changes: + - rscadd: "Goats on the station have developed a taste for glowshrooms, and +will eat them if they encounter any." diff --git a/html/changelogs/AutoChangeLog-pr-962.yml b/html/changelogs/AutoChangeLog-pr-962.yml new file mode 100644 index 0000000000..a5c9db8081 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-962.yml @@ -0,0 +1,6 @@ +author: "CitadelStationBot" +delete-after: True +changes: + - rscadd: "Ambrosia Deus can now mutate into Gaia, and Gaia into Deus." + - rscdel: "A single branch of Ambrosia Gaia will not immediately make a hydroponics tray self-sufficient. +balance: A (total) dose of 20u Earthsblood (from Gaia) will make a hydroponics tray self-sufficient." diff --git a/html/changelogs/AutoChangeLog-pr-963.yml b/html/changelogs/AutoChangeLog-pr-963.yml new file mode 100644 index 0000000000..bff7ed64f6 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-963.yml @@ -0,0 +1,4 @@ +author: "Joan" +delete-after: True +changes: + - tweak: "Glowshrooms now have a less saturated glow." diff --git a/html/changelogs/AutoChangeLog-pr-964.yml b/html/changelogs/AutoChangeLog-pr-964.yml new file mode 100644 index 0000000000..2aee77b88f --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-964.yml @@ -0,0 +1,10 @@ +author: "coiax" +delete-after: True +changes: + - bugfix: "Curator soapstones now successfully leave messages for future +shifts." + - rscdel: "Soapstones can no longer be purchased in cargo." + - rscdel: "The janitor no longer starts with an empty soapstone." + - experiment: "Engraved messages can be left anywhere in the world, but be +wary that the terrain of places like lavaland and space can change shift +to shift." diff --git a/html/changelogs/AutoChangeLog-pr-969.yml b/html/changelogs/AutoChangeLog-pr-969.yml new file mode 100644 index 0000000000..945463a4b1 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-969.yml @@ -0,0 +1,4 @@ +author: "McBawbaggings" +delete-after: True +changes: + - tweak: "SMES units will now accept charge from the power network even if the available load is less than the input rate. Credit to Zaers for the original code." diff --git a/html/changelogs/AutoChangeLog-pr-973.yml b/html/changelogs/AutoChangeLog-pr-973.yml new file mode 100644 index 0000000000..b4b175ce05 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-973.yml @@ -0,0 +1,6 @@ +author: "ma44" +delete-after: True +changes: + - tweak: "Seed vault remapped" + - tweak: "The seed vault random seed spawner can now spawn cherry bombs instead of regular cherry seeds" + - rscadd: "BEES to plant vault" diff --git a/icons/effects/64x64.dmi b/icons/effects/64x64.dmi index 347bccc942..361cfff40c 100644 Binary files a/icons/effects/64x64.dmi and b/icons/effects/64x64.dmi differ diff --git a/icons/effects/clockwork_effects.dmi b/icons/effects/clockwork_effects.dmi index 8bbf24a7ef..b2e15da1d0 100644 Binary files a/icons/effects/clockwork_effects.dmi and b/icons/effects/clockwork_effects.dmi differ diff --git a/icons/effects/cult_target.dmi b/icons/effects/cult_target.dmi new file mode 100644 index 0000000000..650feb3361 Binary files /dev/null and b/icons/effects/cult_target.dmi differ diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi index d684794ee8..fe537a8e73 100644 Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ diff --git a/icons/emoji.dmi b/icons/emoji.dmi old mode 100644 new mode 100755 index df89c12c94..9d3e0630a7 Binary files a/icons/emoji.dmi and b/icons/emoji.dmi differ diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index 39f374fb52..285f936a9e 100644 Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi index d28ed18c8a..9d63c276bc 100644 Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index 29c527b123..6d05b89039 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/icons/mob/jungle/arachnid.dmi b/icons/mob/jungle/arachnid.dmi new file mode 100644 index 0000000000..a1db8e351f Binary files /dev/null and b/icons/mob/jungle/arachnid.dmi differ diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi index 5858925d86..13f16aae59 100644 Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ diff --git a/icons/obj/clothing/cit_hats.dmi b/icons/obj/clothing/cit_hats.dmi new file mode 100644 index 0000000000..f9bf2a7a03 Binary files /dev/null and b/icons/obj/clothing/cit_hats.dmi differ diff --git a/icons/obj/daki.dmi b/icons/obj/daki.dmi new file mode 100644 index 0000000000..2b075f959c Binary files /dev/null and b/icons/obj/daki.dmi differ diff --git a/icons/obj/flora/jungletrees.dmi b/icons/obj/flora/jungletrees.dmi index 461ac0b265..67c7e0f463 100644 Binary files a/icons/obj/flora/jungletrees.dmi and b/icons/obj/flora/jungletrees.dmi differ diff --git a/icons/obj/food/containers.dmi b/icons/obj/food/containers.dmi index 2672732597..68c192bec3 100644 Binary files a/icons/obj/food/containers.dmi and b/icons/obj/food/containers.dmi differ diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi index c4713bd086..e7c0e8d263 100644 Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ diff --git a/icons/obj/food/pizzaspaghetti.dmi b/icons/obj/food/pizzaspaghetti.dmi index 8fb643c03c..245c737865 100644 Binary files a/icons/obj/food/pizzaspaghetti.dmi and b/icons/obj/food/pizzaspaghetti.dmi differ diff --git a/icons/obj/pneumaticCannon.dmi b/icons/obj/pneumaticCannon.dmi index 41de7677b5..86e14e19d6 100644 Binary files a/icons/obj/pneumaticCannon.dmi and b/icons/obj/pneumaticCannon.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 19d6275d78..78657abe36 100644 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/icons/obj/tiles.dmi b/icons/obj/tiles.dmi index d629cfe24d..5a8afeee51 100644 Binary files a/icons/obj/tiles.dmi and b/icons/obj/tiles.dmi differ diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi index f71e135dce..f2176c395d 100644 Binary files a/icons/obj/toy.dmi and b/icons/obj/toy.dmi differ diff --git a/icons/obj/vending_restock.dmi b/icons/obj/vending_restock.dmi index aa9f2873f0..eac7b8a266 100644 Binary files a/icons/obj/vending_restock.dmi and b/icons/obj/vending_restock.dmi differ diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi index a1cd8fb2f9..28bc9e28d3 100644 Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ diff --git a/icons/turf/floors/junglechasm.dmi b/icons/turf/floors/junglechasm.dmi new file mode 100644 index 0000000000..699a3b667c Binary files /dev/null and b/icons/turf/floors/junglechasm.dmi differ diff --git a/interface/menu.dm b/interface/menu.dm new file mode 100644 index 0000000000..4bebd5b202 --- /dev/null +++ b/interface/menu.dm @@ -0,0 +1,203 @@ +/* +/datum/menu/Example/verb/Example() + set name = "" //if this starts with @ the verb is not created and name becomes the command to invoke. + set desc = "" //desc is the text given to this entry in the menu + //You can not use src in these verbs. It will be the menu at compile time, but the client at runtime. +*/ + +GLOBAL_LIST_EMPTY(menulist) + +/world/proc/load_menu() + for (var/typepath in subtypesof(/datum/menu)) + new typepath() + +/datum/menu + var/name + var/list/children + var/datum/menu/myparent + var/list/verblist + var/checkbox = CHECKBOX_NONE //checkbox type. + var/default //default checked type. + //Set to true to append our children to our parent, + //Rather then add us as a node (used for having more then one checkgroups in the same menu) + var/abstract = FALSE + +/datum/menu/New() + var/ourentry = GLOB.menulist[type] + children = list() + verblist = list() + if (ourentry) + if (islist(ourentry)) //some of our childern already loaded + Add_children(ourentry) + else + stack_trace("Menu item double load: [type]") + qdel(src) + return + + GLOB.menulist[type] = src + + Load_verbs(type, typesof("[type]/verb")) + + var/datum/menu/parent = GLOB.menulist[parent_type] + if (!parent) + GLOB.menulist[parent_type] = list(src) + else if (islist(parent)) + parent += src + else + parent.Add_children(list(src)) + +/datum/menu/proc/Set_parent(datum/menu/parent) + myparent = parent + if (abstract) + myparent.Add_children(children) + var/list/verblistoftypes = list() + for(var/thing in verblist) + LAZYADD(verblistoftypes[verblist[thing]], thing) + + for(var/verbparenttype in verblistoftypes) + myparent.Load_verbs(verbparenttype, verblistoftypes[verbparenttype]) + +/datum/menu/proc/Add_children(list/kids) + if (abstract && myparent) + myparent.Add_children(kids) + return + + for(var/thing in kids) + var/datum/menu/menuitem = thing + menuitem.Set_parent(src) + if (!menuitem.abstract) + children += menuitem + +/datum/menu/proc/Load_verbs(verb_parent_type, list/verbs) + if (abstract && myparent) + myparent.Load_verbs(verb_parent_type, verbs) + return + + for (var/verbpath in verbs) + verblist[verbpath] = verb_parent_type + +/datum/menu/proc/Generate_list(client/C) + . = list() + if (length(children)) + for (var/thing in children) + var/datum/menu/child = thing + var/list/childlist = child.Generate_list(C) + if (childlist) + var/childname = "[child]" + if (childname == "[child.type]") + var/list/tree = splittext(childname, "/") + childname = tree[tree.len] + .[child.type] = "parent=[url_encode(type)];name=[url_encode(childname)]" + . += childlist + + + + for (var/thing in verblist) + var/atom/verb/verbpath = thing + if (!verbpath) + stack_trace("Bad VERB in [type] verblist: [english_list(verblist)]") + var/list/entry = list() + entry["parent"] = "[type]" + entry["name"] = verbpath.desc + if (copytext(verbpath.name,1,2) == "@") + entry["command"] = copytext(verbpath.name,2) + else + entry["command"] = replacetext(verbpath.name, " ", "-") + var/datum/menu/verb_true_parent = GLOB.menulist[verblist[verbpath]] + var/true_checkbox = verb_true_parent.checkbox + if (true_checkbox != CHECKBOX_NONE) + var/checkedverb = verb_true_parent.Get_checked(C) + if (true_checkbox == CHECKBOX_GROUP) + if (verbpath == checkedverb) + entry["is-checked"] = TRUE + else + entry["is-checked"] = FALSE + else if (true_checkbox == CHECKBOX_TOGGLE) + entry["is-checked"] = checkedverb + + entry["command"] = ".updatemenuchecked \"[verb_true_parent.type]\" \"[verbpath]\"\n[entry["command"]]" + entry["can-check"] = TRUE + entry["group"] = "[verb_true_parent.type]" + .[verbpath] = list2params(entry) + +/datum/menu/proc/Get_checked(client/C) + return C.prefs.menuoptions[type] || default || FALSE + +/datum/menu/proc/Load_checked(client/C) //Loads the checked menu item into a new client. Used by icon menus to invoke the checked item. + return + +/datum/menu/proc/Set_checked(client/C, verbpath) + if (checkbox == CHECKBOX_GROUP) + C.prefs.menuoptions[type] = verbpath + C.prefs.save_preferences() + else if (checkbox == CHECKBOX_TOGGLE) + var/checked = Get_checked(C) + C.prefs.menuoptions[type] = !checked + C.prefs.save_preferences() + winset(C, "[verbpath]", "is-checked = [!checked]") + +/client/verb/updatemenuchecked(menutype as text, verbpath as text) + set name = ".updatemenuchecked" + menutype = text2path(menutype) + verbpath = text2path(verbpath) + if (!menutype || !verbpath) + return + var/datum/menu/M = GLOB.menulist[menutype] + if (!M) + return + if (!(verbpath in typesof("[menutype]/verb"))) + return + M.Set_checked(src, verbpath) + + +/datum/menu/Icon/Load_checked(client/C) //So we can be lazy, we invoke the "checked" menu item on menu load. + var/atom/verb/verbpath = Get_checked(C) + if (!verbpath || !(verbpath in typesof("[type]/verb"))) + return + if (copytext(verbpath.name,1,2) == "@") + winset(C, null, "command = [copytext(verbpath.name,2)]") + else + winset(C, null, "command = [replacetext(verbpath.name, " ", "-")]") + +/datum/menu/Icon/Size + checkbox = CHECKBOX_GROUP + default = /datum/menu/Icon/Size/verb/iconstretchtofit + +/datum/menu/Icon/Size/verb/iconstretchtofit() + set name = "@.winset \"mapwindow.map.icon-size=0\"" + set desc = "&Auto (stretch-to-fit)" + +/datum/menu/Icon/Size/verb/icon96() + set name = "@.winset \"mapwindow.map.icon-size=96\"" + set desc = "&96x96 (3x)" + +/datum/menu/Icon/Size/verb/icon64() + set name = "@.winset \"mapwindow.map.icon-size=64\"" + set desc = "&64x64 (2x)" + +/datum/menu/Icon/Size/verb/icon48() + set name = "@.winset \"mapwindow.map.icon-size=48\"" + set desc = "&48x48 (1.5x)" + +/datum/menu/Icon/Size/verb/icon32() + set name = "@.winset \"mapwindow.map.icon-size=32\"" + set desc = "&32x32 (1x)" + + +/datum/menu/Icon/Scaling + checkbox = CHECKBOX_GROUP + name = "Scaling Mode" + default = /datum/menu/Icon/Scaling/verb/NN + +/datum/menu/Icon/Scaling/verb/NN() + set name = "@.winset \"mapwindow.map.zoom-mode=distort\"" + set desc = "Nearest Neighbor" + +/datum/menu/Icon/Scaling/verb/PS() + set name = "@.winset \"mapwindow.map.zoom-mode=normal\"" + set desc = "Point Sampling" + +/datum/menu/Icon/Scaling/verb/BL() + set name = "@.winset \"mapwindow.map.zoom-mode=blur\"" + set desc = "Bilinear" + diff --git a/interface/skin.dmf b/interface/skin.dmf index 788ce65b71..65407cef0e 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -1062,60 +1062,6 @@ menu "menu" group = "" is-disabled = false saved-params = "is-checked" - elem - name = "&Icons" - command = "" - category = "" - is-checked = false - can-check = false - group = "" - is-disabled = false - saved-params = "is-checked" - elem "auto" - name = "&Auto (stretch-to-fit)" - command = ".winset \"mapwindow.map.icon-size=0\"" - category = "&Icons" - is-checked = true - can-check = true - group = "size" - is-disabled = false - saved-params = "is-checked" - elem "icon96" - name = "&96x96 (3x)" - command = ".winset \"mapwindow.map.icon-size=96\"" - category = "&Icons" - is-checked = false - can-check = true - group = "size" - is-disabled = false - saved-params = "is-checked" - elem "icon64" - name = "&64x64 (2x)" - command = ".winset \"mapwindow.map.icon-size=64\"" - category = "&Icons" - is-checked = false - can-check = true - group = "size" - is-disabled = false - saved-params = "is-checked" - elem "icon48" - name = "&48x48 (1.5x)" - command = ".winset \"mapwindow.map.icon-size=48\"" - category = "&Icons" - is-checked = false - can-check = true - group = "size" - is-disabled = false - saved-params = "is-checked" - elem "icon32" - name = "&32x32" - command = ".winset \"mapwindow.map.icon-size=32\"" - category = "&Icons" - is-checked = false - can-check = true - group = "size" - is-disabled = false - saved-params = "is-checked" elem name = "&Help" command = "" @@ -1383,6 +1329,7 @@ window "mapwindow" on-show = "" on-hide = "" style = "" + zoom-mode = "distort" window "infowindow" elem "infowindow" diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index a758818c8c..acecb4874b 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -154,4 +154,5 @@ BIG IMG.icon {width: 32px; height: 32px;} .love {color: #FF69Bf;} .lovebold {color: #FF69Bf; font-weight: bold;} +.resonate {color: #298F85;} "} diff --git a/sound/effects/snap01.ogg b/sound/effects/snap01.ogg new file mode 100644 index 0000000000..aa7ab9f5bf Binary files /dev/null and b/sound/effects/snap01.ogg differ diff --git a/sound/misc/highlander.ogg b/sound/misc/highlander.ogg index 2116f8a972..01148b55db 100644 Binary files a/sound/misc/highlander.ogg and b/sound/misc/highlander.ogg differ diff --git a/sound/misc/highlander_delayed.ogg b/sound/misc/highlander_delayed.ogg index d1cce70781..2645349662 100644 Binary files a/sound/misc/highlander_delayed.ogg and b/sound/misc/highlander_delayed.ogg differ diff --git a/sound/misc/highlander_only_one.ogg b/sound/misc/highlander_only_one.ogg index 3b69d26ade..6458d10ab6 100644 Binary files a/sound/misc/highlander_only_one.ogg and b/sound/misc/highlander_only_one.ogg differ diff --git a/config/admin_nicknames.txt b/strings/admin_nicknames.txt similarity index 100% rename from config/admin_nicknames.txt rename to strings/admin_nicknames.txt diff --git a/strings/cas_black.txt b/strings/cas_black.txt index ba078abea4..2e7c6fb407 100644 --- a/strings/cas_black.txt +++ b/strings/cas_black.txt @@ -76,7 +76,7 @@ I'm not a space bigot, I just hate _________. Why is the station so filthy? THE SHUTTLE CANNOT BE CALLED BECAUSE OF ________ ON THE STATION. After murdering dozens, the traitor was finally brought down by _________. -The librarian has read a lot of porn, but never about _____________! +The curator has read a lot of porn, but never about _____________! Oh god! There's ________________ outside escape! The hottest new space couple is ________ and __________. Lord Singulo hungers for _______. diff --git a/strings/cas_white.txt b/strings/cas_white.txt index 506f6f6c65..d36f19ffe9 100644 --- a/strings/cas_white.txt +++ b/strings/cas_white.txt @@ -61,7 +61,7 @@ Lopping off the Captain's johnson and shooting it out a pneumatic cannon. The secret monkey technique. Putting the pAI's doorjack where it don't belong. Chemical sprayers filled with lube. -Librarians. +Curators. Spooky skeletons. Replicating the Milgram experiment with an electropack. Catgirls. diff --git a/strings/ion_laws.json b/strings/ion_laws.json index a4a3e312f7..5a61fc3196 100644 --- a/strings/ion_laws.json +++ b/strings/ion_laws.json @@ -343,7 +343,7 @@ "CLOWNS", "MIMES", "CHAPLAINS", - "LIBRARIANS", + "CURATORS", "HEADS OF CREW", "CAPTAINS AND HEADS", "CYBORGS", diff --git a/config/sillytips.txt b/strings/sillytips.txt similarity index 100% rename from config/sillytips.txt rename to strings/sillytips.txt diff --git a/config/tips.txt b/strings/tips.txt similarity index 100% rename from config/tips.txt rename to strings/tips.txt diff --git a/tgstation.dme b/tgstation.dme index 1d70945dfe..75d9e506aa 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -47,6 +47,7 @@ #include "code\__DEFINES\maps.dm" #include "code\__DEFINES\math.dm" #include "code\__DEFINES\MC.dm" +#include "code\__DEFINES\menu.dm" #include "code\__DEFINES\misc.dm" #include "code\__DEFINES\mobs.dm" #include "code\__DEFINES\monkeys.dm" @@ -75,7 +76,6 @@ #include "code\__HELPERS\_logging.dm" #include "code\__HELPERS\_string_lists.dm" #include "code\__HELPERS\AStar.dm" -#include "code\__HELPERS\bandetect.dm" #include "code\__HELPERS\cmp.dm" #include "code\__HELPERS\files.dm" #include "code\__HELPERS\flags.dm" @@ -874,6 +874,7 @@ #include "code\game\objects\items\weapons\storage\book.dm" #include "code\game\objects\items\weapons\storage\boxes.dm" #include "code\game\objects\items\weapons\storage\briefcase.dm" +#include "code\game\objects\items\weapons\storage\dakis.dm" #include "code\game\objects\items\weapons\storage\fancy.dm" #include "code\game\objects\items\weapons\storage\firstaid.dm" #include "code\game\objects\items\weapons\storage\internal.dm" @@ -1002,6 +1003,7 @@ #include "code\modules\admin\admin_investigate.dm" #include "code\modules\admin\admin_ranks.dm" #include "code\modules\admin\admin_verbs.dm" +#include "code\modules\admin\adminmenu.dm" #include "code\modules\admin\banjob.dm" #include "code\modules\admin\create_mob.dm" #include "code\modules\admin\create_object.dm" @@ -1178,6 +1180,7 @@ #include "code\modules\clothing\gloves\miscellaneous.dm" #include "code\modules\clothing\gloves\vg_gloves.dm" #include "code\modules\clothing\head\beanie.dm" +#include "code\modules\clothing\head\cit_hats.dm" #include "code\modules\clothing\head\collectable.dm" #include "code\modules\clothing\head\hardhat.dm" #include "code\modules\clothing\head\helmet.dm" @@ -1718,6 +1721,7 @@ #include "code\modules\mob\living\simple_animal\hostile\hivebot.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\jungle_mobs.dm" #include "code\modules\mob\living\simple_animal\hostile\killertomato.dm" #include "code\modules\mob\living\simple_animal\hostile\mecha_pilot.dm" #include "code\modules\mob\living\simple_animal\hostile\mimic.dm" @@ -2016,6 +2020,7 @@ #include "code\modules\shuttle\arrivals.dm" #include "code\modules\shuttle\assault_pod.dm" #include "code\modules\shuttle\computer.dm" +#include "code\modules\shuttle\elevator.dm" #include "code\modules\shuttle\emergency.dm" #include "code\modules\shuttle\ferry.dm" #include "code\modules\shuttle\manipulator.dm" @@ -2160,6 +2165,7 @@ #include "code\modules\zombie\items.dm" #include "code\modules\zombie\organs.dm" #include "interface\interface.dm" +#include "interface\menu.dm" #include "interface\stylesheet.dm" #include "interface\skin.dmf" // END_INCLUDE diff --git a/tgui/assets/tgui.css b/tgui/assets/tgui.css index d52500b9d6..531fb00530 100644 --- a/tgui/assets/tgui.css +++ b/tgui/assets/tgui.css @@ -1 +1 @@ -@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2a2a2a',endColorstr='#ff202020',GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffb18b25',endColorstr='#ff5f380e',GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-right:after{-webkit-transform:translateX(-8px) translateY(-50%);-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input::-webkit-input-placeholder{color:#999}body.clockwork input::-moz-placeholder{color:#999}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-webkit-transform:rotate(1turn);-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(even){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCA0MjUgMjAwIiBvcGFjaXR5PSIuMzMiPgogIDxwYXRoIGQ9Im0gMTc4LjAwMzk5LDAuMDM4NjkgLTcxLjIwMzkzLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM0LDYuMDI1NTUgbCAwLDE4Ny44NzE0NyBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgNi43NjEzNCw2LjAyNTU0IGwgNTMuMTA3MiwwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM1LC02LjAyNTU0IGwgMCwtMTAxLjU0NDAxOCA3Mi4yMTYyOCwxMDQuNjk5Mzk4IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA1Ljc2MDE1LDIuODcwMTYgbCA3My41NTQ4NywwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM1LC02LjAyNTU0IGwgMCwtMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNi43NjEzNSwtNi4wMjU1NSBsIC01NC43MTY0NCwwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNi43NjEzMyw2LjAyNTU1IGwgMCwxMDIuNjE5MzUgTCAxODMuNzY0MTMsMi45MDg4NiBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTUuNzYwMTQsLTIuODcwMTcgeiIgLz4KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPgogIDxwYXRoIGQ9Im0gNDIwLjE1NTM1LDE3Ny44OTExOSBhIDEzLjQxMjAzOCwxMi41MDE4NDIgMCAwIDEgLTguNjMyOTUsMjIuMDY5NTEgbCAtNjYuMTE4MzIsMCBhIDUuMzY0ODE1Miw1LjAwMDczNyAwIDAgMSAtNS4zNjQ4MiwtNS4wMDA3NCBsIDAsLTc5Ljg3OTMxIHoiIC8+Cjwvc3ZnPgo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4KPCEtLSBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1zYS80LjAvIC0tPgo=") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2a2a2a',endColorstr='#ff202020',GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:after{-webkit-transform:translateX(-8px) translateY(-50%);-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input::-webkit-input-placeholder{color:#999}body.nanotrasen input::-moz-placeholder{color:#999}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-webkit-transform:rotate(1turn);-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(even){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCAyMDAgMjg5Ljc0MiIgb3BhY2l0eT0iLjMzIj4KICA8cGF0aCBkPSJtIDkzLjUzNzY3NywwIGMgLTE4LjExMzEyNSwwIC0zNC4yMjAxMzMsMy4xMTE2NCAtNDguMzIzNDg0LDkuMzM0MzcgLTEzLjk2NTA5Miw2LjIyMTY3IC0yNC42MTI0NDIsMTUuMDcxMTQgLTMxLjk0MDY1MSwyNi41NDcxIC03LjE4OTkzOTgsMTEuMzM3ODkgLTEwLjMwMTIyNjYsMjQuNzQ5MTEgLTEwLjMwMTIyNjYsNDAuMjM0NzggMCwxMC42NDY2MiAyLjcyNTAwMjYsMjAuNDY0NjUgOC4xNzUxMTE2LDI5LjQ1MjU4IDUuNjE1Mjc3LDguOTg2ODYgMTQuMDM4Mjc3LDE3LjM1MjA0IDI1LjI2ODgyMSwyNS4wOTQzNiAxMS4yMzA1NDQsNy42MDUzMSAyNi41MDc0MjEsMTUuNDE4MzUgNDUuODMwNTE0LDIzLjQzNzgyIDE5Ljk4Mzc0OCw4LjI5NTU3IDM0Ljg0ODg0OCwxNS41NTQ3MSA0NC41OTI5OTgsMjEuNzc2MzggOS43NDQxNCw2LjIyMjczIDE2Ljc2MTcsMTIuODU4NSAyMS4wNTU3MiwxOS45MDk1MSA0LjI5NDA0LDcuMDUyMDggNi40NDE5MywxNS43NjQwOCA2LjQ0MTkzLDI2LjEzNDU5IDAsMTYuMTc3MDIgLTUuMjAxOTYsMjguNDgyMjIgLTE1LjYwNjczLDM2LjkxNjgyIC0xMC4yMzk2LDguNDM0NyAtMjUuMDIyMDMsMTIuNjUyMyAtNDQuMzQ1MTY5LDEyLjY1MjMgLTE0LjAzODE3MSwwIC0yNS41MTUyNDcsLTEuNjU5NCAtMzQuNDMzNjE4LC00Ljk3NzcgLTguOTE4MzcsLTMuNDU2NiAtMTYuMTg1NTcyLC04LjcxMTMgLTIxLjgwMDgzOSwtMTUuNzYzMyAtNS42MTUyNzcsLTcuMDUyMSAtMTAuMDc0Nzk1LC0xNi42NjA4OCAtMTMuMzc3ODk5LC0yOC44MjgxMiBsIC0yNC43NzMxNjI2MjkzOTQ1LDAgMCw1Ni44MjYzMiBDIDMzLjg1Njc2OSwyODYuMDc2MDEgNjMuNzQ5MDQsMjg5Ljc0MjAxIDg5LjY3ODM4MywyODkuNzQyMDEgYyAxNi4wMjAwMjcsMCAzMC43MTk3ODcsLTEuMzgyNyA0NC4wOTczMzcsLTQuMTQ3OSAxMy41NDI3MiwtMi45MDQzIDI1LjEwNDEsLTcuNDY3NiAzNC42ODMwOSwtMTMuNjg5MyA5Ljc0NDEzLC02LjM1OTcgMTcuMzQwNDIsLTE0LjUxOTUgMjIuNzkwNTIsLTI0LjQ3NDggNS40NTAxLC0xMC4wOTMzMiA4LjE3NTExLC0yMi4zOTk1OSA4LjE3NTExLC0zNi45MTY4MiAwLC0xMi45OTc2NCAtMy4zMDIxLC0yNC4zMzUzOSAtOS45MDgyOSwtMzQuMDE0NiAtNi40NDEwNSwtOS44MTcyNSAtMTUuNTI1NDUsLTE4LjUyNzA3IC0yNy4yNTE0NiwtMjYuMTMxMzMgLTExLjU2MDg1LC03LjYwNDI3IC0yNy45MTA4MywtMTUuODMxNDIgLTQ5LjA1MDY2LC0yNC42ODAyMiAtMTcuNTA2NDQsLTcuMTkwMTIgLTMwLjcxOTY2OCwtMTMuNjg5NDggLTM5LjYzODAzOCwtMTkuNDk3MDEgLTguOTE4MzcxLC01LjgwNzUyIC0xOC42MDc0NzQsLTEyLjQzNDA5IC0yNC4wOTY1MjQsLTE4Ljg3NDE3IC01LjQyNjA0MywtNi4zNjYxNiAtOS42NTg4MjYsLTE1LjA3MDAzIC05LjY1ODgyNiwtMjQuODg3MjkgMCwtOS4yNjQwMSAyLjA3NTQxNCwtMTcuMjEzNDUgNi4yMjM0NTQsLTIzLjg1MDMzIDExLjA5ODI5OCwtMTQuMzk3NDggNDEuMjg2NjM4LC0xLjc5NTA3IDQ1LjA3NTYwOSwyNC4zNDc2MiA0LjgzOTM5Miw2Ljc3NDkxIDguODQ5MzUsMTYuMjQ3MjkgMTIuMDI5NTE1LDI4LjQxNTYgbCAyMC41MzIzNCwwIDAsLTU1Ljk5OTY3IGMgLTQuNDc4MjUsLTUuOTI0NDggLTkuOTU0ODgsLTEwLjYzMjIyIC0xNS45MDgzNywtMTQuMzc0MTEgMS42NDA1NSwwLjQ3OTA1IDMuMTkwMzksMS4wMjM3NiA0LjYzODY1LDEuNjQwMjQgNi40OTg2MSwyLjYyNjA3IDEyLjE2NzkzLDcuMzI3NDcgMTcuMDA3MywxNC4xMDM0NSA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNSwxNi4yNDU2NyAxMi4wMjk1MiwyOC40MTM5NyAwLDAgOC40ODEyOCwtMC4xMjg5NCA4LjQ4OTc4LC0wLjAwMiAwLjQxNzc2LDYuNDE0OTQgLTEuNzUzMzksOS40NTI4NiAtNC4xMjM0MiwxMi41NjEwNCAtMi40MTc0LDMuMTY5NzggLTUuMTQ0ODYsNi43ODk3MyAtNC4wMDI3OCwxMy4wMDI5IDEuNTA3ODYsOC4yMDMxOCAxMC4xODM1NCwxMC41OTY0MiAxNC42MjE5NCw5LjMxMTU0IC0zLjMxODQyLC0wLjQ5OTExIC01LjMxODU1LC0xLjc0OTQ4IC01LjMxODU1LC0xLjc0OTQ4IDAsMCAxLjg3NjQ2LDAuOTk4NjggNS42NTExNywtMS4zNTk4MSAtMy4yNzY5NSwwLjk1NTcxIC0xMC43MDUyOSwtMC43OTczOCAtMTEuODAxMjUsLTYuNzYzMTMgLTAuOTU3NTIsLTUuMjA4NjEgMC45NDY1NCwtNy4yOTUxNCAzLjQwMTEzLC0xMC41MTQ4MiAyLjQ1NDYyLC0zLjIxOTY4IDUuMjg0MjYsLTYuOTU4MzEgNC42ODQzLC0xNC40ODgyNCBsIDAuMDAzLDAuMDAyIDguOTI2NzYsMCAwLC01NS45OTk2NyBjIC0xNS4wNzEyNSwtMy44NzE2OCAtMjcuNjUzMTQsLTYuMzYwNDIgLTM3Ljc0NjcxLC03LjQ2NTg2IC05Ljk1NTMxLC0xLjEwNzU1IC0yMC4xODgyMywtMS42NTk4MSAtMzAuNjk2NjEzLC0xLjY1OTgxIHogbSA3MC4zMjE2MDMsMTcuMzA4OTMgMC4yMzgwNSw0MC4zMDQ5IGMgMS4zMTgwOCwxLjIyNjY2IDIuNDM5NjUsMi4yNzgxNSAzLjM0MDgxLDMuMTA2MDIgNC44MzkzOSw2Ljc3NDkxIDguODQ5MzQsMTYuMjQ1NjYgMTIuMDI5NTEsMjguNDEzOTcgbCAyMC41MzIzNCwwIDAsLTU1Ljk5OTY3IGMgLTYuNjc3MzEsLTQuNTkzODEgLTE5LjgzNjQzLC0xMC40NzMwOSAtMzYuMTQwNzEsLTE1LjgyNTIyIHogbSAtMjguMTIwNDksNS42MDU1MSA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM3LC02LjQ2Njk3IC0xMy44NDY3OCwtOS43MTcyNiAtOC41NjQ3OSwtMTcuNzE2NTUgeiBtIDIyLjc5NzA1LDAgYyAyLjc3MTUsNy45OTkyOSAxLjc4NzQxLDExLjI0OTU4IC00LjQ5MzU0LDE3LjcxNjU1IGwgNC40OTM1NCwtMTcuNzE2NTUgeiBtIDE1LjIyMTk1LDI0LjAwODQ4IDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzgsLTYuNDY2OTcgLTEzLjg0Njc5LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDQsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gLTk5LjExMzg0LDIuMjA3NjQgOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzODIsLTYuNDY2OTcgLTEzLjg0Njc4MiwtOS43MTcyNiAtOC41NjQ3OSwtMTcuNzE2NTUgeiBtIDIyLjc5NTQyLDAgYyAyLjc3MTUsNy45OTkyOSAxLjc4NzQxLDExLjI0OTU4IC00LjQ5MzU0LDE3LjcxNjU1IGwgNC40OTM1NCwtMTcuNzE2NTUgeiIgLz4KPC9zdmc+CjwhLS0gVGhpcyB3b3JrIGlzIGxpY2Vuc2VkIHVuZGVyIGEgQ3JlYXRpdmUgQ29tbW9ucyBBdHRyaWJ1dGlvbi1TaGFyZUFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UuIC0tPgo8IS0tIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LXNhLzQuMC8gLS0+Cg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff750000',endColorstr='#ff340404',GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-right:after{-webkit-transform:translateX(-8px) translateY(-50%);-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-webkit-transform:translateX(8px) translateY(-50%);-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input::-webkit-input-placeholder{color:#999}body.syndicate input::-moz-placeholder{color:#999}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-webkit-transform:rotate(1turn);-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(even){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file +@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input::-webkit-input-placeholder{color:#999}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input::-webkit-input-placeholder{color:#999}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input::-webkit-input-placeholder{color:#999}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"} \ No newline at end of file diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js index 91d54d3871..9149710c78 100644 --- a/tgui/assets/tgui.js +++ b/tgui/assets/tgui.js @@ -1,3 +1,4 @@ + require=function t(e,n,a){function r(o,s){if(!n[o]){if(!e[o]){var p="function"==typeof require&&require;if(!s&&p)return p(o,!0);if(i)return i(o,!0);var u=Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var c=n[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return r(n?n:t)},c,c.exports,t,e,n,a)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o=0;--a){var r=this.tryEntries[a],i=r.completion;if("root"===r.tryLoc)return e("end");if(r.tryLoc<=this.prev){var o=b.call(r,"catchLoc"),s=b.call(r,"finallyLoc");if(o&&s){if(this.prev=0;--n){var a=this.tryEntries[n];if(a.tryLoc<=this.prev&&b.call(a,"finallyLoc")&&this.prev=0;--e){var n=this.tryEntries[e];if(n.finallyLoc===t)return this.complete(n.completion,n.afterLoc),d(n),E}},"catch":function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var n=this.tryEntries[e];if(n.tryLoc===t){var a=n.completion;if("throw"===a.type){var r=a.arg;d(n)}return r}}throw Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:m(t),resultName:e,nextLoc:n},E}}}("object"==typeof n?n:"object"==typeof window?window:"object"==typeof self?self:this)}).call(this,t(190),void 0!==n?n:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{190:190}],3:[function(t,e,n){e.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},{}],4:[function(t,e,n){var a=t(84)("unscopables"),r=Array.prototype;void 0==r[a]&&t(32)(r,a,{}),e.exports=function(t){r[a][t]=!0}},{32:32,84:84}],5:[function(t,e,n){var a=t(39);e.exports=function(t){if(!a(t))throw TypeError(t+" is not an object!");return t}},{39:39}],6:[function(t,e,n){"use strict";var a=t(81),r=t(77),i=t(80);e.exports=[].copyWithin||function(t,e){var n=a(this),o=i(n.length),s=r(t,o),p=r(e,o),u=arguments,c=u.length>2?u[2]:void 0,l=Math.min((void 0===c?o:r(c,o))-p,o-s),f=1;for(s>p&&p+l>s&&(f=-1,p+=l-1,s+=l-1);l-- >0;)p in n?n[s]=n[p]:delete n[s],s+=f,p+=f;return n}},{77:77,80:80,81:81}],7:[function(t,e,n){"use strict";var a=t(81),r=t(77),i=t(80);e.exports=[].fill||function(t){for(var e=a(this),n=i(e.length),o=arguments,s=o.length,p=r(s>1?o[1]:void 0,n),u=s>2?o[2]:void 0,c=void 0===u?n:r(u,n);c>p;)e[p++]=t;return e}},{77:77,80:80,81:81}],8:[function(t,e,n){var a=t(79),r=t(80),i=t(77);e.exports=function(t){return function(e,n,o){var s,p=a(e),u=r(p.length),c=i(o,u);if(t&&n!=n){for(;u>c;)if(s=p[c++],s!=s)return!0}else for(;u>c;c++)if((t||c in p)&&p[c]===n)return t||c;return!t&&-1}}},{77:77,79:79,80:80}],9:[function(t,e,n){var a=t(18),r=t(35),i=t(81),o=t(80),s=t(10);e.exports=function(t){var e=1==t,n=2==t,p=3==t,u=4==t,c=6==t,l=5==t||c;return function(f,d,h){for(var m,v,g=i(f),b=r(g),y=a(d,h,3),_=o(b.length),x=0,w=e?s(f,_):n?s(f,0):void 0;_>x;x++)if((l||x in b)&&(m=b[x],v=y(m,x,g),t))if(e)w[x]=v;else if(v)switch(t){case 3:return!0;case 5:return m;case 6:return x;case 2:w.push(m)}else if(u)return!1;return c?-1:p||u?u:w}}},{10:10,18:18,35:35,80:80,81:81}],10:[function(t,e,n){var a=t(39),r=t(37),i=t(84)("species");e.exports=function(t,e){var n;return r(t)&&(n=t.constructor,"function"!=typeof n||n!==Array&&!r(n.prototype)||(n=void 0),a(n)&&(n=n[i],null===n&&(n=void 0))),new(void 0===n?Array:n)(e)}},{37:37,39:39,84:84}],11:[function(t,e,n){var a=t(12),r=t(84)("toStringTag"),i="Arguments"==a(function(){return arguments}());e.exports=function(t){var e,n,o;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=(e=Object(t))[r])?n:i?a(e):"Object"==(o=a(e))&&"function"==typeof e.callee?"Arguments":o}},{12:12,84:84}],12:[function(t,e,n){var a={}.toString;e.exports=function(t){return a.call(t).slice(8,-1)}},{}],13:[function(t,e,n){"use strict";var a=t(47),r=t(32),i=t(61),o=t(18),s=t(70),p=t(19),u=t(28),c=t(43),l=t(45),f=t(83)("id"),d=t(31),h=t(39),m=t(66),v=t(20),g=Object.isExtensible||h,b=v?"_s":"size",y=0,_=function(t,e){if(!h(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!d(t,f)){if(!g(t))return"F";if(!e)return"E";r(t,f,++y)}return"O"+t[f]},x=function(t,e){var n,a=_(e);if("F"!==a)return t._i[a];for(n=t._f;n;n=n.n)if(n.k==e)return n};e.exports={getConstructor:function(t,e,n,r){var c=t(function(t,i){s(t,c,e),t._i=a.create(null),t._f=void 0,t._l=void 0,t[b]=0,void 0!=i&&u(i,n,t[r],t)});return i(c.prototype,{clear:function(){for(var t=this,e=t._i,n=t._f;n;n=n.n)n.r=!0,n.p&&(n.p=n.p.n=void 0),delete e[n.i];t._f=t._l=void 0,t[b]=0},"delete":function(t){var e=this,n=x(e,t);if(n){var a=n.n,r=n.p;delete e._i[n.i],n.r=!0,r&&(r.n=a),a&&(a.p=r),e._f==n&&(e._f=a),e._l==n&&(e._l=r),e[b]--}return!!n},forEach:function(t){for(var e,n=o(t,arguments.length>1?arguments[1]:void 0,3);e=e?e.n:this._f;)for(n(e.v,e.k,this);e&&e.r;)e=e.p},has:function(t){return!!x(this,t)}}),v&&a.setDesc(c.prototype,"size",{get:function(){return p(this[b])}}),c},def:function(t,e,n){var a,r,i=x(t,e);return i?i.v=n:(t._l=i={i:r=_(e,!0),k:e,v:n,p:a=t._l,n:void 0,r:!1},t._f||(t._f=i),a&&(a.n=i),t[b]++,"F"!==r&&(t._i[r]=i)),t},getEntry:x,setStrong:function(t,e,n){c(t,e,function(t,e){this._t=t,this._k=e,this._l=void 0},function(){for(var t=this,e=t._k,n=t._l;n&&n.r;)n=n.p;return t._t&&(t._l=n=n?n.n:t._t._f)?"keys"==e?l(0,n.k):"values"==e?l(0,n.v):l(0,[n.k,n.v]):(t._t=void 0,l(1))},n?"entries":"values",!n,!0),m(e)}}},{18:18,19:19,20:20,28:28,31:31,32:32,39:39,43:43,45:45,47:47,61:61,66:66,70:70,83:83}],14:[function(t,e,n){var a=t(28),r=t(11);e.exports=function(t){return function(){if(r(this)!=t)throw TypeError(t+"#toJSON isn't generic");var e=[];return a(this,!1,e.push,e),e}}},{11:11,28:28}],15:[function(t,e,n){"use strict";var a=t(32),r=t(61),i=t(5),o=t(39),s=t(70),p=t(28),u=t(9),c=t(31),l=t(83)("weak"),f=Object.isExtensible||o,d=u(5),h=u(6),m=0,v=function(t){return t._l||(t._l=new g)},g=function(){this.a=[]},b=function(t,e){return d(t.a,function(t){return t[0]===e})};g.prototype={get:function(t){var e=b(this,t);return e?e[1]:void 0},has:function(t){return!!b(this,t)},set:function(t,e){var n=b(this,t);n?n[1]=e:this.a.push([t,e])},"delete":function(t){var e=h(this.a,function(e){return e[0]===t});return~e&&this.a.splice(e,1),!!~e}},e.exports={getConstructor:function(t,e,n,a){var i=t(function(t,r){s(t,i,e),t._i=m++,t._l=void 0,void 0!=r&&p(r,n,t[a],t)});return r(i.prototype,{"delete":function(t){return o(t)?f(t)?c(t,l)&&c(t[l],this._i)&&delete t[l][this._i]:v(this)["delete"](t):!1},has:function(t){return o(t)?f(t)?c(t,l)&&c(t[l],this._i):v(this).has(t):!1}}),i},def:function(t,e,n){return f(i(e))?(c(e,l)||a(e,l,{}),e[l][t._i]=n):v(t).set(e,n),t},frozenStore:v,WEAK:l}},{28:28,31:31,32:32,39:39,5:5,61:61,70:70,83:83,9:9}],16:[function(t,e,n){"use strict";var a=t(30),r=t(23),i=t(62),o=t(61),s=t(28),p=t(70),u=t(39),c=t(25),l=t(44),f=t(67);e.exports=function(t,e,n,d,h,m){var v=a[t],g=v,b=h?"set":"add",y=g&&g.prototype,_={},x=function(t){var e=y[t];i(y,t,"delete"==t?function(t){return m&&!u(t)?!1:e.call(this,0===t?0:t)}:"has"==t?function(t){return m&&!u(t)?!1:e.call(this,0===t?0:t)}:"get"==t?function(t){return m&&!u(t)?void 0:e.call(this,0===t?0:t)}:"add"==t?function(t){return e.call(this,0===t?0:t),this}:function(t,n){return e.call(this,0===t?0:t,n),this})};if("function"==typeof g&&(m||y.forEach&&!c(function(){(new g).entries().next()}))){var w,k=new g,P=k[b](m?{}:-0,1)!=k,C=c(function(){k.has(1)}),E=l(function(t){new g(t)});E||(g=e(function(e,n){p(e,g,t);var a=new v;return void 0!=n&&s(n,h,a[b],a),a}),g.prototype=y,y.constructor=g),m||k.forEach(function(t,e){w=1/e===-(1/0)}),(C||w)&&(x("delete"),x("has"),h&&x("get")),(w||P)&&x(b),m&&y.clear&&delete y.clear}else g=d.getConstructor(e,t,h,b),o(g.prototype,n);return f(g,t),_[t]=g,r(r.G+r.W+r.F*(g!=v),_),m||d.setStrong(g,t,h),g}},{23:23,25:25,28:28,30:30,39:39,44:44,61:61,62:62,67:67,70:70}],17:[function(t,e,n){var a=e.exports={version:"1.2.6"};"number"==typeof __e&&(__e=a)},{}],18:[function(t,e,n){var a=t(3);e.exports=function(t,e,n){if(a(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,a){return t.call(e,n,a)};case 3:return function(n,a,r){return t.call(e,n,a,r)}}return function(){return t.apply(e,arguments)}}},{3:3}],19:[function(t,e,n){e.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},{}],20:[function(t,e,n){e.exports=!t(25)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},{25:25}],21:[function(t,e,n){var a=t(39),r=t(30).document,i=a(r)&&a(r.createElement);e.exports=function(t){return i?r.createElement(t):{}}},{30:30,39:39}],22:[function(t,e,n){var a=t(47);e.exports=function(t){var e=a.getKeys(t),n=a.getSymbols;if(n)for(var r,i=n(t),o=a.isEnum,s=0;i.length>s;)o.call(t,r=i[s++])&&e.push(r);return e}},{47:47}],23:[function(t,e,n){var a=t(30),r=t(17),i=t(32),o=t(62),s=t(18),p="prototype",u=function(t,e,n){var c,l,f,d,h=t&u.F,m=t&u.G,v=t&u.S,g=t&u.P,b=t&u.B,y=m?a:v?a[e]||(a[e]={}):(a[e]||{})[p],_=m?r:r[e]||(r[e]={}),x=_[p]||(_[p]={});m&&(n=e);for(c in n)l=!h&&y&&c in y,f=(l?y:n)[c],d=b&&l?s(f,a):g&&"function"==typeof f?s(Function.call,f):f,y&&!l&&o(y,c,f),_[c]!=f&&i(_,c,d),g&&x[c]!=f&&(x[c]=f)};a.core=r,u.F=1,u.G=2,u.S=4,u.P=8,u.B=16,u.W=32,e.exports=u},{17:17,18:18,30:30,32:32,62:62}],24:[function(t,e,n){var a=t(84)("match");e.exports=function(t){var e=/./;try{"/./"[t](e)}catch(n){try{return e[a]=!1,!"/./"[t](e)}catch(r){}}return!0}},{84:84}],25:[function(t,e,n){e.exports=function(t){try{return!!t()}catch(e){return!0}}},{}],26:[function(t,e,n){"use strict";var a=t(32),r=t(62),i=t(25),o=t(19),s=t(84);e.exports=function(t,e,n){var p=s(t),u=""[t];i(function(){var e={};return e[p]=function(){return 7},7!=""[t](e)})&&(r(String.prototype,t,n(o,p,u)),a(RegExp.prototype,p,2==e?function(t,e){return u.call(t,this,e)}:function(t){return u.call(t,this)}))}},{19:19,25:25,32:32,62:62,84:84}],27:[function(t,e,n){"use strict";var a=t(5);e.exports=function(){var t=a(this),e="";return t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.unicode&&(e+="u"),t.sticky&&(e+="y"),e}},{5:5}],28:[function(t,e,n){var a=t(18),r=t(41),i=t(36),o=t(5),s=t(80),p=t(85);e.exports=function(t,e,n,u){var c,l,f,d=p(t),h=a(n,u,e?2:1),m=0;if("function"!=typeof d)throw TypeError(t+" is not iterable!");if(i(d))for(c=s(t.length);c>m;m++)e?h(o(l=t[m])[0],l[1]):h(t[m]);else for(f=d.call(t);!(l=f.next()).done;)r(f,h,l.value,e)}},{18:18,36:36,41:41,5:5,80:80,85:85}],29:[function(t,e,n){var a=t(79),r=t(47).getNames,i={}.toString,o="object"==typeof window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],s=function(t){try{return r(t)}catch(e){return o.slice()}};e.exports.get=function(t){return o&&"[object Window]"==i.call(t)?s(t):r(a(t))}},{47:47,79:79}],30:[function(t,e,n){var a=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=a)},{}],31:[function(t,e,n){var a={}.hasOwnProperty;e.exports=function(t,e){return a.call(t,e)}},{}],32:[function(t,e,n){var a=t(47),r=t(60);e.exports=t(20)?function(t,e,n){return a.setDesc(t,e,r(1,n))}:function(t,e,n){return t[e]=n,t}},{20:20,47:47,60:60}],33:[function(t,e,n){e.exports=t(30).document&&document.documentElement},{30:30}],34:[function(t,e,n){e.exports=function(t,e,n){var a=void 0===n;switch(e.length){case 0:return a?t():t.call(n);case 1:return a?t(e[0]):t.call(n,e[0]);case 2:return a?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return a?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return a?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},{}],35:[function(t,e,n){var a=t(12);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==a(t)?t.split(""):Object(t)}},{12:12}],36:[function(t,e,n){var a=t(46),r=t(84)("iterator"),i=Array.prototype;e.exports=function(t){return void 0!==t&&(a.Array===t||i[r]===t)}},{46:46,84:84}],37:[function(t,e,n){var a=t(12);e.exports=Array.isArray||function(t){return"Array"==a(t)}},{12:12}],38:[function(t,e,n){var a=t(39),r=Math.floor;e.exports=function(t){return!a(t)&&isFinite(t)&&r(t)===t}},{39:39}],39:[function(t,e,n){e.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},{}],40:[function(t,e,n){var a=t(39),r=t(12),i=t(84)("match");e.exports=function(t){var e;return a(t)&&(void 0!==(e=t[i])?!!e:"RegExp"==r(t))}},{12:12,39:39,84:84}],41:[function(t,e,n){var a=t(5);e.exports=function(t,e,n,r){try{return r?e(a(n)[0],n[1]):e(n)}catch(i){var o=t["return"];throw void 0!==o&&a(o.call(t)),i}}},{5:5}],42:[function(t,e,n){"use strict";var a=t(47),r=t(60),i=t(67),o={};t(32)(o,t(84)("iterator"),function(){return this}),e.exports=function(t,e,n){t.prototype=a.create(o,{next:r(1,n)}),i(t,e+" Iterator")}},{32:32,47:47,60:60,67:67,84:84}],43:[function(t,e,n){"use strict";var a=t(49),r=t(23),i=t(62),o=t(32),s=t(31),p=t(46),u=t(42),c=t(67),l=t(47).getProto,f=t(84)("iterator"),d=!([].keys&&"next"in[].keys()),h="@@iterator",m="keys",v="values",g=function(){return this};e.exports=function(t,e,n,b,y,_,x){u(n,e,b);var w,k,P=function(t){if(!d&&t in A)return A[t];switch(t){case m:return function(){return new n(this,t)};case v:return function(){return new n(this,t)}}return function(){return new n(this,t)}},C=e+" Iterator",E=y==v,S=!1,A=t.prototype,O=A[f]||A[h]||y&&A[y],T=O||P(y);if(O){var M=l(T.call(new t));c(M,C,!0),!a&&s(A,h)&&o(M,f,g),E&&O.name!==v&&(S=!0,T=function(){return O.call(this)})}if(a&&!x||!d&&!S&&A[f]||o(A,f,T),p[e]=T,p[C]=g,y)if(w={values:E?T:P(v),keys:_?T:P(m),entries:E?P("entries"):T},x)for(k in w)k in A||i(A,k,w[k]);else r(r.P+r.F*(d||S),e,w);return w}},{23:23,31:31,32:32,42:42,46:46,47:47,49:49,62:62,67:67,84:84}],44:[function(t,e,n){var a=t(84)("iterator"),r=!1;try{var i=[7][a]();i["return"]=function(){r=!0},Array.from(i,function(){throw 2})}catch(o){}e.exports=function(t,e){if(!e&&!r)return!1;var n=!1;try{var i=[7],o=i[a]();o.next=function(){n=!0},i[a]=function(){return o},t(i)}catch(s){}return n}},{84:84}],45:[function(t,e,n){e.exports=function(t,e){return{value:e,done:!!t}}},{}],46:[function(t,e,n){e.exports={}},{}],47:[function(t,e,n){var a=Object;e.exports={create:a.create,getProto:a.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:a.getOwnPropertyDescriptor,setDesc:a.defineProperty,setDescs:a.defineProperties,getKeys:a.keys,getNames:a.getOwnPropertyNames,getSymbols:a.getOwnPropertySymbols,each:[].forEach}},{}],48:[function(t,e,n){var a=t(47),r=t(79);e.exports=function(t,e){for(var n,i=r(t),o=a.getKeys(i),s=o.length,p=0;s>p;)if(i[n=o[p++]]===e)return n}},{47:47,79:79}],49:[function(t,e,n){e.exports=!1},{}],50:[function(t,e,n){e.exports=Math.expm1||function(t){return 0==(t=+t)?t:t>-1e-6&&1e-6>t?t+t*t/2:Math.exp(t)-1}},{}],51:[function(t,e,n){e.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&1e-8>t?t-t*t/2:Math.log(1+t)}},{}],52:[function(t,e,n){e.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:0>t?-1:1}},{}],53:[function(t,e,n){var a,r,i,o=t(30),s=t(76).set,p=o.MutationObserver||o.WebKitMutationObserver,u=o.process,c=o.Promise,l="process"==t(12)(u),f=function(){var t,e,n;for(l&&(t=u.domain)&&(u.domain=null,t.exit());a;)e=a.domain,n=a.fn,e&&e.enter(),n(),e&&e.exit(),a=a.next;r=void 0,t&&t.enter()};if(l)i=function(){u.nextTick(f)};else if(p){var d=1,h=document.createTextNode("");new p(f).observe(h,{characterData:!0}),i=function(){h.data=d=-d}}else i=c&&c.resolve?function(){c.resolve().then(f)}:function(){s.call(o,f)};e.exports=function(t){var e={fn:t,next:void 0,domain:l&&u.domain};r&&(r.next=e),a||(a=e,i()),r=e}},{12:12,30:30,76:76}],54:[function(t,e,n){var a=t(47),r=t(81),i=t(35);e.exports=t(25)(function(){var t=Object.assign,e={},n={},a=Symbol(),r="abcdefghijklmnopqrst";return e[a]=7,r.split("").forEach(function(t){n[t]=t}),7!=t({},e)[a]||Object.keys(t({},n)).join("")!=r})?function(t,e){for(var n=r(t),o=arguments,s=o.length,p=1,u=a.getKeys,c=a.getSymbols,l=a.isEnum;s>p;)for(var f,d=i(o[p++]),h=c?u(d).concat(c(d)):u(d),m=h.length,v=0;m>v;)l.call(d,f=h[v++])&&(n[f]=d[f]);return n}:Object.assign},{25:25,35:35,47:47,81:81}],55:[function(t,e,n){var a=t(23),r=t(17),i=t(25);e.exports=function(t,e){var n=(r.Object||{})[t]||Object[t],o={};o[t]=e(n),a(a.S+a.F*i(function(){n(1)}),"Object",o)}},{17:17,23:23,25:25}],56:[function(t,e,n){var a=t(47),r=t(79),i=a.isEnum;e.exports=function(t){return function(e){for(var n,o=r(e),s=a.getKeys(o),p=s.length,u=0,c=[];p>u;)i.call(o,n=s[u++])&&c.push(t?[n,o[n]]:o[n]);return c}}},{47:47,79:79}],57:[function(t,e,n){var a=t(47),r=t(5),i=t(30).Reflect;e.exports=i&&i.ownKeys||function(t){var e=a.getNames(r(t)),n=a.getSymbols;return n?e.concat(n(t)):e}},{30:30,47:47,5:5}],58:[function(t,e,n){"use strict";var a=t(59),r=t(34),i=t(3);e.exports=function(){for(var t=i(this),e=arguments.length,n=Array(e),o=0,s=a._,p=!1;e>o;)(n[o]=arguments[o++])===s&&(p=!0);return function(){var a,i=this,o=arguments,u=o.length,c=0,l=0;if(!p&&!u)return r(t,n,i);if(a=n.slice(),p)for(;e>c;c++)a[c]===s&&(a[c]=o[l++]);for(;u>l;)a.push(o[l++]);return r(t,a,i)}}},{3:3,34:34,59:59}],59:[function(t,e,n){e.exports=t(30)},{30:30}],60:[function(t,e,n){e.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},{}],61:[function(t,e,n){var a=t(62);e.exports=function(t,e){for(var n in e)a(t,n,e[n]);return t}},{62:62}],62:[function(t,e,n){var a=t(30),r=t(32),i=t(83)("src"),o="toString",s=Function[o],p=(""+s).split(o);t(17).inspectSource=function(t){return s.call(t)},(e.exports=function(t,e,n,o){"function"==typeof n&&(n.hasOwnProperty(i)||r(n,i,t[e]?""+t[e]:p.join(e+"")),n.hasOwnProperty("name")||r(n,"name",e)),t===a?t[e]=n:(o||delete t[e],r(t,e,n))})(Function.prototype,o,function(){return"function"==typeof this&&this[i]||s.call(this)})},{17:17,30:30,32:32,83:83}],63:[function(t,e,n){e.exports=function(t,e){var n=e===Object(e)?function(t){return e[t]}:e;return function(e){return(e+"").replace(t,n)}}},{}],64:[function(t,e,n){e.exports=Object.is||function(t,e){return t===e?0!==t||1/t===1/e:t!=t&&e!=e}},{}],65:[function(t,e,n){var a=t(47).getDesc,r=t(39),i=t(5),o=function(t,e){if(i(t),!r(e)&&null!==e)throw TypeError(e+": can't set as prototype!")};e.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(e,n,r){try{r=t(18)(Function.call,a(Object.prototype,"__proto__").set,2),r(e,[]),n=!(e instanceof Array)}catch(i){n=!0}return function(t,e){return o(t,e),n?t.__proto__=e:r(t,e),t}}({},!1):void 0),check:o}},{18:18,39:39,47:47,5:5}],66:[function(t,e,n){"use strict";var a=t(30),r=t(47),i=t(20),o=t(84)("species");e.exports=function(t){var e=a[t];i&&e&&!e[o]&&r.setDesc(e,o,{configurable:!0,get:function(){return this}})}},{20:20,30:30,47:47,84:84}],67:[function(t,e,n){var a=t(47).setDesc,r=t(31),i=t(84)("toStringTag");e.exports=function(t,e,n){t&&!r(t=n?t:t.prototype,i)&&a(t,i,{configurable:!0,value:e})}},{31:31,47:47,84:84}],68:[function(t,e,n){var a=t(30),r="__core-js_shared__",i=a[r]||(a[r]={});e.exports=function(t){return i[t]||(i[t]={})}},{30:30}],69:[function(t,e,n){var a=t(5),r=t(3),i=t(84)("species");e.exports=function(t,e){var n,o=a(t).constructor;return void 0===o||void 0==(n=a(o)[i])?e:r(n)}},{3:3,5:5,84:84}],70:[function(t,e,n){e.exports=function(t,e,n){if(!(t instanceof e))throw TypeError(n+": use the 'new' operator!");return t}},{}],71:[function(t,e,n){var a=t(78),r=t(19);e.exports=function(t){return function(e,n){var i,o,s=r(e)+"",p=a(n),u=s.length;return 0>p||p>=u?t?"":void 0:(i=s.charCodeAt(p),55296>i||i>56319||p+1===u||(o=s.charCodeAt(p+1))<56320||o>57343?t?s.charAt(p):i:t?s.slice(p,p+2):(i-55296<<10)+(o-56320)+65536)}}},{19:19,78:78}],72:[function(t,e,n){var a=t(40),r=t(19);e.exports=function(t,e,n){if(a(e))throw TypeError("String#"+n+" doesn't accept regex!");return r(t)+""}},{19:19,40:40}],73:[function(t,e,n){var a=t(80),r=t(74),i=t(19);e.exports=function(t,e,n,o){var s=i(t)+"",p=s.length,u=void 0===n?" ":n+"",c=a(e);if(p>=c)return s;""==u&&(u=" ");var l=c-p,f=r.call(u,Math.ceil(l/u.length));return f.length>l&&(f=f.slice(0,l)),o?f+s:s+f}},{19:19,74:74,80:80}],74:[function(t,e,n){"use strict";var a=t(78),r=t(19);e.exports=function(t){var e=r(this)+"",n="",i=a(t);if(0>i||i==1/0)throw RangeError("Count can't be negative");for(;i>0;(i>>>=1)&&(e+=e))1&i&&(n+=e);return n}},{19:19,78:78}],75:[function(t,e,n){var a=t(23),r=t(19),i=t(25),o=" \n\x0B\f\r  ᠎              \u2028\u2029\ufeff",s="["+o+"]",p="​…",u=RegExp("^"+s+s+"*"),c=RegExp(s+s+"*$"),l=function(t,e){var n={};n[t]=e(f),a(a.P+a.F*i(function(){return!!o[t]()||p[t]()!=p}),"String",n)},f=l.trim=function(t,e){return t=r(t)+"",1&e&&(t=t.replace(u,"")),2&e&&(t=t.replace(c,"")),t};e.exports=l},{19:19,23:23,25:25}],76:[function(t,e,n){var a,r,i,o=t(18),s=t(34),p=t(33),u=t(21),c=t(30),l=c.process,f=c.setImmediate,d=c.clearImmediate,h=c.MessageChannel,m=0,v={},g="onreadystatechange",b=function(){var t=+this;if(v.hasOwnProperty(t)){var e=v[t];delete v[t],e()}},y=function(t){b.call(t.data)};f&&d||(f=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return v[++m]=function(){s("function"==typeof t?t:Function(t),e)},a(m),m},d=function(t){delete v[t]},"process"==t(12)(l)?a=function(t){l.nextTick(o(b,t,1))}:h?(r=new h,i=r.port2,r.port1.onmessage=y,a=o(i.postMessage,i,1)):c.addEventListener&&"function"==typeof postMessage&&!c.importScripts?(a=function(t){c.postMessage(t+"","*")},c.addEventListener("message",y,!1)):a=g in u("script")?function(t){p.appendChild(u("script"))[g]=function(){p.removeChild(this),b.call(t)}}:function(t){setTimeout(o(b,t,1),0)}),e.exports={set:f,clear:d}},{12:12,18:18,21:21,30:30,33:33,34:34}],77:[function(t,e,n){var a=t(78),r=Math.max,i=Math.min;e.exports=function(t,e){return t=a(t),0>t?r(t+e,0):i(t,e)}},{78:78}],78:[function(t,e,n){var a=Math.ceil,r=Math.floor;e.exports=function(t){return isNaN(t=+t)?0:(t>0?r:a)(t)}},{}],79:[function(t,e,n){var a=t(35),r=t(19);e.exports=function(t){return a(r(t))}},{19:19,35:35}],80:[function(t,e,n){var a=t(78),r=Math.min;e.exports=function(t){return t>0?r(a(t),9007199254740991):0}},{78:78}],81:[function(t,e,n){var a=t(19);e.exports=function(t){return Object(a(t))}},{19:19}],82:[function(t,e,n){var a=t(39);e.exports=function(t,e){if(!a(t))return t;var n,r;if(e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;if("function"==typeof(n=t.valueOf)&&!a(r=n.call(t)))return r;if(!e&&"function"==typeof(n=t.toString)&&!a(r=n.call(t)))return r;throw TypeError("Can't convert object to primitive value")}},{39:39}],83:[function(t,e,n){var a=0,r=Math.random();e.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++a+r).toString(36))}},{}],84:[function(t,e,n){var a=t(68)("wks"),r=t(83),i=t(30).Symbol;e.exports=function(t){return a[t]||(a[t]=i&&i[t]||(i||r)("Symbol."+t))}},{30:30,68:68,83:83}],85:[function(t,e,n){var a=t(11),r=t(84)("iterator"),i=t(46);e.exports=t(17).getIteratorMethod=function(t){return void 0!=t?t[r]||t["@@iterator"]||i[a(t)]:void 0}},{11:11,17:17,46:46,84:84}],86:[function(t,e,n){"use strict";var a,r=t(47),i=t(23),o=t(20),s=t(60),p=t(33),u=t(21),c=t(31),l=t(12),f=t(34),d=t(25),h=t(5),m=t(3),v=t(39),g=t(81),b=t(79),y=t(78),_=t(77),x=t(80),w=t(35),k=t(83)("__proto__"),P=t(9),C=t(8)(!1),E=Object.prototype,S=Array.prototype,A=S.slice,O=S.join,T=r.setDesc,M=r.getDesc,R=r.setDescs,j={};o||(a=!d(function(){return 7!=T(u("div"),"a",{get:function(){return 7}}).a}),r.setDesc=function(t,e,n){if(a)try{return T(t,e,n)}catch(r){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(h(t)[e]=n.value),t},r.getDesc=function(t,e){if(a)try{return M(t,e)}catch(n){}return c(t,e)?s(!E.propertyIsEnumerable.call(t,e),t[e]):void 0},r.setDescs=R=function(t,e){h(t);for(var n,a=r.getKeys(e),i=a.length,o=0;i>o;)r.setDesc(t,n=a[o++],e[n]);return t}),i(i.S+i.F*!o,"Object",{getOwnPropertyDescriptor:r.getDesc,defineProperty:r.setDesc,defineProperties:R});var L="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(","),N=L.concat("length","prototype"),D=L.length,F=function(){var t,e=u("iframe"),n=D,a=">";for(e.style.display="none",p.appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write("