diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt
index 11cb5b4e3aa..9754c511d0f 100644
--- a/SQL/database_changelog.txt
+++ b/SQL/database_changelog.txt
@@ -1,3 +1,13 @@
+1 September 2016, by Jordie0608
+
+Modified table 'notes', adding column 'secret'.
+
+ALTER TABLE `feedback`.`notes` ADD COLUMN `secret` TINYINT(1) NOT NULL DEFAULT '1' AFTER `server`
+
+Remember to add a prefix to the table name if you use them
+
+----------------------------------------------------
+
19 August 2016, by Shadowlight213
Changed appearance bans to be jobbans.
diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql
index 666ae0a53af..d476d5202b9 100644
--- a/SQL/tgstation_schema.sql
+++ b/SQL/tgstation_schema.sql
@@ -361,6 +361,7 @@ CREATE TABLE `notes` (
`last_editor` varchar(32),
`edits` text,
`server` varchar(50) NOT NULL,
+ `secret` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql
index 44b8b5da50a..f605339ee3d 100644
--- a/SQL/tgstation_schema_prefixed.sql
+++ b/SQL/tgstation_schema_prefixed.sql
@@ -356,6 +356,7 @@ CREATE TABLE `SS13_notes` (
`last_editor` varchar(32),
`edits` text,
`server` varchar(50) NOT NULL,
+ `secret` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm
index cb50d1885d0..762e3df9dbe 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm
@@ -3,7 +3,7 @@
/turf/template_noop,
/area/template_noop)
"b" = (
-/turf/open/floor/plasteel/cult{
+/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface;
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
@@ -22,7 +22,7 @@
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered)
"f" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/plating/asteroid/basalt/lava_land_surface,
/area/ruin/unpowered)
"g" = (
@@ -36,14 +36,14 @@
sound = 'sound/hallucinations/turn_around1.ogg';
triggerer_only = 1
},
-/turf/open/floor/plasteel/cult{
+/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface;
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
/area/ruin/unpowered)
"h" = (
/obj/effect/decal/cleanable/blood/old,
-/turf/open/floor/plasteel/cult{
+/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface;
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
@@ -51,7 +51,7 @@
"i" = (
/obj/effect/decal/remains/human,
/obj/effect/decal/cleanable/blood/old,
-/turf/open/floor/plasteel/cult{
+/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface;
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
@@ -68,7 +68,7 @@
"k" = (
/obj/effect/decal/remains/human,
/obj/item/weapon/melee/cultblade,
-/turf/open/floor/plasteel/cult{
+/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface;
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
@@ -77,14 +77,14 @@
/obj/effect/decal/remains/human,
/obj/item/clothing/shoes/cult,
/obj/item/clothing/suit/cultrobes,
-/turf/open/floor/plasteel/cult{
+/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface;
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
/area/ruin/unpowered)
"m" = (
/obj/effect/decal/remains/human,
-/turf/open/floor/plasteel/cult{
+/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface;
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
@@ -101,7 +101,7 @@
sound = 'sound/hallucinations/turn_around1.ogg';
triggerer_only = 1
},
-/turf/open/floor/plasteel/cult{
+/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface;
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
@@ -124,7 +124,7 @@
message = "You've made a grave mistake, haven't you?";
name = "ohfuck"
},
-/turf/open/floor/plasteel/cult{
+/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface;
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
@@ -141,7 +141,7 @@
sound = 'sound/hallucinations/turn_around1.ogg';
triggerer_only = 1
},
-/turf/open/floor/plasteel/cult{
+/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface;
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
@@ -151,7 +151,7 @@
/obj/item/clothing/shoes/cult,
/obj/item/clothing/suit/cultrobes,
/obj/effect/decal/cleanable/blood/old,
-/turf/open/floor/plasteel/cult{
+/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface;
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
@@ -168,7 +168,7 @@
sound = 'sound/hallucinations/turn_around1.ogg';
triggerer_only = 1
},
-/turf/open/floor/plasteel/cult{
+/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/asteroid/basalt/lava_land_surface;
initial_gas_mix = "o2=14;n2=23;TEMP=300"
},
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm
new file mode 100644
index 00000000000..4426c66cab8
--- /dev/null
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm
@@ -0,0 +1,64 @@
+"a" = (/turf/closed/indestructible/riveted/hierophant,/area/ruin/unpowered/hierophant)
+"b" = (/obj/effect/decal/cleanable/blood/tracks,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"c" = (/obj/effect/decal/cleanable/cobweb,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"d" = (/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"e" = (/obj/effect/gibspawner/human,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"f" = (/obj/effect/decal/cleanable/blood/gibs/limb,/obj/effect/decal/cleanable/blood,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"g" = (/obj/effect/light_emitter{set_cap = 3; set_luminosity = 7},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"h" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (EAST)"; icon_state = "tracks"; dir = 4},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"i" = (/obj/effect/decal/cleanable/blood/old,/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (EAST)"; icon_state = "tracks"; dir = 4},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"j" = (/obj/effect/decal/cleanable/blood/old,/obj/effect/decal/remains/human,/obj/effect/light_emitter{set_cap = 3; set_luminosity = 5},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"k" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (SOUTHWEST)"; icon_state = "tracks"; dir = 10},/obj/effect/decal/cleanable/blood,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"l" = (/obj/effect/light_emitter{set_cap = 3; set_luminosity = 5},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"m" = (/obj/effect/gibspawner/generic,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"n" = (/obj/effect/decal/cleanable/blood,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"o" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (NORTHEAST)"; icon_state = "tracks"; dir = 5},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"p" = (/obj/effect/light_emitter,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"q" = (/obj/effect/decal/cleanable/blood/old,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"r" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (NORTHWEST)"; icon_state = "tracks"; dir = 9},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"s" = (/obj/effect/decal/cleanable/blood/gibs/limb,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"t" = (/obj/effect/decal/cleanable/ash,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"u" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (SOUTHWEST)"; icon_state = "tracks"; dir = 10},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"v" = (/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood,/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (NORTHEAST)"; icon_state = "tracks"; dir = 5},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"w" = (/obj/effect/gibspawner/human,/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (SOUTHEAST)"; icon_state = "tracks"; dir = 6},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"x" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (WEST)"; icon_state = "tracks"; dir = 8},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"y" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (WEST)"; icon_state = "tracks"; dir = 8},/obj/effect/light_emitter{set_cap = 3; set_luminosity = 7},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"z" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (NORTHWEST)"; icon_state = "tracks"; dir = 9},/obj/effect/decal/cleanable/blood,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"A" = (/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (SOUTHEAST)"; icon_state = "tracks"; dir = 6},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"B" = (/mob/living/simple_animal/hostile/megafauna/hierophant,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"C" = (/obj/effect/decal/cleanable/blood,/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (WEST)"; icon_state = "tracks"; dir = 8},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"D" = (/obj/effect/decal/remains/human,/obj/effect/decal/cleanable/blood,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"E" = (/obj/effect/decal/cleanable/blood/gibs/up,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"F" = (/obj/effect/decal/cleanable/blood/old,/obj/effect/decal/remains/human,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"G" = (/obj/effect/decal/cleanable/blood/gibs/core,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"H" = (/obj/effect/decal/cleanable/blood,/obj/effect/decal/cleanable/blood/tracks{tag = "icon-tracks (SOUTHWEST)"; icon_state = "tracks"; dir = 10},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"I" = (/obj/effect/gibspawner/human,/obj/effect/light_emitter{set_cap = 3; set_luminosity = 5},/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+"J" = (/obj/effect/decal/cleanable/blood/gibs/down,/turf/open/indestructible/hierophant,/area/ruin/unpowered/hierophant)
+
+(1,1,1) = {"
+aaaaaaaaaaaabaaaaaaaaaaaa
+acdddddddddddddddddddddda
+adeddfddddddgdddhhhdiddda
+addjddddddddkhhddddddldda
+adddadddaaaaaaaaadddaddda
+addddmhdhddddddddddmddnda
+adddddgdddddddddddgddodda
+addddddddkdopddfdddbdddda
+adqdadddddadddaddddbaddda
+adddadddddrdddddddddaddda
+adstadddadudhhdvadhwabdda
+adddadrxxmddddduddddaddda
+xxyoazApddddBddddpddadyxC
+addbabddddddddtdddddaddda
+addbabddadDdEdddadddafdda
+adddabddddddndddddqdaddda
+adddabddddadddadddddadnda
+adqedbddsdddpddddddddddda
+addddAgddddeddddddgFdddGa
+addddmdddddHdehddxdedddda
+adddadddaaaaaaaaadddaddda
+addlddddddddrdddddAddIdda
+adddddJdddddgdddqddddddda
+adnddddddFddbdddddddnddda
+aaaaaaaaaaaabaaaaaaaaaaaa
+"}
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_ww_vault.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_ww_vault.dmm
index 5b722426566..56d0ad808d4 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_ww_vault.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_ww_vault.dmm
@@ -9,7 +9,7 @@
/turf/open/floor/engine/cult,
/area/ruin/powered)
"d" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/engine/cult,
/area/ruin/powered)
"e" = (
@@ -57,7 +57,7 @@
/turf/open/floor/plasteel/circuit/gcircuit/off,
/area/ruin/powered)
"o" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/plasteel/circuit/gcircuit/off,
/area/ruin/powered)
"p" = (
@@ -69,7 +69,7 @@
/turf/open/floor/plasteel/circuit/gcircuit/off,
/area/ruin/powered)
"r" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/plasteel/circuit/off,
/area/ruin/powered)
"s" = (
@@ -96,7 +96,7 @@
/turf/open/floor/engine/cult,
/area/ruin/powered)
"x" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/lava/smooth
},
diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm
index 75239b9ae53..04afc8e1fb7 100644
--- a/_maps/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm
+++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm
@@ -615,7 +615,15 @@
"O" = (
/obj/structure/alien/weeds/node,
/turf/template_noop,
-/area/template_noop)
+/area/awaycontent/a5{
+ always_unpowered = 1;
+ has_gravity = 1;
+ name = "The Hive";
+ power_environ = 0;
+ power_equip = 0;
+ power_light = 0;
+ poweralm = 0
+ })
"P" = (
/obj/structure/alien/weeds{
icon_state = "weeds2"
@@ -644,13 +652,29 @@
"R" = (
/obj/structure/alien/weeds,
/turf/template_noop,
-/area/template_noop)
+/area/awaycontent/a5{
+ always_unpowered = 1;
+ has_gravity = 1;
+ name = "The Hive";
+ power_environ = 0;
+ power_equip = 0;
+ power_light = 0;
+ poweralm = 0
+ })
"S" = (
/obj/structure/alien/weeds{
icon_state = "weeds2"
},
/turf/template_noop,
-/area/template_noop)
+/area/awaycontent/a5{
+ always_unpowered = 1;
+ has_gravity = 1;
+ name = "The Hive";
+ power_environ = 0;
+ power_equip = 0;
+ power_light = 0;
+ poweralm = 0
+ })
"T" = (
/obj/structure/alien/weeds/node,
/obj/structure/alien/resin/wall,
@@ -1468,7 +1492,7 @@ a
a
a
a
-P
+c
"}
(26,1,1) = {"
a
@@ -1499,8 +1523,8 @@ c
a
a
a
-U
-N
+b
+h
"}
(27,1,1) = {"
a
@@ -1529,10 +1553,10 @@ g
q
b
c
-N
-P
-T
-R
+h
+c
+y
+g
"}
(28,1,1) = {"
a
@@ -1563,8 +1587,8 @@ q
b
O
R
-V
-S
+p
+q
"}
(29,1,1) = {"
a
@@ -1595,8 +1619,8 @@ l
b
O
S
-V
-R
+p
+g
"}
(30,1,1) = {"
a
@@ -1625,10 +1649,10 @@ h
c
b
c
-P
-T
-S
-V
+c
+y
+q
+p
"}
(31,1,1) = {"
a
@@ -1658,9 +1682,9 @@ a
a
a
a
-P
-R
-S
+c
+g
+q
"}
(32,1,1) = {"
a
@@ -1690,9 +1714,9 @@ a
a
a
a
-N
-V
-R
+h
+p
+g
"}
(33,1,1) = {"
a
@@ -1721,9 +1745,9 @@ a
a
a
a
-P
-P
-S
+c
+c
+q
a
"}
(34,1,1) = {"
@@ -1753,7 +1777,7 @@ a
a
a
a
-P
+c
a
a
a
diff --git a/_maps/RandomZLevels/Academy.dmm b/_maps/RandomZLevels/Academy.dmm
index 3a62b4a2686..4577417fc7b 100644
--- a/_maps/RandomZLevels/Academy.dmm
+++ b/_maps/RandomZLevels/Academy.dmm
@@ -235,7 +235,7 @@
/turf/open/floor/carpet,
/area/awaymission/academy/headmaster)
"aJ" = (
-/obj/structure/cult/tome,
+/obj/structure/destructible/cult/tome,
/obj/item/weapon/dice/d20/fate,
/turf/open/floor/wood,
/area/awaymission/academy/headmaster)
@@ -3429,7 +3429,7 @@
},
/area/awaymission/academy/academyaft)
"jw" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/plasteel/yellow/side{
dir = 10
},
@@ -3438,7 +3438,7 @@
/turf/open/floor/plasteel/yellow/side,
/area/awaymission/academy/academyaft)
"jy" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/plasteel/yellow/side{
dir = 6
},
diff --git a/_maps/RandomZLevels/caves.dmm b/_maps/RandomZLevels/caves.dmm
index 8e6daec7544..839dee842a4 100644
--- a/_maps/RandomZLevels/caves.dmm
+++ b/_maps/RandomZLevels/caves.dmm
@@ -92,7 +92,7 @@
name = "\improper BMP Asteroid Level 4"
})
"an" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/plating/asteroid/basalt/lava{
initial_gas_mix = "n2=23;o2=14"
},
@@ -108,7 +108,7 @@
name = "\improper BMP Asteroid Level 4"
})
"ap" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/lava/smooth;
initial_gas_mix = "n2=23;o2=14"
@@ -151,7 +151,7 @@
name = "\improper BMP Asteroid Level 4"
})
"au" = (
-/obj/structure/cult/talisman,
+/obj/structure/destructible/cult/talisman,
/obj/effect/decal/remains/human,
/obj/item/stack/sheet/runed_metal{
amount = 25
@@ -199,7 +199,7 @@
name = "\improper BMP Asteroid Level 4"
})
"ay" = (
-/obj/structure/cult/tome,
+/obj/structure/destructible/cult/tome,
/obj/item/weapon/tome,
/obj/item/stack/sheet/runed_metal{
amount = 25
@@ -260,7 +260,7 @@
name = "\improper BMP Asteroid Level 4"
})
"aE" = (
-/obj/structure/cult/tome,
+/obj/structure/destructible/cult/tome,
/obj/item/stack/sheet/runed_metal{
amount = 25
},
@@ -497,7 +497,7 @@
name = "\improper BMP Asteroid Level 4"
})
"ba" = (
-/obj/structure/cult/talisman,
+/obj/structure/destructible/cult/talisman,
/obj/item/weapon/plasma_fist_scroll,
/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/lava/smooth;
@@ -700,7 +700,7 @@
name = "\improper BMP Asteroid Level 3"
})
"bv" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/plating/asteroid/basalt{
initial_gas_mix = "n2=23;o2=14"
},
@@ -745,7 +745,7 @@
name = "\improper BMP Asteroid Level 4"
})
"bA" = (
-/obj/structure/cult/tome,
+/obj/structure/destructible/cult/tome,
/obj/item/device/necromantic_stone,
/obj/effect/decal/cleanable/blood,
/turf/open/floor/engine/cult{
@@ -781,7 +781,7 @@
name = "\improper BMP Asteroid Level 3"
})
"bE" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/obj/effect/decal/cleanable/blood,
/turf/open/floor/engine/cult{
baseturf = /turf/open/floor/plating/lava/smooth;
diff --git a/_maps/RandomZLevels/wildwest.dmm b/_maps/RandomZLevels/wildwest.dmm
index 5bd6c81ba20..025f32aeb63 100644
--- a/_maps/RandomZLevels/wildwest.dmm
+++ b/_maps/RandomZLevels/wildwest.dmm
@@ -9,7 +9,7 @@
/turf/open/floor/engine/cult,
/area/awaymission/wwvault)
"ad" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/engine/cult,
/area/awaymission/wwvault)
"ae" = (
@@ -71,7 +71,7 @@
/turf/open/floor/plasteel/circuit/gcircuit/off,
/area/awaymission/wwvault)
"aq" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/plasteel/circuit/gcircuit/off,
/area/awaymission/wwvault)
"ar" = (
@@ -131,7 +131,7 @@
/turf/open/floor/plasteel/circuit/gcircuit/off,
/area/awaymission/wwvault)
"aB" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/plasteel/circuit/off,
/area/awaymission/wwvault)
"aC" = (
diff --git a/_maps/map_files/DreamStation/dreamstation04.dmm b/_maps/map_files/DreamStation/dreamstation04.dmm
index 1cc8b6c30e6..d3573c3e30b 100644
--- a/_maps/map_files/DreamStation/dreamstation04.dmm
+++ b/_maps/map_files/DreamStation/dreamstation04.dmm
@@ -42441,7 +42441,7 @@
/obj/structure/bookcase{
name = "Forbidden Knowledge"
},
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"bGN" = (
/obj/structure/table/wood,
@@ -42459,7 +42459,7 @@
pixel_y = 20;
tag = "NORTH"
},
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"bGO" = (
/obj/structure/table/wood,
@@ -42469,7 +42469,7 @@
tag = "every single paper bin is edited to this"
},
/obj/item/weapon/pen/invisible,
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"bGP" = (
/obj/structure/table,
@@ -43659,19 +43659,19 @@
/turf/open/floor/wood,
/area/library)
"bIO" = (
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"bIP" = (
/obj/structure/chair/comfy/brown{
dir = 1
},
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"bIQ" = (
-/obj/structure/cult/tome,
+/obj/structure/destructible/cult/tome,
/obj/item/clothing/under/suit_jacket/red,
/obj/item/weapon/book/codex_gigas,
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"bIR" = (
/obj/structure/filingcabinet/chestdrawer/wheeled,
@@ -44499,7 +44499,7 @@
name = "Private Study";
req_access_txt = "37"
},
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"bKs" = (
/obj/structure/cable/green{
diff --git a/_maps/map_files/EfficiencyStation/EfficiencyStation.dmm b/_maps/map_files/EfficiencyStation/EfficiencyStation.dmm
index e454c0954b3..45e4e748284 100644
--- a/_maps/map_files/EfficiencyStation/EfficiencyStation.dmm
+++ b/_maps/map_files/EfficiencyStation/EfficiencyStation.dmm
@@ -34136,7 +34136,7 @@
name = "Private Study";
req_access_txt = "37"
},
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"bqq" = (
/obj/structure/cable{
@@ -35086,13 +35086,13 @@
/obj/machinery/light/small{
dir = 8
},
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"bsg" = (
/obj/structure/bookcase{
name = "Forbidden Knowledge"
},
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"bsh" = (
/obj/structure/cable{
@@ -35658,7 +35658,7 @@
/obj/effect/landmark/start{
name = "Librarian"
},
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"bts" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden{
@@ -35669,7 +35669,7 @@
pixel_x = 27
},
/obj/structure/table/wood,
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"btt" = (
/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
@@ -36381,9 +36381,9 @@
/turf/open/floor/plasteel,
/area/storage/art)
"buT" = (
-/obj/structure/cult/tome,
+/obj/structure/destructible/cult/tome,
/obj/item/weapon/book/codex_gigas,
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"buU" = (
/obj/machinery/atmospherics/components/unary/vent_scrubber{
@@ -36398,7 +36398,7 @@
},
/obj/item/weapon/pen/invisible,
/obj/structure/table/wood,
-/turf/open/floor/plasteel/cult,
+/turf/open/floor/engine/cult,
/area/library)
"buV" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm
index 68ee5f769bb..1713fbaec40 100644
--- a/_maps/map_files/MetaStation/MetaStation.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.dmm
@@ -35087,6 +35087,7 @@
d2 = 8;
icon_state = "4-8"
},
+/obj/machinery/portable_atmospherics/canister/water_vapor,
/mob/living/simple_animal/hostile/lizard{
name = "Wags-His-Tail";
real_name = "Wags-His-Tail"
@@ -49974,7 +49975,6 @@
dir = 4
},
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
-/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel,
/area/atmos)
"bHQ" = (
@@ -49985,7 +49985,6 @@
dir = 2;
on = 1
},
-/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel/black/corner{
dir = 2
},
@@ -54758,9 +54757,7 @@
name = "Private Study";
req_access_txt = "37"
},
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"bQz" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
@@ -55651,22 +55648,18 @@
/turf/open/floor/wood,
/area/library)
"bSh" = (
-/obj/structure/cult/tome,
+/obj/structure/destructible/cult/tome,
/obj/machinery/newscaster{
pixel_x = -30;
pixel_y = 0
},
/obj/item/clothing/under/suit_jacket/red,
/obj/effect/decal/cleanable/cobweb,
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"bSi" = (
/obj/structure/chair/comfy/brown,
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"bSj" = (
/obj/effect/landmark{
@@ -55679,9 +55672,7 @@
pixel_x = 30;
pixel_y = 0
},
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"bSk" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
@@ -56427,9 +56418,7 @@
pixel_y = 7
},
/obj/item/weapon/pen/invisible,
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"bTy" = (
/obj/item/device/taperecorder{
@@ -56440,17 +56429,13 @@
pixel_y = -25
},
/obj/structure/table/wood,
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"bTz" = (
/obj/structure/bookcase{
name = "Forbidden Knowledge"
},
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"bTA" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
@@ -73570,7 +73555,6 @@
dir = 2;
icon_state = "pipe-c"
},
-/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel/warning{
dir = 4
},
@@ -74098,7 +74082,6 @@
/turf/open/floor/plasteel/bot,
/area/toxins/storage)
"cxf" = (
-/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel/warning{
dir = 8
},
@@ -74106,7 +74089,6 @@
"cxg" = (
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/obj/structure/disposalpipe/segment,
-/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel/warning{
dir = 4
},
diff --git a/_maps/map_files/TgStation/tgstation.2.1.3.dmm b/_maps/map_files/TgStation/tgstation.2.1.3.dmm
index 602803562ed..d6a019fa8e2 100644
--- a/_maps/map_files/TgStation/tgstation.2.1.3.dmm
+++ b/_maps/map_files/TgStation/tgstation.2.1.3.dmm
@@ -7375,20 +7375,15 @@
/turf/closed/wall/mineral/titanium/overspace,
/area/shuttle/pod_1)
"apG" = (
-/turf/open/space,
-/turf/closed/wall/shuttle{
- dir = 2;
- icon_state = "swall_f10";
- layer = 2
- },
-/area/shuttle/pod_1)
+/obj/machinery/portable_atmospherics/canister/water_vapor,
+/turf/open/floor/plasteel,
+/area/janitor)
"apH" = (
/obj/structure/grille,
/obj/structure/window/shuttle,
/turf/open/floor/plating,
/area/shuttle/pod_1)
"apI" = (
-/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel/floorgrime,
/area/toxins/storage)
"apJ" = (
@@ -18576,9 +18571,7 @@
/obj/structure/bookcase{
name = "Forbidden Knowledge"
},
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"aPh" = (
/obj/structure/table/wood,
@@ -18587,9 +18580,7 @@
pixel_y = 7
},
/obj/item/weapon/pen/invisible,
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"aPi" = (
/obj/structure/table/wood,
@@ -18600,9 +18591,7 @@
/obj/item/device/radio/intercom{
pixel_y = 25
},
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"aPj" = (
/obj/machinery/light_switch{
@@ -19058,17 +19047,13 @@
/area/library)
"aQr" = (
/obj/machinery/light/small,
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"aQs" = (
-/obj/structure/cult/tome,
+/obj/structure/destructible/cult/tome,
/obj/item/clothing/under/suit_jacket/red,
/obj/item/weapon/book/codex_gigas,
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"aQt" = (
/obj/effect/landmark{
@@ -19077,9 +19062,7 @@
/obj/structure/chair/comfy/brown{
dir = 1
},
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"aQu" = (
/turf/open/floor/plasteel/chapel,
@@ -19580,9 +19563,7 @@
name = "Private Study";
req_access_txt = "37"
},
-/turf/open/floor/plasteel/cult{
- dir = 2
- },
+/turf/open/floor/engine/cult,
/area/library)
"aRR" = (
/obj/machinery/firealarm{
@@ -36609,7 +36590,6 @@
scrub_N2O = 0;
scrub_Toxins = 0
},
-/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel/floorgrime,
/area/toxins/storage)
"bCY" = (
@@ -37059,7 +37039,6 @@
icon_state = "4-8";
pixel_y = 0
},
-/obj/machinery/portable_atmospherics/canister/freon,
/mob/living/simple_animal/mouse,
/turf/open/floor/plasteel/floorgrime,
/area/toxins/storage)
@@ -37109,7 +37088,6 @@
icon_state = "4-8";
pixel_y = 0
},
-/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel/floorgrime,
/area/toxins/storage)
"bEd" = (
@@ -41843,7 +41821,6 @@
/obj/structure/disposalpipe/segment{
dir = 4
},
-/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel,
/area/atmos)
"bNR" = (
@@ -41876,7 +41853,6 @@
scrub_N2O = 0;
scrub_Toxins = 0
},
-/obj/machinery/portable_atmospherics/canister/freon,
/turf/open/floor/plasteel,
/area/atmos)
"bNT" = (
@@ -91946,7 +91922,7 @@ aLY
aLY
bBx
bCv
-bDL
+apG
bFk
bDs
bCv
diff --git a/_maps/map_files/generic/z2.dmm b/_maps/map_files/generic/z2.dmm
index ce5d8e815ef..b9586bc48b5 100644
--- a/_maps/map_files/generic/z2.dmm
+++ b/_maps/map_files/generic/z2.dmm
@@ -2524,7 +2524,7 @@
},
/area/centcom/evac)
"hL" = (
-/obj/structure/cult/talisman{
+/obj/structure/destructible/cult/talisman{
desc = "A altar dedicated to the Wizard's Federation"
},
/obj/item/weapon/kitchen/knife/ritual,
@@ -3969,7 +3969,7 @@
},
/area/wizard_station)
"mp" = (
-/obj/structure/cult/tome,
+/obj/structure/destructible/cult/tome,
/turf/open/floor/plasteel/cult,
/area/wizard_station)
"mq" = (
@@ -4195,7 +4195,7 @@
/turf/open/floor/engine/cult,
/area/wizard_station)
"mW" = (
-/obj/structure/cult/pylon,
+/obj/structure/destructible/cult/pylon,
/turf/open/floor/engine/cult,
/area/wizard_station)
"mX" = (
@@ -4612,7 +4612,7 @@
/turf/open/floor/plating/beach/sand,
/area/centcom/holding)
"oo" = (
-/obj/structure/cult/forge{
+/obj/structure/destructible/cult/forge{
desc = "A engine used in powering the wizards ship";
name = "magma engine"
},
@@ -5797,7 +5797,7 @@
/turf/open/floor/engine/cult,
/area/wizard_station)
"sb" = (
-/obj/structure/cult/tome,
+/obj/structure/destructible/cult/tome,
/turf/open/floor/engine/cult,
/area/wizard_station)
"sc" = (
@@ -5835,14 +5835,23 @@
/area/awaymission/errorroom)
"tm" = (
/obj/item/rupee,
-/turf/open/floor/mineral/abductor,
+/turf/open/floor/plating/ashplanet/wateryrock{
+ initial_gas_mix = "o2=22;n2=82;TEMP=293.15";
+ planetary_atmos = 0
+ },
/area/awaymission/errorroom)
"tn" = (
-/turf/open/floor/mineral/abductor,
+/turf/open/floor/plating/ashplanet/wateryrock{
+ initial_gas_mix = "o2=22;n2=82;TEMP=293.15";
+ planetary_atmos = 0
+ },
/area/awaymission/errorroom)
"to" = (
/obj/effect/landmark/error,
-/turf/open/floor/mineral/abductor,
+/turf/open/floor/plating/ashplanet/wateryrock{
+ initial_gas_mix = "o2=22;n2=82;TEMP=293.15";
+ planetary_atmos = 0
+ },
/area/awaymission/errorroom)
"tp" = (
/obj/structure/signpost/salvation{
@@ -5850,7 +5859,10 @@
icon_state = "ladder10";
invisibility = 100
},
-/turf/open/floor/mineral/abductor,
+/turf/open/floor/plating/ashplanet/wateryrock{
+ initial_gas_mix = "o2=22;n2=82;TEMP=293.15";
+ planetary_atmos = 0
+ },
/area/awaymission/errorroom)
"tq" = (
/obj/structure/closet/cardboard,
diff --git a/_maps/shuttles/emergency_wabbajack.dmm b/_maps/shuttles/emergency_wabbajack.dmm
index 006d61c31c7..90473b6ac08 100644
--- a/_maps/shuttles/emergency_wabbajack.dmm
+++ b/_maps/shuttles/emergency_wabbajack.dmm
@@ -291,7 +291,7 @@
},
/area/shuttle/escape)
"ba" = (
-/obj/structure/cult/forge{
+/obj/structure/destructible/cult/forge{
desc = "A engine used in powering the shuttle.";
name = "magma engine"
},
@@ -312,7 +312,7 @@
},
/area/shuttle/escape)
"bd" = (
-/obj/structure/cult/forge{
+/obj/structure/destructible/cult/forge{
desc = "A engine used in powering the shuttle.";
name = "magma engine"
},
diff --git a/code/__DEFINES/admin.dm b/code/__DEFINES/admin.dm
index 50f83c2d947..a50bf74d557 100644
--- a/code/__DEFINES/admin.dm
+++ b/code/__DEFINES/admin.dm
@@ -51,6 +51,6 @@
#define ADMIN_LOOKUPFLW(user) "[key_name_admin(user)][ADMIN_QUE(user)] [ADMIN_FLW(user)]"
#define ADMIN_SET_SD_CODE "(SETCODE)"
#define ADMIN_FULLMONTY(user) "[key_name_admin(user)] [ADMIN_QUE(user)] [ADMIN_PP(user)] [ADMIN_VV(user)] [ADMIN_SM(user)] [ADMIN_FLW(user)] [ADMIN_TP(user)]"
-#define ADMIN_JMP(src) "(JMP)"
+#define ADMIN_JMP(src) "(JMP)"
#define COORD(src) "[src ? "([src.x],[src.y],[src.z])" : "nonexistent location"]"
#define ADMIN_COORDJMP(src) "[src ? "[COORD(src)] [ADMIN_JMP(src)]" : "nonexistent location"]"
diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm
index 5baea0ba429..1e66100e551 100644
--- a/code/__DEFINES/is_helpers.dm
+++ b/code/__DEFINES/is_helpers.dm
@@ -16,6 +16,7 @@
#define ispodperson(A) (is_species(A, /datum/species/podperson))
#define isflyperson(A) (is_species(A, /datum/species/fly))
#define isslimeperson(A) (is_species(A, /datum/species/jelly/slime))
+#define isshadowperson(A) (is_species(A, /datum/species/shadow))
#define iszombie(A) (is_species(A, /datum/species/zombie))
#define ishumanbasic(A) (is_species(A, /datum/species/human))
diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm
index fb3b61cd80f..27a5a3f1034 100644
--- a/code/__DEFINES/layers.dm
+++ b/code/__DEFINES/layers.dm
@@ -2,7 +2,9 @@
//KEEP THESE IN A NICE ACSCENDING ORDER, PLEASE
//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define
-#define ABOVE_OPEN_TURF_LAYER 2.01
+#define MID_TURF_LAYER 2.02
+#define HIGH_TURF_LAYER 2.03
+#define ABOVE_OPEN_TURF_LAYER 2.04
#define CLOSED_TURF_LAYER 2.05
#define ABOVE_NORMAL_TURF_LAYER 2.08
#define LATTICE_LAYER 2.2
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index c859696ccb4..906a3b3498d 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -495,6 +495,7 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define COLOSSUS_SCORE "Colossus Killed"
#define BUBBLEGUM_SCORE "Bubblegum Killed"
#define DRAKE_SCORE "Drakes Killed"
+#define BIRD_SCORE "Hierophants Killed"
#define BOSS_SCORE "Bosses Killed"
#define TENDRIL_CLEAR_SCORE "Tendrils Killed"
@@ -524,4 +525,6 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
// Caps for NTNet logging. Less than 10 would make logging useless anyway, more than 500 may make the log browser too laggy. Defaults to 100 unless user changes it.
#define MAX_NTNET_LOGS 300
-#define MIN_NTNET_LOGS 10
\ No newline at end of file
+#define MIN_NTNET_LOGS 10
+//TODO Move to a pref
+#define STATION_GOAL_BUDGET 1
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index dc90e583805..39892a67e3a 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -966,12 +966,9 @@ var/list/WALLITEMS_INVERSE = list(
tY = max(1, min(origin.y + 7 - tY, world.maxy))
return locate(tX, tY, tZ)
-/proc/IsValidSrc(A)
- if(istype(A, /datum))
- var/datum/B = A
- return !qdeleted(B)
- if(istype(A, /client))
- return 1
+/proc/IsValidSrc(datum/D)
+ if(istype(D))
+ return !qdeleted(D)
return 0
diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm
index b5014ec7c91..28e55d7e03f 100644
--- a/code/_globalvars/lists/objects.dm
+++ b/code/_globalvars/lists/objects.dm
@@ -23,5 +23,5 @@ var/global/list/apcs_list = list() //list of all Area Power Controller machi
var/global/list/tracked_implants = list() //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented...
var/global/list/poi_list = list() //list of points of interest for observe/follow
var/global/list/pinpointer_list = list() //list of all pinpointers. Used to change stuff they are pointing to all at once.
-// A list of all zombie_infection organs, for any mass "animation"
-var/global/list/zombie_infection_list = list()
+var/global/list/zombie_infection_list = list() // A list of all zombie_infection organs, for any mass "animation"
+var/global/list/meteor_list = list() // List of all meteors.
\ No newline at end of file
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index b0d8930bf70..2e99889a323 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -284,7 +284,7 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
desc += "[clockwork_daemons] Tinkerer's Daemons: [servants * 0.2 < clockwork_daemons ? "DISABLED":"ACTIVE"]
"
else
desc += "No Tinkerer's Daemons.
"
- for(var/obj/structure/clockwork/massive/celestial_gateway/G in all_clockwork_objects)
+ for(var/obj/structure/destructible/clockwork/massive/celestial_gateway/G in all_clockwork_objects)
var/area/gate_area = get_area(G)
desc += "Ark Location: [uppertext(gate_area.map_name)]
"
if(G.ratvar_portal)
@@ -299,8 +299,8 @@ or shoot a gun to move around via Newton's 3rd Law of Motion."
var/nezbere_available = clockwork_generals_invoked["nezbere"] <= world.time
var/nezcrentr_available = clockwork_generals_invoked["nzcrentr"] <= world.time
if(inathneq_available || sevtug_available || nezbere_available || nezcrentr_available)
- desc += "Generals available:
[inathneq_available ? "INATH-NEQ
":""][sevtug_available ? "SEVTUG
":""]\
- [nezbere_available ? "NEZBERE
":""][nezcrentr_available ? "NZCRENTR":""]
"
+ desc += "Generals available:[inathneq_available ? "
INATH-NEQ":""][sevtug_available ? "
SEVTUG":""]\
+ [nezbere_available ? "
NEZBERE":""][nezcrentr_available ? "
NZCRENTR":""]
"
else
desc += "Generals available: NONE
"
else
diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm
index dcd14ee9663..0b050c9322f 100644
--- a/code/_onclick/telekinesis.dm
+++ b/code/_onclick/telekinesis.dm
@@ -121,15 +121,16 @@ var/const/tk_maxrange = 15
focus_object(target, user)
return
- if(focus.anchored)
+ if(focus.anchored || !isturf(focus.loc))
qdel(src)
+ return
if(target == focus)
target.attack_self_tk(user)
return // todo: something like attack_self not laden with assumptions inherent to attack_self
- if(!istype(target, /turf) && istype(focus,/obj/item) && target.Adjacent(focus))
+ if(!isturf(target) && istype(focus,/obj/item) && target.Adjacent(focus))
var/obj/item/I = focus
var/resolved = target.attackby(I, user, params)
if(!resolved && target && I)
@@ -139,7 +140,6 @@ var/const/tk_maxrange = 15
focus.throw_at(target, 10, 1,user)
last_throw = world.time
user.changeNext_move(CLICK_CD_MELEE)
- return
/proc/tkMaxRangeCheck(mob/user, atom/target, atom/focus)
var/d = get_dist(user, target)
@@ -155,7 +155,7 @@ var/const/tk_maxrange = 15
/obj/item/tk_grab/proc/focus_object(obj/target, mob/living/user)
- if(!istype(target,/obj))
+ if(!isobj(target))
return//Cant throw non objects atm might let it do mobs later
if(target.anchored || !isturf(target.loc))
qdel(src)
diff --git a/code/controllers/subsystem/server_maintenance.dm b/code/controllers/subsystem/server_maintenance.dm
index 70c03b7591d..ee368c4c429 100644
--- a/code/controllers/subsystem/server_maintenance.dm
+++ b/code/controllers/subsystem/server_maintenance.dm
@@ -17,7 +17,7 @@ var/datum/subsystem/server_maint/SSserver
if(!istype(C.mob, /mob/dead))
log_access("AFK: [key_name(C)]")
C << "You have been inactive for more than 10 minutes and have been disconnected."
- del(C)
+ qdel(C)
if(config.sql_enabled)
sql_poll_players()
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 450367ce2e7..cdc90a8bb3f 100644
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -55,7 +55,6 @@ var/datum/subsystem/ticker/ticker
var/maprotatechecked = 0
-
/datum/subsystem/ticker/New()
NEW_SS_GLOBAL(ticker)
@@ -443,6 +442,8 @@ var/datum/subsystem/ticker/ticker
for(var/i in total_antagonists)
log_game("[i]s[total_antagonists[i]].")
+ mode.declare_station_goal_completion()
+
//Adds the del() log to world.log in a format condensable by the runtime condenser found in tools
if(SSgarbage.didntgc.len)
var/dellog = ""
diff --git a/code/controllers/subsystem/voting.dm b/code/controllers/subsystem/voting.dm
index 164de5d5521..d939e23fba0 100644
--- a/code/controllers/subsystem/voting.dm
+++ b/code/controllers/subsystem/voting.dm
@@ -58,15 +58,20 @@ var/datum/subsystem/vote/SSvote
greatest_votes = votes
//default-vote for everyone who didn't vote
if(!config.vote_no_default && choices.len)
- var/non_voters = (clients.len - total_votes)
- if(non_voters > 0)
+ var/list/non_voters = directory.Copy()
+ non_voters -= voted
+ for (var/non_voter_ckey in non_voters)
+ var/client/C = non_voters[non_voter_ckey]
+ if (!C || C.is_afk())
+ non_voters -= non_voter_ckey
+ if(non_voters.len > 0)
if(mode == "restart")
- choices["Continue Playing"] += non_voters
+ choices["Continue Playing"] += non_voters.len
if(choices["Continue Playing"] >= greatest_votes)
greatest_votes = choices["Continue Playing"]
else if(mode == "gamemode")
if(master_mode in choices)
- choices[master_mode] += non_voters
+ choices[master_mode] += non_voters.len
if(choices[master_mode] >= greatest_votes)
greatest_votes = choices[master_mode]
//get all options with that many votes and return them in a list
diff --git a/code/datums/action.dm b/code/datums/action.dm
index 775e08f8e49..ed4f2416701 100644
--- a/code/datums/action.dm
+++ b/code/datums/action.dm
@@ -189,6 +189,40 @@
/datum/action/item_action/toggle_helmet_light
name = "Toggle Helmet Light"
+/datum/action/item_action/toggle_unfriendly_fire
+ name = "Toggle Friendly Fire \[ON\]"
+ desc = "Toggles if the staff causes friendly fire."
+ button_icon_state = "vortex_ff_on"
+
+/datum/action/item_action/toggle_unfriendly_fire/Trigger()
+ if(..())
+ UpdateButtonIcon()
+
+/datum/action/item_action/toggle_unfriendly_fire/UpdateButtonIcon()
+ if(istype(target, /obj/item/weapon/hierophant_staff))
+ var/obj/item/weapon/hierophant_staff/H = target
+ if(H.friendly_fire_check)
+ button_icon_state = "vortex_ff_off"
+ name = "Toggle Friendly Fire \[OFF\]"
+ button.name = name
+ else
+ button_icon_state = "vortex_ff_on"
+ name = "Toggle Friendly Fire \[ON\]"
+ button.name = name
+ ..()
+
+/datum/action/item_action/vortex_recall
+ name = "Vortex Recall"
+ desc = "Recall yourself, and anyone nearby, to an attuned hierophant rune at any time.
If no such rune exists, will produce a rune at your location."
+ button_icon_state = "vortex_recall"
+
+/datum/action/item_action/vortex_recall/IsAvailable()
+ if(istype(target, /obj/item/weapon/hierophant_staff))
+ var/obj/item/weapon/hierophant_staff/H = target
+ if(H.teleporting)
+ return 0
+ return ..()
+
/datum/action/item_action/clock
background_icon_state = "bg_clock"
buttontooltipstyle = "clockcult"
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index f8f46c007d7..ed93eb9369a 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -4,10 +4,15 @@ var/global/list/internal_byond_list_vars = list("contents" = TRUE, "verbs" = TRU
/datum
var/var_edited = 0 //Warrenty void if seal is broken
+ var/datum/reagents/reagents = null
+ var/fingerprintslast = null
/datum/proc/on_varedit(modified_var) //called whenever a var is edited
var_edited = 1
+/datum/proc/on_reagent_change()
+ return
+
/client/proc/debug_variables(datum/D in world)
set category = "Debug"
set name = "View Variables"
@@ -384,19 +389,20 @@ body
else if (isfile(value))
html += "[html_encode(name)] = '[value]'"
+ else if (istype(value, /client))
+ var/client/C = value
+ html += "[html_encode(name)] \ref[value] = [C] [C.type]"
+
else if (istype(value, /datum))
var/datum/D = value
html += "[html_encode(name)] \ref[value] = [D.type]"
- else if (istype(value, /client))
- var/client/C = value
- html += "[html_encode(name)] \ref[value] = [C] [C.type]"
-//
else if (istype(value, /list))
var/list/L = value
html += "[html_encode(name)] = /list ([L.len])"
if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500))
+ name = "[name]" //Needs to be a string or it will go out of bounds in the internal_byond_list_vars array
html += "
"
var/index = 1
for(var/entry in L)
@@ -523,8 +529,8 @@ body
return
var/D = locate(href_list["datumedit"])
- if(!istype(D,/datum) && !istype(D,/client))
- usr << "This can only be used on instances of types /client or /datum"
+ if(!istype(D,/datum))
+ usr << "This can only be used on datums"
return
modify_variables(D, href_list["varnameedit"], 1)
@@ -534,8 +540,8 @@ body
return
var/D = locate(href_list["datumchange"])
- if(!istype(D,/datum) && !istype(D,/client))
- usr << "This can only be used on instances of types /client or /datum"
+ if(!istype(D,/datum))
+ usr << "This can only be used on datums"
return
modify_variables(D, href_list["varnamechange"], 0)
diff --git a/code/datums/dna.dm b/code/datums/dna.dm
index ca05c8bc3bf..ee19e8483a6 100644
--- a/code/datums/dna.dm
+++ b/code/datums/dna.dm
@@ -261,12 +261,12 @@ mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutat
/mob/proc/domutcheck()
return
-/mob/living/carbon/domutcheck()
+/mob/living/carbon/domutcheck(force_powers=0) //Set force_powers to 1 to bypass the power chance
if(!has_dna())
return
for(var/datum/mutation/human/A in good_mutations | bad_mutations | not_good_mutations)
- if(ismob(A.check_block(src)))
+ if(ismob(A.check_block(src, force_powers)))
return //we got monkeyized/humanized, this mob will be deleted, no need to continue.
update_mutations_overlay()
diff --git a/code/datums/gas_overrides.dm b/code/datums/gas_overrides.dm
index 027aa07e6dc..c58d5ad176a 100644
--- a/code/datums/gas_overrides.dm
+++ b/code/datums/gas_overrides.dm
@@ -1,2 +1,5 @@
/datum/proc/freon_gas_act()
- return
\ No newline at end of file
+ return 0
+
+/datum/proc/water_vapor_gas_act() // We get it
+ return 0 // You vape
\ No newline at end of file
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index f5c465d390e..61c61673d11 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -238,7 +238,7 @@
enslaved_to = creator
- current.faction = creator.faction
+ current.faction = creator.faction.Copy()
if(special_role)
message_admins("[key_name_admin(current)](?) has been created by [key_name_admin(creator)](?), an antagonist.")
diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm
index 6dbe877d833..af57e091efa 100644
--- a/code/datums/mutations.dm
+++ b/code/datums/mutations.dm
@@ -48,9 +48,9 @@
if(hex2num(getblock(se_string, dna_block)) >= lowest_value)
return 1
-/datum/mutation/human/proc/check_block(mob/living/carbon/human/owner)
+/datum/mutation/human/proc/check_block(mob/living/carbon/human/owner, force_powers=0)
if(check_block_string(owner.dna.struc_enzymes))
- if(prob(get_chance))
+ if(prob(get_chance)||force_powers)
. = on_acquiring(owner)
else
. = on_losing(owner)
diff --git a/code/datums/recipe.dm b/code/datums/recipe.dm
index d3085976a18..3c94862ea2e 100644
--- a/code/datums/recipe.dm
+++ b/code/datums/recipe.dm
@@ -34,7 +34,7 @@
* */
/datum/recipe
- var/list/reagents // example: = list("berryjuice" = 5) // do not list same reagent twice
+ var/list/reagents_list // example: = list("berryjuice" = 5) // do not list same reagent twice
var/list/items // example: =list(/obj/item/weapon/crowbar, /obj/item/weapon/welder) // place /foo/bar before /foo
var/result //example: = /obj/item/weapon/reagent_containers/food/snacks/donut
var/time = 100 // 1/10 part of second
@@ -49,7 +49,7 @@
. = -1
else
return 0
- if ((reagents?(reagents.len):(0)) < avail_reagents.reagent_list.len)
+ if ((reagents_list?(reagents_list.len):(0)) < avail_reagents.reagent_list.len)
return -1
return .
@@ -112,7 +112,7 @@
. = possible_recipes[1]
for (var/datum/recipe/recipe in possible_recipes)
var/N_i = (recipe.items)?(recipe.items.len):0
- var/N_r = (recipe.reagents)?(recipe.reagents.len):0
+ var/N_r = (recipe.reagents_list)?(recipe.reagents_list.len):0
if (N_i > i_count || (N_i== i_count && N_r > r_count ))
r_count = N_r
i_count = N_i
diff --git a/code/datums/ruins/lavaland.dm b/code/datums/ruins/lavaland.dm
index 6c3be021fb6..d74eb6ba3b5 100644
--- a/code/datums/ruins/lavaland.dm
+++ b/code/datums/ruins/lavaland.dm
@@ -126,6 +126,14 @@
// Generates nothing but atmos runtimes and salt
cost = 0
+/datum/map_template/ruin/lavaland/hierophant
+ name = "Hierophant's Arena"
+ id = "hierophant"
+ description = "A huge fucking bird priest awaits you in this arena."
+ suffix = "lavaland_surface_hierophant.dmm"
+ cost = 0
+ allow_duplicates = FALSE
+
/datum/map_template/ruin/lavaland/ufo_crash
name = "UFO Crash"
id = "ufo-crash"
diff --git a/code/datums/weather/weather_types.dm b/code/datums/weather/weather_types.dm
index 535f882d4bf..9f75bf714e6 100644
--- a/code/datums/weather/weather_types.dm
+++ b/code/datums/weather/weather_types.dm
@@ -118,7 +118,7 @@
name = "radiation storm"
desc = "A cloud of intense radiation passes through the area dealing rad damage to those who are unprotected."
- telegraph_duration = 600
+ telegraph_duration = 400
telegraph_message = "The air begins to grow warm."
weather_message = "You feel waves of heat wash over you! Find shelter!"
@@ -137,28 +137,49 @@
immunity_type = "rad"
+/datum/weather/rad_storm/telegraph()
+ ..()
+ status_alarm("alert")
+
+
/datum/weather/rad_storm/impact(mob/living/L)
- if(prob(20))
+ var/resist = L.getarmor(null, "rad")
+ if(prob(40))
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.dna && H.dna.species)
if(!(RADIMMUNE in H.dna.species.specflags))
- if(prob(50))
+ if(prob(max(0,100-resist)))
randmuti(H)
- if(prob(90))
- randmutb(H)
- else
- randmutg(H)
- H.domutcheck()
+ if(prob(50))
+ if(prob(90))
+ randmutb(H)
+ else
+ randmutg(H)
+ H.domutcheck()
L.rad_act(20,1)
- L.adjustToxLoss(4)
-
-
-
-
-
/datum/weather/rad_storm/end()
if(..())
return
- priority_announce("The radiation threat has passed. Please return to your workplaces.", "Anomaly Alert")
\ No newline at end of file
+ priority_announce("The radiation threat has passed. Please return to your workplaces.", "Anomaly Alert")
+ status_alarm()
+
+
+/datum/weather/rad_storm/proc/status_alarm(command) //Makes the status displays show the radiation warning for those who missed the announcement.
+ var/datum/radio_frequency/frequency = SSradio.return_frequency(1435)
+
+ if(!frequency)
+ return
+
+ var/datum/signal/status_signal = new
+ var/atom/movable/virtualspeaker/virt = PoolOrNew(/atom/movable/virtualspeaker,null)
+ status_signal.source = virt
+ status_signal.transmission_method = 1
+ status_signal.data["command"] = "shuttle"
+
+ if(command == "alert")
+ status_signal.data["command"] = "alert"
+ status_signal.data["picture_state"] = "radiation"
+
+ frequency.post_signal(src, status_signal)
\ No newline at end of file
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 310603af01a..3be5b294dcc 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -348,9 +348,9 @@
if(L.&& L.client)
L.client.played = 0
-/proc/has_gravity(atom/AT, turf/T)
- if(!T)
- T = get_turf(AT)
+/atom/proc/has_gravity(turf/T)
+ if(!T || !isturf(T))
+ T = get_turf(src)
var/area/A = get_area(T)
if(istype(T, /turf/open/space)) // Turf never has gravity
return 0
diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm
index 430e60db662..64356b908fb 100644
--- a/code/game/asteroid.dm
+++ b/code/game/asteroid.dm
@@ -75,7 +75,7 @@ var/global/max_secret_rooms = 6
floortypes = list(/turf/open/floor/plasteel/cult)
treasureitems = list(/obj/item/device/soulstone/anybody=1, /obj/item/clothing/suit/space/hardsuit/cult=1, /obj/item/weapon/bedsheet/cult=2,
/obj/item/clothing/suit/cultrobes=2, /mob/living/simple_animal/hostile/creature=3)
- fluffitems = list(/obj/effect/gateway=1,/obj/effect/gibspawner=1,/obj/structure/cult/talisman=1,/obj/item/toy/crayon/red=2,
+ fluffitems = list(/obj/effect/gateway=1,/obj/effect/gibspawner=1,/obj/structure/destructible/cult/talisman=1,/obj/item/toy/crayon/red=2,
/obj/item/organ/heart=2, /obj/effect/decal/cleanable/blood=4,/obj/structure/table/wood=2,/obj/item/weapon/ectoplasm=3,
/obj/item/clothing/shoes/cult=1)
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 7a19a16a171..1be70564a1b 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -4,13 +4,9 @@
var/flags = 0
var/list/fingerprints
var/list/fingerprintshidden
- var/fingerprintslast = null
var/list/blood_DNA
var/admin_spawned = 0 //was this spawned by an admin? used for stat tracking stuff.
- ///Chemistry.
- var/datum/reagents/reagents = null
-
//This atom's HUD (med/sec, etc) images. Associative list.
var/list/image/hud_list = null
//HUD images that this atom can provide.
@@ -102,8 +98,6 @@
/atom/proc/check_eye(mob/user)
return
-/atom/proc/on_reagent_change()
- return
/atom/proc/Bumped(AM as mob|obj)
return
diff --git a/code/game/gamemodes/changeling/powers/strained_muscles.dm b/code/game/gamemodes/changeling/powers/strained_muscles.dm
index f2d4d98fccd..1c7ce8d11a5 100644
--- a/code/game/gamemodes/changeling/powers/strained_muscles.dm
+++ b/code/game/gamemodes/changeling/powers/strained_muscles.dm
@@ -16,7 +16,7 @@
if(active)
user << "Our muscles tense and strengthen."
else
- user.status_flags -= GOTTAGOFAST
+ user.status_flags &= ~GOTTAGOFAST
user << "Our muscles relax."
if(stacks >= 10)
user << "We collapse in exhaustion."
@@ -29,7 +29,7 @@
active = !active
user << "Our muscles relax without the energy to strengthen them."
user.Weaken(2)
- user.status_flags -= GOTTAGOFAST
+ user.status_flags &= ~GOTTAGOFAST
break
stacks++
diff --git a/code/game/gamemodes/clock_cult/clock_cult.dm b/code/game/gamemodes/clock_cult/clock_cult.dm
index 63397149602..81e00e6b877 100644
--- a/code/game/gamemodes/clock_cult/clock_cult.dm
+++ b/code/game/gamemodes/clock_cult/clock_cult.dm
@@ -27,6 +27,15 @@ This file's folder contains:
clock_unsorted.dm: Anything else with no place to be
clockcult defines are in __DEFINES/clockcult.dm
+
+Credit where due:
+1. VelardAmakar from /vg/ for the entire design document, idea, and plan. Thank you very much.
+2. SkowronX from /vg/ for MANY of the assets
+3. FuryMcFlurry from /vg/ for many of the assets
+4. PJB3005 from /vg/ for the failed continuation PR
+5. Xhuis from /tg/ for coding the basic gamemode as it is today
+6. ChangelingRain from /tg/ for maintaining the gamemode for months after its release
+
*/
///////////
@@ -90,10 +99,11 @@ This file's folder contains:
whim without hesitation.")
ticker.mode.servants_of_ratvar += M.mind
ticker.mode.update_servant_icons_added(M.mind)
+ all_clockwork_mobs += M
+ M.faction |= "ratvar"
M.mind.special_role = "Servant of Ratvar"
M.languages_spoken |= RATVAR
M.languages_understood |= RATVAR
- all_clockwork_mobs += M
M.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons
M.attack_log += "\[[time_stamp()]\] Has been converted to the cult of Ratvar!"
if(issilicon(M))
@@ -152,6 +162,7 @@ This file's folder contains:
ticker.mode.servants_of_ratvar -= M.mind
ticker.mode.update_servant_icons_removed(M.mind)
all_clockwork_mobs -= M
+ M.faction -= "ratvar"
M.mind.memory = "" //Not sure if there's a better way to do this
M.mind.special_role = null
M.languages_spoken &= ~RATVAR
@@ -335,7 +346,7 @@ This file's folder contains:
else
var/half_victory = FALSE
if(clockwork_objective == CLOCKCULT_GATEWAY)
- var/obj/structure/clockwork/massive/celestial_gateway/G = locate() in all_clockwork_objects
+ var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = locate() in all_clockwork_objects
if(G)
half_victory = TRUE
if(half_victory)
diff --git a/code/game/gamemodes/clock_cult/clock_items.dm b/code/game/gamemodes/clock_cult/clock_items.dm
index 2e8960560cc..d3164bffe80 100644
--- a/code/game/gamemodes/clock_cult/clock_items.dm
+++ b/code/game/gamemodes/clock_cult/clock_items.dm
@@ -983,7 +983,7 @@
icon_state = "tinkerers_daemon"
w_class = 3
var/specific_component //The type of component that the daemon is set to produce in particular, if any
- var/obj/structure/clockwork/cache/cache //The cache the daemon is feeding
+ var/obj/structure/destructible/clockwork/cache/cache //The cache the daemon is feeding
var/production_time = 0 //Progress towards production of the next component in seconds
var/production_cooldown = 200 //How many deciseconds it takes to produce a new component
var/component_slowdown_mod = 2 //how many deciseconds are added to the cooldown when producing a component for each of that component type
@@ -999,7 +999,7 @@
return ..()
/obj/item/clockwork/tinkerers_daemon/process()
- if(!cache || !istype(loc, /obj/structure/clockwork/cache))
+ if(!cache || !istype(loc, /obj/structure/destructible/clockwork/cache))
visible_message("[src] shuts down!")
new/obj/item/clockwork/daemon_shell(get_turf(src))
qdel(src)
diff --git a/code/game/gamemodes/clock_cult/clock_machines.dm b/code/game/gamemodes/clock_cult/clock_machines.dm
index 2c26836fecf..c682142aa5d 100644
--- a/code/game/gamemodes/clock_cult/clock_machines.dm
+++ b/code/game/gamemodes/clock_cult/clock_machines.dm
@@ -3,29 +3,29 @@
////////////////////////
//not-actually-machines
-/obj/structure/clockwork/powered
+/obj/structure/destructible/clockwork/powered
var/obj/machinery/power/apc/target_apc
var/active = FALSE
var/needs_power = TRUE
var/active_icon = null //icon_state while process() is being called
var/inactive_icon = null //icon_state while process() isn't being called
-/obj/structure/clockwork/powered/examine(mob/user)
+/obj/structure/destructible/clockwork/powered/examine(mob/user)
..()
if(is_servant_of_ratvar(user) || isobserver(user))
var/powered = total_accessable_power()
user << "It has access to [powered == INFINITY ? "INFINITY":"[powered]"]W of power."
-/obj/structure/clockwork/powered/Destroy()
+/obj/structure/destructible/clockwork/powered/Destroy()
SSfastprocess.processing -= src
SSobj.processing -= src
return ..()
-/obj/structure/clockwork/powered/process()
+/obj/structure/destructible/clockwork/powered/process()
var/powered = total_accessable_power()
return powered == PROCESS_KILL ? 25 : powered //make sure we don't accidentally return the arbitrary PROCESS_KILL define
-/obj/structure/clockwork/powered/proc/toggle(fast_process, mob/living/user)
+/obj/structure/destructible/clockwork/powered/proc/toggle(fast_process, mob/living/user)
if(user)
if(!is_servant_of_ratvar(user))
return 0
@@ -45,7 +45,7 @@
STOP_PROCESSING(SSobj, src)
-/obj/structure/clockwork/powered/proc/total_accessable_power() //how much power we have and can use
+/obj/structure/destructible/clockwork/powered/proc/total_accessable_power() //how much power we have and can use
if(!needs_power || ratvar_awakens)
return INFINITY //oh yeah we've got power why'd you ask
@@ -54,7 +54,7 @@
power += accessable_sigil_power()
return power
-/obj/structure/clockwork/powered/proc/accessable_apc_power()
+/obj/structure/destructible/clockwork/powered/proc/accessable_apc_power()
var/power = 0
var/area/A = get_area(src)
var/area/targetAPCA
@@ -72,14 +72,14 @@
power += apccharge
return power
-/obj/structure/clockwork/powered/proc/accessable_sigil_power()
+/obj/structure/destructible/clockwork/powered/proc/accessable_sigil_power()
var/power = 0
for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
power += T.power_charge
return power
-/obj/structure/clockwork/powered/proc/try_use_power(amount) //try to use an amount of power
+/obj/structure/destructible/clockwork/powered/proc/try_use_power(amount) //try to use an amount of power
if(!needs_power || ratvar_awakens)
return 1
if(amount <= 0)
@@ -89,7 +89,7 @@
return 0
return use_power(amount)
-/obj/structure/clockwork/powered/proc/use_power(amount) //we've made sure we had power, so now we use it
+/obj/structure/destructible/clockwork/powered/proc/use_power(amount) //we've made sure we had power, so now we use it
var/sigilpower = accessable_sigil_power()
var/list/sigils_in_range = list()
for(var/obj/effect/clockwork/sigil/transmission/T in range(1, src))
@@ -114,7 +114,7 @@
else
return 1
-/obj/structure/clockwork/powered/proc/return_power(amount) //returns a given amount of power to all nearby sigils
+/obj/structure/destructible/clockwork/powered/proc/return_power(amount) //returns a given amount of power to all nearby sigils
if(amount <= 0)
return 0
var/list/sigils_in_range = list()
@@ -130,7 +130,7 @@
return 1
-/obj/structure/clockwork/powered/mending_motor //Mending motor: A prism that consumes replicant alloy to repair nearby mechanical servants at a quick rate.
+/obj/structure/destructible/clockwork/powered/mending_motor //Mending motor: A prism that consumes replicant alloy to repair nearby mechanical servants at a quick rate.
name = "mending motor"
desc = "A dark onyx prism, held in midair by spiraling tendrils of stone."
clockwork_desc = "A powerful prism that rapidly repairs nearby mechanical servants and clockwork structures."
@@ -151,18 +151,18 @@
var/structure_cost = 250
var/cyborg_cost = 300
-/obj/structure/clockwork/powered/mending_motor/prefilled
+/obj/structure/destructible/clockwork/powered/mending_motor/prefilled
stored_alloy = 2500 //starts with 1 replicant alloy/100 liquified alloy
-/obj/structure/clockwork/powered/mending_motor/total_accessable_power()
+/obj/structure/destructible/clockwork/powered/mending_motor/total_accessable_power()
. = ..()
if(. != INFINITY)
. += accessable_alloy_power()
-/obj/structure/clockwork/powered/mending_motor/proc/accessable_alloy_power()
+/obj/structure/destructible/clockwork/powered/mending_motor/proc/accessable_alloy_power()
return stored_alloy
-/obj/structure/clockwork/powered/mending_motor/use_power(amount)
+/obj/structure/destructible/clockwork/powered/mending_motor/use_power(amount)
var/alloypower = accessable_alloy_power()
while(alloypower >= 50 && amount >= 50)
stored_alloy -= 50
@@ -170,13 +170,13 @@
amount -= 50
return ..()
-/obj/structure/clockwork/powered/mending_motor/examine(mob/user)
+/obj/structure/destructible/clockwork/powered/mending_motor/examine(mob/user)
..()
if(is_servant_of_ratvar(user) || isobserver(user))
user << "It contains [stored_alloy*0.04]/[max_alloy*0.04] units of liquified alloy, which is equivalent to [stored_alloy]W/[max_alloy]W of power."
user << "It requires [mob_cost]W to heal clockwork mobs, [structure_cost]W for clockwork structures, and [cyborg_cost]W for cyborgs."
-/obj/structure/clockwork/powered/mending_motor/process()
+/obj/structure/destructible/clockwork/powered/mending_motor/process()
if(..() < mob_cost)
visible_message("[src] emits an airy chuckling sound and falls dark!")
toggle()
@@ -194,8 +194,8 @@
if(!try_use_power(mob_cost))
break
W.adjustHealth(-15)
- else if(istype(M, /obj/structure/clockwork))
- var/obj/structure/clockwork/C = M
+ else if(istype(M, /obj/structure/destructible/clockwork))
+ var/obj/structure/destructible/clockwork/C = M
if(C.health == C.max_health)
continue
if(!try_use_power(structure_cost))
@@ -211,14 +211,14 @@
S.adjustFireLoss(-15)
return 1
-/obj/structure/clockwork/powered/mending_motor/attack_hand(mob/living/user)
+/obj/structure/destructible/clockwork/powered/mending_motor/attack_hand(mob/living/user)
if(user.canUseTopic(src, BE_CLOSE))
if(total_accessable_power() < mob_cost)
user << "[src] needs more power or replicant alloy to function!"
return 0
toggle(0, user)
-/obj/structure/clockwork/powered/mending_motor/attackby(obj/item/I, mob/user, params)
+/obj/structure/destructible/clockwork/powered/mending_motor/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/clockwork/component/replicant_alloy) && is_servant_of_ratvar(user))
if(stored_alloy + 2500 > max_alloy)
user << "[src] is too full to accept any more alloy!"
@@ -235,7 +235,7 @@
-/obj/structure/clockwork/powered/mania_motor //Mania motor: A pair of antenna that, while active, cause braindamage and hallucinations in nearby human mobs.
+/obj/structure/destructible/clockwork/powered/mania_motor //Mania motor: A pair of antenna that, while active, cause braindamage and hallucinations in nearby human mobs.
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."
@@ -265,12 +265,12 @@
"\"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/clockwork/powered/mania_motor/examine(mob/user)
+/obj/structure/destructible/clockwork/powered/mania_motor/examine(mob/user)
..()
if(is_servant_of_ratvar(user) || isobserver(user))
user << "It requires [mania_cost]W to run, and [convert_attempt_cost + convert_cost]W to convert humans adjecent to it."
-/obj/structure/clockwork/powered/mania_motor/process()
+/obj/structure/destructible/clockwork/powered/mania_motor/process()
var/turf/T = get_turf(src)
if(!..())
visible_message("[src] hums loudly, then the sockets at its base fall dark!")
@@ -369,7 +369,7 @@
playsound(src, 'sound/effects/screech.ogg', 40, 1)
toggle(0)
-/obj/structure/clockwork/powered/mania_motor/attack_hand(mob/living/user)
+/obj/structure/destructible/clockwork/powered/mania_motor/attack_hand(mob/living/user)
if(user.canUseTopic(src, BE_CLOSE))
if(!total_accessable_power() >= mania_cost)
user << "[src] needs more power to function!"
@@ -378,7 +378,7 @@
-/obj/structure/clockwork/powered/interdiction_lens //Interdiction lens: A powerful artifact that constantly disrupts electronics but, if it fails to find something to disrupt, turns off.
+/obj/structure/destructible/clockwork/powered/interdiction_lens //Interdiction lens: A powerful artifact that constantly disrupts electronics but, if it fails to find something to disrupt, turns off.
name = "interdiction lens"
desc = "An ominous, double-pronged brass totem. There's a strange gemstone clasped between the pincers."
clockwork_desc = "A powerful totem that constantly disrupts nearby electronics and funnels power into nearby Sigils of Transmission."
@@ -394,7 +394,7 @@
var/interdiction_range = 14 //how large an area it drains and disables in
var/disrupt_cost = 50 //how much power to use when disabling an object
-/obj/structure/clockwork/powered/interdiction_lens/examine(mob/user)
+/obj/structure/destructible/clockwork/powered/interdiction_lens/examine(mob/user)
..()
user << "Its gemstone [recharging > world.time ? "has been breached by writhing tendrils of blackness that cover the totem" \
: "vibrates in place and thrums with power"]."
@@ -402,14 +402,14 @@
user << "It requires [disrupt_cost]W of power for each nearby disruptable electronic."
user << "If it fails to both drain any power and disrupt any electronics, it will disable itself for [round(recharge_time/600, 1)] minutes."
-/obj/structure/clockwork/powered/interdiction_lens/toggle(fast_process, mob/living/user)
+/obj/structure/destructible/clockwork/powered/interdiction_lens/toggle(fast_process, mob/living/user)
..()
if(active)
SetLuminosity(4,2)
else
SetLuminosity(0)
-/obj/structure/clockwork/powered/interdiction_lens/attack_hand(mob/living/user)
+/obj/structure/destructible/clockwork/powered/interdiction_lens/attack_hand(mob/living/user)
if(user.canUseTopic(src, BE_CLOSE))
if(disabled)
user << "As you place your hand on the gemstone, cold tendrils of black matter crawl up your arm. You quickly pull back."
@@ -419,7 +419,7 @@
return 0
toggle(0, user)
-/obj/structure/clockwork/powered/interdiction_lens/process()
+/obj/structure/destructible/clockwork/powered/interdiction_lens/process()
if(recharging > world.time)
return
if(disabled)
@@ -529,7 +529,7 @@
-/obj/structure/clockwork/powered/clockwork_obelisk
+/obj/structure/destructible/clockwork/powered/clockwork_obelisk
name = "clockwork obelisk"
desc = "A large brass obelisk hanging in midair."
clockwork_desc = "A powerful obelisk that can send a message to all servants or open a gateway to a target servant or clockwork obelisk."
@@ -546,16 +546,16 @@
var/gateway_cost = 2000 //how much it costs to open a gateway
var/gateway_active = FALSE
-/obj/structure/clockwork/powered/clockwork_obelisk/New()
+/obj/structure/destructible/clockwork/powered/clockwork_obelisk/New()
..()
toggle(1)
-/obj/structure/clockwork/powered/clockwork_obelisk/examine(mob/user)
+/obj/structure/destructible/clockwork/powered/clockwork_obelisk/examine(mob/user)
..()
if(is_servant_of_ratvar(user) || isobserver(user))
user << "It requires [hierophant_cost]W to broadcast over the Hierophant Network, and [gateway_cost]W to open a Spatial Gateway."
-/obj/structure/clockwork/powered/clockwork_obelisk/process()
+/obj/structure/destructible/clockwork/powered/clockwork_obelisk/process()
if(locate(/obj/effect/clockwork/spatial_gateway) in loc)
icon_state = active_icon
density = 0
@@ -565,7 +565,7 @@
density = 1
gateway_active = FALSE
-/obj/structure/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user)
+/obj/structure/destructible/clockwork/powered/clockwork_obelisk/attack_hand(mob/living/user)
if(!is_servant_of_ratvar(user) || !total_accessable_power() >= hierophant_cost)
user << "You place your hand on the obelisk, but it doesn't react."
return
diff --git a/code/game/gamemodes/clock_cult/clock_proselytizer.dm b/code/game/gamemodes/clock_cult/clock_proselytizer.dm
index 5094389e663..a00443d6cfb 100644
--- a/code/game/gamemodes/clock_cult/clock_proselytizer.dm
+++ b/code/game/gamemodes/clock_cult/clock_proselytizer.dm
@@ -243,7 +243,7 @@
/obj/structure/grille/ratvar/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
return FALSE
-/obj/structure/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
+/obj/structure/destructible/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
. = TRUE
if(proselytizer.repairing) //no spamclicking for fast repairs, bucko
user << "You are already repairing [proselytizer.repairing] with [proselytizer]!"
@@ -296,7 +296,7 @@
"You finish repairing [src]. It is now at [health]/[max_health] integrity.")
return
-/obj/structure/clockwork/cache/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
+/obj/structure/destructible/clockwork/cache/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
. = ..()
if(proselytizer.can_use_alloy(0) || proselytizer.stored_alloy + REPLICANT_ALLOY_UNIT > proselytizer.max_alloy)
user << "[proselytizer]'s containers of liquified alloy are full!"
@@ -318,7 +318,7 @@
"You finish filling [proselytizer] with liquified alloy. It now contains [proselytizer.stored_alloy]/[proselytizer.max_alloy] units of liquified alloy.")
return
-/obj/structure/clockwork/wall_gear/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
+/obj/structure/destructible/clockwork/wall_gear/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
return list("operation_time" = 10, "new_obj_type" = /obj/effect/overlay/temp/ratvar/beam/itemconsume, "alloy_cost" = -REPLICANT_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
/obj/item/clockwork/alloy_shards/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
diff --git a/code/game/gamemodes/clock_cult/clock_ratvar.dm b/code/game/gamemodes/clock_cult/clock_ratvar.dm
index d69b02ee132..34033722cf7 100644
--- a/code/game/gamemodes/clock_cult/clock_ratvar.dm
+++ b/code/game/gamemodes/clock_cult/clock_ratvar.dm
@@ -1,22 +1,22 @@
-/obj/structure/clockwork/massive //For objects that are typically very large
+/obj/structure/destructible/clockwork/massive //For objects that are typically very large
name = "massive construct"
desc = "A very large construction."
layer = MASSIVE_OBJ_LAYER
density = FALSE
burn_state = LAVA_PROOF
-/obj/structure/clockwork/massive/New()
+/obj/structure/destructible/clockwork/massive/New()
..()
poi_list += src
-/obj/structure/clockwork/massive/Destroy()
+/obj/structure/destructible/clockwork/massive/Destroy()
poi_list -= src
return ..()
-/obj/structure/clockwork/massive/singularity_pull(S, current_size)
+/obj/structure/destructible/clockwork/massive/singularity_pull(S, current_size)
return
-/obj/structure/clockwork/massive/celestial_gateway //The gateway to Reebe, from which Ratvar emerges
+/obj/structure/destructible/clockwork/massive/celestial_gateway //The gateway to Reebe, from which Ratvar emerges
name = "Gateway to the Celestial Derelict"
desc = "A massive, thrumming rip in spacetime."
clockwork_desc = "A portal to the Celestial Derelict. Massive and intimidating, it is the only thing that can both transport Ratvar and withstand the massive amount of energy he emits."
@@ -36,7 +36,7 @@
var/obj/effect/clockwork/overlay/gateway_glow/glow
var/obj/effect/countdown/clockworkgate/countdown
-/obj/structure/clockwork/massive/celestial_gateway/New()
+/obj/structure/destructible/clockwork/massive/celestial_gateway/New()
..()
glow = new(get_turf(src))
countdown = new(src)
@@ -45,7 +45,7 @@
var/area/gate_area = get_area(src)
hierophant_message("A gateway to the Celestial Derelict has been created in [gate_area.map_name]!", FALSE, src)
-/obj/structure/clockwork/massive/celestial_gateway/Destroy()
+/obj/structure/destructible/clockwork/massive/celestial_gateway/Destroy()
STOP_PROCESSING(SSobj, src)
if(!purpose_fulfilled)
var/area/gate_area = get_area(src)
@@ -59,7 +59,7 @@
countdown = null
. = ..()
-/obj/structure/clockwork/massive/celestial_gateway/destroyed()
+/obj/structure/destructible/clockwork/massive/celestial_gateway/destroyed()
countdown.stop()
visible_message("The [src] begins to pulse uncontrollably... you might want to run!")
world << sound('sound/effects/clockcult_gateway_disrupted.ogg', 0, channel = 8, volume = 50)
@@ -71,23 +71,23 @@
qdel(src)
return 1
-/obj/structure/clockwork/massive/celestial_gateway/proc/make_glow()
+/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/make_glow()
if(!glow)
glow = PoolOrNew(/obj/effect/clockwork/overlay/gateway_glow, get_turf(src))
glow.linked = src
-/obj/structure/clockwork/massive/celestial_gateway/ex_act(severity)
+/obj/structure/destructible/clockwork/massive/celestial_gateway/ex_act(severity)
var/damage = max((health * 0.70) / severity, 100) //requires multiple bombs to take down
take_damage(damage, BRUTE)
-/obj/structure/clockwork/massive/celestial_gateway/proc/get_arrival_text(s_on_time)
+/obj/structure/destructible/clockwork/massive/celestial_gateway/proc/get_arrival_text(s_on_time)
. = "IMMINENT"
if(!health)
. = "DETONATING"
else if(GATEWAY_RATVAR_ARRIVAL - progress_in_seconds > 0)
. = "[round(max((GATEWAY_RATVAR_ARRIVAL - progress_in_seconds) / (GATEWAY_SUMMON_RATE * 0.5), 0), 1)][s_on_time ? "S":""]"
-/obj/structure/clockwork/massive/celestial_gateway/process()
+/obj/structure/destructible/clockwork/massive/celestial_gateway/process()
if(!progress_in_seconds || prob(7))
for(var/M in mob_list)
M << "You hear otherworldly sounds from the [dir2text(get_dir(get_turf(M), get_turf(src)))]..."
@@ -129,7 +129,7 @@
QDEL_IN(src, 3)
clockwork_gateway_activated = TRUE
if(ratvar_portal)
- new/obj/structure/clockwork/massive/ratvar(startpoint)
+ new/obj/structure/destructible/clockwork/massive/ratvar(startpoint)
else
world << "\"[text2ratvar("Behold")]!\"\n\"[text2ratvar("See Engine's mercy")]!\"\n\
\"[text2ratvar("Observe Engine's design skills")]!\"\n\"[text2ratvar("Behold Engine's light")]!!\"\n\
@@ -153,7 +153,7 @@
if(M.stat == CONSCIOUS)
clockwork_say(M, text2ratvar(pick("Purge all untruths and honor Engine!", "All glory to Engine's light!", "Engine's power is unmatched!")))
-/obj/structure/clockwork/massive/celestial_gateway/examine(mob/user)
+/obj/structure/destructible/clockwork/massive/celestial_gateway/examine(mob/user)
icon_state = "spatial_gateway" //cheat wildly by pretending to have an icon
..()
icon_state = initial(icon_state)
@@ -183,7 +183,7 @@
layer = MASSIVE_OBJ_LAYER
-/obj/structure/clockwork/massive/ratvar
+/obj/structure/destructible/clockwork/massive/ratvar
name = "Ratvar, the Clockwork Justiciar"
desc = "What is what is what are what real what is all a lie all a lie it's all a lie why how can what is"
clockwork_desc = "Ratvar, the Clockwork Justiciar, your master eternal."
@@ -197,7 +197,7 @@
var/clashing = FALSE //If Ratvar is FUCKING FIGHTING WITH NAR-SIE
var/proselytize_range = 10
-/obj/structure/clockwork/massive/ratvar/New()
+/obj/structure/destructible/clockwork/massive/ratvar/New()
..()
ratvar_awakens++
for(var/obj/item/clockwork/ratvarian_spear/R in all_clockwork_objects)
@@ -211,7 +211,7 @@
addtimer(SSshuttle.emergency, "request", 50, FALSE, null, 0.1)
-/obj/structure/clockwork/massive/ratvar/Destroy()
+/obj/structure/destructible/clockwork/massive/ratvar/Destroy()
ratvar_awakens--
for(var/obj/item/clockwork/ratvarian_spear/R in all_clockwork_objects)
R.update_force()
@@ -220,7 +220,7 @@
return ..()
-/obj/structure/clockwork/massive/ratvar/attack_ghost(mob/dead/observer/O)
+/obj/structure/destructible/clockwork/massive/ratvar/attack_ghost(mob/dead/observer/O)
var/alertresult = alert(O, "Embrace the Justiciar's light? You can no longer be cloned!",,"Yes", "No")
if(alertresult == "No" || !O)
return 0
@@ -229,17 +229,17 @@
R.key = O.key
-/obj/structure/clockwork/massive/ratvar/Bump(atom/A)
+/obj/structure/destructible/clockwork/massive/ratvar/Bump(atom/A)
var/turf/T = get_turf(A)
forceMove(T)
T.ratvar_act()
-/obj/structure/clockwork/massive/ratvar/Process_Spacemove()
+/obj/structure/destructible/clockwork/massive/ratvar/Process_Spacemove()
return clashing
-/obj/structure/clockwork/massive/ratvar/process()
+/obj/structure/destructible/clockwork/massive/ratvar/process()
if(clashing) //I'm a bit occupied right now, thanks
return
for(var/I in circlerangeturfs(src, proselytize_range))
@@ -273,7 +273,7 @@
dir_to_step_in = get_dir(src, prey) //Unlike Nar-Sie, Ratvar ruthlessly chases down his target
step(src, dir_to_step_in)
-/obj/structure/clockwork/massive/ratvar/narsie_act()
+/obj/structure/destructible/clockwork/massive/ratvar/narsie_act()
if(clashing)
return 0
clashing = TRUE
@@ -287,7 +287,7 @@
break
return 1
-/obj/structure/clockwork/massive/ratvar/proc/clash_of_the_titans(obj/singularity/narsie/narsie)
+/obj/structure/destructible/clockwork/massive/ratvar/proc/clash_of_the_titans(obj/singularity/narsie/narsie)
var/winner = "Undeclared"
var/base_victory_chance = 1
while(TRUE)
diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm
index ff7a04995b8..28f3574c91c 100644
--- a/code/game/gamemodes/clock_cult/clock_scripture.dm
+++ b/code/game/gamemodes/clock_cult/clock_scripture.dm
@@ -395,7 +395,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
channel_time = 50
required_components = list("belligerent_eye" = 0, "vanguard_cogwheel" = 0, "guvax_capacitor" = 0, "replicant_alloy" = 2, "hierophant_ansible" = 0)
consumed_components = list("belligerent_eye" = 0, "vanguard_cogwheel" = 0, "guvax_capacitor" = 0, "replicant_alloy" = 1, "hierophant_ansible" = 0)
- object_path = /obj/structure/clockwork/cache
+ object_path = /obj/structure/destructible/clockwork/cache
creator_message = "You form a tinkerer's cache, which is capable of storing components, which will automatically be used by slabs."
observer_message = "A hollow brass spire rises and begins to blaze!"
usage_tip = "Slabs will draw components from the global cache after the slab's own repositories, making caches very efficient."
@@ -456,7 +456,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
channel_time = 120
required_components = list("belligerent_eye" = 2, "replicant_alloy" = 1)
consumed_components = list("belligerent_eye" = 1, "replicant_alloy" = 1)
- object_path = /obj/structure/clockwork/ocular_warden
+ object_path = /obj/structure/destructible/clockwork/ocular_warden
creator_message = "You form an ocular warden, which will focus its searing gaze upon nearby unenlightened."
observer_message = "A brass eye takes shape and slowly rises into the air, its red iris glaring!"
usage_tip = "Although powerful, the warden is very weak and should optimally be placed behind barricades."
@@ -464,7 +464,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
one_per_tile = TRUE
/datum/clockwork_scripture/create_object/ocular_warden/check_special_requirements()
- for(var/obj/structure/clockwork/ocular_warden/W in range(3, invoker))
+ for(var/obj/structure/destructible/clockwork/ocular_warden/W in range(3, invoker))
invoker << "You sense another ocular warden too near this location. Placing another this close would cause them to fight." //fluff message
return 0
return ..()
@@ -656,7 +656,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
for(var/mob/living/L in living_mob_list)
if(is_servant_of_ratvar(L) && !L.stat != DEAD)
other_servants++
- for(var/obj/structure/clockwork/powered/clockwork_obelisk/O in all_clockwork_objects)
+ for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in all_clockwork_objects)
other_servants++
if(!other_servants)
invoker << "There are no other servants or clockwork obelisks!"
@@ -701,7 +701,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
channel_time = 50
required_components = list("belligerent_eye" = 2, "hierophant_ansible" = 1)
consumed_components = list("belligerent_eye" = 1, "hierophant_ansible" = 1)
- object_path = /obj/structure/clockwork/shell/cogscarab
+ object_path = /obj/structure/destructible/clockwork/shell/cogscarab
creator_message = "You form a cogscarab, a constructor soul vessel receptable."
observer_message = "The slab disgorges a puddle of black metal that contracts and forms into a strange shell!"
usage_tip = "Useless without a soul vessel and should not be created without one."
@@ -738,7 +738,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
channel_time = 70
required_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 1, "replicant_alloy" = 3)
consumed_components = list("belligerent_eye" = 1, "vanguard_cogwheel" = 1, "replicant_alloy" = 2)
- object_path = /obj/structure/clockwork/shell/fragment
+ object_path = /obj/structure/destructible/clockwork/shell/fragment
creator_message = "You form an anima fragment, a powerful soul vessel receptable."
observer_message = "The slab disgorges a puddle of black metal that expands and forms into a strange shell!"
usage_tip = "Useless without a soul vessel and should not be created without one."
@@ -874,7 +874,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
channel_time = 80
required_components = list("belligerent_eye" = 1, "replicant_alloy" = 4, "hierophant_ansible" = 1)
consumed_components = list("belligerent_eye" = 1, "replicant_alloy" = 3, "hierophant_ansible" = 1)
- object_path = /obj/structure/clockwork/powered/interdiction_lens
+ 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!"
invokers_required = 2
@@ -893,7 +893,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
channel_time = 80
required_components = list("vanguard_cogwheel" = 4, "guvax_capacitor" = 1, "replicant_alloy" = 1)
consumed_components = list("vanguard_cogwheel" = 3, "guvax_capacitor" = 1, "replicant_alloy" = 1)
- object_path = /obj/structure/clockwork/powered/mending_motor/prefilled
+ object_path = /obj/structure/destructible/clockwork/powered/mending_motor/prefilled
creator_message = "You form a mending motor, which will consume power or replicant alloy to mend the wounds of mechanized servants."
observer_message = "An onyx prism forms in midair and sprouts tendrils to support itself!"
invokers_required = 2
@@ -912,7 +912,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
channel_time = 80
required_components = list("vanguard_cogwheel" = 1, "replicant_alloy" = 1, "hierophant_ansible" = 4)
consumed_components = list("vanguard_cogwheel" = 1, "replicant_alloy" = 1, "hierophant_ansible" = 3)
- object_path = /obj/structure/clockwork/powered/clockwork_obelisk
+ 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 handing in midair!"
invokers_required = 2
@@ -931,7 +931,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
channel_time = 80
required_components = list("guvax_capacitor" = 4, "replicant_alloy" = 1, "hierophant_ansible" = 1)
consumed_components = list("guvax_capacitor" = 3, "replicant_alloy" = 1, "hierophant_ansible" = 1)
- object_path = /obj/structure/clockwork/powered/mania_motor
+ 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."
observer_message = "A two-pronged machine rises from the ground!"
invokers_required = 2
@@ -1002,24 +1002,24 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
hierophant_message("[text2ratvar("Armorer: \"I heed your call, champions. May your artifacts bring ruin upon the heathens that oppose our master!")]\"", FALSE, invoker)
clockwork_generals_invoked["nezbere"] = world.time + CLOCKWORK_GENERAL_COOLDOWN
playsound(invoker, 'sound/magic/clockwork/invoke_general.ogg', 50, 0)
- for(var/obj/structure/clockwork/ocular_warden/W in all_clockwork_objects) //Ocular wardens have increased damage and radius
+ for(var/obj/structure/destructible/clockwork/ocular_warden/W in all_clockwork_objects) //Ocular wardens have increased damage and radius
W.damage_per_tick *= 1.5
W.sight_range *= 2
for(var/obj/item/clockwork/clockwork_proselytizer/P in all_clockwork_objects) //Proselytizers no longer require alloy
P.uses_alloy = FALSE
for(var/obj/item/clockwork/tinkerers_daemon/D in all_clockwork_objects) //Daemons produce components twice as quickly
D.production_time *= 0.5
- for(var/obj/structure/clockwork/powered/M in all_clockwork_objects) //Powered clockwork structures no longer need power
+ for(var/obj/structure/destructible/clockwork/powered/M in all_clockwork_objects) //Powered clockwork structures no longer need power
M.needs_power = FALSE
spawn(600)
- for(var/obj/structure/clockwork/ocular_warden/W in all_clockwork_objects)
+ for(var/obj/structure/destructible/clockwork/ocular_warden/W in all_clockwork_objects)
W.damage_per_tick = initial(W.damage_per_tick)
W.sight_range = initial(W.sight_range)
for(var/obj/item/clockwork/clockwork_proselytizer/P in all_clockwork_objects)
P.uses_alloy = initial(P.uses_alloy)
for(var/obj/item/clockwork/tinkerers_daemon/D in all_clockwork_objects)
D.production_time = initial(D.production_time)
- for(var/obj/structure/clockwork/powered/M in all_clockwork_objects)
+ for(var/obj/structure/destructible/clockwork/powered/M in all_clockwork_objects)
M.needs_power = initial(M.needs_power)
return 1
@@ -1220,7 +1220,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
if(ratvar_awakens)
invoker << "\"I am already here, idiot.\""
return 0
- for(var/obj/structure/clockwork/massive/celestial_gateway/G in all_clockwork_objects)
+ for(var/obj/structure/destructible/clockwork/massive/celestial_gateway/G in all_clockwork_objects)
var/area/gate_area = get_area(G)
invoker << "There is already a gateway at [gate_area.map_name]!"
return 0
@@ -1274,7 +1274,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed
playsound(T, 'sound/magic/clockwork/invoke_general.ogg', 75, 0)
sleep(10)
if(check_special_requirements())
- var/obj/structure/clockwork/massive/celestial_gateway/CG = new/obj/structure/clockwork/massive/celestial_gateway(T)
+ var/obj/structure/destructible/clockwork/massive/celestial_gateway/CG = new/obj/structure/destructible/clockwork/massive/celestial_gateway(T)
if(ticker && ticker.mode && ticker.mode.clockwork_objective != CLOCKCULT_GATEWAY)
CG.ratvar_portal = FALSE
hierophant_message("This newly constructed gateway will not free Ratvar, \
diff --git a/code/game/gamemodes/clock_cult/clock_structures.dm b/code/game/gamemodes/clock_cult/clock_structures.dm
index cddd9cb68af..83477d09822 100644
--- a/code/game/gamemodes/clock_cult/clock_structures.dm
+++ b/code/game/gamemodes/clock_cult/clock_structures.dm
@@ -2,7 +2,7 @@
// CLOCKWORK STRUCTURES //
//////////////////////////
-/obj/structure/clockwork
+/obj/structure/destructible/clockwork
name = "meme structure"
desc = "Some frog or something, the fuck?"
var/clockwork_desc //Shown to servants when they examine
@@ -10,77 +10,32 @@
icon_state = "rare_pepe"
anchored = 1
density = 1
- opacity = 0
- layer = OBJ_LAYER
- var/max_health = 100 //All clockwork structures have health that can be removed via attacks
- var/health = 100
var/repair_amount = 5 //how much a proselytizer can repair each cycle
var/can_be_repaired = TRUE //if a proselytizer can repair it at all
- var/takes_damage = TRUE //If the structure can be damaged
- var/break_message = "The frog isn't a meme after all!" //The message shown when a structure breaks
- var/break_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' //The sound played when a structure breaks
- var/list/debris = list(/obj/item/clockwork/alloy_shards/large = 1, \
+ break_message = "The frog isn't a meme after all!" //The message shown when a structure breaks
+ break_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' //The sound played when a structure breaks
+ debris = list(/obj/item/clockwork/alloy_shards/large = 1, \
/obj/item/clockwork/alloy_shards/medium = 2, \
/obj/item/clockwork/alloy_shards/small = 3) //Parts left behind when a structure breaks
var/construction_value = 0 //How much value the structure contributes to the overall "power" of the structures on the station
-/obj/structure/clockwork/New()
+/obj/structure/destructible/clockwork/New()
..()
change_construction_value(construction_value)
all_clockwork_objects += src
-/obj/structure/clockwork/Destroy()
+/obj/structure/destructible/clockwork/Destroy()
change_construction_value(-construction_value)
all_clockwork_objects -= src
return ..()
-/obj/structure/clockwork/proc/destroyed()
- if(!takes_damage)
- return 0
- for(var/I in debris)
- for(var/i in 1 to debris[I])
- new I (get_turf(src))
- visible_message(break_message)
- playsound(src, break_sound, 50, 1)
- qdel(src)
- return 1
-
-/obj/structure/clockwork/burn()
- SSobj.burning -= src
- if(takes_damage)
- playsound(src, 'sound/items/Welder.ogg', 100, 1)
- visible_message("[src] is warped by the heat!")
- take_damage(rand(50, 100), BURN)
-
-/obj/structure/clockwork/proc/take_damage(amount, damage_type)
- if(!amount || !damage_type || !damage_type in list(BRUTE, BURN))
- return 0
- if(takes_damage)
- health = max(0, health - amount)
- if(!health)
- destroyed()
- return 1
- return 0
-
-/obj/structure/clockwork/narsie_act()
+/obj/structure/destructible/clockwork/narsie_act()
if(take_damage(rand(25, 50), BRUTE) && src) //if we still exist
var/previouscolor = color
color = "#960000"
animate(src, color = previouscolor, time = 8)
-/obj/structure/clockwork/ex_act(severity)
- var/damage = 0
- switch(severity)
- if(1)
- damage = max_health //100% max health lost
- if(2)
- damage = max_health * (0.01 * rand(50, 70)) //50-70% max health lost
- if(3)
- damage = max_health * (0.01 * rand(10, 30)) //10-30% max health lost
- if(damage)
- take_damage(damage, BRUTE)
-
-/obj/structure/clockwork/examine(mob/user)
+/obj/structure/destructible/clockwork/examine(mob/user)
var/can_see_clockwork = is_servant_of_ratvar(user) || isobserver(user)
if(can_see_clockwork && clockwork_desc)
desc = clockwork_desc
@@ -103,49 +58,7 @@
heavily_damaged = TRUE
user << "[can_see_clockwork ? "[servant_message]":"[other_message]"][heavily_damaged ? "!":"."]"
-/obj/structure/clockwork/bullet_act(obj/item/projectile/P)
- . = ..()
- visible_message("[src] is hit by \a [P]!")
- playsound(src, P.hitsound, 50, 1)
- take_damage(P.damage, P.damage_type)
-
-/obj/structure/clockwork/proc/attack_generic(mob/user, damage = 0, damage_type = BRUTE) //used by attack_alien, attack_animal, and attack_slime
- user.do_attack_animation(src)
- user.changeNext_move(CLICK_CD_MELEE)
- user.visible_message("[user] smashes into [src]!")
- take_damage(damage, damage_type)
-
-/obj/structure/clockwork/attack_alien(mob/living/user)
- playsound(src, 'sound/weapons/bladeslice.ogg', 50, 1)
- attack_generic(user, 15)
-
-/obj/structure/clockwork/attack_animal(mob/living/simple_animal/M)
- if(!M.melee_damage_upper && !M.obj_damage)
- return
- playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
- if(M.obj_damage)
- attack_generic(M, M.obj_damage, M.melee_damage_type)
- else
- attack_generic(M, M.melee_damage_upper, M.melee_damage_type)
-
-/obj/structure/clockwork/attack_slime(mob/living/simple_animal/slime/user)
- if(!user.is_adult)
- return
- playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
- attack_generic(user, rand(10, 15))
-
-/obj/structure/clockwork/attacked_by(obj/item/I, mob/living/user)
- . = ..()
- if(I.force && takes_damage)
- playsound(src, I.hitsound, 50, 1)
- take_damage(I.force, I.damtype)
-
-/obj/structure/clockwork/mech_melee_attack(obj/mecha/M)
- if(..())
- playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
- take_damage(M.force, M.damtype)
-
-/obj/structure/clockwork/cache //Tinkerer's cache: Stores components for later use.
+/obj/structure/destructible/clockwork/cache //Tinkerer's cache: Stores components for later use.
name = "tinkerer's cache"
desc = "A large brass spire with a flaming hole in its center."
clockwork_desc = "A brass container capable of storing a large amount of components.\n\
@@ -158,7 +71,7 @@
var/wall_generation_cooldown
var/turf/closed/wall/clockwork/linkedwall //if we've got a linked wall and are producing
-/obj/structure/clockwork/cache/New()
+/obj/structure/destructible/clockwork/cache/New()
..()
START_PROCESSING(SSobj, src)
clockwork_caches++
@@ -166,7 +79,7 @@
for(var/i in all_clockwork_mobs)
cache_check(i)
-/obj/structure/clockwork/cache/Destroy()
+/obj/structure/destructible/clockwork/cache/Destroy()
clockwork_caches--
STOP_PROCESSING(SSobj, src)
if(linkedwall)
@@ -176,14 +89,14 @@
cache_check(i)
return ..()
-/obj/structure/clockwork/cache/destroyed()
+/obj/structure/destructible/clockwork/cache/destroyed()
if(takes_damage)
for(var/I in src)
var/atom/movable/A = I
A.forceMove(get_turf(src)) //drop any daemons we have
return ..()
-/obj/structure/clockwork/cache/process()
+/obj/structure/destructible/clockwork/cache/process()
for(var/turf/closed/wall/clockwork/C in view(4, src))
if(!C.linkedcache && !linkedwall)
C.linkedcache = src
@@ -198,7 +111,7 @@
visible_message("Something clunks around inside of [src]...")
break
-/obj/structure/clockwork/cache/attackby(obj/item/I, mob/living/user, params)
+/obj/structure/destructible/clockwork/cache/attackby(obj/item/I, mob/living/user, params)
if(!is_servant_of_ratvar(user))
return ..()
if(istype(I, /obj/item/clockwork/component))
@@ -236,7 +149,7 @@
else
return ..()
-/obj/structure/clockwork/cache/attack_hand(mob/user)
+/obj/structure/destructible/clockwork/cache/attack_hand(mob/user)
if(!is_servant_of_ratvar(user))
return 0
if(!clockwork_component_cache["replicant_alloy"])
@@ -248,7 +161,7 @@
user.put_in_hands(A)
return 1
-/obj/structure/clockwork/cache/examine(mob/user)
+/obj/structure/destructible/clockwork/cache/examine(mob/user)
..()
if(is_servant_of_ratvar(user) || isobserver(user))
if(linkedwall)
@@ -258,7 +171,7 @@
user << "[get_component_name(i)]s: [clockwork_component_cache[i]]"
-/obj/structure/clockwork/ocular_warden //Ocular warden: Low-damage, low-range turret. Deals constant damage to whoever it makes eye contact with.
+/obj/structure/destructible/clockwork/ocular_warden //Ocular warden: Low-damage, low-range turret. Deals constant damage to whoever it makes eye contact with.
name = "ocular warden"
desc = "A large brass eye with tendrils trailing below it and a wide red iris."
clockwork_desc = "A stalwart turret that will deal sustained damage to any non-faithful it sees."
@@ -276,19 +189,19 @@
var/list/idle_messages = list(" sulkily glares around.", " lazily drifts from side to side.", " looks around for something to burn.", " slowly turns in circles.")
var/mech_damage_cycle = 0 //only hits every few cycles so mechs have a chance against it
-/obj/structure/clockwork/ocular_warden/New()
+/obj/structure/destructible/clockwork/ocular_warden/New()
..()
START_PROCESSING(SSfastprocess, src)
-/obj/structure/clockwork/ocular_warden/Destroy()
+/obj/structure/destructible/clockwork/ocular_warden/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
-/obj/structure/clockwork/ocular_warden/examine(mob/user)
+/obj/structure/destructible/clockwork/ocular_warden/examine(mob/user)
..()
user << "[target ? "It's fixated on [target]!" : "Its gaze is wandering aimlessly."]"
-/obj/structure/clockwork/ocular_warden/process()
+/obj/structure/destructible/clockwork/ocular_warden/process()
var/list/validtargets = acquire_nearby_targets()
if(ratvar_awakens && (damage_per_tick == initial(damage_per_tick) || sight_range == initial(sight_range))) //Massive buff if Ratvar has returned
damage_per_tick = 10
@@ -328,7 +241,7 @@
else
setDir(pick(cardinal))//Random rotation
-/obj/structure/clockwork/ocular_warden/proc/acquire_nearby_targets()
+/obj/structure/destructible/clockwork/ocular_warden/proc/acquire_nearby_targets()
. = list()
for(var/mob/living/L in viewers(sight_range, src)) //Doesn't attack the blind
var/obj/item/weapon/storage/book/bible/B = L.bible_check()
@@ -345,7 +258,7 @@
if(get_dist(M, src) <= sight_range && M.occupant && !is_servant_of_ratvar(M.occupant) && (M in view(sight_range, src)))
. += M
-/obj/structure/clockwork/ocular_warden/proc/lose_target()
+/obj/structure/destructible/clockwork/ocular_warden/proc/lose_target()
if(!target)
return 0
mech_damage_cycle = 0
@@ -354,7 +267,7 @@
return 1
-/obj/structure/clockwork/shell
+/obj/structure/destructible/clockwork/shell
construction_value = 0
anchored = 0
density = 0
@@ -363,7 +276,7 @@
var/mobtype = /mob/living/simple_animal/hostile/clockwork
var/spawn_message = " is an error and you should yell at whoever spawned this shell."
-/obj/structure/clockwork/shell/attackby(obj/item/I, mob/living/user, params)
+/obj/structure/destructible/clockwork/shell/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/device/mmi/posibrain/soul_vessel))
if(!is_servant_of_ratvar(user))
..()
@@ -388,7 +301,7 @@
else
return ..()
-/obj/structure/clockwork/shell/cogscarab
+/obj/structure/destructible/clockwork/shell/cogscarab
name = "cogscarab shell"
desc = "A small brass shell with a cube-shaped receptable in its center. It gives off an aura of obsessive perfectionism."
clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a weak construct with an inbuilt proselytizer."
@@ -396,7 +309,7 @@
mobtype = /mob/living/simple_animal/drone/cogscarab
spawn_message = "'s eyes blink open, glowing bright red."
-/obj/structure/clockwork/shell/fragment //Anima fragment: Useless on its own, but can accept an active soul vessel to create a powerful construct.
+/obj/structure/destructible/clockwork/shell/fragment //Anima fragment: Useless on its own, but can accept an active soul vessel to create a powerful construct.
name = "fragment shell"
desc = "A massive brass shell with a small cube-shaped receptable in its center. It gives off an aura of contained power."
clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a powerful construct."
@@ -405,7 +318,7 @@
spawn_message = " whirs and rises from the ground on a flickering jet of reddish fire."
-/obj/structure/clockwork/wall_gear
+/obj/structure/destructible/clockwork/wall_gear
name = "massive gear"
icon_state = "wall_gear"
climbable = TRUE
@@ -418,13 +331,13 @@
/obj/item/clockwork/alloy_shards/medium = 4, \
/obj/item/clockwork/alloy_shards/small = 2) //slightly more debris than the default, totals 26 alloy
-/obj/structure/clockwork/wall_gear/attackby(obj/item/I, mob/user, params)
+/obj/structure/destructible/clockwork/wall_gear/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/wrench))
default_unfasten_wrench(user, I, 10)
return 1
return ..()
-/obj/structure/clockwork/wall_gear/examine(mob/user)
+/obj/structure/destructible/clockwork/wall_gear/examine(mob/user)
..()
user << "[src] is [anchored ? "secured to the floor":"mobile, and not secured"]."
diff --git a/code/game/gamemodes/clock_cult/clock_unsorted.dm b/code/game/gamemodes/clock_cult/clock_unsorted.dm
index fbc532f2ddc..2b775f76678 100644
--- a/code/game/gamemodes/clock_cult/clock_unsorted.dm
+++ b/code/game/gamemodes/clock_cult/clock_unsorted.dm
@@ -85,7 +85,7 @@
var/list/teleportnames = list()
var/list/duplicatenamecount = list()
- for(var/obj/structure/clockwork/powered/clockwork_obelisk/O in all_clockwork_objects)
+ for(var/obj/structure/destructible/clockwork/powered/clockwork_obelisk/O in all_clockwork_objects)
if(!O.Adjacent(invoker) && O != src && (O.z <= ZLEVEL_SPACEMAX)) //don't list obelisks that we're next to
var/area/A = get_area(O)
var/locname = initial(A.name)
@@ -116,13 +116,13 @@
var/atom/movable/target = possible_targets[input_target_key]
if(!src || !target || !invoker || !invoker.canUseTopic(src, BE_CLOSE) || !is_servant_of_ratvar(invoker) || (istype(src, /obj/item) && invoker.get_active_held_item() != src))
return 0 //if any of the involved things no longer exist, the invoker is stunned, too far away to use the object, or does not serve ratvar, or if the object is an item and not in the mob's active hand, fail
- var/istargetobelisk = istype(target, /obj/structure/clockwork/powered/clockwork_obelisk)
+ var/istargetobelisk = istype(target, /obj/structure/destructible/clockwork/powered/clockwork_obelisk)
if(istargetobelisk)
gateway_uses *= 2
time_duration *= 2
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(istype(src, /obj/structure/clockwork/powered/clockwork_obelisk) ? get_turf(src) : get_step(get_turf(invoker), invoker.dir))
+ var/obj/effect/clockwork/spatial_gateway/S1 = new(istype(src, /obj/structure/destructible/clockwork/powered/clockwork_obelisk) ? get_turf(src) : get_step(get_turf(invoker), invoker.dir))
var/obj/effect/clockwork/spatial_gateway/S2 = new(istargetobelisk ? get_turf(target) : get_step(get_turf(target), target.dir))
//Set up the portals now that they've spawned
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index db52c9cfd8e..0f419ad2fec 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -185,7 +185,7 @@
user.Dizzy(30)
user.Weaken(5)
else
- user << "\"Putting on things you don't own is bad, you know.\""
+ user << "\"Trying to use things you don't own is bad, you know.\""
user << "The armor squeezes at your body!"
user.emote("scream")
user.adjustBruteLoss(25)
@@ -239,7 +239,7 @@
user.Dizzy(30)
user.Weaken(5)
else
- user << "\"Putting on things you don't own is bad, you know.\""
+ user << "\"Trying to use things you don't own is bad, you know.\""
user << "The robes squeeze at your body!"
user.emote("scream")
user.adjustBruteLoss(25)
diff --git a/code/game/gamemodes/cult/cult_structures.dm b/code/game/gamemodes/cult/cult_structures.dm
index bd6315d7271..405b6512001 100644
--- a/code/game/gamemodes/cult/cult_structures.dm
+++ b/code/game/gamemodes/cult/cult_structures.dm
@@ -1,18 +1,47 @@
-/obj/structure/cult
+/obj/structure/destructible/cult
density = 1
anchored = 1
icon = 'icons/obj/cult.dmi'
var/cooldowntime = 0
- var/health = 100
- var/maxhealth = 100
+ break_sound = 'sound/hallucinations/veryfar_noise.ogg'
+ debris = list(/obj/item/stack/sheet/runed_metal = 1)
-/obj/structure/cult/examine(mob/user)
+/obj/structure/destructible/cult/examine(mob/user)
+ var/can_see_cult = iscultist(user) || isobserver(user)
..()
+ if(takes_damage)
+ var/cultist_message = "It is at [health]/[max_health] stability"
+ var/other_message = "It seems extremely stable"
+ var/heavily_damaged = FALSE
+ var/healthpercent = (health/max_health) * 100
+ if(healthpercent >= 100)
+ other_message = "It seems extremely stable"
+ else if(healthpercent >= 50)
+ other_message = "It looks slightly unstable"
+ else if(healthpercent >= 25)
+ other_message = "It appears very unstable"
+ heavily_damaged = TRUE
+ else if(healthpercent >= 0)
+ other_message = "It's glowing faintly and is extremely unstable"
+ heavily_damaged = TRUE
+ user << "[heavily_damaged ? "":""][can_see_cult ? "[cultist_message]":"[other_message]"][heavily_damaged ? "!":"."]"
user << "\The [src] is [anchored ? "":"not "]secured to the floor."
- if(iscultist(user) && cooldowntime > world.time)
+ if(can_see_cult && cooldowntime > world.time)
user << "The magic in [src] is weak, it will be ready to use again in [getETA()]."
-/obj/structure/cult/attackby(obj/I, mob/user, params)
+/obj/structure/destructible/cult/attack_animal(mob/living/simple_animal/M)
+ if(istype(M, /mob/living/simple_animal/hostile/construct/builder))
+ if(health < max_health)
+ health = min(max_health, health + 5)
+ Beam(M, icon_state="sendbeam", icon='icons/effects/effects.dmi', time=4)
+ M.visible_message("[M] repairs \the [src].", \
+ "You repair [src], leaving it at [health]/[max_health] stability.")
+ else
+ M << "You cannot repair [src], as it is undamaged!"
+ else
+ ..()
+
+/obj/structure/destructible/cult/attackby(obj/I, mob/user, params)
if(istype(I, /obj/item/weapon/tome) && iscultist(user))
anchored = !anchored
user << "You [anchored ? "":"un"]secure \the [src] [anchored ? "to":"from"] the floor."
@@ -23,7 +52,13 @@
else
return ..()
-/obj/structure/cult/proc/getETA()
+/obj/structure/destructible/cult/ratvar_act()
+ if(take_damage(rand(25, 50), BURN) && src) //if we still exist
+ var/previouscolor = color
+ color = "#FAE48C"
+ animate(src, color = previouscolor, time = 8)
+
+/obj/structure/destructible/cult/proc/getETA()
var/time = (cooldowntime - world.time)/600
var/eta = "[round(time, 1)] minutes"
if(time <= 1)
@@ -31,12 +66,13 @@
eta = "[round(time, 1)] seconds"
return eta
-/obj/structure/cult/talisman
+/obj/structure/destructible/cult/talisman
name = "altar"
desc = "A bloodstained altar dedicated to Nar-Sie."
icon_state = "talismanaltar"
+ break_message = "The altar shatters, leaving only the wailing of the damned!"
-/obj/structure/cult/talisman/attack_hand(mob/living/user)
+/obj/structure/destructible/cult/talisman/attack_hand(mob/living/user)
if(!iscultist(user))
user << "You're pretty sure you know exactly what this is used for and you can't seem to touch it."
return
@@ -61,13 +97,14 @@
user << "You kneel before the altar and your faith is rewarded with an [N]!"
-/obj/structure/cult/forge
+/obj/structure/destructible/cult/forge
name = "daemon forge"
desc = "A forge used in crafting the unholy weapons used by the armies of Nar-Sie."
icon_state = "forge"
luminosity = 3
+ break_message = "The force breaks apart into shards with a howling scream!"
-/obj/structure/cult/forge/attack_hand(mob/living/user)
+/obj/structure/destructible/cult/forge/attack_hand(mob/living/user)
if(!iscultist(user))
user << "The heat radiating from [src] pushes you back."
return
@@ -99,25 +136,27 @@ var/list/blacklisted_pylon_turfs = typecacheof(list(
/turf/open/floor/plating/lava,
/turf/open/chasm))
-/obj/structure/cult/pylon
+/obj/structure/destructible/cult/pylon
name = "pylon"
desc = "A floating crystal that slowly heals those faithful to Nar'Sie."
icon_state = "pylon"
luminosity = 5
+ break_sound = 'sound/effects/Glassbr2.ogg'
+ break_message = "The blood-red crystal falls to the floor and shatters!"
var/heal_delay = 25
var/last_heal = 0
var/corrupt_delay = 50
var/last_corrupt = 0
-/obj/structure/cult/pylon/New()
+/obj/structure/destructible/cult/pylon/New()
START_PROCESSING(SSfastprocess, src)
..()
-/obj/structure/cult/pylon/Destroy()
+/obj/structure/destructible/cult/pylon/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()
-/obj/structure/cult/pylon/process()
+/obj/structure/destructible/cult/pylon/process()
if(!anchored)
return
if(last_heal <= world.time)
@@ -161,13 +200,14 @@ var/list/blacklisted_pylon_turfs = typecacheof(list(
// convertable turfs?
last_corrupt = world.time + corrupt_delay*2
-/obj/structure/cult/tome
+/obj/structure/destructible/cult/tome
name = "archives"
desc = "A desk covered in arcane manuscripts and tomes in unknown languages. Looking at the text makes your skin crawl."
icon_state = "tomealtar"
luminosity = 1
+ break_message = "The books and tomes of the archives burn into ash as the desk shatters!"
-/obj/structure/cult/tome/attack_hand(mob/living/user)
+/obj/structure/destructible/cult/tome/attack_hand(mob/living/user)
if(!iscultist(user))
user << "All of these books seem to be gibberish."
return
diff --git a/code/game/gamemodes/cult/ritual.dm b/code/game/gamemodes/cult/ritual.dm
index 7e59472d1a6..fb375070f9d 100644
--- a/code/game/gamemodes/cult/ritual.dm
+++ b/code/game/gamemodes/cult/ritual.dm
@@ -101,6 +101,8 @@ This file contains the arcane tome files.
text += "Blood Boil
When invoked, this rune will do a massive amount of damage to all non-cultist viewers, but it will also emit a small explosion upon invocation. \
It requires three invokers.
"
+ text += "Drain Life
This rune will drain the life of every living creature above the rune, healing the invoker for each creature drained by it.
"
+
text += "Manifest Spirit
This rune allows you to summon spirits as humanoid fighters. When invoked, a spirit above the rune will be brought to life as a human, wearing nothing, that seeks only to serve you and the Geometer. \
However, the spirit's link to reality is fragile - you must remain on top of the rune, and you will slowly take damage. Upon stepping off the rune, all summoned spirits will dissipate, dropping their items to the ground. You may manifest \
multiple spirits with one rune, but you will rapidly take damage in doing so.
"
@@ -111,7 +113,7 @@ This file contains the arcane tome files.
text += "Talisman of Teleportation
The talisman form of the Teleport rune will transport the invoker to a selected Teleport rune once.
"
- text += "Talisman of Construction
This talisman is the main way of creating construct shells. To use it, one must strike 30 sheets of metal with the talisman. The sheets will then be twisted into a construct shell, ready to recieve a soul to occupy it.
"
+ text += "Talisman of Construction
This talisman is the main way of creating construct shells. To use it, one must strike 25 sheets of metal with the talisman. The sheets will then be twisted into a construct shell, ready to recieve a soul to occupy it.
"
text += "Talisman of Tome Summoning
This talisman will produce a single tome at your feet.
"
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 7abb19384ef..abfdfa813d6 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -158,7 +158,7 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/malformed/New()
..()
- icon_state = "[rand(1,6)]"
+ icon_state = "[rand(1,7)]"
color = rgb(rand(0,255), rand(0,255), rand(0,255))
/obj/effect/rune/malformed/invoke(var/list/invokers)
@@ -372,7 +372,7 @@ var/list/teleport_runes = list()
/obj/effect/rune/sacrifice/New()
..()
- icon_state = "[rand(1,6)]"
+ icon_state = "[rand(1,7)]"
/obj/effect/rune/sacrifice/invoke(var/list/invokers)
if(rune_in_use)
@@ -675,7 +675,7 @@ var/list/teleport_runes = list()
cultist_name = "Astral Communion"
cultist_desc = "severs the link between one's spirit and body. This effect is taxing and one's physical body will take damage while this is active."
invocation = "Fwe'sh mah erl nyag r'ya!"
- icon_state = "6"
+ icon_state = "7"
color = rgb(126, 23, 23)
rune_in_use = 0 //One at a time, please!
construct_invoke = 0
@@ -692,7 +692,7 @@ var/list/teleport_runes = list()
log_game("Astral Communion rune failed - more than one user")
return list()
var/turf/T = get_turf(src)
- if(!user in T.contents)
+ if(!(user in T))
user << "You must be standing on top of [src]!"
log_game("Astral Communion rune failed - user not standing on rune")
return list()
@@ -714,8 +714,8 @@ var/list/teleport_runes = list()
affecting = null //In case it's assigned to a number or something
rune_in_use = 0
return
- affecting.apply_damage(1, BRUTE)
- if(!(user in T.contents))
+ affecting.apply_damage(0.1, BRUTE)
+ if(!(user in T))
user.visible_message("A spectral tendril wraps around [user] and pulls them back to the rune!")
Beam(user,icon_state="drainbeam",icon='icons/effects/effects.dmi',time=2)
user.forceMove(get_turf(src)) //NO ESCAPE :^)
@@ -728,19 +728,17 @@ var/list/teleport_runes = list()
affecting = null
return
if(user.stat == UNCONSCIOUS)
- if(prob(10))
+ if(prob(1))
var/mob/dead/observer/G = user.get_ghost()
- if(G)
- G << "You feel the link between you and your body weakening... you must hurry!"
+ G << "You feel the link between you and your body weakening... you must hurry!"
if(user.stat == DEAD)
user.color = initial(user.color)
rune_in_use = 0
affecting = null
var/mob/dead/observer/G = user.get_ghost()
- if(G)
- G << "You suddenly feel your physical form pass on. [src]'s exertion has killed you!"
+ G << "You suddenly feel your physical form pass on. [src]'s exertion has killed you!"
return
- sleep(10)
+ sleep(1)
rune_in_use = 0
@@ -869,6 +867,44 @@ var/list/teleport_runes = list()
explosion(T, -1, 0, 1, 5)
+//Deals brute damage to all targets on the rune and heals the invoker for each target drained.
+/obj/effect/rune/leeching
+ cultist_name = "Drain Life"
+ cultist_desc = "drains the life of all targets on the rune, restoring life to the user."
+ invocation = "Yu'gular faras desdae. Umathar uf'kal thenar!"
+ icon_state = "3"
+ color = rgb(159, 28, 52)
+
+/obj/effect/rune/leeching/can_invoke(mob/living/user)
+ if(world.time <= user.next_move)
+ return list()
+ var/turf/T = get_turf(src)
+ var/list/potential_targets = list()
+ for(var/mob/living/carbon/M in T.contents - user)
+ if(M.stat != DEAD)
+ potential_targets += M
+ if(!potential_targets.len)
+ user << "There must be at least one valid target on the rune!"
+ log_game("Leeching rune failed - no valid targets")
+ return list()
+ return ..()
+
+/obj/effect/rune/leeching/invoke(var/list/invokers)
+ var/mob/living/user = invokers[1]
+ user.changeNext_move(CLICK_CD_CLICK_ABILITY)
+ ..()
+ var/turf/T = get_turf(src)
+ for(var/mob/living/carbon/M in T.contents - user)
+ if(M.stat != DEAD)
+ var/drained_amount = rand(10,20)
+ M.apply_damage(drained_amount, BRUTE, "chest")
+ user.adjustBruteLoss(-drained_amount)
+ M << "You feel extremely weak."
+ user.Beam(T,icon_state="drainbeam",icon='icons/effects/effects.dmi',time=5)
+ user.visible_message("Blood flows from the rune into [user]!", \
+ "Blood flows into you, healing your wounds and revitalizing your spirit.")
+
+
//Rite of Spectral Manifestation: Summons a ghost on top of the rune as a cultist human with no items. User must stand on the rune at all times, and takes damage for each summoned ghost.
/obj/effect/rune/manifest
cultist_name = "Manifest Spirit"
diff --git a/code/game/gamemodes/cult/talisman.dm b/code/game/gamemodes/cult/talisman.dm
index ddeb74770c4..08e09f57fcb 100644
--- a/code/game/gamemodes/cult/talisman.dm
+++ b/code/game/gamemodes/cult/talisman.dm
@@ -56,7 +56,7 @@
dat += "Please choose the chant to be imbued into the fabric of reality.
"
dat += "
"
dat += "N'ath reth sh'yro eth d'raggathnor! - Summons an arcane tome, used to scribe runes and communicate with other cultists.
"
- dat += "Ar'Tee ess! - Provides 5 runed metal.
"
+ dat += "Bar'tea eas! - Provides 5 runed metal.
"
dat += "Sas'so c'arta forbici! - Allows you to move to a selected teleportation rune.
"
dat += "Ta'gh fara'qha fel d'amar det! - Allows you to destroy technology in a short range.
"
dat += "Fuu ma'jin! - Allows you to stun a person by attacking them with the talisman.
"
@@ -81,7 +81,8 @@
if(istype(src, /obj/item/weapon/paper/talisman/supply/weak))
usr.visible_message("Lesser supply talismans lack the strength to materialize runed metal!")
return
- new /obj/item/stack/sheet/runed_metal(get_turf(usr),5)
+ var/obj/item/stack/sheet/runed_metal/R = new(usr,5)
+ usr.put_in_hands(R)
if("teleport")
var/obj/item/weapon/paper/talisman/teleport/T = new(usr)
usr.put_in_hands(T)
@@ -319,12 +320,13 @@
qdel(src)
-//Talisman of Fabrication: Creates a construct shell out of 25 metal sheets.
+//Talisman of Fabrication: Creates a construct shell out of 25 metal sheets, or converts plasteel into runed metal up to 25 times
/obj/item/weapon/paper/talisman/construction
cultist_name = "Talisman of Construction"
cultist_desc = "Use this talisman on at least twenty-five metal sheets to create an empty construct shell"
invocation = "Ethra p'ni dedol!"
color = "#000000" // black
+ uses = 25
/obj/item/weapon/paper/talisman/construction/attack_self(mob/living/user)
if(iscultist(user))
@@ -335,8 +337,10 @@
/obj/item/weapon/paper/talisman/construction/attack(obj/M,mob/living/user)
if(iscultist(user))
- user << "This talisman will only work on a stack of metal sheets!"
+ user << "This talisman will only work on a stack of metal or plasteel sheets!"
log_game("Construct talisman failed - not a valid target")
+ else
+ ..()
/obj/item/weapon/paper/talisman/construction/afterattack(obj/item/stack/sheet/target, mob/user, proximity_flag, click_parameters)
..()
@@ -347,15 +351,20 @@
new /obj/structure/constructshell(T)
user << "The talisman clings to the metal and twists it into a construct shell!"
user << sound('sound/effects/magic.ogg',0,1,25)
+ invoke(user, 1)
qdel(src)
- if(istype(target, /obj/item/stack/sheet/plasteel))
- var/quantity = target.amount
- var/turf/T = get_turf(target)
- new /obj/item/stack/sheet/runed_metal(T,quantity)
- target.use(quantity)
- user << "The talisman clings to the plasteel, transforming it into runed metal!"
- user << sound('sound/effects/magic.ogg',0,1,25)
- qdel(src)
+ else
+ user << "You need more metal to produce a construct shell!"
+ if(istype(target, /obj/item/stack/sheet/plasteel))
+ var/quantity = min(target.amount, uses)
+ uses -= quantity
+ new /obj/item/stack/sheet/runed_metal(T,quantity)
+ target.use(quantity)
+ user << "The talisman clings to the plasteel, transforming it into runed metal!"
+ user << sound('sound/effects/magic.ogg',0,1,25)
+ invoke(user, 1)
+ if(uses <= 0)
+ qdel(src)
else
user << "The talisman must be used on metal or plasteel!"
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index cc7b43a6adb..09ca3b85fab 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -41,6 +41,8 @@
var/const/waittime_l = 600
var/const/waittime_h = 1800 // started at 1800
+ var/list/datum/station_goal/station_goals = list()
+
/datum/game_mode/proc/announce() //Shows the gamemode's name and a fast description.
world << "The gamemode is: [name]!"
@@ -87,6 +89,7 @@
if(report)
spawn (rand(waittime_l, waittime_h))
send_intercept(0)
+ generate_station_goals()
start_state = new /datum/station_state()
start_state.count(1)
return 1
@@ -279,6 +282,12 @@
for(var/V in possible_modes)
intercepttext += i_text.build(V)
+ if(station_goals.len)
+ intercepttext += "Special Orders for [station_name()]:"
+ for(var/datum/station_goal/G in station_goals)
+ G.on_report()
+ intercepttext += G.get_report()
+
print_command_report(intercepttext, "Central Command Status Summary")
priority_announce("A summary has been copied and printed to all communications consoles.", "Enemy communication intercepted. Security level elevated.", 'sound/AI/intercept.ogg')
if(security_level < SEC_LEVEL_BLUE)
@@ -532,3 +541,25 @@
ticker.mode.remove_gangster(newborgie, 0, remove_bosses=1)
ticker.mode.remove_hog_follower(newborgie, 0)
remove_servant_of_ratvar(newborgie.current, TRUE)
+
+
+/datum/game_mode/proc/generate_station_goals()
+ var/list/possible = list()
+ for(var/T in subtypesof(/datum/station_goal))
+ var/datum/station_goal/G = T
+ if(config_tag in initial(G.gamemode_blacklist))
+ continue
+ //if(num_players() < initial(G.required_crew))
+ // continue
+ possible += T
+ var/goal_weights = 0
+ while(possible.len && goal_weights < STATION_GOAL_BUDGET)
+ var/datum/station_goal/picked = pick_n_take(possible)
+ goal_weights += initial(picked.weight)
+ station_goals += new picked
+
+
+/datum/game_mode/proc/declare_station_goal_completion()
+ for(var/V in station_goals)
+ var/datum/station_goal/G = V
+ G.print_result()
\ No newline at end of file
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index 9fa58377691..a1272ee75da 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -118,11 +118,13 @@
get_hit()
/obj/effect/meteor/Destroy()
+ meteor_list -= src
walk(src,0) //this cancels the walk_towards() proc
. = ..()
/obj/effect/meteor/New()
..()
+ meteor_list += src
if(SSaugury)
SSaugury.register_doom(src, threat)
SpinAnimation()
diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm
index 4cb75a4b544..5cb7ec18535 100644
--- a/code/game/gamemodes/wizard/spellbook.dm
+++ b/code/game/gamemodes/wizard/spellbook.dm
@@ -397,18 +397,6 @@
item_path = /obj/item/weapon/twohanded/singularityhammer
log_name = "SI"
-/datum/spellbook_entry/item/cursed_heart
- name = "Cursed Heart"
- desc = "A heart that has been revived by dark magicks, the user must \
- concentrate to ensure the heart beats, but every beat heals them. It \
- must beat every 6 seconds. The heart is fickle, and will not work for a \
- lich."
- item_path = /obj/item/organ/heart/cursed/wizard
- log_name = "CH"
- cost = 1
- category = "Defensive"
-
-
/datum/spellbook_entry/item/battlemage
name = "Battlemage Armour"
desc = "An ensorcelled suit of armour, protected by a powerful shield. The shield can completly negate sixteen attacks before being permanently depleted."
diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm
index f1d58580c4a..165f8e21e07 100644
--- a/code/game/machinery/cloning.dm
+++ b/code/game/machinery/cloning.dm
@@ -163,9 +163,11 @@
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src)
+ H.hardset_dna(ui, se, H.real_name, null, mrace, features)
+
if(efficiency > 2)
- for(var/A in bad_se_blocks)
- setblock(H.dna.struc_enzymes, A, construct_block(0,2))
+ var/list/unclean_mutations = (not_good_mutations|bad_mutations)
+ H.dna.remove_mutation_group(unclean_mutations)
if(efficiency > 5 && prob(20))
randmutvg(H)
if(efficiency < 3 && prob(50))
@@ -197,7 +199,6 @@
beginning to regenerate in a cloning pod. You will \
become conscious when it is complete."
- H.hardset_dna(ui, H.dna.struc_enzymes, H.real_name, null, mrace, features)
if(H)
H.faction |= factions
@@ -343,7 +344,7 @@
occupant.forceMove(T)
icon_state = "pod_0"
eject_wait = FALSE //If it's still set somehow.
- occupant.domutcheck() //Waiting until they're out before possible monkeyizing.
+ 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()
diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm
index fdc6d980933..7df6df63362 100644
--- a/code/game/machinery/computer/dna_console.dm
+++ b/code/game/machinery/computer/dna_console.dm
@@ -96,7 +96,7 @@
occupant_status += ""
occupant_status += "Health:
[viable_occupant.health] %
"
occupant_status += "Radiation Level:
[viable_occupant.radiation] %
"
- var/rejuvenators = viable_occupant.reagents.get_reagent_amount("epinephrine")
+ var/rejuvenators = viable_occupant.reagents.get_reagent_amount("potass_iodide")
occupant_status += "Rejuvenators:
[rejuvenators] units
"
occupant_status += "Unique Enzymes :
[viable_occupant.dna.unique_enzymes]
"
occupant_status += "Last Operation:
[last_change ? last_change : "----"]
"
@@ -350,9 +350,9 @@
current_screen = href_list["text"]
if("rejuv")
if(viable_occupant && viable_occupant.reagents)
- var/epinephrine_amount = viable_occupant.reagents.get_reagent_amount("epinephrine")
- var/can_add = max(min(REJUVENATORS_MAX - epinephrine_amount, REJUVENATORS_INJECT), 0)
- viable_occupant.reagents.add_reagent("epinephrine", can_add)
+ var/potassiodide_amount = viable_occupant.reagents.get_reagent_amount("potass_iodide")
+ var/can_add = max(min(REJUVENATORS_MAX - potassiodide_amount, REJUVENATORS_INJECT), 0)
+ viable_occupant.reagents.add_reagent("potass_iodide", can_add)
if("setbufferlabel")
var/text = sanitize(input(usr, "Input a new label:", "Input an Text", null) as text|null)
if(num && text)
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 4080aca5c91..4203573df56 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -313,11 +313,6 @@ Class Procs:
if(!user.IsAdvancedToolUser() && !IsAdminGhost(user))
usr << "You don't have the dexterity to do this!"
return 1
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- if(prob(H.getBrainLoss()))
- user << "You momentarily forget how to use [src]!"
- return 1
if(!is_interactable())
return 1
if(set_machine)
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index 70ed306061a..f923502ef4b 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -143,7 +143,7 @@
return resources
/obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D)
- if(D.reagents.len) // No reagents storage - no reagent designs.
+ if(D.reagents_list.len) // No reagents storage - no reagent designs.
return 0
if(materials.has_materials(get_resources_w_coeff(D)))
return 1
diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm
index 7ca593e3c3e..3e68fc24e98 100644
--- a/code/game/objects/effects/effect_system/effects_foam.dm
+++ b/code/game/objects/effects/effect_system/effects_foam.dm
@@ -7,7 +7,7 @@
opacity = 0
anchored = 1
density = 0
- layer = ABOVE_ALL_MOB_LAYER
+ layer = WALL_OBJ_LAYER
mouse_opacity = 0
var/amount = 3
animate_movement = 0
diff --git a/code/game/objects/effects/effect_system/effects_other.dm b/code/game/objects/effects/effect_system/effects_other.dm
index 099847c5f7b..fe303b4782c 100644
--- a/code/game/objects/effects/effect_system/effects_other.dm
+++ b/code/game/objects/effects/effect_system/effects_other.dm
@@ -66,7 +66,7 @@
processing = 0
var/turf/T = get_turf(holder)
if(T != oldposition)
- if(!has_gravity(T))
+ if(!T.has_gravity())
var/obj/effect/particle_effect/ion_trails/I = PoolOrNew(effect_type, oldposition)
I.setDir(holder.dir)
flick("ion_fade", I)
diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm
index 1c2bd7c4b8e..20ac8176ef4 100644
--- a/code/game/objects/effects/effect_system/effects_smoke.dm
+++ b/code/game/objects/effects/effect_system/effects_smoke.dm
@@ -9,6 +9,7 @@
pixel_x = -32
pixel_y = -32
opacity = 0
+ layer = FLY_LAYER
anchored = 1
mouse_opacity = 0
animate_movement = 0
@@ -25,6 +26,8 @@
var/step = alpha / frames
for(var/i = 0, i < frames, i++)
alpha -= step
+ if(alpha < 160)
+ opacity = 0 //if we were blocking view, we aren't now because we're fading out
stoplag()
/obj/effect/particle_effect/smoke/New()
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
index eef512c6f04..d6e75752338 100644
--- a/code/game/objects/effects/mines.dm
+++ b/code/game/objects/effects/mines.dm
@@ -55,7 +55,7 @@
/obj/effect/mine/kickmine/mineEffect(mob/victim)
if(isliving(victim) && victim.client)
victim << "You have been kicked FOR NO REISIN!"
- del(victim.client)
+ qdel(victim.client)
/obj/effect/mine/gas
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
index 654ede990a9..d0d79764c09 100644
--- a/code/game/objects/effects/overlays.dm
+++ b/code/game/objects/effects/overlays.dm
@@ -144,6 +144,9 @@
appearance = mimiced_atom.appearance
setDir(mimiced_atom.dir)
mouse_opacity = 0
+
+/obj/effect/overlay/temp/decoy/fading/New(loc, atom/mimiced_atom)
+ ..()
animate(src, alpha = 0, time = duration)
/obj/effect/overlay/temp/cult
diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm
index 9fb43d7c0a0..e4bd858f716 100644
--- a/code/game/objects/effects/spawners/lootdrop.dm
+++ b/code/game/objects/effects/spawners/lootdrop.dm
@@ -143,7 +143,7 @@
/obj/item/weapon/wirecutters = 1,
/obj/item/weapon/wrench = 4,
/obj/item/weapon/relic = 3,
- /obj/item/weaponcrafting/reciever = 1,
+ /obj/item/weaponcrafting/reciever = 2,
/obj/item/clothing/head/cone = 2,
/obj/item/weapon/grenade/smokebomb = 2,
/obj/item/device/geiger_counter = 3,
@@ -157,7 +157,7 @@
/obj/item/clothing/gloves/color/random = 8,
/obj/item/clothing/shoes/laceup = 1,
/obj/item/weapon/storage/secure/briefcase = 3,
- "" = 4
+ "" = 3
)
/obj/effect/spawner/lootdrop/crate_spawner
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index dc2cbdb926d..a04be038af7 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -337,6 +337,7 @@
if(!can_claim_for_gang(user, target))
return
tag_for_gang(user, target)
+ affected_turfs += target
else
switch(paint_mode)
if(PAINT_NORMAL)
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index cc3c124a807..1622d8cb791 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -224,7 +224,14 @@ var/global/list/datum/stack_recipe/cardboard_recipes = list ( \
* Runed Metal
*/
-var/global/list/datum/stack_recipe/runed_metal_recipes = list ()
+var/global/list/datum/stack_recipe/runed_metal_recipes = list ( \
+ new/datum/stack_recipe("runed door", /obj/machinery/door/airlock/cult, 1, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("runed girder", /obj/structure/girder/cult, 1, time = 50, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("pylon", /obj/structure/destructible/cult/pylon, 4, time = 40, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("forge", /obj/structure/destructible/cult/forge, 3, time = 40, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("archives", /obj/structure/destructible/cult/tome, 3, time = 40, one_per_turf = 1, on_floor = 1), \
+ new/datum/stack_recipe("altar", /obj/structure/destructible/cult/talisman, 3, time = 40, one_per_turf = 1, on_floor = 1), \
+ )
/obj/item/stack/sheet/runed_metal
name = "runed metal"
diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm
index 47306dd27eb..241474b391b 100644
--- a/code/game/objects/items/weapons/storage/boxes.dm
+++ b/code/game/objects/items/weapons/storage/boxes.dm
@@ -703,38 +703,31 @@
/obj/item/weapon/storage/box/ingredients/wildcard/New()
..()
- for(var/i in 1 to 6)
- //Pick common ingredients
+ for(var/i in 1 to 7)
var/randomFood = pick(/obj/item/weapon/reagent_containers/food/snacks/grown/chili,
- /obj/item/weapon/reagent_containers/food/snacks/grown/tomato,
- /obj/item/weapon/reagent_containers/food/snacks/grown/carrot,
- /obj/item/weapon/reagent_containers/food/snacks/grown/potato,
- /obj/item/weapon/reagent_containers/food/snacks/grown/apple,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/tomato,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/carrot,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/potato,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/potato/sweet,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/apple,
/obj/item/weapon/reagent_containers/food/snacks/chocolatebar,
- /obj/item/weapon/reagent_containers/food/snacks/grown/cherries,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/cherries,
/obj/item/weapon/reagent_containers/food/snacks/grown/banana,
/obj/item/weapon/reagent_containers/food/snacks/grown/cabbage,
/obj/item/weapon/reagent_containers/food/snacks/grown/soybeans,
- /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris,
- /obj/item/weapon/reagent_containers/food/snacks/grown/corn)
- new randomFood(src)
- //Pick one random rare ingredient
- var/randomRareFood = pick(/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/deus,
- /obj/item/weapon/reagent_containers/food/snacks/grown/apple/gold,
- /obj/item/weapon/reagent_containers/food/snacks/grown/icepepper,
- /obj/item/weapon/reagent_containers/food/snacks/grown/ghost_chili,
- /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/corn,
+ /obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/plumphelmet,
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/chanterelle)
- new randomRareFood(src)
+ new randomFood(src)
/obj/item/weapon/storage/box/ingredients/fiesta
item_state = "fiesta"
/obj/item/weapon/storage/box/ingredients/fiesta/New()
..()
- for(var/i in 1 to 3)
- new /obj/item/weapon/reagent_containers/food/snacks/tortilla(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/tortilla(src)
for(var/i in 1 to 2)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/corn(src)
new /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans(src)
new /obj/item/weapon/reagent_containers/food/snacks/grown/chili(src)
@@ -745,32 +738,80 @@
..()
for(var/i in 1 to 3)
new /obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src)
- new /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris(src)
- new /obj/item/weapon/reagent_containers/food/snacks/faggot(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/faggot(src)
+ new /obj/item/weapon/reagent_containers/food/drinks/bottle/wine(src)
/obj/item/weapon/storage/box/ingredients/vegetarian
item_state = "vegetarian"
/obj/item/weapon/storage/box/ingredients/vegetarian/New()
..()
- for(var/i in 1 to 3)
- new /obj/item/weapon/reagent_containers/food/snacks/grown/ambrosia/vulgaris(src)
- new /obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src)
+ for(var/i in 1 to 2)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/carrot(src)
new /obj/item/weapon/reagent_containers/food/snacks/grown/eggplant(src)
new /obj/item/weapon/reagent_containers/food/snacks/grown/potato(src)
new /obj/item/weapon/reagent_containers/food/snacks/grown/apple(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/corn(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src)
+
+/obj/item/weapon/storage/box/ingredients/american
+ item_state = "american"
+
+/obj/item/weapon/storage/box/ingredients/american/New()
+ ..()
+ for(var/i in 1 to 2)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/potato(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/tomato(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/corn(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/faggot(src)
+
+/obj/item/weapon/storage/box/ingredients/fruity
+ item_state = "fruity"
+
+/obj/item/weapon/storage/box/ingredients/fruity/New()
+ ..()
+ for(var/i in 1 to 2)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/apple(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/orange(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lemon(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/citrus/lime(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/watermelon(src)
/obj/item/weapon/storage/box/ingredients/sweets
item_state = "sweets"
/obj/item/weapon/storage/box/ingredients/sweets/New()
+ ..()
+ for(var/i in 1 to 2)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/cherries(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/banana(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/apple(src)
+
+/obj/item/weapon/storage/box/ingredients/delights
+ item_state = "delights"
+
+/obj/item/weapon/storage/box/ingredients/delights/New()
+ ..()
+ for(var/i in 1 to 2)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/potato/sweet(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/bluecherries(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/vanillapod(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/berries(src)
+
+/obj/item/weapon/storage/box/ingredients/grains
+ item_state = "grains"
+
+/obj/item/weapon/storage/box/ingredients/grains/New()
..()
for(var/i in 1 to 3)
- new /obj/item/weapon/reagent_containers/food/snacks/chocolatebar(src)
- new /obj/item/weapon/reagent_containers/food/condiment/sugar(src)
- new /obj/item/weapon/reagent_containers/food/snacks/grown/cherries(src)
- new /obj/item/weapon/reagent_containers/food/snacks/grown/banana(src)
- new /obj/item/weapon/reagent_containers/food/snacks/icecream(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/oat(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/wheat(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/cocoapod(src)
+ new /obj/item/weapon/reagent_containers/honeycomb(src)
+ new /obj/item/seeds/poppy(src)
/obj/item/weapon/storage/box/ingredients/carnivore
item_state = "carnivore"
@@ -779,22 +820,22 @@
..()
new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/bear(src)
new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/spider(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/spidereggs(src)
new /obj/item/weapon/reagent_containers/food/snacks/carpmeat(src)
- new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime(src)
- new /obj/item/weapon/reagent_containers/food/snacks/faggot(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno(src)
new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/corgi(src)
- new /obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/faggot(src)
/obj/item/weapon/storage/box/ingredients/exotic
item_state = "exotic"
/obj/item/weapon/storage/box/ingredients/exotic/New()
..()
- new /obj/item/weapon/reagent_containers/food/condiment/soysauce(src)
for(var/i in 1 to 2)
- new /obj/item/weapon/reagent_containers/food/snacks/grown/cabbage(src)
- new /obj/item/weapon/reagent_containers/food/snacks/soydope(src)
new /obj/item/weapon/reagent_containers/food/snacks/carpmeat(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/soybeans(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/cabbage(src)
+ new /obj/item/weapon/reagent_containers/food/snacks/grown/chili(src)
/obj/item/weapon/storage/box/ingredients/New()
..()
diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm
index 5e4b18df42c..9f27404afae 100644
--- a/code/game/objects/items/weapons/storage/uplink_kits.dm
+++ b/code/game/objects/items/weapons/storage/uplink_kits.dm
@@ -2,7 +2,7 @@
/obj/item/weapon/storage/box/syndicate/New()
..()
- switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "implant" = 1, "hacker" = 3, "lordsingulo" = 1, "darklord" = 1, "Sniper" = 1)))
+ switch (pickweight(list("bloodyspai" = 3, "stealth" = 2, "bond" = 2, "screwed" = 2, "sabotage" = 3, "guns" = 2, "murder" = 2, "implant" = 1, "hacker" = 3, "lordsingulo" = 1, "darklord" = 1, "sniper" = 1, "metaops" = 1)))
if("bloodyspai") // 27 tc now this is more right
new /obj/item/clothing/under/chameleon(src) // 2 tc since it's not the full set
new /obj/item/clothing/mask/chameleon(src) // Goes with above
@@ -112,8 +112,8 @@
new /obj/item/weapon/spellbook/oneuse/summonitem(src)
return
- if("Sniper") //This shit is unique so can't really balance it around tc, also no silencer because getting killed without ANY indicator on what killed you sucks
- new /obj/item/weapon/gun/projectile/automatic/sniper_rifle(src)
+ if("sniper") //This shit is unique so can't really balance it around tc, also no silencer because getting killed without ANY indicator on what killed you sucks
+ new /obj/item/weapon/gun/projectile/automatic/sniper_rifle(src) // 12 tc
new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src)
new /obj/item/clothing/glasses/thermal/syndi(src)
new /obj/item/clothing/gloves/color/latex/nitrile(src)
@@ -121,6 +121,17 @@
new /obj/item/clothing/under/suit_jacket/really_black(src)
return
+ if("metaops") // 30 tc
+ new /obj/item/clothing/suit/space/hardsuit/syndi(src) // 8 tc
+ new /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog/unrestricted(src) // 8 tc
+ new /obj/item/weapon/implanter/explosive(src) // 2 tc
+ new /obj/item/ammo_box/magazine/m12g/buckshot(src) // 2 tc
+ new /obj/item/ammo_box/magazine/m12g/buckshot(src) // 2 tc
+ new /obj/item/weapon/grenade/plastic/c4 (src) // 1 tc
+ new /obj/item/weapon/grenade/plastic/c4 (src) // 1 tc
+ new /obj/item/weapon/card/emag(src) // 6 tc
+ return
+
/obj/item/weapon/storage/box/syndie_kit
name = "box"
desc = "A sleek, sturdy box."
@@ -138,7 +149,6 @@
/*/obj/item/weapon/storage/box/syndie_kit/imp_compress
name = "Compressed Matter Implant (with injector)"
-
/obj/item/weapon/storage/box/syndie_kit/imp_compress/New()
new /obj/item/weapon/implanter/compressed(src)
..()
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index 478d6f16f40..91dc8cbc17b 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -175,12 +175,13 @@
desc = "An improvised stun baton."
icon_state = "stunprod_nocell"
item_state = "prod"
+ w_class = 4
force = 3
throwforce = 5
stunforce = 5
- hitcost = 2500
+ hitcost = 2000
throw_hit_chance = 10
- slot_flags = null
+ slot_flags = SLOT_BACK
var/obj/item/device/assembly/igniter/sparkler = 0
/obj/item/weapon/melee/baton/cattleprod/New()
diff --git a/code/game/objects/items/weapons/teleprod.dm b/code/game/objects/items/weapons/teleprod.dm
index 8ac8b9ebaf9..0ff48df05fa 100644
--- a/code/game/objects/items/weapons/teleprod.dm
+++ b/code/game/objects/items/weapons/teleprod.dm
@@ -1,9 +1,11 @@
/obj/item/weapon/melee/baton/cattleprod/teleprod
name = "teleprod"
desc = "A prod with a bluespace crystal on the end. The crystal doesn't look too fun to touch."
+ w_class = 3
icon_state = "teleprod_nocell"
item_state = "teleprod"
origin_tech = "combat=2;bluespace=4;materials=3"
+ slot_flags = null
/obj/item/weapon/melee/baton/cattleprod/teleprod/attack(mob/living/carbon/M, mob/living/carbon/user)//handles making things teleport when hit
..()
diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm
index b7b71cf6266..ba7f17da609 100644
--- a/code/game/objects/items/weapons/twohanded.dm
+++ b/code/game/objects/items/weapons/twohanded.dm
@@ -107,6 +107,11 @@
unwield(M)
return
+/obj/item/weapon/twohanded/equipped(mob/user, slot)
+ ..()
+ if(slot != slot_l_hand && slot != slot_r_hand && wielded)
+ unwield(user)
+
///////////OFFHAND///////////////
/obj/item/weapon/twohanded/offhand
name = "offhand"
@@ -152,9 +157,6 @@
else
unwield(user)
-
-/obj/item/weapon/twohanded/
-
/*
* Fireaxe
*/
diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm
index 983705144d1..0434b288c9c 100644
--- a/code/game/objects/items/weapons/weaponry.dm
+++ b/code/game/objects/items/weapons/weaponry.dm
@@ -470,7 +470,7 @@ var/highlander_claymores = 0
playsound(get_turf(src), 'sound/weapons/HOMERUN.ogg', 100, 1)
homerun_ready = 0
return
- else
+ else if(!target.anchored)
target.throw_at(throw_target, rand(1,2), 7, user)
/obj/item/weapon/melee/baseball_bat/ablative
diff --git a/code/game/objects/radiation.dm b/code/game/objects/radiation.dm
index 87fec24f831..0dfa2b1b907 100644
--- a/code/game/objects/radiation.dm
+++ b/code/game/objects/radiation.dm
@@ -31,8 +31,11 @@
/mob/living/rad_act(amount, silent = 0)
if(amount)
- var/message = silent ? null : "Your clothes feel warm."
- var/blocked = run_armor_check(null, "rad", message, message)
+ var/blocked = getarmor(null, "rad")
+
+ if(!silent)
+ src << "Your skin feels warm."
+
apply_effect(amount, IRRADIATE, blocked)
for(var/obj/I in src) //Radiation is also applied to items held by the mob
I.rad_act(amount)
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index 946b2caf509..b81634de888 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -38,7 +38,7 @@ LINEN BINS
/obj/item/weapon/bedsheet/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/wirecutters) || I.is_sharp())
- var/obj/item/stack/sheet/cloth/C = new (loc, 3)
+ var/obj/item/stack/sheet/cloth/C = new (get_turf(src), 3)
transfer_fingerprints_to(C)
C.add_fingerprint(user)
qdel(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
index edc5b8d1dca..439c5b32fbc 100644
--- a/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets/utility_closets.dm
@@ -27,13 +27,17 @@
if ("small")
new /obj/item/weapon/tank/internals/emergency_oxygen(src)
new /obj/item/weapon/tank/internals/emergency_oxygen(src)
+ new /obj/item/clothing/mask/breath(src)
+ new /obj/item/clothing/mask/breath(src)
if ("aid")
new /obj/item/weapon/tank/internals/emergency_oxygen(src)
new /obj/item/weapon/storage/firstaid/o2(src)
+ new /obj/item/clothing/mask/breath(src)
if ("tank")
new /obj/item/weapon/tank/internals/air(src)
+ new /obj/item/clothing/mask/breath(src)
if ("both")
new /obj/item/weapon/tank/internals/emergency_oxygen(src)
diff --git a/code/game/objects/structures/destructible_structures.dm b/code/game/objects/structures/destructible_structures.dm
new file mode 100644
index 00000000000..688715f5202
--- /dev/null
+++ b/code/game/objects/structures/destructible_structures.dm
@@ -0,0 +1,89 @@
+/obj/structure/destructible //a base for destructible structures
+ var/max_health = 100
+ var/health = 100
+ var/takes_damage = TRUE //If the structure can be damaged
+ var/break_message = "The strange, admin-y structure breaks!" //The message shown when a structure breaks
+ var/break_sound = 'sound/magic/clockwork/invoke_general.ogg' //The sound played when a structure breaks
+ var/list/debris = null //Parts left behind when a structure breaks, takes the form of list(path = amount_to_spawn)
+
+/obj/structure/destructible/proc/take_damage(amount, damage_type)
+ var/static/list/physical_damage_types = list(BRUTE = TRUE, BURN = TRUE)
+ if(!takes_damage || !amount || !damage_type || !physical_damage_types[damage_type])
+ return 0
+ health = max(0, health - amount)
+ if(!health)
+ destroyed()
+ return amount
+
+/obj/structure/destructible/proc/destroyed()
+ if(!takes_damage)
+ return 0
+ if(islist(debris))
+ for(var/I in debris)
+ for(var/i in 1 to debris[I])
+ new I (get_turf(src))
+ visible_message(break_message)
+ playsound(src, break_sound, 50, 1)
+ qdel(src)
+ return 1
+
+/obj/structure/destructible/burn()
+ SSobj.burning -= src
+ if(takes_damage)
+ playsound(src, 'sound/items/Welder.ogg', 100, 1)
+ visible_message("[src] is warped by the heat!")
+ take_damage(rand(50, 100), BURN)
+
+/obj/structure/destructible/ex_act(severity)
+ var/damage = 0
+ switch(severity)
+ if(1)
+ damage = max_health //100% max health lost
+ if(2)
+ damage = max_health * (0.01 * rand(50, 70)) //50-70% max health lost
+ if(3)
+ damage = max_health * (0.01 * rand(10, 30)) //10-30% max health lost
+ if(damage)
+ take_damage(damage, BRUTE)
+
+/obj/structure/destructible/bullet_act(obj/item/projectile/P)
+ . = ..()
+ visible_message("[src] is hit by \a [P]!")
+ playsound(src, P.hitsound, 50, 1)
+ take_damage(P.damage, P.damage_type)
+
+/obj/structure/destructible/proc/attack_generic(mob/user, damage = 0, damage_type = BRUTE) //used by attack_alien, attack_animal, and attack_slime
+ user.do_attack_animation(src)
+ user.changeNext_move(CLICK_CD_MELEE)
+ user.visible_message("[user] smashes into [src]!")
+ take_damage(damage, damage_type)
+
+/obj/structure/destructible/attack_alien(mob/living/user)
+ playsound(src, 'sound/weapons/bladeslice.ogg', 50, 1)
+ attack_generic(user, 15)
+
+/obj/structure/destructible/attack_animal(mob/living/simple_animal/M)
+ if(!M.melee_damage_upper && !M.obj_damage)
+ return
+ playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
+ if(M.obj_damage)
+ attack_generic(M, M.obj_damage, M.melee_damage_type)
+ else
+ attack_generic(M, M.melee_damage_upper, M.melee_damage_type)
+
+/obj/structure/destructible/attack_slime(mob/living/simple_animal/slime/user)
+ if(!user.is_adult)
+ return
+ playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
+ attack_generic(user, rand(10, 15))
+
+/obj/structure/destructible/attacked_by(obj/item/I, mob/living/user)
+ . = ..()
+ var/turf/T = get_turf(src)
+ if(take_damage(I.force, I.damtype))
+ playsound(T, I.hitsound, 50, 1)
+
+/obj/structure/destructible/mech_melee_attack(obj/mecha/M)
+ if(..())
+ playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
+ take_damage(M.force, M.damtype)
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index 48192946ac6..08a823f44be 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -23,7 +23,9 @@
return
user.visible_message("[user] fells [src] with the [W].","You fell [src] with the [W].", "You hear the sound of a tree falling.")
playsound(get_turf(src), 'sound/effects/meteorimpact.ogg', 100 , 0, 0)
+ icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "tree_stump"
+ pixel_x = -16
name += " stump"
cut = TRUE
for(var/i=1 to log_amount)
@@ -56,6 +58,15 @@
icon = 'icons/obj/flora/deadtrees.dmi'
icon_state = "tree_1"
+/obj/structure/flora/tree/palm
+ icon = 'icons/misc/beach2.dmi'
+ icon_state = "palm1"
+
+/obj/structure/flora/tree/palm/New()
+ ..()
+ icon_state = pick("palm1","palm2")
+ pixel_x = 0
+
/obj/structure/festivus
name = "festivus pole"
icon = 'icons/obj/flora/pinetrees.dmi'
diff --git a/code/game/objects/structures/table_frames.dm b/code/game/objects/structures/table_frames.dm
index 5f165715ed1..5115443a8bf 100644
--- a/code/game/objects/structures/table_frames.dm
+++ b/code/game/objects/structures/table_frames.dm
@@ -35,8 +35,7 @@
user << "You need one plasteel sheet to do this!"
return
user << "You start adding [P] to [src]..."
- if(do_after(user, 50, target = src))
- P.use(1)
+ if(do_after(user, 50, target = src) && P.use(1))
new /obj/structure/table/reinforced(src.loc)
qdel(src)
else if(istype(I, /obj/item/stack/sheet/metal))
@@ -45,8 +44,7 @@
user << "You need one metal sheet to do this!"
return
user << "You start adding [M] to [src]..."
- if(do_after(user, 20, target = src))
- M.use(1)
+ if(do_after(user, 20, target = src) && M.use(1))
new /obj/structure/table(src.loc)
qdel(src)
else if(istype(I, /obj/item/stack/sheet/glass))
@@ -55,9 +53,7 @@
user << "You need one glass sheet to do this!"
return
user << "You start adding [G] to [src]..."
- if(do_after(user, 20, target = src))
- G.use(1)
-
+ if(do_after(user, 20, target = src) && G.use(1))
new /obj/structure/table/glass(src.loc)
qdel(src)
else if(istype(I, /obj/item/stack/sheet/mineral/silver))
@@ -66,10 +62,18 @@
user << "You need one silver sheet to do this!"
return
user << "You start adding [S] to [src]..."
- if(do_after(user, 20, target = src))
- S.use(1)
+ if(do_after(user, 20, target = src) && S.use(1))
new /obj/structure/table/optable(src.loc)
qdel(src)
+ else if(istype(I, /obj/item/stack/tile/carpet))
+ var/obj/item/stack/tile/carpet/C = I
+ if(C.get_amount() < 1)
+ user << "You need one carpet sheet to do this!"
+ return
+ user << "You start adding [C] to [src]..."
+ if(do_after(user, 20, target = src) && C.use(1))
+ new /obj/structure/table/wood/fancy(src.loc)
+ qdel(src)
else
return ..()
@@ -101,8 +105,7 @@
user << "You need one wood sheet to do this!"
return
user << "You start adding [W] to [src]..."
- if(do_after(user, 20, target = src))
- W.use(1)
+ if(do_after(user, 20, target = src) && W.use(1))
new /obj/structure/table/wood(src.loc)
qdel(src)
return
@@ -112,8 +115,7 @@
user << "You need one carpet sheet to do this!"
return
user << "You start adding [C] to [src]..."
- if(do_after(user, 20, target = src))
- C.use(1)
+ if(do_after(user, 20, target = src) && C.use(1))
new /obj/structure/table/wood/poker(src.loc)
qdel(src)
else
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index ed406cc22aa..f2aad755601 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -281,7 +281,7 @@
check_break(M)
/obj/structure/table/glass/proc/check_break(mob/living/M)
- if(has_gravity(M) && M.mob_size > MOB_SIZE_SMALL)
+ if(M.has_gravity() && M.mob_size > MOB_SIZE_SMALL)
table_shatter(M)
/obj/structure/table/glass/proc/table_shatter(mob/M)
@@ -334,6 +334,24 @@
/obj/structure/table/wood/poker/narsie_act()
new /obj/structure/table/wood(src.loc)
+/obj/structure/table/wood/fancy
+ name = "fancy table"
+ desc = "A standard metal table frame covered with an amazingly fancy, patterned cloth."
+ icon = 'icons/obj/structures.dmi'
+ icon_state = "fancy_table"
+ frame = /obj/structure/table_frame
+ framestack = /obj/item/stack/rods
+ buildstack = /obj/item/stack/tile/carpet
+ canSmoothWith = list(/obj/structure/table/wood/fancy)
+
+/obj/structure/table/wood/fancy/New()
+ icon = 'icons/obj/smooth_structures/fancy_table.dmi' //so that the tables place correctly in the map editor
+ ..()
+
+/obj/structure/table/wood/fancy/burn() //basically made out of metal
+ new frame(loc)
+ qdel(src)
+
/*
* Reinforced tables
*/
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index 6d164565ac9..5fc29b24f79 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -72,7 +72,30 @@
for(var/obj/I in contents)
if(!I.is_frozen) //let it go
I.make_frozen_visual(I)
+ for(var/mob/living/L in contents)
+ if(L.bodytemperature >= 10)
+ L.bodytemperature -= 10
+ if(L.bodytemperature <= 50)
+ L.apply_status_effect(/datum/status_effect/freon)
MakeSlippery(TURF_WET_PERMAFROST, 5)
+ return 1
+
+/turf/open/water_vapor_gas_act()
+ MakeSlippery(min_wet_time = 10, wet_time_to_add = 5)
+
+ for(var/mob/living/simple_animal/slime/M in src)
+ M.apply_water()
+
+ clean_blood()
+ for(var/obj/effect/O in src)
+ if(is_cleanable(O))
+ qdel(O)
+
+ var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in src)
+ if(hotspot && !istype(src, /turf/open/space))
+ air.temperature = max(min(air.temperature-2000,air.temperature/2),0)
+ qdel(hotspot)
+ return 1
/turf/open/handle_fall(mob/faller, forced)
faller.lying = pick(90, 270)
@@ -95,8 +118,7 @@
return 0
if(!(lube&SLIDE_ICE))
C << "You slipped[ O ? " on the [O.name]" : ""]!"
-
- C.attack_log += "\[[time_stamp()]\] Slipped[O ? " on the [O.name]" : ""][(lube&SLIDE)? " (LUBE)" : ""]!"
+ C.attack_log += "\[[time_stamp()]\] Slipped[O ? " on the [O.name]" : ""][(lube&SLIDE)? " (LUBE)" : ""]!"
if(!(lube&SLIDE_ICE))
playsound(C.loc, 'sound/misc/slip.ogg', 50, 1, -3)
@@ -119,8 +141,10 @@
step(C, olddir)
C.spin(1,1)
else if(lube&SLIDE_ICE)
+ C.slipping = TRUE
spawn(1)
step(C, olddir)
+ C.slipping = FALSE
return 1
/turf/open/proc/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0) // 1 = Water, 2 = Lube, 3 = Ice, 4 = Permafrost, 5 = Slide
diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm
index 6509d415684..edefd3b9f66 100644
--- a/code/game/turfs/simulated/floor/fancy_floor.dm
+++ b/code/game/turfs/simulated/floor/fancy_floor.dm
@@ -28,10 +28,11 @@
initial_gas_mix = "TEMP=2.7"
/turf/open/floor/grass
- name = "Grass patch"
+ name = "grass patch"
icon_state = "grass"
floor_tile = /obj/item/stack/tile/grass
broken_states = list("sand")
+ var/ore_type = /obj/item/weapon/ore/glass
/turf/open/floor/grass/New()
..()
@@ -39,13 +40,47 @@
update_icon()
/turf/open/floor/grass/attackby(obj/item/C, mob/user, params)
+ if(istype(C, /obj/item/weapon/shovel) && params)
+ new ore_type(src)
+ new ore_type(src) //Make some sand if you shovel grass
+ user << "You shovel [src]."
+ make_plating()
if(..())
return
- if(istype(C, /obj/item/weapon/shovel))
- new /obj/item/weapon/ore/glass(src)
- new /obj/item/weapon/ore/glass(src) //Make some sand if you shovel grass
- user << "You shovel the grass."
- make_plating()
+
+/turf/open/floor/grass/snow
+ name = "snow"
+ icon = 'icons/turf/snow.dmi'
+ desc = "Looks cold."
+ icon_state = "snow"
+ ore_type = /obj/item/stack/sheet/mineral/snow
+ planetary_atmos = TRUE
+ floor_tile = null
+ 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
+ ..()
+
+/turf/open/floor/grass/snow/basalt //By your powers combined, I am captain planet
+ name = "volcanic floor"
+ icon = 'icons/turf/floors.dmi'
+ icon_state = "basalt"
+ ore_type = /obj/item/weapon/ore/glass/basalt
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ slowdown = 0
+
+/turf/open/floor/grass/snow/basalt/New()
+ ..()
+ if(prob(15))
+ icon_state = "basalt[rand(0, 12)]"
+ switch(icon_state)
+ if("basalt1", "basalt2", "basalt3")
+ SetLuminosity(1, 1)
+
/turf/open/floor/carpet
name = "Carpet"
diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm
index ef0ec3732bf..e06fd5bf633 100644
--- a/code/game/turfs/simulated/floor/plating.dm
+++ b/code/game/turfs/simulated/floor/plating.dm
@@ -239,8 +239,12 @@
initial_gas_mix = "TEMP=2.7"
/turf/open/floor/plating/lava/Entered(atom/movable/AM)
- burn_stuff()
- START_PROCESSING(SSobj, src)
+ if(burn_stuff(AM))
+ START_PROCESSING(SSobj, src)
+
+/turf/open/floor/plating/lava/hitby(atom/movable/AM)
+ if(burn_stuff(AM))
+ START_PROCESSING(SSobj, src)
/turf/open/floor/plating/lava/process()
if(!burn_stuff())
@@ -257,9 +261,12 @@
/turf/open/floor/plating/lava/TakeTemperature(temp)
-/turf/open/floor/plating/lava/proc/burn_stuff()
+/turf/open/floor/plating/lava/proc/burn_stuff(AM)
. = 0
- for(var/thing in contents)
+ var/thing_to_check = src
+ if (AM)
+ thing_to_check = list(AM)
+ for(var/thing in thing_to_check)
if(isobj(thing))
var/obj/O = thing
if(O.burn_state == LAVA_PROOF || O.throwing)
diff --git a/code/game/turfs/simulated/walls_misc.dm b/code/game/turfs/simulated/walls_misc.dm
index d407cbfcf1c..30ff871f894 100644
--- a/code/game/turfs/simulated/walls_misc.dm
+++ b/code/game/turfs/simulated/walls_misc.dm
@@ -45,7 +45,7 @@
desc = "A huge chunk of warm metal. The clanging of machinery emanates from within."
explosion_block = 2
var/obj/effect/clockwork/overlay/wall/realappearence
- var/obj/structure/clockwork/cache/linkedcache
+ var/obj/structure/destructible/clockwork/cache/linkedcache
/turf/closed/wall/clockwork/New()
..()
@@ -123,7 +123,7 @@
O.loc = src
/turf/closed/wall/clockwork/break_wall()
- return new/obj/structure/clockwork/wall_gear(src)
+ return new/obj/structure/destructible/clockwork/wall_gear(src)
/turf/closed/wall/clockwork/devastate_wall()
for(var/i in 1 to 2)
diff --git a/code/modules/admin/DB_ban/functions.dm b/code/modules/admin/DB_ban/functions.dm
index 02f585a502f..c86200ba19f 100644
--- a/code/modules/admin/DB_ban/functions.dm
+++ b/code/modules/admin/DB_ban/functions.dm
@@ -132,7 +132,7 @@
if(kickbannedckey)
if(banned_mob && banned_mob.client && banned_mob.client.ckey == banckey)
- del(banned_mob.client)
+ qdel(banned_mob.client)
/datum/admins/proc/DB_ban_unban(ckey, bantype, job = "")
diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm
index 6a5782c7d60..279de52a4c2 100644
--- a/code/modules/admin/NewBan.dm
+++ b/code/modules/admin/NewBan.dm
@@ -117,9 +117,9 @@ var/savefile/Banlist
if (temp)
Banlist["minutes"] << bantimestamp
if(!temp)
- add_note(ckey, "Permanently banned - [reason]", null, bannedby, 0)
+ add_note(ckey, "Permanently banned - [reason]", null, bannedby, 0, null, 0)
else
- add_note(ckey, "Banned for [minutes] minutes - [reason]", null, bannedby, 0)
+ add_note(ckey, "Banned for [minutes] minutes - [reason]", null, bannedby, 0, null, 0)
return 1
/proc/RemoveBan(foldername)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 844fcd3a1c6..22b243bc1ef 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -779,7 +779,7 @@ var/global/BSACooldown = 0
if(message)
C << message
kicked_client_names.Add("[C.ckey]")
- del(C)
+ qdel(C)
return kicked_client_names
//returns 1 to let the dragdrop code know we are trapping this event
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 3b64aa6a72c..c67f8d1c3b2 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -145,6 +145,7 @@ var/list/admin_verbs_debug = list(
/client/proc/cmd_display_del_log,
/client/proc/reset_latejoin_spawns,
/client/proc/create_outfits,
+ /client/proc/modify_goals,
/client/proc/debug_huds,
/client/proc/map_template_load,
/client/proc/map_template_upload,
diff --git a/code/modules/admin/sql_notes.dm b/code/modules/admin/sql_notes.dm
index 6c026cabfbb..88652cc7b09 100644
--- a/code/modules/admin/sql_notes.dm
+++ b/code/modules/admin/sql_notes.dm
@@ -1,4 +1,4 @@
-/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server)
+/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server, secret)
if(!dbcon.IsConnected())
usr << "Failed to establish database connection."
return
@@ -13,7 +13,7 @@
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
return
if(!query_find_ckey.NextRow())
- if(alert(usr, "[new_ckey] has not been seen before, are you sure you want to add them to the watchlist?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
+ if(alert(usr, "[new_ckey] has not been seen before, are you sure you want to add a note for them?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
return
target_ckey = new_ckey
var/target_sql_ckey = sanitizeSQL(target_ckey)
@@ -33,7 +33,15 @@
if (config && config.server_name)
server = config.server_name
server = sanitizeSQL(server)
- var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server) VALUES ('[target_sql_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]')")
+ if(isnull(secret))
+ switch(alert("Hide note from being viewed by players?", "Secret Note?","Yes","No","Cancel"))
+ if("Yes")
+ secret = 1
+ if("No")
+ secret = 0
+ else
+ return
+ var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server, secret) VALUES ('[target_sql_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]', '[secret]')")
if(!query_noteadd.Execute())
var/err = query_noteadd.ErrorMsg()
log_game("SQL ERROR adding new note to table. Error : \[[err]\]\n")
@@ -104,6 +112,33 @@
message_admins("[key_name_admin(usr)] has edited [target_ckey]'s note made by [adminckey] from
[old_note]
to
[new_note]")
show_note(target_ckey)
+/proc/toggle_note_secrecy(note_id)
+ if(!dbcon.IsConnected())
+ usr << "Failed to establish database connection."
+ return
+ if(!note_id)
+ return
+ note_id = text2num(note_id)
+ var/DBQuery/query_find_note_secret = dbcon.NewQuery("SELECT ckey, adminckey, secret FROM [format_table_name("notes")] WHERE id = [note_id]")
+ if(!query_find_note_secret.Execute())
+ var/err = query_find_note_secret.ErrorMsg()
+ log_game("SQL ERROR obtaining ckey, adminckey, secret from notes table. Error : \[[err]\]\n")
+ return
+ if(query_find_note_secret.NextRow())
+ var/target_ckey = query_find_note_secret.item[1]
+ var/adminckey = query_find_note_secret.item[2]
+ var/secret = text2num(query_find_note_secret.item[3])
+ var/sql_ckey = sanitizeSQL(usr.ckey)
+ var/edit_text = "Made [secret ? "not secret" : "secret"] by [sql_ckey] on [SQLtime()]
"
+ var/DBQuery/query_update_note = dbcon.NewQuery("UPDATE [format_table_name("notes")] SET secret = NOT secret, last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [note_id]")
+ if(!query_update_note.Execute())
+ var/err = query_update_note.ErrorMsg()
+ log_game("SQL ERROR toggling note secrecy. Error : \[[err]\]\n")
+ return
+ log_admin("[key_name(usr)] has toggled [target_ckey]'s note made by [adminckey] to [secret ? "not secret" : "secret"]")
+ message_admins("[key_name_admin(usr)] has toggled [target_ckey]'s note made by [adminckey] to [secret ? "not secret" : "secret"]")
+ show_note(target_ckey)
+
/proc/show_note(target_ckey, index, linkless = 0)
var/output
var/navbar
@@ -120,10 +155,10 @@
output = navbar
if(target_ckey)
var/target_sql_ckey = sanitizeSQL(target_ckey)
- var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
+ var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT secret, timestamp, notetext, adminckey, last_editor, server, id FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
if(!query_get_notes.Execute())
var/err = query_get_notes.ErrorMsg()
- log_game("SQL ERROR obtaining ckey, notetext, adminckey, last_editor, server from notes table. Error : \[[err]\]\n")
+ log_game("SQL ERROR obtaining secret, timestamp, notetext, adminckey, last_editor, server, id from notes table. Error : \[[err]\]\n")
return
output += "Notes of [target_ckey]
"
if(!linkless)
@@ -133,15 +168,18 @@
output += " \[Refresh Page\]"
output += ruler
while(query_get_notes.NextRow())
- var/id = query_get_notes.item[1]
+ var/secret = text2num(query_get_notes.item[1])
+ if(linkless && secret)
+ continue
var/timestamp = query_get_notes.item[2]
var/notetext = query_get_notes.item[3]
var/adminckey = query_get_notes.item[4]
var/last_editor = query_get_notes.item[5]
var/server = query_get_notes.item[6]
+ var/id = query_get_notes.item[7]
output += "[timestamp] | [server] | [adminckey]"
if(!linkless)
- output += " \[Remove Note\] \[Edit Note\]"
+ output += " \[Remove Note\] [secret ? "\[Secret\]" : "\[Not Secret\]"] \[Edit Note\]"
if(last_editor)
output += " Last edit by [last_editor] (Click here to see edit log)"
output += "
[notetext]
"
@@ -199,7 +237,7 @@
if(query_convert_time.NextRow())
timestamp = query_convert_time.item[1]
if(ckey && notetext && timestamp && adminckey && server)
- add_note(ckey, notetext, timestamp, adminckey, 0, server)
+ add_note(ckey, notetext, timestamp, adminckey, 0, server, 1)
notesfile.cd = "/"
notesfile.dir.Remove(ckey)
@@ -217,4 +255,4 @@ this proc can take several minutes to execute fully if converting and cause DD t
world << "Deleting NOTESFILE"
fdel(NOTESFILE)
world << "Finished mass note conversion, remember to turn off AUTOCONVERT_NOTES"*/
-#undef NOTESFILE
\ No newline at end of file
+#undef NOTESFILE
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index f81cebf3259..d47aaa90f2d 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -234,7 +234,7 @@
message_admins("Ban process: A mob matching [playermob.ckey] was found at location [playermob.x], [playermob.y], [playermob.z]. Custom ip and computer id fields replaced with the ip and computer id from the located mob.")
DB_ban_record(bantype, playermob, banduration, banreason, banjob, null, banckey, banip, bancid )
- add_note(banckey, banreason, null, usr.ckey, 0)
+ add_note(banckey, banreason, null, usr.ckey, 0, null, 0)
else if(href_list["editrights"])
edit_rights_topic(href_list)
@@ -535,7 +535,7 @@
DB_ban_record(BANTYPE_JOB_PERMA, M, -1, reason, "appearance")
if(M.client)
jobban_buildcache(M.client)
- add_note(M.ckey, "Appearance banned - [reason]", null, usr.ckey, 0)
+ add_note(M.ckey, "Appearance banned - [reason]", null, usr.ckey, 0, null, 0)
message_admins("[key_name_admin(usr)] appearance banned [key_name_admin(M)].")
M << "You have been appearance banned by [usr.client.ckey]."
M << "The reason is: [reason]"
@@ -981,7 +981,7 @@
msg = job
else
msg += ", [job]"
- add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 0)
+ add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 0, null, 0)
message_admins("[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes.")
M << "You have been [(msg == ("ooc" || "appearance")) ? "banned" : "jobbanned"] by [usr.client.ckey] from: [msg]."
M << "The reason is: [reason]"
@@ -1004,7 +1004,7 @@
msg = job
else
msg += ", [job]"
- add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 0)
+ add_note(M.ckey, "Banned from [msg] - [reason]", null, usr.ckey, 0, null, 0)
message_admins("[key_name_admin(usr)] banned [key_name_admin(M)] from [msg].")
M << "You have been [(msg == ("ooc" || "appearance")) ? "banned" : "jobbanned"] by [usr.client.ckey] from: [msg]."
M << "The reason is: [reason]"
@@ -1054,7 +1054,7 @@
log_admin("[key_name(usr)] kicked [key_name(M)].")
message_admins("[key_name_admin(usr)] kicked [key_name_admin(M)].")
//M.client = null
- del(M.client)
+ qdel(M.client)
//Player Notes
else if(href_list["addnote"])
@@ -1104,6 +1104,10 @@
var/edit_log = query_noteedits.item[1]
usr << browse(edit_log,"window=noteedits")
+ else if(href_list["secretnote"])
+ var/note_id = href_list["secretnote"]
+ toggle_note_secrecy(note_id)
+
else if(href_list["newban"])
if(!check_rights(R_BAN))
return
@@ -1137,7 +1141,7 @@
log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
message_admins("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
- del(M.client)
+ qdel(M.client)
//qdel(M) // See no reason why to delete mob. Important stuff can be lost. And ban can be lifted before round ends.
if("No")
var/reason = input(usr,"Please State Reason.","Reason") as message
@@ -1162,7 +1166,7 @@
feedback_inc("ban_perma",1)
DB_ban_record(BANTYPE_PERMA, M, -1, reason)
- del(M.client)
+ qdel(M.client)
//qdel(M)
if("Cancel")
return
@@ -2253,3 +2257,20 @@
SD.r_code = code
message_admins("[key_name_admin(usr)] has set the self-destruct \
code to \"[code]\".")
+
+ else if(href_list["add_station_goal"])
+ if(!check_rights(R_ADMIN))
+ return
+ var/list/type_choices = typesof(/datum/station_goal)
+ var/picked = input("Choose goal type") in type_choices|null
+ if(!picked)
+ return
+ var/datum/station_goal/G = new picked()
+ if(picked == /datum/station_goal)
+ var/newname = input("Enter goal name:") as text
+ G.name = newname
+ var/description = input("Enter centcom message contents:") as message
+ G.report_message = description
+ message_admins("[key_name(usr)] created \"[G.name]\" station goal.")
+ ticker.mode.station_goals += G
+ modify_goals()
diff --git a/code/modules/admin/verbs/massmodvar.dm b/code/modules/admin/verbs/massmodvar.dm
index d5d81db54be..364a5af4750 100644
--- a/code/modules/admin/verbs/massmodvar.dm
+++ b/code/modules/admin/verbs/massmodvar.dm
@@ -83,6 +83,10 @@
var_value = "\icon[var_value]"
default = "icon"
+ else if(istype(var_value,/client))
+ usr << "Variable appears to be CLIENT."
+ default = "cancel"
+
else if(istype(var_value,/atom) || istype(var_value,/datum))
usr << "Variable appears to be TYPE."
default = "type"
@@ -91,10 +95,6 @@
usr << "Variable appears to be LIST."
default = "list"
- else if(istype(var_value,/client))
- usr << "Variable appears to be CLIENT."
- default = "cancel"
-
else
usr << "Variable appears to be FILE."
default = "file"
diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm
index 4b4a3364196..29c0661f8bd 100644
--- a/code/modules/admin/verbs/modifyvariables.dm
+++ b/code/modules/admin/verbs/modifyvariables.dm
@@ -77,7 +77,7 @@ var/list/VVckey_edit = list("key", "ckey")
var_value = new type()
if("new datum")
- var/type = input("Enter type:","Type") as null|anything in (typesof(/datum)-typesof(/obj,/mob,/area,/turf))
+ var/type = input("Enter type:","Type") as null|anything in (typesof(/datum)-typesof(/obj,/mob,/area,/turf,/client))
var_value = new type()
if(!var_value) return
@@ -142,7 +142,7 @@ var/list/VVckey_edit = list("key", "ckey")
var_value = new type()
if("new datum")
- var/type = input("Enter type:","Type") as null|anything in (typesof(/datum)-typesof(/obj,/mob,/area,/turf))
+ var/type = input("Enter type:","Type") as null|anything in (typesof(/datum)-typesof(/obj,/mob,/area,/turf,/client))
var_value = new type()
if(!var_value) return
@@ -243,6 +243,10 @@ var/list/VVckey_edit = list("key", "ckey")
variable = "\icon[variable]"
default = "icon"
+ else if(istype(variable,/client))
+ usr << "Variable appears to be CLIENT."
+ default = "cancel"
+
else if(istype(variable,/atom) || istype(variable,/datum))
usr << "Variable appears to be TYPE."
default = "type"
@@ -251,10 +255,6 @@ var/list/VVckey_edit = list("key", "ckey")
usr << "Variable appears to be LIST."
default = "list"
- else if(istype(variable,/client))
- usr << "Variable appears to be CLIENT."
- default = "cancel"
-
else
usr << "Variable appears to be FILE."
default = "file"
@@ -401,7 +401,7 @@ var/list/VVckey_edit = list("key", "ckey")
L[L.Find(variable)] = new_var
if("new datum")
- var/type = input("Enter type:","Type") as null|anything in (typesof(/datum)-typesof(/obj,/mob,/area,/turf))
+ var/type = input("Enter type:","Type") as null|anything in (typesof(/datum)-typesof(/obj,/mob,/area,/turf,/client))
new_var = new type()
if(assoc)
L[assoc_key] = new_var
@@ -471,6 +471,10 @@ var/list/VVckey_edit = list("key", "ckey")
var_value = "\icon[var_value]"
class = "icon"
+ else if(istype(var_value,/client))
+ usr << "Variable appears to be CLIENT."
+ class = "cancel"
+
else if(istype(var_value,/atom) || istype(var_value,/datum))
usr << "Variable appears to be TYPE."
class = "type"
@@ -479,10 +483,6 @@ var/list/VVckey_edit = list("key", "ckey")
usr << "Variable appears to be LIST."
class = "list"
- else if(istype(var_value,/client))
- usr << "Variable appears to be CLIENT."
- class = "cancel"
-
else
usr << "Variable appears to be FILE."
class = "file"
@@ -535,6 +535,10 @@ var/list/VVckey_edit = list("key", "ckey")
var_value = "\icon[var_value]"
default = "icon"
+ else if(istype(var_value,/client))
+ usr << "Variable appears to be CLIENT."
+ default = "cancel"
+
else if(istype(var_value,/atom) || istype(var_value,/datum))
usr << "Variable appears to be TYPE."
default = "type"
@@ -543,10 +547,6 @@ var/list/VVckey_edit = list("key", "ckey")
usr << "Variable appears to be LIST."
default = "list"
- else if(istype(var_value,/client))
- usr << "Variable appears to be CLIENT."
- default = "cancel"
-
else
usr << "Variable appears to be FILE."
default = "file"
@@ -685,7 +685,7 @@ var/list/VVckey_edit = list("key", "ckey")
O.vars[variable] = var_new
if("new datum")
- var/type = input("Enter type:","Type") as null|anything in (typesof(/datum)-typesof(/obj,/mob,/area,/turf))
+ var/type = input("Enter type:","Type") as null|anything in (typesof(/datum)-typesof(/obj,/mob,/area,/turf,/client))
var/var_new = new type()
if(var_new==null) return
O.vars[variable] = var_new
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index eadb377ea2f..1008453f85b 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -1137,3 +1137,19 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
H.regenerate_icons()
#undef ON_PURRBATION
+
+/client/proc/modify_goals()
+ set category = "Debug"
+ set name = "Modify station goals"
+
+ if(!check_rights(R_ADMIN))
+ return
+
+ holder.modify_goals()
+
+/datum/admins/proc/modify_goals()
+ var/dat = ""
+ for(var/datum/station_goal/S in ticker.mode.station_goals)
+ dat += "[S.name] - Announce | Remove
"
+ dat += "
Add New Goal"
+ usr << browse(dat, "window=goals;size=400x400")
\ No newline at end of file
diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm
index c7ed7f4fb33..1adcdb42f7b 100644
--- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm
+++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm
@@ -6,7 +6,6 @@ What are the archived variables for?
#define MINIMUM_HEAT_CAPACITY 0.0003
#define QUANTIZE(variable) (round(variable,0.0000001))/*I feel the need to document what happens here. Basically this is used to catch most rounding errors, however it's previous value made it so that
once gases got hot enough, most procedures wouldnt occur due to the fact that the mole counts would get rounded away. Thus, we lowered it a few orders of magnititude */
-
var/list/meta_gas_info = meta_gas_list() //see ATMOSPHERICS/gas_types.dm
var/list/gaslist_cache = null
@@ -181,13 +180,16 @@ var/list/gaslist_cache = null
//world << "post [temperature], [cached_gases["plasma"][MOLES]], [cached_gases["co2"][MOLES]]
*/
if(holder)
- if(cached_gases["freon"] && cached_gases["o2"])
- if(cached_gases["freon"][MOLES] >= 3)
- if(return_temperature() < 50)
- holder.freon_gas_act()
- cached_gases["freon"][MOLES] -= 3
- cached_gases["o2"][MOLES] += 3
- temperature += 1
+ if(cached_gases["freon"])
+ if(cached_gases["freon"][MOLES] >= MOLES_PLASMA_VISIBLE)
+ if(holder.freon_gas_act())
+ cached_gases["freon"][MOLES] -= MOLES_PLASMA_VISIBLE
+
+ if(cached_gases["water_vapor"])
+ if(cached_gases["water_vapor"][MOLES] >= MOLES_PLASMA_VISIBLE)
+ if(holder.water_vapor_gas_act())
+ cached_gases["water_vapor"][MOLES] -= MOLES_PLASMA_VISIBLE
+
fuel_burnt = 0
if(temperature > FIRE_MINIMUM_TEMPERATURE_TO_EXIST)
//world << "pre [temperature], [cached_gases["o2"][MOLES]], [cached_gases["plasma"][MOLES]]"
@@ -342,7 +344,6 @@ var/list/gaslist_cache = null
amount = min(amount, sum) //Can not take more air than tile has!
if(amount <= 0)
return null
-
var/list/cached_gases = gases
var/datum/gas_mixture/removed = new
var/list/removed_gases = removed.gases //accessing datum vars is slower than proc vars
@@ -370,6 +371,7 @@ var/list/gaslist_cache = null
removed.add_gas(id)
removed_gases[id][MOLES] = QUANTIZE(cached_gases[id][MOLES] * ratio)
cached_gases[id][MOLES] -= removed_gases[id][MOLES]
+
garbage_collect()
return removed
@@ -394,6 +396,7 @@ var/list/gaslist_cache = null
for(var/id in sample_gases)
assert_gas(id)
cached_gases[id][MOLES] = sample_gases[id][MOLES]
+
//remove all gases not in the sample
cached_gases &= sample_gases
diff --git a/code/modules/atmospherics/gasmixtures/gas_types.dm b/code/modules/atmospherics/gasmixtures/gas_types.dm
index 650b331d681..439026c2551 100644
--- a/code/modules/atmospherics/gasmixtures/gas_types.dm
+++ b/code/modules/atmospherics/gasmixtures/gas_types.dm
@@ -51,12 +51,19 @@ var/list/hardcoded_gases = list("o2","n2","co2","plasma") //the main four gases,
gas_overlay = "plasma"
moles_visible = MOLES_PLASMA_VISIBLE
+/datum/gas/water_vapor
+ id = "water_vapor"
+ specific_heat = 40
+ name = "Water Vapor"
+ gas_overlay = "water_vapor"
+ moles_visible = MOLES_PLASMA_VISIBLE
+
/datum/gas/freon
id = "freon"
- specific_heat = 1000
+ specific_heat = 2000
name = "Freon"
gas_overlay = "freon"
- moles_visible = 3
+ moles_visible = MOLES_PLASMA_VISIBLE
/datum/gas/nitrous_oxide
id = "n2o"
@@ -84,7 +91,7 @@ var/list/hardcoded_gases = list("o2","n2","co2","plasma") //the main four gases,
icon = 'icons/effects/tile_effects.dmi'
mouse_opacity = 0
layer = FLY_LAYER
- appearance_flags = RESET_COLOR|TILE_BOUND
+ appearance_flags = TILE_BOUND
/obj/effect/overlay/gas/New(state)
. = ..()
diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm
index 912cad976c7..9d2c5627bc2 100644
--- a/code/modules/atmospherics/machinery/airalarm.dm
+++ b/code/modules/atmospherics/machinery/airalarm.dm
@@ -78,6 +78,7 @@
"n2o" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
"bz" = new/datum/tlv(-1, -1, 0.2, 0.5),
"freon" = new/datum/tlv(-1, -1, 0.2, 0.5),
+ "water_vapor" = new/datum/tlv(-1, -1, 0.2, 0.5)
)
/obj/machinery/airalarm/server // No checks here.
@@ -91,6 +92,7 @@
"n2o" = new/datum/tlv(-1, -1, -1, -1),
"bz" = new/datum/tlv(-1, -1, -1, -1),
"freon" = new/datum/tlv(-1, -1, -1, -1),
+ "water_vapor" = new/datum/tlv(-1, -1, -1, -1)
)
/obj/machinery/airalarm/kitchen_cold_room // Copypasta: to check temperatures.
@@ -104,6 +106,7 @@
"n2o" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
"bz" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
"freon" = new/datum/tlv(-1, -1, 0.2, 0.5), // Partial pressure, kpa
+ "water_vapor" = new/datum/tlv(-1, -1, 0.2, 0.5)
)
//all air alarms in area are connected via magic
@@ -228,16 +231,17 @@
if(!info || info["frequency"] != frequency)
continue
data["scrubbers"] += list(list(
- "id_tag" = id_tag,
- "long_name" = sanitize(long_name),
- "power" = info["power"],
- "scrubbing" = info["scrubbing"],
- "widenet" = info["widenet"],
- "filter_co2" = info["filter_co2"],
- "filter_toxins" = info["filter_toxins"],
- "filter_n2o" = info["filter_n2o"],
- "filter_bz" = info["filter_bz"],
- "filter_freon" = info["filter_freon"]
+ "id_tag" = id_tag,
+ "long_name" = sanitize(long_name),
+ "power" = info["power"],
+ "scrubbing" = info["scrubbing"],
+ "widenet" = info["widenet"],
+ "filter_co2" = info["filter_co2"],
+ "filter_toxins" = info["filter_toxins"],
+ "filter_n2o" = info["filter_n2o"],
+ "filter_bz" = info["filter_bz"],
+ "filter_freon" = info["filter_freon"],
+ "filter_water_vapor" = info["filter_water_vapor"]
))
data["mode"] = mode
data["modes"] = list()
@@ -293,7 +297,7 @@
if(usr.has_unlimited_silicon_privilege && !wires.is_cut(WIRE_IDSCAN))
locked = !locked
. = TRUE
- if("power", "co2_scrub", "tox_scrub", "n2o_scrub", "bz_scrub", "freon_scrub", "widenet", "scrubbing")
+ if("power", "co2_scrub", "tox_scrub", "n2o_scrub", "bz_scrub", "freon_scrub","water_vapor_scrub", "widenet", "scrubbing")
send_signal(device_id, list("[action]" = text2num(params["val"])))
. = TRUE
if("excheck")
@@ -410,8 +414,9 @@
"co2_scrub" = 1,
"tox_scrub" = 0,
"n2o_scrub" = 0,
- "bz_scrub" = 1,
- "freon_scrub"= 1,
+ "bz_scrub" = 0,
+ "freon_scrub"= 0,
+ "water_vapor_scrub"= 0,
"scrubbing" = 1,
"widenet" = 0,
))
@@ -430,6 +435,7 @@
"n2o_scrub" = 1,
"bz_scrub" = 1,
"freon_scrub"= 1,
+ "water_vapor_scrub"= 1,
"scrubbing" = 1,
"widenet" = 1,
))
@@ -460,7 +466,8 @@
"tox_scrub" = 0,
"n2o_scrub" = 0,
"bz_scrub" = 0,
- "freon_scrub"= 1,
+ "freon_scrub"= 0,
+ "water_vapor_scrub"= 0,
"scrubbing" = 1,
"widenet" = 0,
))
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
index 181cce17d29..f95900688ec 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm
@@ -20,7 +20,9 @@
var/scrub_Toxins = 0
var/scrub_N2O = 0
var/scrub_BZ = 0
- var/scrub_Freon = 1
+ var/scrub_Freon = 0
+ var/scrub_WaterVapor = 0
+
var/volume_rate = 200
var/widenet = 0 //is this scrubber acting on the 3x3 area around it.
@@ -72,6 +74,8 @@
amount += idle_power_usage
if(scrub_Freon)
amount += idle_power_usage
+ if(scrub_WaterVapor)
+ amount += idle_power_usage
else //scrubbing == SIPHONING
amount = active_power_usage
@@ -122,7 +126,8 @@
"filter_toxins" = scrub_Toxins,
"filter_n2o" = scrub_N2O,
"filter_bz" = scrub_BZ,
- "filter_Freon" = scrub_Freon,
+ "filter_freon" = scrub_Freon,
+ "filter_water_vapor" = scrub_WaterVapor,
"sigtype" = "status"
)
@@ -218,6 +223,11 @@
filtered_out.gases["freon"][MOLES] = removed_gases["freon"][MOLES]
removed.gases["freon"][MOLES] = 0
+ if(scrub_WaterVapor && removed_gases["water_vapor"])
+ filtered_out.assert_gas("water_vapor")
+ filtered_out.gases["water_vapor"][MOLES] = removed_gases["water_vapor"][MOLES]
+ removed.gases["water_vapor"][MOLES] = 0
+
removed.garbage_collect()
//Remix the resulting gases
@@ -303,6 +313,11 @@
if("toggle_freon_scrub" in signal.data)
scrub_Freon = !scrub_Freon
+ if("water_vapor_scrub" in signal.data)
+ scrub_WaterVapor = text2num(signal.data["water_vapor_scrub"])
+ if("toggle_water_vapor_scrub" in signal.data)
+ scrub_WaterVapor = !scrub_WaterVapor
+
if("init" in signal.data)
name = signal.data["init"]
return
diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm
index 6cdb1ce2b12..2188de76733 100644
--- a/code/modules/atmospherics/machinery/portable/canister.dm
+++ b/code/modules/atmospherics/machinery/portable/canister.dm
@@ -31,6 +31,8 @@
"n2o" = /obj/machinery/portable_atmospherics/canister/nitrous_oxide,
"bz" = /obj/machinery/portable_atmospherics/canister/bz,
"air" = /obj/machinery/portable_atmospherics/canister/air,
+ "freon" = /obj/machinery/portable_atmospherics/canister/freon,
+ "water vapor" = /obj/machinery/portable_atmospherics/canister/water_vapor,
"caution" = /obj/machinery/portable_atmospherics/canister,
)
@@ -85,7 +87,14 @@
desc = "Freon. Great for the atmosphere!"
icon_state = "freon"
gas_type = "freon"
- starter_temp = 2.7
+ starter_temp = 120
+
+/obj/machinery/portable_atmospherics/canister/water_vapor
+ name = "water vapor canister"
+ desc = "Water Vapor. We get it, you vape."
+ icon_state = "water_vapor"
+ gas_type = "water_vapor"
+ filled = 1
/obj/machinery/portable_atmospherics/canister/New(loc, datum/gas_mixture/existing_mixture)
..()
diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm
index 04cda991256..308daa43f2a 100644
--- a/code/modules/atmospherics/machinery/portable/scrubber.dm
+++ b/code/modules/atmospherics/machinery/portable/scrubber.dm
@@ -7,7 +7,7 @@
var/volume_rate = 1000
volume = 1000
- var/list/scrubbing = list("plasma", "co2", "n2o", "agent_b", "bz", "freon")
+ var/list/scrubbing = list("plasma", "co2", "n2o", "agent_b", "bz", "freon", "water_vapor")
/obj/machinery/portable_atmospherics/scrubber/Destroy()
var/turf/T = get_turf(src)
diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm
index 761b2e15a21..ae759a49bf8 100644
--- a/code/modules/cargo/console.dm
+++ b/code/modules/cargo/console.dm
@@ -61,7 +61,7 @@
"name" = P.group,
"packs" = list()
)
- if((P.hidden && !emagged) || (P.contraband && !contraband))
+ if((P.hidden && !emagged) || (P.contraband && !contraband) || (P.special && !P.special_enabled))
continue
data["supplies"][P.group]["packs"] += list(list(
"name" = P.name,
diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm
index 81fab5def1a..5764994c628 100644
--- a/code/modules/cargo/packs.dm
+++ b/code/modules/cargo/packs.dm
@@ -1,4 +1,4 @@
-/datum/supply_pack
+datum/supply_pack
var/name = "Crate"
var/group = ""
var/hidden = FALSE
@@ -9,6 +9,8 @@
var/crate_name = "crate"
var/crate_type = /obj/structure/closet/crate
var/dangerous = FALSE // Should we message admins?
+ var/special = FALSE //Event/Station Goals/Admin enabled packs
+ var/special_enabled = FALSE
/datum/supply_pack/proc/generate(turf/T)
var/obj/structure/closet/crate/C = new crate_type(T)
@@ -153,9 +155,8 @@
dangerous = TRUE
/datum/supply_pack/emergency/syndicate/fill(obj/structure/closet/crate/C)
- var/static/list/uplink_items = get_uplink_items()
-
var/crate_value = 50
+ var/list/uplink_items = get_uplink_items(ticker.mode)
while(crate_value)
var/category = pick(uplink_items)
var/item = pick(uplink_items[category])
@@ -1534,3 +1535,58 @@
/obj/item/toy/crayon/rainbow,
/obj/item/toy/crayon/rainbow)
crate_name= "art supply crate"
+
+
+/datum/supply_pack/misc/bsa
+ name = "Bluespace Artillery Parts"
+ cost = 15000
+ special = TRUE
+ contains = list(/obj/item/weapon/circuitboard/machine/bsa/front,
+ /obj/item/weapon/circuitboard/machine/bsa/middle,
+ /obj/item/weapon/circuitboard/machine/bsa/back,
+ /obj/item/weapon/circuitboard/machine/computer/bsa_control
+ )
+ crate_name= "bluespace artillery parts crate"
+
+/datum/supply_pack/misc/dna_vault
+ name = "DNA Vault Parts"
+ cost = 12000
+ special = TRUE
+ contains = list(
+ /obj/item/weapon/circuitboard/machine/dna_vault
+ )
+ crate_name= "dna vault parts crate"
+
+/datum/supply_pack/misc/dna_probes
+ name = "DNA Vault Samplers"
+ cost = 3000
+ special = TRUE
+ contains = list(/obj/item/device/dna_probe,
+ /obj/item/device/dna_probe,
+ /obj/item/device/dna_probe,
+ /obj/item/device/dna_probe,
+ /obj/item/device/dna_probe
+ )
+ crate_name= "dna samplers crate"
+
+
+/datum/supply_pack/misc/shield_sat
+ name = "Shield Generator Satellite"
+ cost = 3000
+ special = TRUE
+ contains = list(
+ /obj/machinery/satellite/meteor_shield,
+ /obj/machinery/satellite/meteor_shield,
+ /obj/machinery/satellite/meteor_shield
+ )
+ crate_name= "shield sat crate"
+
+
+/datum/supply_pack/misc/shield_sat_control
+ name = "Shield System Control Board"
+ cost = 5000
+ special = TRUE
+ contains = list(
+ /obj/item/weapon/circuitboard/machine/computer/sat_control
+ )
+ crate_name= "shield control board crate"
\ No newline at end of file
diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm
index c31d2afb9af..f8fdf49ff7e 100644
--- a/code/modules/client/client_defines.dm
+++ b/code/modules/client/client_defines.dm
@@ -1,5 +1,9 @@
/client
+ //////////////////////
+ //BLACK MAGIC THINGS//
+ //////////////////////
+ parent_type = /datum
////////////////
//ADMIN THINGS//
////////////////
@@ -50,6 +54,3 @@
//datum that controls the displaying and hiding of tooltips
var/datum/tooltip/tooltips
-
- //Used for var edit flagging, also defined in datums (clients are not a child of datums for some reason)
- var/var_edited = 0
\ No newline at end of file
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 5993129892b..29ffcdf0c50 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -156,7 +156,7 @@ var/next_external_rsc = 0
if (holder)
src << "Because you are an admin, you are being allowed to walk past this limitation, But it is still STRONGLY suggested you upgrade"
else
- del(src)
+ qdel(src)
return 0
else if (byond_version < config.client_warn_version) //We have words for this client.
src << "Your version of byond may be getting out of date:"
@@ -168,11 +168,11 @@ var/next_external_rsc = 0
if (connection == "web")
if (!config.allowwebclient)
src << "Web client is disabled"
- del(src)
+ qdel(src)
return 0
if (config.webclientmembersonly && !IsByondMember())
src << "Sorry, but the web client is restricted to byond members only."
- del(src)
+ qdel(src)
return 0
if( (world.address == address || !address) && !host )
@@ -194,7 +194,7 @@ var/next_external_rsc = 0
log_access("Failed Login: [key] - New account attempting to connect during panic bunker")
message_admins("Failed Login: [key] - New account attempting to connect during panic bunker")
src << "Sorry but the server is currently not accepting connections from never before seen players."
- del(src)
+ qdel(src)
return 0
if (config.notify_new_player_age >= 0)
@@ -259,6 +259,8 @@ var/next_external_rsc = 0
clients -= src
return ..()
+/client/Destroy()
+ return QDEL_HINT_HARDDEL_NOW
/client/proc/set_client_age_from_db()
if (IsGuestKey(src.key))
@@ -352,7 +354,7 @@ var/next_external_rsc = 0
log_access("Failed Login: [key] [computer_id] [address] - CID randomizer confirmed (oldcid: [oldcid])")
- del(src)
+ qdel(src)
return TRUE
else
if (cidcheck_failedckeys[ckey])
@@ -381,7 +383,7 @@ var/next_external_rsc = 0
//teeheehee (in case the above method doesn't work, its not 100% reliable.)
src << "
Network connection shutting down due to read error.
"
- del(src)
+ qdel(src)
return TRUE
/client/proc/note_randomizer_user()
@@ -405,7 +407,7 @@ var/next_external_rsc = 0
if (query_get_notes.NextRow())
if (query_get_notes.item[1] == adminckey)
return
- add_note(ckey, "Detected as using a cid randomizer.", null, adminckey, logged = 0)
+ add_note(ckey, "Detected as using a cid randomizer.", null, adminckey, 0, null, 0)
/client/proc/check_ip_intel()
diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm
index d22c2785ea8..7788d269c21 100644
--- a/code/modules/client/verbs/ooc.dm
+++ b/code/modules/client/verbs/ooc.dm
@@ -151,7 +151,7 @@ var/global/normal_ooc_colour = OOC_COLOR
usr << "Sorry, that function is not enabled on this server."
return
- show_note(usr, null, 1)
+ show_note(usr.ckey, null, 1)
/client/proc/ignore_key(client)
var/client/C = client
diff --git a/code/modules/clothing/shoes/magboots.dm b/code/modules/clothing/shoes/magboots.dm
index 6b9b5d1c8c3..82fd000760d 100644
--- a/code/modules/clothing/shoes/magboots.dm
+++ b/code/modules/clothing/shoes/magboots.dm
@@ -31,7 +31,7 @@
icon_state = "[magboot_state][magpulse]"
user << "You [magpulse ? "enable" : "disable"] the mag-pulse traction system."
user.update_inv_shoes() //so our mob-overlays update
- user.update_gravity(user.mob_has_gravity())
+ user.update_gravity(user.has_gravity())
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
diff --git a/code/modules/countdown/countdown.dm b/code/modules/countdown/countdown.dm
index 53eb8d34caf..9b108de8e31 100644
--- a/code/modules/countdown/countdown.dm
+++ b/code/modules/countdown/countdown.dm
@@ -112,7 +112,7 @@
layer = POINT_LAYER
/obj/effect/countdown/clockworkgate/get_value()
- var/obj/structure/clockwork/massive/celestial_gateway/G = attached_to
+ var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = attached_to
if(!istype(G))
return
else if(G.health && !G.purpose_fulfilled)
diff --git a/code/modules/events/shuttle_loan.dm b/code/modules/events/shuttle_loan.dm
index 1383081b659..4649f851152 100644
--- a/code/modules/events/shuttle_loan.dm
+++ b/code/modules/events/shuttle_loan.dm
@@ -100,11 +100,11 @@
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian)
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian/ranged) //drops a mateba
- shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear)
+ shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear/russian)
if(prob(75))
shuttle_spawns.Add(/mob/living/simple_animal/hostile/russian)
if(prob(50))
- shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear)
+ shuttle_spawns.Add(/mob/living/simple_animal/hostile/bear/russian)
if(SPIDER_GIFT)
var/datum/supply_pack/pack = SSshuttle.supply_packs[/datum/supply_pack/emergency/specialops]
diff --git a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
index 2f88a2ae9d5..62532557e49 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/gibber.dm
@@ -62,7 +62,7 @@
/obj/machinery/gibber/RefreshParts()
var/gib_time = 40
for(var/obj/item/weapon/stock_parts/matter_bin/B in component_parts)
- meat_produced += 3 * B.rating
+ meat_produced += B.rating
for(var/obj/item/weapon/stock_parts/manipulator/M in component_parts)
gib_time -= 5 * M.rating
gibtime = gib_time
@@ -229,7 +229,7 @@
var/obj/item/meatslab = allmeat[i]
meatslab.loc = src.loc
meatslab.throw_at_fast(pick(nearby_turfs),i,3)
- for (var/turfs=1 to meat_produced*3)
+ for (var/turfs=1 to meat_produced)
var/turf/gibturf = pick(nearby_turfs)
if (!gibturf.density && src in view(gibturf))
new gibtype(gibturf,i)
diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm
index ddabb6efe88..40c2a19addb 100644
--- a/code/modules/mining/abandoned_crates.dm
+++ b/code/modules/mining/abandoned_crates.dm
@@ -214,10 +214,14 @@
else
..()
+/obj/structure/closet/crate/secure/loot/burn()
+ SSobj.burning -= src
+ boom()
+
/obj/structure/closet/crate/secure/loot/proc/boom(mob/user)
- user << "The crate's anti-tamper system activates!"
+ if(user)
+ user << "The crate's anti-tamper system activates!"
for(var/atom/movable/AM in src)
qdel(AM)
- var/turf/T = get_turf(src)
- explosion(T, -1, -1, 1, 1)
+ explosion(get_turf(src), 0, 1, 5, 5)
qdel(src)
\ No newline at end of file
diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm
new file mode 100644
index 00000000000..2d831483647
--- /dev/null
+++ b/code/modules/mining/lavaland/ash_flora.dm
@@ -0,0 +1,252 @@
+/obj/structure/flora/ash
+ gender = PLURAL
+ layer = PROJECTILE_HIT_THRESHHOLD_LAYER //sporangiums up don't shoot
+ icon = 'icons/obj/lavaland/ash_flora.dmi'
+ icon_state = "l_mushroom"
+ name = "large mushrooms"
+ desc = "A number of large mushrooms, covered in a faint layer of ash and what can only be spores."
+ var/harvested_name = "shortened mushrooms"
+ var/harvested_desc = "Some quickly regrowing mushrooms, formerly known to be quite large."
+ var/needs_sharp_harvest = TRUE
+ var/harvest = /obj/item/ash_flora/shavings
+ var/harvest_amount_low = 1
+ var/harvest_amount_high = 3
+ var/harvest_time = 60
+ var/harvest_message_low = "You pick a mushroom, but fail to collect many shavings from its cap."
+ var/harvest_message_med = "You pick a mushroom, carefully collecting the shavings from its cap."
+ var/harvest_message_high = "You harvest and collect shavings from several mushroom caps."
+ var/harvested = FALSE
+ var/base_icon
+ var/regrowth_time_low = 4800
+ var/regrowth_time_high = 8400
+
+/obj/structure/flora/ash/New()
+ ..()
+ base_icon = "[icon_state][rand(1, 4)]"
+ icon_state = base_icon
+ if(prob(15))
+ harvest(null, TRUE)
+
+/obj/structure/flora/ash/proc/harvest(user, no_drop)
+ if(harvested)
+ return 0
+ if(!no_drop)
+ var/rand_harvested = rand(harvest_amount_low, harvest_amount_high)
+ if(rand_harvested)
+ if(user)
+ var/msg = harvest_message_med
+ if(rand_harvested == harvest_amount_low)
+ msg = harvest_message_low
+ else if(rand_harvested == harvest_amount_high)
+ msg = harvest_message_high
+ user << "[msg]"
+ for(var/i in 1 to rand_harvested)
+ new harvest(get_turf(src))
+ icon_state = "[base_icon]p"
+ name = harvested_name
+ desc = harvested_desc
+ harvested = TRUE
+ addtimer(src, "regrow", rand(regrowth_time_low, regrowth_time_high))
+ return 1
+
+/obj/structure/flora/ash/proc/regrow()
+ icon_state = base_icon
+ name = initial(name)
+ desc = initial(desc)
+ harvested = FALSE
+
+/obj/structure/flora/ash/attackby(obj/item/weapon/W, mob/user, params)
+ if(!harvested && needs_sharp_harvest && W.sharpness)
+ user.visible_message("[user] starts to harvest from [src] with [W].","You begin to harvest from [src] with [W].")
+ if(do_after(user, harvest_time, target = src))
+ harvest(user)
+ else
+ return ..()
+
+/obj/structure/flora/ash/attack_hand(mob/user)
+ if(!harvested && !needs_sharp_harvest)
+ user.visible_message("[user] starts to harvest from [src].","You begin to harvest from [src].")
+ if(do_after(user, harvest_time, target = src))
+ harvest(user)
+ else
+ ..()
+
+/obj/structure/flora/ash/leaf_shroom
+ icon_state = "s_mushroom"
+ name = "leafy mushrooms"
+ desc = "A number of mushrooms, each of which surrounds a greenish sporangium with a number of leaf-like structures."
+ harvested_name = "leafless mushrooms"
+ harvested_desc = "A bunch of formerly-leafed mushrooms, with their sporangiums exposed. Scandalous?"
+ harvest = /obj/item/ash_flora/mushroom_leaf
+ needs_sharp_harvest = FALSE
+ harvest_amount_high = 4
+ harvest_time = 20
+ harvest_message_low = "You pluck a single, suitable leaf."
+ harvest_message_med = "You pluck a number of leaves, leaving a few unsuitable ones."
+ harvest_message_high = "You pluck quite a lot of suitable leaves."
+ regrowth_time_low = 2400
+ regrowth_time_high = 6000
+
+/obj/structure/flora/ash/cap_shroom
+ icon_state = "r_mushroom"
+ name = "tall mushrooms"
+ desc = "Several mushrooms, the larger of which have a ring of conks at the midpoint of their stems."
+ harvested_name = "small mushrooms"
+ harvested_desc = "Several small mushrooms near the stumps of what likely were larger mushrooms."
+ harvest = /obj/item/ash_flora/mushroom_cap
+ harvest_amount_high = 4
+ harvest_time = 50
+ harvest_message_low = "You slice the cap off of a mushroom."
+ harvest_message_med = "You slice off a few conks from the larger mushrooms."
+ harvest_message_high = "You slice off a number of caps and conks from these mushrooms."
+ regrowth_time_low = 3000
+ regrowth_time_high = 5400
+
+/obj/structure/flora/ash/stem_shroom
+ icon_state = "t_mushroom"
+ name = "numerous mushrooms"
+ desc = "A large number of mushrooms, some of which have long, fleshy stems."
+ harvested_name = "tiny mushrooms"
+ harvested_desc = "A few tiny mushrooms around larger stumps. You can already see them growing back."
+ harvest = /obj/item/ash_flora/mushroom_stem
+ harvest_amount_high = 4
+ harvest_time = 40
+ harvest_message_low = "You pick and slice the cap off of a mushroom, leaving the stem."
+ harvest_message_med = "You pick and decapitate several mushrooms for their stems."
+ harvest_message_high = "You acquire a number of stems from these mushrooms."
+ regrowth_time_low = 3000
+ regrowth_time_high = 6000
+
+/obj/structure/flora/ash/cacti
+ icon_state = "cactus"
+ name = "fruiting cacti"
+ desc = "Several prickly cacti, brimming with ripe fruit and covered in a thin layer of ash."
+ harvested_name = "cacti"
+ harvested_desc = "A bunch of prickly cacti. You can see fruits slowly growing beneath the covering of ash."
+ harvest = /obj/item/ash_flora/cactus_fruit
+ needs_sharp_harvest = FALSE
+ harvest_amount_high = 2
+ harvest_time = 10
+ harvest_message_low = "You pick a cactus fruit."
+ harvest_message_med = "You pick several cactus fruit." //shouldn't show up, because you can't get more than two
+ harvest_message_high = "You pick a pair of cactus fruit."
+ regrowth_time_low = 4800
+ regrowth_time_high = 7200
+
+/obj/structure/flora/ash/cacti/Crossed(mob/AM)
+ if(ishuman(AM) && has_gravity(loc) && prob(70))
+ var/mob/living/carbon/human/H = AM
+ if(!H.shoes && !H.lying) //ouch, my feet.
+ var/picked_def_zone = pick("l_leg", "r_leg")
+ var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone)
+ if(!istype(O) || (PIERCEIMMUNE in H.dna.species.specflags))
+ return
+ H.apply_damage(rand(3, 6), BRUTE, picked_def_zone)
+ H.Weaken(2)
+ H.visible_message("[H] steps on a cactus!", \
+ "You step on a cactus!")
+
+/obj/item/ash_flora
+ name = "mushroom shavings"
+ desc = "Some shavings from a tall mushroom. With enough, might serve as a bowl."
+ icon = 'icons/obj/lavaland/ash_flora.dmi'
+ icon_state = "mushroom_shavings"
+ w_class = 1
+ burn_state = FLAMMABLE
+ burntime = 30
+ var/prepared = FALSE
+ var/prepared_type = /obj/item/ash_flora/shavings
+ var/standard_prep = TRUE
+
+/obj/item/ash_flora/New()
+ ..()
+ pixel_x = rand(-4, 4)
+ pixel_y = rand(-4, 4)
+
+/obj/item/ash_flora/attackby(obj/item/weapon/W, mob/user, params)
+ if(!standard_prep || !W.sharpness || !prepare(user))
+ return ..()
+
+/obj/item/ash_flora/proc/prepare(mob/user)
+ if(!prepared)
+ prepared = TRUE
+ user << "You prepare [src]."
+ var/obj/item/ash_flora/A = new prepared_type(get_turf(src))
+ if(src in get_both_hands(user))
+ user.unEquip(src, TRUE)
+ user.put_in_hands(A)
+ qdel(src)
+ . = 1
+
+/obj/item/ash_flora/shavings //for actual crafting
+ prepared = TRUE
+
+/obj/item/ash_flora/mushroom_leaf
+ name = "mushroom leaf"
+ desc = "A leaflike structure from a mushroom. You should probably wash the ash off."
+ icon_state = "mushroom_leaf"
+ standard_prep = FALSE
+ prepared_type = /obj/item/ash_flora/mushroom_leaf/prepared
+
+/obj/item/ash_flora/mushroom_leaf/afterattack(atom/target, mob/user, proximity_flag)
+ if(proximity_flag && (istype(target, /turf/open/floor/plating/ashplanet/wateryrock) || istype(target, /obj/structure/sink)))
+ prepare(user)
+
+/obj/item/ash_flora/mushroom_leaf/prepared
+ name = "washed mushroom leaf"
+ desc = "A greenish leaflike structure from a mushroom. Kind of like lettuce?"
+ icon_state = "mushroom_leaf_p"
+ prepared = TRUE
+
+/obj/item/ash_flora/mushroom_cap
+ name = "mushroom cap"
+ desc = "A mushroom cap. Possibly delicious, at least if you cut it up a bit first."
+ icon_state = "mushroom_cap"
+ prepared_type = /obj/item/ash_flora/mushroom_cap/prepared
+
+/obj/item/ash_flora/mushroom_cap/prepared
+ name = "sliced mushroom cap"
+ desc = "A sliced-up mushroom cap, revealing pale yellow innards. It smells faintly salty."
+ icon_state = "mushroom_cap_p"
+ prepared = TRUE
+
+/obj/item/ash_flora/mushroom_stem
+ name = "mushroom stem"
+ desc = "A mushroom stem. Slice it up, throw it in a stew."
+ icon_state = "mushroom_stem"
+ prepared_type = /obj/item/ash_flora/mushroom_stem/prepared
+
+/obj/item/ash_flora/mushroom_stem/prepared
+ name = "sliced mushroom stem"
+ desc = "A mushroom stem, cut in half to reveal orange flesh. Smells almost like potatos, but with a sour undertone."
+ icon_state = "mushroom_stem_p"
+ prepared = TRUE
+
+/obj/item/ash_flora/cactus_fruit
+ name = "cactus fruit"
+ desc = "A cactus fruit covered in a thick, reddish skin. And some ash."
+ icon_state = "cactus_fruit"
+ prepared_type = /obj/item/ash_flora/cactus_fruit/prepared
+
+/obj/item/ash_flora/cactus_fruit/prepared
+ name = "peeled cactus fruit"
+ desc = "A cactus fruit with the skin and ash carefully scraped off, revealing a faintly sweet-smelling yellow center."
+ icon_state = "cactus_fruit_p"
+ prepared = TRUE
+
+/obj/item/mushroom_bowl
+ name = "mushroom bowl"
+ desc = "A bowl made out of mushrooms. Not food, though it might have contained some at some point."
+ icon = 'icons/obj/lavaland/ash_flora.dmi'
+ icon_state = "mushroom_bowl"
+ w_class = 2
+ burn_state = FLAMMABLE
+ burntime = 40
+
+//what you can craft with these things
+/datum/crafting_recipe/mushroom_bowl
+ name = "Mushroom Bowl"
+ result = /obj/item/mushroom_bowl
+ reqs = list(/obj/item/ash_flora/shavings = 5)
+ time = 30
+ //category = CAT_PRIMAL //uncomment once ashplanet exists and this wouldn't just take up space fnr
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 68a3ca84760..993ac2b2d57 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -193,19 +193,23 @@
weaken = 3
var/chain
-/obj/item/ammo_casing/magic/hook/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
+/obj/item/projectile/hook/fire(setAngle)
+ if(firer)
+ chain = Beam(firer, icon_state = "chain", icon = 'icons/obj/lavaland/artefacts.dmi', time = INFINITY, maxdistance = INFINITY)
..()
- var/obj/item/projectile/hook/P = BB
- spawn(1)
- P.chain = P.Beam(user,icon_state="chain",icon = 'icons/obj/lavaland/artefacts.dmi',time=1000, maxdistance = 30)
/obj/item/projectile/hook/on_hit(atom/target)
. = ..()
if(isliving(target))
var/mob/living/L = target
- L.visible_message("[L] is snagged by [firer]'s hook!")
- L.forceMove(get_turf(firer))
- qdel(chain)
+ if(!L.anchored)
+ L.visible_message("[L] is snagged by [firer]'s hook!")
+ L.forceMove(get_turf(firer))
+
+/obj/item/projectile/hook/Destroy()
+ qdel(chain)
+ return ..()
+
//Immortality Talisman
/obj/item/device/immortality_talisman
@@ -628,7 +632,9 @@
var/transform_string = "lava"
var/reset_turf_type = /turf/open/floor/plating/asteroid/basalt
var/reset_string = "basalt"
- var/cooldown = 200
+ var/create_cooldown = 100
+ var/create_delay = 30
+ var/reset_cooldown = 50
var/timer = 0
var/banned_turfs
@@ -650,15 +656,31 @@
if(!istype(T))
return
if(!istype(T, turf_type))
- user.visible_message("[user] turns \the [T] into [transform_string]!")
- message_admins("[key_name_admin(user)] fired the lava staff at ([get_area(target)] ([T.x], [T.y], [T.z])).")
- log_game("[key_name(user)] fired the lava staff at [get_area(target)] ([T.x], [T.y], [T.z]).")
- T.ChangeTurf(turf_type)
+ var/obj/effect/overlay/temp/lavastaff/L = PoolOrNew(/obj/effect/overlay/temp/lavastaff, T)
+ L.alpha = 0
+ animate(L, alpha = 255, time = create_delay)
+ user.visible_message("[user] points [src] at [T]!")
+ timer = world.time + create_delay + 1
+ if(do_after(user, create_delay, target = T))
+ user.visible_message("[user] turns \the [T] into [transform_string]!")
+ message_admins("[key_name_admin(user)] fired the lava staff at [get_area(target)]. [ADMIN_COORDJMP(T)]")
+ log_game("[key_name(user)] fired the lava staff at [get_area(target)] [COORD(T)].")
+ T.ChangeTurf(turf_type)
+ timer = world.time + create_cooldown
+ qdel(L)
+ else
+ timer = world.time
+ qdel(L)
+ return
else
user.visible_message("[user] turns \the [T] into [reset_string]!")
T.ChangeTurf(reset_turf_type)
- playsound(get_turf(src),'sound/magic/Fireball.ogg', 200, 1)
- timer = world.time + cooldown
+ timer = world.time + reset_cooldown
+ playsound(T,'sound/magic/Fireball.ogg', 200, 1)
+
+/obj/effect/overlay/temp/lavastaff
+ icon_state = "lavastaff_warn"
+ duration = 50
///Bubblegum
@@ -733,3 +755,189 @@
H.put_in_hands_or_del(new /obj/item/weapon/kitchen/knife/butcher(H))
qdel(src)
+
+//Hierophant
+
+/obj/item/weapon/hierophant_staff
+ name = "Hierophant's staff"
+ desc = "A large club with intense magic power infused into it."
+ icon_state = "hierophant_staff"
+ item_state = "hierophant_staff"
+ icon = 'icons/obj/guns/magic.dmi'
+ slot_flags = SLOT_BACK
+ w_class = 4
+ force = 20
+ hitsound = "swing_hit"
+ //hitsound = 'sound/weapons/sonic_jackhammer.ogg'
+ actions_types = list(/datum/action/item_action/vortex_recall, /datum/action/item_action/toggle_unfriendly_fire)
+ var/cooldown_time = 20 //how long the cooldown between non-melee ranged attacks is
+ var/chaser_cooldown = 101 //how long the cooldown between firing chasers at mobs is
+ var/chaser_timer = 0 //what our current chaser cooldown is
+ var/timer = 0 //what our current cooldown is
+ var/blast_range = 3 //how long the cardinal blast's walls are
+ var/obj/effect/hierophant/rune //the associated rune we teleport to
+ var/teleporting = FALSE //if we ARE teleporting
+ var/friendly_fire_check = FALSE //if the blasts we make will consider our faction against the faction of hit targets
+
+/obj/item/weapon/hierophant_staff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
+ ..()
+ var/turf/T = get_turf(target)
+ if(!T || timer > world.time)
+ return
+ timer = world.time + CLICK_CD_MELEE //by default, melee attacks only cause melee blasts, and have an accordingly short cooldown
+ if(proximity_flag)
+ addtimer(src, "aoe_burst", 0, FALSE, T, user)
+ add_logs(user, target, "fired 3x3 blast at", src)
+ else
+ if(istype(target, /turf/closed/mineral) && get_dist(user, target) < 6) //target is minerals, we can hit it(even if we can't see it)
+ addtimer(src, "cardinal_blasts", 0, FALSE, T, user)
+ timer = world.time + cooldown_time
+ else if(target in view(5, get_turf(user))) //if the target is in view, hit it
+ timer = world.time + cooldown_time
+ if(isliving(target) && chaser_timer <= world.time) //living and chasers off cooldown? fire one!
+ chaser_timer = world.time + chaser_cooldown
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(get_turf(user), user, target, 1.5, friendly_fire_check))
+ add_logs(user, target, "fired a chaser at", src)
+ else
+ addtimer(src, "cardinal_blasts", 0, FALSE, T, user) //otherwise, just do cardinal blast
+ add_logs(user, target, "fired cardinal blast at", src)
+ else
+ user << "That target is out of range!" //too far away
+
+/obj/item/weapon/hierophant_staff/ui_action_click(mob/user, actiontype)
+ if(actiontype == /datum/action/item_action/toggle_unfriendly_fire) //toggle friendly fire...
+ friendly_fire_check = !friendly_fire_check
+ user << "You toggle friendly fire [friendly_fire_check ? "off":"on"]!"
+ return
+ if(!rune)
+ if(isturf(user.loc))
+ user.visible_message("[user] holds [src] carefully in front of them, moving it in a strange pattern...", \
+ "You start creating a hierophant rune to teleport to...")
+ timer = world.time + 51
+ if(do_after(user, 50, target = user))
+ var/turf/T = get_turf(user)
+ playsound(T,'sound/magic/Blind.ogg', 200, 1, -4)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(T, user))
+ var/obj/effect/hierophant/H = new/obj/effect/hierophant(T)
+ rune = H
+ user.update_action_buttons_icon()
+ user.visible_message("[user] creates a strange rune beneath them!", \
+ "You create a hierophant rune, which you can teleport yourself and any allies to at any time!\n\
+ You can remove the rune to place a new one by striking it with the staff.")
+ else
+ timer = world.time
+ else
+ user << "You need to be on solid ground to produce a rune!"
+ return
+ if(src != user.l_hand && src != user.r_hand) //you need to hold the staff to teleport
+ user << "You need to hold the staff in your hands to [rune ? "teleport with it":"create a rune"]!"
+ return
+ if(get_dist(user, rune) <= 2) //rune too close abort
+ user << "You are too close to the rune to teleport to it!"
+ return
+ if(is_blocked_turf(get_turf(rune)))
+ user << "The rune is blocked by something, preventing teleportation!"
+ return
+ teleporting = TRUE //start channel
+ user.update_action_buttons_icon()
+ user.visible_message("[user] starts to glow faintly...")
+ timer = world.time + 50
+ if(do_after(user, 40, target = user) && rune)
+ var/turf/T = get_turf(rune)
+ var/turf/source = get_turf(user)
+ if(is_blocked_turf(T))
+ teleporting = FALSE
+ user << "The rune is blocked by something, preventing teleportation!"
+ user.update_action_buttons_icon()
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, user))
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(source, user))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1)
+ playsound(source,'sound/magic/blink.ogg', 200, 1)
+ //playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
+ if(!do_after(user, 3, target = user) || !rune) //no walking away shitlord
+ teleporting = FALSE
+ if(user)
+ user.update_action_buttons_icon()
+ return
+ if(is_blocked_turf(T))
+ teleporting = FALSE
+ user << "The rune is blocked by something, preventing teleportation!"
+ user.update_action_buttons_icon()
+ return
+ add_logs(user, rune, "teleported self from ([source.x],[source.y],[source.z]) to")
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(T, user))
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(source, user))
+ for(var/t in RANGE_TURFS(1, T))
+ var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, user, TRUE)) //blasts produced will not hurt allies
+ B.damage = 30
+ for(var/t in RANGE_TURFS(1, source))
+ var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, user, TRUE)) //but absolutely will hurt enemies
+ B.damage = 30
+ for(var/mob/living/L in range(1, source))
+ addtimer(src, "teleport_mob", 0, FALSE, source, L, T, user) //regardless, take all mobs near us along
+ sleep(6) //at this point the blasts detonate
+ else
+ timer = world.time
+ teleporting = FALSE
+ if(user)
+ user.update_action_buttons_icon()
+
+/obj/item/weapon/hierophant_staff/proc/teleport_mob(turf/source, mob/M, turf/target, mob/user)
+ var/turf/turf_to_teleport_to = get_step(target, get_dir(source, M)) //get position relative to caster
+ if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to))
+ return
+ animate(M, alpha = 0, time = 2, easing = EASE_OUT) //fade out
+ sleep(1)
+ if(!M)
+ return
+ M.visible_message("[M] fades out!")
+ sleep(2)
+ if(!M)
+ return
+ M.forceMove(turf_to_teleport_to)
+ sleep(1)
+ if(!M)
+ return
+ animate(M, alpha = 255, time = 2, easing = EASE_IN) //fade IN
+ sleep(1)
+ if(!M)
+ return
+ M.visible_message("[M] fades in!")
+ if(user != M)
+ add_logs(user, M, "teleported", null, "from ([source.x],[source.y],[source.z])")
+
+/obj/item/weapon/hierophant_staff/proc/cardinal_blasts(turf/T, mob/living/user) //fire cardinal cross blasts with a delay
+ if(!T)
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/cardinal, list(T, user))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/effects/bin_close.ogg', 200, 1)
+ sleep(2)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, user, friendly_fire_check))
+ for(var/d in cardinal)
+ addtimer(src, "blast_wall", 0, FALSE, T, d, user)
+
+/obj/item/weapon/hierophant_staff/proc/blast_wall(turf/T, dir, mob/living/user) //make a wall of blasts blast_range tiles long
+ if(!T)
+ return
+ var/range = blast_range
+ var/turf/previousturf = T
+ var/turf/J = get_step(previousturf, dir)
+ for(var/i in 1 to range)
+ if(!J)
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(J, user, friendly_fire_check))
+ previousturf = J
+ J = get_step(previousturf, dir)
+
+/obj/item/weapon/hierophant_staff/proc/aoe_burst(turf/T, mob/living/user) //make a 3x3 blast around a target
+ if(!T)
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, user))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/effects/bin_close.ogg', 200, 1)
+ sleep(2)
+ for(var/t in RANGE_TURFS(1, T))
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, user, friendly_fire_check))
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index d298e3c146a..443f37ea406 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -88,11 +88,12 @@
else
process_sheet(O)
i++
- if(i > 0)
- var/msg = "Now available in the cargo Bay: \n"
+ if(i > 0 && z == ZLEVEL_STATION)
+ var/area/orm_area = get_area(src)
+ var/msg = "Now available in [orm_area.map_name]:"
for(var/s in stack_list) // Making an announcement for cargo
var/obj/item/stack/sheet/mats = stack_list[s]
- msg += "[capitalize(mats.name)]: [mats.amount] sheets \n"
+ msg += "\n[capitalize(mats.name)]: [mats.amount] sheets"
for(var/obj/machinery/requests_console/D in allConsoles)
if(D.department == "Science" || D.department == "Robotics" || D.department == "Research Director's Desk" || D.department == "Chemistry" || D.department == "Bar")
D.createmessage("Ore Redemption Machine", "New minerals available!", msg, 1, 0)
diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm
index ecb2988d2fb..bf154f66071 100644
--- a/code/modules/mining/mine_items.dm
+++ b/code/modules/mining/mine_items.dm
@@ -2,10 +2,16 @@
//this item is intended to give the effect of entering the mine, so that light gradually fades
/obj/effect/light_emitter
- name = "Light-emtter"
+ name = "Light emitter"
anchored = 1
unacidable = 1
- luminosity = 8
+ invisibility = 101
+ var/set_luminosity = 8
+ var/set_cap = 0
+
+/obj/effect/light_emitter/New()
+ ..()
+ SetLuminosity(set_luminosity, set_cap)
/**********************Miner Lockers**************************/
@@ -535,9 +541,15 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
say("Launch sequence activated! Prepare for drop!")
playsound(loc, 'sound/machines/warning-buzzer.ogg', 70, 0)
launch_warning = FALSE
- feedback_add_details("colonies_dropped") //Number of times a base has been dropped!
..()
+
+
+/obj/machinery/computer/shuttle/auxillary_base/onShuttleMove(turf/T1, rotation)
+ ..()
+ if(z == ZLEVEL_MINING) //Avoids double logging and landing on other Z-levels due to badminnery
+ feedback_add_details("colonies_dropped", "[x]|[y]|[z]") //Number of times a base has been dropped!
+
/obj/machinery/computer/shuttle/auxillary_base/proc/set_mining_mode()
if(z == ZLEVEL_MINING) //The console switches to controlling the mining shuttle once landed.
req_access = list()
@@ -713,4 +725,4 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
anti_spam_cd = 0
/obj/structure/mining_shuttle_beacon/attack_robot(mob/user)
- return (attack_hand(user)) //So borgies can help
\ No newline at end of file
+ return (attack_hand(user)) //So borgies can help
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index bf40e0b4564..2438bd0b626 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -6,7 +6,7 @@
icon_state = "rock"
var/smooth_icon = 'icons/turf/smoothrocks.dmi'
smooth = SMOOTH_MORE|SMOOTH_BORDER
- canSmoothWith = list (/turf/closed/mineral, /turf/closed/wall)
+ canSmoothWith = list (/turf/closed)
baseturf = /turf/open/floor/plating/asteroid/airless
initial_gas_mix = "TEMP=2.7"
opacity = 1
@@ -278,7 +278,7 @@
/turf/open/floor/plating/asteroid/airless/cave/volcanic
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goldgrub = 10, /mob/living/simple_animal/hostile/asteroid/goliath/beast = 50, /mob/living/simple_animal/hostile/asteroid/basilisk/watcher = 40, /mob/living/simple_animal/hostile/asteroid/hivelord/legion = 30,
/mob/living/simple_animal/hostile/spawner/lavaland = 2, /mob/living/simple_animal/hostile/spawner/lavaland/goliath = 3, /mob/living/simple_animal/hostile/spawner/lavaland/legion = 3, \
- /mob/living/simple_animal/hostile/megafauna/dragon = 2, /mob/living/simple_animal/hostile/megafauna/bubblegum = 2)
+ /mob/living/simple_animal/hostile/megafauna/dragon = 2, /mob/living/simple_animal/hostile/megafauna/bubblegum = 2, /mob/living/simple_animal/hostile/megafauna/colossus = 2)
data_having_type = /turf/open/floor/plating/asteroid/airless/cave/volcanic/has_data
turf_type = /turf/open/floor/plating/asteroid/basalt/lava_land_surface
@@ -506,6 +506,9 @@
/turf/open/floor/plating/asteroid/snow/temperatre
initial_gas_mix = "TEMP=255.37"
+/turf/open/floor/plating/asteroid/snow/atmosphere
+ initial_gas_mix = "o2=22;n2=82;TEMP=180"
+
/turf/open/floor/plating/asteroid/New()
var/proper_name = name
..()
@@ -617,15 +620,18 @@
/turf/open/chasm/Entered(atom/movable/AM)
START_PROCESSING(SSobj, src)
- drop_stuff()
+ drop_stuff(AM)
/turf/open/chasm/process()
if(!drop_stuff())
STOP_PROCESSING(SSobj, src)
-/turf/open/chasm/proc/drop_stuff()
+/turf/open/chasm/proc/drop_stuff(AM)
. = 0
- for(var/thing in contents)
+ var/thing_to_check = src
+ if(AM)
+ thing_to_check = list(AM)
+ for(var/thing in thing_to_check)
if(droppable(thing))
. = 1
addtimer(src, "drop", 0, FALSE, thing)
@@ -811,48 +817,60 @@
name = "rock"
icon = 'icons/turf/mining.dmi'
smooth_icon = 'icons/turf/walls/rock_wall.dmi'
- icon_state = "rock"
+ icon_state = "rock2"
smooth = SMOOTH_MORE|SMOOTH_BORDER
- canSmoothWith = list (/turf/closed/mineral, /turf/closed/wall)
- baseturf = /turf/open/floor/plating/ash
+ canSmoothWith = list (/turf/closed)
+ baseturf = /turf/open/floor/plating/ashplanet/wateryrock
initial_gas_mix = "o2=14;n2=23;TEMP=300"
environment_type = "waste"
- turf_type = /turf/open/floor/plating/ash
+ turf_type = /turf/open/floor/plating/ashplanet/rocky
defer_change = 1
-/turf/open/floor/plating/ash
+/turf/open/floor/plating/ashplanet
icon = 'icons/turf/mining.dmi'
name = "ash"
icon_state = "ash"
smooth = SMOOTH_MORE|SMOOTH_BORDER
- canSmoothWith = list (/turf/open/floor/plating/ash, /turf/closed)
var/smooth_icon = 'icons/turf/floors/ash.dmi'
desc = "The ground is covered in volcanic ash."
- baseturf = /turf/open/floor/plating/ash //I assume this will be a chasm eventually, once this becomes an actual surface
- slowdown = 1
+ baseturf = /turf/open/floor/plating/ashplanet/wateryrock //I assume this will be a chasm eventually, once this becomes an actual surface
initial_gas_mix = "o2=14;n2=23;TEMP=300"
planetary_atmos = TRUE
-/turf/open/floor/plating/ash/New()
- pixel_y = -4
- pixel_x = -4
- icon = smooth_icon
+/turf/open/floor/plating/ashplanet/New()
+ if(smooth)
+ pixel_y = -4
+ pixel_x = -4
+ icon = smooth_icon
..()
-/turf/open/floor/plating/ash/break_tile()
+/turf/open/floor/plating/ashplanet/break_tile()
return
-/turf/open/floor/plating/ash/burn_tile()
+/turf/open/floor/plating/ashplanet/burn_tile()
return
-/turf/open/floor/plating/ash/rocky
+/turf/open/floor/plating/ashplanet/ash
+ canSmoothWith = list(/turf/open/floor/plating/ashplanet/ash, /turf/closed)
+ layer = HIGH_TURF_LAYER
+ slowdown = 1
+
+/turf/open/floor/plating/ashplanet/rocky
name = "rocky ground"
icon_state = "rockyash"
- icon = 'icons/turf/mining.dmi'
smooth_icon = 'icons/turf/floors/rocky_ash.dmi'
- slowdown = 0
- smooth = SMOOTH_MORE|SMOOTH_BORDER
- canSmoothWith = list (/turf/open/floor/plating/ash/rocky, /turf/closed)
+ layer = MID_TURF_LAYER
+ canSmoothWith = list(/turf/open/floor/plating/ashplanet/rocky, /turf/closed)
+
+/turf/open/floor/plating/ashplanet/wateryrock
+ name = "wet rocky ground"
+ smooth = null
+ icon_state = "wateryrock"
+ slowdown = 2
+
+/turf/open/floor/plating/ashplanet/wateryrock/New()
+ icon_state = "[icon_state][rand(1, 9)]"
+ ..()
//Necropolis
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
index 7f6704cb81e..379500f5002 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
@@ -45,7 +45,7 @@
if(leaping || stat || buckled || lying)
return
- if(!has_gravity(src) || !has_gravity(A))
+ if(!has_gravity() || !A.has_gravity())
src << "It is unsafe to leap without gravity!"
//It's also extremely buggy visually, so it's balance+bugfix
return
diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm
index 0d0c8cb3ce4..479e9459c5c 100644
--- a/code/modules/mob/living/carbon/carbon_movement.dm
+++ b/code/modules/mob/living/carbon/carbon_movement.dm
@@ -11,7 +11,8 @@ var/const/GALOSHES_DONT_HELP = 4
var/const/SLIDE_ICE = 8
/mob/living/carbon/slip(s_amount, w_amount, obj/O, lube)
- add_logs(src,, "slipped",, "on [O ? O.name : "floor"]")
+ if(!(lube&SLIDE_ICE))
+ add_logs(src,, "slipped",, "on [O ? O.name : "floor"]")
return loc.handle_slip(src, s_amount, w_amount, O, lube)
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 3bb4c433f4c..98d53ef104f 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -15,7 +15,7 @@
return 0
return ..()
-/mob/living/carbon/human/mob_has_gravity()
+/mob/living/carbon/human/has_gravity()
. = ..()
if(!.)
if(mob_negates_gravity())
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index 699ded25a7a..619e9a7e139 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -854,7 +854,7 @@
. -= 2
if(!(H.status_flags & IGNORESLOWDOWN))
- if(!has_gravity(H))
+ if(!H.has_gravity())
if(FLYING in specflags)
. += speedmod
return
@@ -1419,7 +1419,6 @@
if(-INFINITY to 120)
H.throw_alert("temp", /obj/screen/alert/cold, 3)
H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod, BURN)
- H.apply_status_effect(/datum/status_effect/freon)
else
H.clear_alert("temp")
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 9cd7b339a0f..f44ca1855ba 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -43,7 +43,7 @@
//stuff in the stomach
handle_stomach()
- update_gravity(mob_has_gravity())
+ update_gravity(has_gravity())
if(machine)
machine.check_eye(src)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 3e808f12a1c..d5d566211d1 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -602,7 +602,7 @@
. += config.walk_speed
/mob/living/proc/makeTrail(turf/T)
- if(!has_gravity(src))
+ if(!has_gravity())
return
var/blood_exists = 0
@@ -666,8 +666,8 @@
if (AM.density && AM.anchored)
pressure_resistance_prob_delta -= 20
break
-
- ..(pressure_difference, direction, pressure_resistance_prob_delta)
+ if(!slipping)
+ ..(pressure_difference, direction, pressure_resistance_prob_delta)
/mob/living/verb/resist()
set name = "Resist"
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 83103ebf337..0dafbfe1137 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -71,3 +71,5 @@
var/blood_volume = 0 //how much blood the mob has
var/obj/effect/proc_holder/ranged_ability //Any ranged ability the mob has, as a click override
+
+ var/slipping = FALSE
\ No newline at end of file
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 75ed1c827d7..06e5ad4ff7f 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -144,7 +144,7 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
/mob/living/send_speech(message, message_range = 7, obj/source = src, bubble_type = bubble_icon, list/spans)
var/list/listening = get_hearers_in_view(message_range, source)
for(var/mob/M in player_list)
- if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7)) && client) // client is so that ghosts don't have to listen to mice
+ if(M.stat == DEAD && M.client && ((M.client.prefs.chat_toggles & CHAT_GHOSTEARS) || (get_dist(M, src) <= 7 && M.z == z)) && client) // client is so that ghosts don't have to listen to mice
listening |= M
var/rendered = compose_message(src, languages_spoken, message, , spans)
diff --git a/code/modules/mob/living/silicon/ai/examine.dm b/code/modules/mob/living/silicon/ai/examine.dm
index a47c0e8293c..b7980140e2c 100644
--- a/code/modules/mob/living/silicon/ai/examine.dm
+++ b/code/modules/mob/living/silicon/ai/examine.dm
@@ -19,4 +19,6 @@
msg += "[src]Core.exe has stopped responding! NTOS is searching for a solution to the problem...\n"
msg += "*---------*"
- user << msg
\ No newline at end of file
+ user << msg
+
+ ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 946f2e04900..0c3b45c2d5c 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -9,7 +9,7 @@
else //I'm not removing that shitton of tabs, unneeded as they are. -- Urist
//Being dead doesn't mean your temperature never changes
- update_gravity(mob_has_gravity())
+ update_gravity(has_gravity())
if(malfhack && malfhack.aidisabled)
deltimer(malfhacking)
diff --git a/code/modules/mob/living/silicon/examine.dm b/code/modules/mob/living/silicon/examine.dm
new file mode 100644
index 00000000000..ab04306d11f
--- /dev/null
+++ b/code/modules/mob/living/silicon/examine.dm
@@ -0,0 +1,4 @@
+/mob/living/silicon/examine(mob/user) //Displays a silicon's laws to ghosts
+ if(laws && isobserver(user))
+ user << "[src] has the following laws:"
+ laws.show_laws(user)
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm
index e4233a06e8d..a05838f81ea 100644
--- a/code/modules/mob/living/silicon/robot/examine.dm
+++ b/code/modules/mob/living/silicon/robot/examine.dm
@@ -47,3 +47,5 @@
msg += "*---------*"
user << msg
+
+ ..()
diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm
index 63d76801c78..695ea3e4978 100644
--- a/code/modules/mob/living/silicon/robot/robot_movement.dm
+++ b/code/modules/mob/living/silicon/robot/robot_movement.dm
@@ -11,7 +11,7 @@
/mob/living/silicon/robot/mob_negates_gravity()
return magpulse
-/mob/living/silicon/robot/mob_has_gravity()
+/mob/living/silicon/robot/has_gravity()
return ..() || mob_negates_gravity()
/mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction)
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index d14a6bf087d..042de50dcad 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -859,7 +859,7 @@ Pass a positive integer as an argument to override a bot's default speed.
src << "You sense your form change as you are uploaded into [src]."
bot_name = name
name = paicard.pai.name
- faction = user.faction
+ faction = user.faction.Copy()
add_logs(user, paicard.pai, "uploaded to [bot_name],")
return 1
else
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index ee5f1893324..35b363ae285 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -245,7 +245,7 @@
/mob/living/simple_animal/drone/mob_negates_gravity()
return 1
-/mob/living/simple_animal/drone/mob_has_gravity()
+/mob/living/simple_animal/drone/has_gravity()
return ..() || mob_negates_gravity()
/mob/living/simple_animal/drone/experience_pressure_difference(pressure_difference, direction)
diff --git a/code/modules/mob/living/simple_animal/guardian/types/charger.dm b/code/modules/mob/living/simple_animal/guardian/types/charger.dm
index 2da19573101..33743138b95 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/charger.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/charger.dm
@@ -38,7 +38,7 @@
/mob/living/simple_animal/hostile/guardian/charger/Move()
if(charging)
- PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src))
+ PoolOrNew(/obj/effect/overlay/temp/decoy/fading, list(loc,src))
. = ..()
/mob/living/simple_animal/hostile/guardian/charger/snapback()
diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm
index b49f25fc669..5dc6b9643bc 100644
--- a/code/modules/mob/living/simple_animal/hostile/bear.dm
+++ b/code/modules/mob/living/simple_animal/hostile/bear.dm
@@ -20,6 +20,7 @@
response_harm = "hits"
maxHealth = 60
health = 60
+ var/armored = FALSE
melee_damage_lower = 20
melee_damage_upper = 30
@@ -46,11 +47,56 @@
icon_state = "snowbear"
icon_living = "snowbear"
icon_dead = "snowbear_dead"
- desc = "It's a polar bear, in space, but not actually in space. "
+ desc = "It's a polar bear, in space, but not actually in space."
+
+/mob/living/simple_animal/hostile/bear/russian
+ name = "combat bear"
+ desc = "A ferocious brown bear decked out in armor plating, a red star with yellow outlining details the shoulder plating."
+ icon_state = "combatbear"
+ icon_living = "combatbear"
+ icon_dead = "combatbear_dead"
+ faction = list("russian")
+ butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1, /obj/item/bear_armor = 1)
+ melee_damage_lower = 25
+ melee_damage_upper = 35
+ armour_penetration = 20
+ health = 120
+ maxHealth = 120
+ armored = TRUE
/mob/living/simple_animal/hostile/bear/Process_Spacemove(movement_dir = 0)
return 1 //No drifting in space for space bears!
+/mob/living/simple_animal/hostile/bear/update_icons()
+ ..()
+ if(armored)
+ var/image/B = image(icon = 'icons/mob/animal.dmi', icon_state = "armor_bear")
+ if(B)
+ add_overlay(B)
+
+/obj/item/bear_armor
+ name = "pile of bear armor"
+ desc = "A scattered pile of various shaped armor pieces fitted for a bear, some duct tape, and a nail filer. Crude instructions \
+ are written on the back of one of the plates in russian. This seems like an awful idea."
+ icon = 'icons/obj/items.dmi'
+ icon_state = "bear_armor_upgrade"
+
+/obj/item/bear_armor/afterattack(atom/target, mob/user, proximity_flag)
+ if(istype(target, /mob/living/simple_animal/hostile/bear) && proximity_flag)
+ var/mob/living/simple_animal/hostile/bear/A = target
+ if(A.armored)
+ user << "[A] has already been armored up!"
+ return
+ A.armored = TRUE
+ A.maxHealth += 60
+ A.health += 60
+ A.armour_penetration += 20
+ A.melee_damage_lower += 5
+ A.melee_damage_upper += 5
+ A.update_icons()
+ user << "You strap the armor plating to [A] and sharpen their claws with the nail filer. This was a great idea."
+ qdel(src)
+
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index 3bd798886b1..013a77e81d1 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -74,6 +74,11 @@
AIStatus = AI_IDLE // otherwise we go idle
return 1
+/mob/living/simple_animal/hostile/attacked_by(obj/item/I, mob/living/user)
+ if(stat == CONSCIOUS && !target && AIStatus != AI_OFF && !client && user)
+ FindTarget(list(user), 1)
+ return ..()
+
/mob/living/simple_animal/hostile/bullet_act(obj/item/projectile/P)
if(stat == CONSCIOUS && !target && AIStatus != AI_OFF && !client)
if(P.firer && get_dist(src, P.firer) <= aggro_vision_range)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
index 8eb3ec0bf4e..c3a657616f8 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/bubblegum.dm
@@ -110,9 +110,9 @@ Difficulty: Hard
/mob/living/simple_animal/hostile/megafauna/bubblegum/Move()
if(!stat)
- playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1)
+ playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1, 2, 1)
if(charging)
- PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src))
+ PoolOrNew(/obj/effect/overlay/temp/decoy/fading, list(loc,src))
DestroySurroundings()
. = ..()
if(charging)
@@ -126,15 +126,21 @@ Difficulty: Hard
charge()
/mob/living/simple_animal/hostile/megafauna/bubblegum/proc/charge()
- var/turf/T = get_step_away(target, src)
+ var/turf/T = get_turf(target)
+ if(!T || T == loc)
+ return
+ PoolOrNew(/obj/effect/overlay/temp/dragon_swoop, T)
charging = 1
DestroySurroundings()
- PoolOrNew(/obj/effect/overlay/temp/dragon_swoop, T)
+ walk(src, 0)
+ setDir(get_dir(src, T))
+ var/obj/effect/overlay/temp/decoy/D = PoolOrNew(/obj/effect/overlay/temp/decoy, list(loc,src))
+ D.color = "#FF0000"
+ animate(D, alpha = 0, color = initial(D.color), transform = matrix()*2, time = 5)
sleep(5)
- walk(src,0)
- throw_at(T, 7, 1, src, 0)
+ throw_at(T, get_dist(src, T), 1, src, 0)
charging = 0
- Goto(target,move_to_delay,minimum_distance)
+ Goto(target, move_to_delay, minimum_distance)
/mob/living/simple_animal/hostile/megafauna/bubblegum/Bump(atom/A)
@@ -148,16 +154,15 @@ Difficulty: Hard
if(!charging)
return ..()
- else if(A)
- if(isliving(A))
- var/mob/living/L = A
- L.visible_message("[src] slams into [L]!", "[src] slams into you!")
- L.apply_damage(40, BRUTE)
- playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, 1)
- shake_camera(L, 4, 3)
- shake_camera(src, 2, 3)
- var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
- L.throw_at_fast(throwtarget)
+ else if(isliving(A))
+ var/mob/living/L = A
+ L.visible_message("[src] slams into [L]!", "[src] slams into you!")
+ L.apply_damage(40, BRUTE)
+ playsound(get_turf(L), 'sound/effects/meteorimpact.ogg', 100, 1)
+ shake_camera(L, 4, 3)
+ shake_camera(src, 2, 3)
+ var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src)))
+ L.throw_at_fast(throwtarget, 3)
charging = 0
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index 9e10ed76efe..a8f7b491bc9 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -46,7 +46,7 @@ Difficulty: Very Hard
del_on_death = 1
medal_type = MEDAL_PREFIX
score_type = COLOSSUS_SCORE
- loot = list(/obj/machinery/smartfridge/black_box)
+ loot = list(/obj/machinery/anomalous_crystal/random)
butcher_results = list(/obj/item/weapon/ore/diamond = 5, /obj/item/stack/sheet/sinew = 5, /obj/item/stack/sheet/animalhide/ashdrake = 10, /obj/item/stack/sheet/bone = 30)
deathmessage = "disintegrates, leaving a glowing core in its wake."
death_sound = 'sound/magic/demon_dies.ogg'
@@ -359,4 +359,389 @@ Difficulty: Very Hard
/obj/machinery/smartfridge/black_box/default_deconstruction_crowbar()
return
+///Anomolous Crystal///
+
+/obj/machinery/anomalous_crystal
+ name = "anomalous crystal"
+ desc = "A strange chunk of crystal, being in the presence of it fills you with equal parts excitement and dread."
+ icon = 'icons/obj/lavaland/artefacts.dmi'
+ icon_state = "anomaly_crystal"
+ luminosity = 8
+ burn_state = LAVA_PROOF
+ use_power = 0
+ density = 1
+ languages_spoken = ALL
+ languages_understood = ALL
+ flags = HEAR
+ var/activation_method = "touch"
+ var/activation_damage_type = null
+ var/last_use_timer = 0
+ var/cooldown_add = 30
+ var/list/affected_targets = list()
+ var/activation_sound = 'sound/effects/break_stone.ogg'
+
+/obj/machinery/anomalous_crystal/New()
+ activation_method = pick("touch","laser","bullet","energy","magic","mob_bump","heat","weapon","speech")
+ ..()
+
+/obj/machinery/anomalous_crystal/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans)
+ ..()
+ if(isliving(speaker))
+ ActivationReaction(speaker,"speech")
+
+/obj/machinery/anomalous_crystal/attack_hand(mob/user)
+ ..()
+ ActivationReaction(user,"touch")
+
+/obj/machinery/anomalous_crystal/attackby(obj/item/I, mob/user, params)
+ if(I.is_hot())
+ ActivationReaction(user,"heat")
+ else
+ ActivationReaction(user,"weapon")
+ ..()
+
+/obj/machinery/anomalous_crystal/bullet_act(obj/item/projectile/P, def_zone)
+ ..()
+ if(istype(P, /obj/item/projectile/magic))
+ ActivationReaction(P.firer, "magic", P.damage_type)
+ return
+ ActivationReaction(P.firer, P.flag, P.damage_type)
+
+/obj/machinery/anomalous_crystal/proc/ActivationReaction(mob/user, method, damtype)
+ if(world.time < last_use_timer)
+ return 0
+ if(activation_damage_type && activation_damage_type != damtype)
+ return 0
+ if(method != activation_method)
+ return 0
+ last_use_timer = (world.time + cooldown_add)
+ playsound(user, activation_sound, 100, 1)
+ return 1
+
+/obj/machinery/anomalous_crystal/Bumped(atom/AM as mob|obj)
+ ..()
+ if(ismob(AM))
+ ActivationReaction(AM,"mob_bump")
+
+/obj/machinery/anomalous_crystal/random/New()//Just a random crysal spawner for loot
+ var/random_crystal = pick(typesof(/obj/machinery/anomalous_crystal) - /obj/machinery/anomalous_crystal/random)
+ new random_crystal(loc)
+ qdel(src)
+
+/obj/machinery/anomalous_crystal/honk //Strips and equips you as a clown. I apologize for nothing
+ activation_method = "mob_bump"
+ activation_sound = 'sound/items/bikehorn.ogg'
+
+/obj/machinery/anomalous_crystal/honk/ActivationReaction(mob/user)
+ if(..() && ishuman(user) && !(user in affected_targets))
+ var/mob/living/carbon/human/H = user
+ for(var/obj/item/W in H)
+ H.unEquip(W)
+ var/datum/job/clown/C = new /datum/job/clown()
+ C.equip(H)
+ qdel(C)
+ affected_targets.Add(H)
+
+/obj/machinery/anomalous_crystal/honk/New()
+ ..()
+ activation_method = pick("mob_bump","speech")
+
+/obj/machinery/anomalous_crystal/theme_warp //Warps the area you're in to look like a new one
+ activation_method = "touch"
+ cooldown_add = 200
+ var/terrain_theme = "winter"
+ var/NewTerrainFloors
+ var/NewTerrainWalls
+ var/NewTerrainChairs
+ var/NewTerrainTables
+ var/list/NewFlora = list()
+ var/florachance = 8
+
+/obj/machinery/anomalous_crystal/theme_warp/New()
+ ..()
+ terrain_theme = pick("lavaland","winter","jungle","ayy lmao")
+ switch(terrain_theme)
+ if("lavaland")//Depressurizes the place... and free cult metal, I guess.
+ NewTerrainFloors = /turf/open/floor/grass/snow/basalt
+ NewTerrainWalls = /turf/closed/wall/mineral/cult
+ NewFlora = list(/mob/living/simple_animal/hostile/asteroid/goldgrub)
+ florachance = 1
+ if("winter") //Snow terrain is slow to move in and cold! Get the assistants to shovel your driveway.
+ NewTerrainFloors = /turf/open/floor/grass/snow
+ NewTerrainWalls = /turf/closed/wall/mineral/wood
+ NewTerrainChairs = /obj/structure/chair/wood/normal
+ NewTerrainTables = /obj/structure/table/glass
+ NewFlora = list(/obj/structure/flora/grass/green, /obj/structure/flora/grass/brown, /obj/structure/flora/grass/both)
+ if("jungle") //Beneficial due to actually having breathable air. Plus, monkeys.
+ NewTerrainFloors = /turf/open/floor/grass
+ NewTerrainWalls = /turf/closed/wall/mineral/sandstone
+ NewTerrainChairs = /obj/structure/chair/wood
+ NewTerrainTables = /obj/structure/table/wood
+ NewFlora = list(/obj/structure/flora/ausbushes/sparsegrass, /obj/structure/flora/ausbushes/fernybush, /obj/structure/flora/ausbushes/leafybush,
+ /obj/structure/flora/ausbushes/grassybush, /obj/structure/flora/ausbushes/sunnybush, /obj/structure/flora/tree/palm, /mob/living/carbon/monkey)
+ florachance = 20
+ if("ayy lmao") //Beneficial, turns stuff into alien alloy which is useful to cargo and research. Also repairs atmos.
+ NewTerrainFloors = /turf/open/floor/plating/abductor
+ NewTerrainWalls = /turf/closed/wall/mineral/abductor
+ NewTerrainChairs = /obj/structure/bed/abductor //ayys apparently don't have chairs. An entire species of people who only recline.
+ NewTerrainTables = /obj/structure/table/abductor
+
+/obj/machinery/anomalous_crystal/theme_warp/ActivationReaction(mob/user, method)
+ if(..())
+ var/area/A = get_area(src)
+ if(!A.outdoors && !(A in affected_targets))
+ for(var/atom/Stuff in A)
+ if(isturf(Stuff))
+ var/turf/T = Stuff
+ if((istype(T, /turf/open/space) || istype(T, /turf/open/floor)) && NewTerrainFloors)
+ var/turf/open/O = T.ChangeTurf(NewTerrainFloors)
+ if(O.air)
+ var/datum/gas_mixture/G = O.air
+ G.copy_from_turf(O)
+ if(prob(florachance) && NewFlora.len && !is_blocked_turf(O))
+ var/atom/Picked = pick(NewFlora)
+ new Picked(O)
+ continue
+ if(istype(T, /turf/closed/wall) && NewTerrainWalls)
+ T.ChangeTurf(NewTerrainWalls)
+ continue
+ if(istype(Stuff, /obj/structure/chair) && NewTerrainChairs)
+ var/obj/structure/chair/Original = Stuff
+ var/obj/structure/chair/C = new NewTerrainChairs(Original.loc)
+ C.setDir(Original.dir)
+ qdel(Stuff)
+ continue
+ if(istype(Stuff, /obj/structure/table) && NewTerrainTables)
+ new NewTerrainTables(Stuff.loc)
+ continue
+ affected_targets += A
+
+/obj/machinery/anomalous_crystal/emitter //Generates a projectile when interacted with
+ activation_method = "touch"
+ cooldown_add = 50
+ var/generated_projectile = /obj/item/projectile/beam/emitter
+
+/obj/machinery/anomalous_crystal/emitter/New()
+ ..()
+ generated_projectile = pick(/obj/item/projectile/beam/emitter,/obj/item/projectile/magic/fireball/infernal,/obj/item/projectile/magic/spellblade,
+ /obj/item/projectile/energy/net, /obj/item/projectile/bullet/meteorshot, /obj/item/projectile/beam/xray)
+
+/obj/machinery/anomalous_crystal/emitter/ActivationReaction(mob/user, method)
+ if(..())
+ var/obj/item/projectile/P = new generated_projectile(get_turf(src))
+ P.setDir(dir)
+ switch(dir)
+ if(NORTH)
+ P.yo = 20
+ P.xo = 0
+ if(EAST)
+ P.yo = 0
+ P.xo = 20
+ if(WEST)
+ P.yo = 0
+ P.xo = -20
+ else
+ P.yo = -20
+ P.xo = 0
+ P.fire()
+
+/obj/machinery/anomalous_crystal/dark_reprise //Revives anyone nearby, but turns them into shadowpeople. Cannot revive shadowpeople, so this is a one time thing.
+ activation_method = "touch"
+
+/obj/machinery/anomalous_crystal/dark_reprise/ActivationReaction(mob/user, method)
+ if(..())
+ for(var/i in range(1, src))
+ if(ishuman(i))
+ var/mob/living/carbon/human/H = i
+ if(H.stat == DEAD && !isshadowperson(H))
+ H.set_species(/datum/species/shadow, 1)
+ H.revive(1,0)
+
+/obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans
+ activation_method = "touch"
+ var/ready_to_deploy = 0
+
+/obj/machinery/anomalous_crystal/helpers/ActivationReaction(mob/user, method)
+ if(..() && !ready_to_deploy)
+ ready_to_deploy = 1
+ notify_ghosts("An anomalous crystal has been activated in [get_area(src)]!", enter_link = "(Click to enter)", source = src, action = NOTIFY_ATTACK)
+
+/obj/machinery/anomalous_crystal/helpers/attack_ghost(mob/dead/observer/user)
+ ..()
+ if(ready_to_deploy)
+ var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No")
+ if(!be_helper == "No")
+ return
+ var/mob/living/simple_animal/hostile/lightgeist/W = new /mob/living/simple_animal/hostile/lightgeist(get_turf(loc))
+ W.key = user.key
+
+/mob/living/simple_animal/hostile/lightgeist
+ name = "lightgeist"
+ desc = "This small floating creature is a completely unknown form of life... being near it fills you with a sense of tranquility."
+ icon_state = "lightgeist"
+ icon_living = "lightgeist"
+ icon_dead = "butterfly_dead"
+ turns_per_move = 1
+ response_help = "waves away"
+ response_disarm = "brushes aside"
+ response_harm = "disrupts"
+ speak_emote = list("oscillates")
+ maxHealth = 2
+ health = 2
+ harm_intent_damage = 1
+ friendly = "mends"
+ density = 0
+ flying = 1
+ pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
+ ventcrawler = 2
+ mob_size = MOB_SIZE_TINY
+ gold_core_spawnable = 0
+ verb_say = "warps"
+ verb_ask = "floats inquisitively"
+ verb_exclaim = "zaps"
+ verb_yell = "bangs"
+ damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
+ luminosity = 4
+ faction = list("neutral")
+ languages_spoken = 0
+ languages_understood = ALL
+ del_on_death = 1
+ unsuitable_atmos_damage = 0
+ flying = 1
+ minbodytemp = 0
+ maxbodytemp = 1500
+ var/heal_power = 5
+
+/mob/living/simple_animal/hostile/lightgeist/New()
+ ..()
+ verbs -= /mob/living/verb/pulled
+ verbs -= /mob/verb/me_verb
+
+/mob/living/simple_animal/hostile/lightgeist/AttackingTarget()
+ ..()
+ if(isliving(target) && target != src)
+ var/mob/living/L = target
+ if(L.stat < DEAD)
+ L.heal_overall_damage(heal_power, heal_power, 1)
+ PoolOrNew(/obj/effect/overlay/temp/heal, list(get_turf(target), "#80F5FF"))
+
+/mob/living/simple_animal/hostile/lightgeist/Life()
+ if(!ckey)
+ death()
+ ..()
+
+
+/obj/machinery/anomalous_crystal/refresher //Deletes and recreates a copy of the item, "refreshing" it. Only works once per item.
+ activation_method = "touch"
+ cooldown_add = 50
+
+/obj/machinery/anomalous_crystal/refresher/ActivationReaction(mob/user, method)
+ if(..())
+ var/list/L
+ var/turf/T = get_step(src, dir)
+ for(var/i in T)
+ if(istype(i, /obj/item) && !istype(i, /obj/item/weapon/storage) && !(i in affected_targets) && !istype(i, /obj/item/weapon/implant) && !istype(i, /obj/item/weapon/implanter) && !istype(i, /obj/item/weapon/disk/nuclear))
+ var/obj/item/W = i
+ if(!W.admin_spawned)
+ L += W
+ var/obj/item/CHOSEN = pick(L)
+ if(CHOSEN)
+ var/A = new CHOSEN.type(T)
+ affected_targets += A
+ qdel(CHOSEN)
+
+/obj/machinery/anomalous_crystal/possessor //Allows you to bodyjack small animals, then exit them at your leisure, but you can only do this once per activation. Because they blow up. Also, if the bodyjacked animal dies, SO DO YOU.
+ activation_method = "touch"
+
+/obj/machinery/anomalous_crystal/possessor/ActivationReaction(mob/user, method)
+ if(..())
+ if(ishuman(user))
+ var/mobcheck = 0
+ for(var/mob/living/simple_animal/A in range(1, src))
+ if(A.melee_damage_upper > 5 || A.mob_size >= MOB_SIZE_LARGE || A.ckey || A.stat)
+ break
+ var/obj/structure/closet/stasis/S = new /obj/structure/closet/stasis(A)
+ user.forceMove(S)
+ mobcheck = 1
+ break
+ if(!mobcheck)
+ new /mob/living/simple_animal/cockroach(loc) //Just in case there aren't any animals on the station, this will leave you with a terrible option to possess if you feel like it
+
+/obj/structure/closet/stasis
+ name = "quantum entanglement stasis warp field"
+ desc = "You can hardly comprehend this thing... which is why you can't see it."
+ icon_state = null //This shouldn't even be visible, so if it DOES show up, at least nobody will notice
+ density = 1
+ anchored = 1
+ health = 0
+ var/mob/living/simple_animal/holder_animal
+
+/obj/structure/closet/stasis/process()
+ if(!isanimal(loc))
+ dump_contents(1)
+ return
+ if(holder_animal)
+ if(holder_animal.stat == DEAD)
+ dump_contents(1)
+ holder_animal.gib()
+
+/obj/structure/closet/stasis/New()
+ ..()
+ if(isanimal(loc))
+ holder_animal = loc
+ START_PROCESSING(SSobj, src)
+
+/obj/structure/closet/stasis/Entered(atom/A)
+ if(isliving(A) && holder_animal)
+ var/mob/living/L = A
+ L.notransform = 1
+ L.disabilities |= MUTE
+ L.status_flags |= GODMODE
+ L.mind.transfer_to(holder_animal)
+ var/obj/effect/proc_holder/spell/targeted/exit_possession/P = new /obj/effect/proc_holder/spell/targeted/exit_possession
+ holder_animal.mind.AddSpell(P)
+ holder_animal.verbs -= /mob/living/verb/pulled
+
+/obj/structure/closet/stasis/dump_contents(var/kill = 0)
+ STOP_PROCESSING(SSobj, src)
+ for(var/mob/living/L in src)
+ L.disabilities &= ~MUTE
+ L.status_flags &= ~GODMODE
+ L.notransform = 0
+ holder_animal.mind.transfer_to(L)
+ L.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession)
+ if(kill || !isanimal(loc))
+ L.death(0)
+ ..()
+
+/obj/structure/closet/stasis/emp_act()
+ return
+
+/obj/effect/proc_holder/spell/targeted/exit_possession
+ name = "Exit Possession"
+ desc = "Exits the body you are possessing"
+ charge_max = 60
+ clothes_req = 0
+ invocation_type = "none"
+ max_targets = 1
+ range = -1
+ include_user = 1
+ selection_type = "view"
+ action_icon_state = "exit_possession"
+ sound = null
+
+/obj/effect/proc_holder/spell/targeted/exit_possession/cast(list/targets, mob/user = usr)
+ if(!istype(user.loc, /turf/open/floor))
+ return
+ var/datum/mind/target_mind = user.mind
+ for(var/i in user)
+ if(istype(i, /obj/structure/closet/stasis))
+ var/obj/structure/closet/stasis/S = i
+ S.dump_contents()
+ qdel(S)
+ break
+ user.gib()
+ target_mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/exit_possession)
+
+
#undef MEDAL_PREFIX
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
index 0da855f44da..67b784fff9a 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm
@@ -191,7 +191,7 @@ Difficulty: Medium
if(stat || swooping)
return
swoop_cooldown = world.time + 200
- var/swoop_target
+ var/atom/swoop_target
if(manual_target)
swoop_target = manual_target
else
@@ -212,7 +212,7 @@ Difficulty: Medium
fire_rain()
icon_state = "dragon"
- if(swoop_target && !qdeleted(swoop_target))
+ if(swoop_target && !qdeleted(swoop_target) && swoop_target.z == src.z)
tturf = get_turf(swoop_target)
else
tturf = get_turf(src)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
new file mode 100644
index 00000000000..ee7e70bdcf2
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/hierophant.dm
@@ -0,0 +1,584 @@
+#define MEDAL_PREFIX "Hierophant"
+/*
+
+The Hierophant
+
+The Hierophant spawns in its arena, an area designed to make it harder to fight than it would otherwise be.
+
+The text this boss speaks is ROT4, use ROT22 to decode
+
+The Hierophant's attacks are as follows, and INTENSIFY at a random chance based on Hierophant's health;
+- Creates a cardinal or diagonal blast(Cross Blast) under its target, exploding after a short time.
+ INTENSITY EFFECT: Creates one of the cross blast types under itself instead of under the target.
+ INTENSITY EFFECT: The created Cross Blast fires in all directions if below half health.
+- If no chasers exist, creates a chaser that will seek its target, leaving a trail of blasts.
+ INTENSITY EFFECT: Creates a second, slower chaser.
+- Creates an expanding AoE burst.
+- INTENSE ATTACKS:
+ If target is at least 2 tiles away; Blinks to the target after a very brief delay, damaging everything near the start and end points.
+ As above, but does so multiple times if below half health.
+ Rapidly creates Cross Blasts under a target.
+ If chasers are off cooldown, creates four high-speed chasers.
+- IF TARGET WAS STRUCK IN MELEE: Creates a 3x3 square of blasts under the target.
+
+Cross Blasts and the AoE burst gain additional range as the Hierophant loses health, while Chasers gain additional speed.
+
+When The Hierophant dies, it leaves behind its staff, which, while much weaker than when wielded by The Hierophant itself, is still quite effective.
+- The staff can place a teleport rune, allowing the user to teleport themself and their allies to the rune.
+
+Difficulty: Hard
+
+*/
+
+/mob/living/simple_animal/hostile/megafauna/hierophant
+ name = "Hierophant"
+ desc = "Stolen from Hyper Light Drifter."
+ health = 2500
+ maxHealth = 2500
+ attacktext = "clubs"
+ //attack_sound = 'sound/weapons/sonic_jackhammer.ogg'
+ attack_sound = "swing_hit"
+ icon_state = "hierophant"
+ icon_living = "hierophant"
+ friendly = "stares down"
+ icon = 'icons/mob/lavaland/hierophant.dmi'
+ faction = list("boss") //asteroid mobs? get that shit out of my beautiful square house
+ speak_emote = list("preaches")
+ armour_penetration = 50
+ melee_damage_lower = 10
+ melee_damage_upper = 10
+ speed = 1
+ move_to_delay = 10
+ ranged = 1
+ pixel_x = -16
+ ranged_cooldown_time = 40
+ aggro_vision_range = 23
+ loot = list(/obj/item/weapon/hierophant_staff)
+ wander = FALSE
+ var/burst_range = 3 //range on burst aoe
+ var/beam_range = 5 //range on cross blast beams
+ var/chaser_speed = 3 //how fast chasers are currently
+ var/chaser_cooldown = 101 //base cooldown/cooldown var between spawning chasers
+ var/major_attack_cooldown = 60 //base cooldown for major attacks
+ var/blinking = FALSE //if we're doing something that requires us to stand still and not attack
+ var/obj/effect/hierophant/spawned_rune //the rune we teleport back to
+ var/timeout_time = 15 //after this many Life() ticks with no target, we return to our rune
+ var/did_reset = TRUE //if we timed out, returned to our rune, and healed some
+ //var/list/kill_phrases = list("Wsyvgi sj irivkc xettih. Vitemvmrk...", "Irivkc wsyvgi jsyrh. Vitemvmrk...", "Jyip jsyrh. Egxmzexmrk vitemv gcgpiw...")
+ //var/list/target_phrases = list("Xevkix psgexih.", "Iriqc jsyrh.", "Eguymvih xevkix.")
+ medal_type = MEDAL_PREFIX
+ score_type = BIRD_SCORE
+ del_on_death = TRUE
+ death_sound = 'sound/magic/Repulse.ogg'
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/New()
+ ..()
+ internal = new/obj/item/device/gps/internal/hierophant(src)
+ spawned_rune = new(loc)
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/Life()
+ . = ..()
+ if(. && spawned_rune && !client)
+ if(target || loc == spawned_rune.loc)
+ timeout_time = initial(timeout_time)
+ else
+ timeout_time--
+ if(timeout_time <= 0 && !did_reset)
+ did_reset = TRUE
+ //visible_message("\"Vixyvrmrk xs fewi...\"")
+ blink(spawned_rune)
+ adjustHealth(max((health - maxHealth) * 0.5, 25)) //heal for 50% of our missing health
+ wander = FALSE
+ /*if(health > maxHealth * 0.9)
+ visible_message("\"Vitemvw gsqtpixi. Stivexmrk ex qebmqyq ijjmgmirgc.\"")
+ else
+ visible_message("\"Vitemvw gsqtpixi. Stivexmsrep ijjmgmirgc gsqtvsqmwih.\"")*/
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/death()
+ if(health > 0 || stat == DEAD)
+ return
+ else
+ stat = DEAD
+ blinking = TRUE //we do a fancy animation, release a huge burst(), and leave our staff.
+ animate(src, alpha = 0, color = "660099", time = 20, easing = EASE_OUT)
+ burst_range = 10
+ //visible_message("\"Mrmxmexmrk wipj-hiwxvygx wiuyirgi...\"")
+ visible_message("[src] disappears in a massive burst of magic, leaving only its staff.")
+ burst(get_turf(src))
+ ..()
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/Destroy()
+ qdel(spawned_rune)
+ . = ..()
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/devour(mob/living/L)
+ for(var/obj/item/W in L)
+ if(!L.unEquip(W))
+ qdel(W)
+ /*visible_message(
+ "\"[pick(kill_phrases)]\"\n[src] annihilates [L]!",
+ "You annihilate [L], restoring your health!")*/
+ visible_message(
+ "\"Caw.\"\n[src] annihilates [L]!",
+ "You annihilate [L], restoring your health!")
+ adjustHealth(-L.maxHealth*0.5)
+ L.dust()
+
+/*/mob/living/simple_animal/hostile/megafauna/hierophant/GiveTarget(new_target)
+ var/targets_the_same = (new_target == target)
+ . = ..()
+ if(. && target && !targets_the_same)
+ visible_message("\"[pick(target_phrases)]\"")*/
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/adjustHealth(amount)
+ . = ..()
+ if(src && amount > 0 && !blinking)
+ wander = TRUE
+ did_reset = FALSE
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/AttackingTarget()
+ if(!blinking)
+ if(target && isliving(target))
+ addtimer(src, "melee_blast", 0, FALSE, get_turf(target)) //melee attacks on living mobs produce a 3x3 blast
+ ..()
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/DestroySurroundings()
+ if(!blinking)
+ ..()
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/Move()
+ if(!blinking)
+ /*if(!stat)
+ playsound(loc, 'sound/mecha/mechmove04.ogg', 150, 1, -4)*/
+ ..()
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/Goto(target, delay, minimum_distance)
+ wander = TRUE
+ if(!blinking)
+ ..()
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/calculate_rage() //how angry we are overall
+ did_reset = FALSE //oh hey we're doing SOMETHING, clearly we might need to heal if we recall
+ anger_modifier = Clamp(((maxHealth - health) / 42),0,50)
+ burst_range = initial(burst_range) + round(anger_modifier * 0.08)
+ beam_range = initial(beam_range) + round(anger_modifier * 0.12)
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/OpenFire()
+ calculate_rage()
+ var/target_is_slow = FALSE
+ if(isliving(target))
+ var/mob/living/L = target
+ if(!blinking && L.stat == DEAD && get_dist(src, L) > 2)
+ blink(L)
+ return
+ if(L.movement_delay() > 1.5)
+ target_is_slow = TRUE
+ chaser_speed = max(1, (3 - anger_modifier * 0.04) + target_is_slow * 0.5)
+ if(blinking)
+ return
+ ranged_cooldown = world.time + max(5, ranged_cooldown_time - anger_modifier * 0.75) //scale cooldown lower with high anger.
+
+ if(prob(anger_modifier * 0.75)) //major ranged attack
+ var/list/possibilities = list()
+ var/cross_counter = 1 + round(anger_modifier * 0.12)
+ if(cross_counter > 1)
+ possibilities += "cross_blast_spam"
+ if(get_dist(src, target) > 2)
+ possibilities += "blink_spam"
+ if(chaser_cooldown < world.time)
+ if(prob(anger_modifier * 2))
+ possibilities = list("chaser_swarm")
+ else
+ possibilities += "chaser_swarm"
+ if(possibilities.len)
+ ranged_cooldown = world.time + max(5, major_attack_cooldown - anger_modifier * 0.75) //we didn't cancel out of an attack, use the higher cooldown
+ var/blink_counter = 1 + round(anger_modifier * 0.08)
+ switch(pick(possibilities))
+ if("blink_spam") //blink either once or multiple times.
+ if(health < maxHealth * 0.5 && !target_is_slow && blink_counter > 1)
+ //visible_message("\"Mx ampp rsx iwgeti.\"")
+ animate(src, color = "#660099", time = 6)
+ while(health && target && blink_counter)
+ if(loc == target.loc || loc == target) //we're on the same tile as them after about a second we can stop now
+ break
+ blink_counter--
+ blinking = FALSE
+ blink(target)
+ blinking = TRUE
+ sleep(5)
+ animate(src, color = initial(color), time = 8)
+ sleep(8)
+ blinking = FALSE
+ else
+ blink(target)
+ if("cross_blast_spam") //fire a lot of cross blasts at a target.
+ //visible_message("\"Piezi mx rsalivi xs vyr.\"")
+ blinking = TRUE
+ animate(src, color = "#660099", time = 6)
+ while(health && target && cross_counter)
+ cross_counter--
+ var/delay = 6
+ if(prob(60))
+ addtimer(src, "cardinal_blasts", 0, FALSE, target)
+ else
+ addtimer(src, "diagonal_blasts", 0, FALSE, target)
+ delay = 5 //this one isn't so mean, so do the next one faster(if there is one)
+ sleep(delay)
+ animate(src, color = initial(color), time = 8)
+ sleep(8)
+ blinking = FALSE
+ if("chaser_swarm") //fire four fucking chasers at a target and their friends.
+ //visible_message("\"Mx gerrsx lmhi.\"")
+ blinking = TRUE
+ animate(src, color = "#660099", time = 10)
+ var/list/targets = ListTargets()
+ var/list/cardinal_copy = cardinal.Copy()
+ while(health && targets.len && cardinal_copy.len)
+ var/mob/living/pickedtarget = pick(targets)
+ if(targets.len > 4)
+ pickedtarget = pick_n_take(targets)
+ if(pickedtarget.stat == DEAD)
+ pickedtarget = target
+ var/obj/effect/overlay/temp/hierophant/chaser/C = PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(loc, src, pickedtarget, chaser_speed, FALSE))
+ C.moving = 3
+ C.moving_dir = pick_n_take(cardinal_copy)
+ sleep(10)
+ chaser_cooldown = world.time + initial(chaser_cooldown)
+ animate(src, color = initial(color), time = 8)
+ sleep(8)
+ blinking = FALSE
+ return
+
+ if(prob(10 + (anger_modifier * 0.5)) && get_dist(src, target) > 2)
+ blink(target)
+
+ else if(prob(70 - anger_modifier)) //a cross blast of some type
+ if(prob(anger_modifier)) //at us?
+ if(prob(anger_modifier * 2) && health < maxHealth * 0.5) //we're super angry do it at all dirs
+ addtimer(src, "alldir_blasts", 0, FALSE, src)
+ else if(prob(60))
+ addtimer(src, "cardinal_blasts", 0, FALSE, src)
+ else
+ addtimer(src, "diagonal_blasts", 0, FALSE, src)
+ else //at them?
+ if(prob(anger_modifier * 2) && health < maxHealth * 0.5 && !target_is_slow) //we're super angry do it at all dirs
+ addtimer(src, "alldir_blasts", 0, FALSE, target)
+ else if(prob(60))
+ addtimer(src, "cardinal_blasts", 0, FALSE, target)
+ else
+ addtimer(src, "diagonal_blasts", 0, FALSE, target)
+ else if(chaser_cooldown < world.time) //if chasers are off cooldown, fire some!
+ var/obj/effect/overlay/temp/hierophant/chaser/C = PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(loc, src, target, chaser_speed, FALSE))
+ chaser_cooldown = world.time + initial(chaser_cooldown)
+ if((prob(anger_modifier) || target.Adjacent(src)) && target != src)
+ var/obj/effect/overlay/temp/hierophant/chaser/OC = PoolOrNew(/obj/effect/overlay/temp/hierophant/chaser, list(loc, src, target, max(1.5, 5 - anger_modifier * 0.07), FALSE))
+ OC.moving = 4
+ OC.moving_dir = pick(cardinal - C.moving_dir)
+ else //just release a burst of power
+ addtimer(src, "burst", 0, FALSE, get_turf(src))
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/diagonal_blasts(mob/victim) //fire diagonal cross blasts with a delay
+ var/turf/T = get_turf(victim)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/diagonal, list(T, src))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/effects/bin_close.ogg', 200, 1)
+ sleep(2)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
+ for(var/d in diagonals)
+ addtimer(src, "blast_wall", 0, FALSE, T, d)
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/cardinal_blasts(mob/victim) //fire cardinal cross blasts with a delay
+ var/turf/T = get_turf(victim)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/cardinal, list(T, src))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/effects/bin_close.ogg', 200, 1)
+ sleep(2)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
+ for(var/d in cardinal)
+ addtimer(src, "blast_wall", 0, FALSE, T, d)
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/alldir_blasts(mob/victim) //fire alldir cross blasts with a delay
+ var/turf/T = get_turf(victim)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/effects/bin_close.ogg', 200, 1)
+ sleep(2)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
+ for(var/d in alldirs)
+ addtimer(src, "blast_wall", 0, FALSE, T, d)
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blast_wall(turf/T, dir) //make a wall of blasts beam_range tiles long
+ var/range = beam_range
+ var/turf/previousturf = T
+ var/turf/J = get_step(previousturf, dir)
+ for(var/i in 1 to range)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(J, src, FALSE))
+ previousturf = J
+ J = get_step(previousturf, dir)
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/blink(mob/victim) //blink to a target
+ if(blinking || !victim)
+ return
+ var/turf/T = get_turf(victim)
+ var/turf/source = get_turf(src)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(source, src))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/magic/Wand_Teleport.ogg', 200, 1)
+ playsound(source,'sound/magic/blink.ogg', 200, 1)
+ //playsound(source,'sound/machines/AirlockOpen.ogg', 200, 1)
+ blinking = TRUE
+ sleep(2) //short delay before we start...
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(T, src))
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(source, src))
+ for(var/t in RANGE_TURFS(1, T))
+ var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, src, FALSE))
+ B.damage = 30
+ for(var/t in RANGE_TURFS(1, source))
+ var/obj/effect/overlay/temp/hierophant/blast/B = PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, src, FALSE))
+ B.damage = 30
+ animate(src, alpha = 0, time = 2, easing = EASE_OUT) //fade out
+ sleep(1)
+ visible_message("[src] fades out!")
+ density = FALSE
+ sleep(2)
+ forceMove(T)
+ sleep(1)
+ animate(src, alpha = 255, time = 2, easing = EASE_IN) //fade IN
+ sleep(1)
+ density = TRUE
+ visible_message("[src] fades in!")
+ sleep(1) //at this point the blasts we made detonate
+ blinking = FALSE
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/melee_blast(mob/victim) //make a 3x3 blast around a target
+ if(!victim)
+ return
+ var/turf/T = get_turf(victim)
+ if(!T)
+ return
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph, list(T, src))
+ playsound(T,'sound/magic/blink.ogg', 200, 1)
+ //playsound(T,'sound/effects/bin_close.ogg', 200, 1)
+ sleep(2)
+ for(var/t in RANGE_TURFS(1, T))
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(t, src, FALSE))
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/proc/burst(turf/original) //release a wave of blasts
+ playsound(original,'sound/magic/blink.ogg', 200, 1)
+ //playsound(original,'sound/machines/AirlockOpen.ogg', 200, 1)
+ var/last_dist = 0
+ for(var/t in spiral_range_turfs(burst_range, original))
+ var/turf/T = t
+ if(!T)
+ continue
+ var/dist = get_dist(original, T)
+ if(dist > last_dist)
+ last_dist = dist
+ sleep(1 + (burst_range - last_dist) * 0.5) //gets faster as it gets further out
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(T, src, FALSE))
+
+/mob/living/simple_animal/hostile/megafauna/hierophant/AltClickOn(atom/A) //player control handler(don't give this to a player holy fuck)
+ if(!istype(A) || get_dist(A, src) <= 2)
+ return
+ blink(A)
+
+//Hierophant overlays
+/obj/effect/overlay/temp/hierophant
+ layer = BELOW_MOB_LAYER
+ var/mob/living/caster //who made this, anyway
+
+/obj/effect/overlay/temp/hierophant/New(loc, new_caster)
+ ..()
+ if(new_caster)
+ caster = new_caster
+
+/obj/effect/overlay/temp/hierophant/chaser //a hierophant's chaser. follows target around, moving and producing a blast every speed deciseconds.
+ duration = 98
+ var/mob/living/target //what it's following
+ var/moving_dir //what dir it's moving in
+ var/previous_moving_dir //what dir it was moving in before that
+ var/more_previouser_moving_dir //what dir it was moving in before THAT
+ var/moving = 0 //how many steps to move before recalculating
+ var/standard_moving_before_recalc = 4 //how many times we step before recalculating normally
+ var/tiles_per_step = 1 //how many tiles we move each step
+ var/speed = 3 //how many deciseconds between each step
+ var/currently_seeking = FALSE
+ var/friendly_fire_check = FALSE //if blasts produced apply friendly fire
+
+/obj/effect/overlay/temp/hierophant/chaser/New(loc, new_caster, new_target, new_speed, is_friendly_fire)
+ ..()
+ target = new_target
+ friendly_fire_check = is_friendly_fire
+ if(new_speed)
+ speed = new_speed
+ addtimer(src, "seek_target", 1)
+
+/obj/effect/overlay/temp/hierophant/chaser/proc/get_target_dir()
+ . = get_cardinal_dir(src, target)
+ if((. != previous_moving_dir && . == more_previouser_moving_dir) || . == 0) //we're alternating, recalculate
+ var/list/cardinal_copy = cardinal.Copy()
+ cardinal_copy -= more_previouser_moving_dir
+ . = pick(cardinal_copy)
+
+/obj/effect/overlay/temp/hierophant/chaser/proc/seek_target()
+ if(!currently_seeking)
+ currently_seeking = TRUE
+ while(target && src && !qdeleted(src) && currently_seeking && x && y && target.x && target.y) //can this target actually be sook out
+ if(!moving) //we're out of tiles to move, find more and where the target is!
+ more_previouser_moving_dir = previous_moving_dir
+ previous_moving_dir = moving_dir
+ moving_dir = get_target_dir()
+ var/standard_target_dir = get_cardinal_dir(src, target)
+ if((standard_target_dir != previous_moving_dir && standard_target_dir == more_previouser_moving_dir) || standard_target_dir == 0)
+ moving = 1 //we would be repeating, only move a tile before checking
+ else
+ moving = standard_moving_before_recalc
+ if(moving) //move in the dir we're moving in right now
+ var/turf/T = get_turf(src)
+ for(var/i in 1 to tiles_per_step)
+ var/maybe_new_turf = get_step(T, moving_dir)
+ if(maybe_new_turf)
+ T = maybe_new_turf
+ else
+ break
+ forceMove(T)
+ make_blast() //make a blast, too
+ moving--
+ sleep(speed)
+
+/obj/effect/overlay/temp/hierophant/chaser/proc/make_blast()
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/blast, list(loc, caster, friendly_fire_check))
+
+/obj/effect/overlay/temp/hierophant/telegraph
+ icon = 'icons/effects/96x96.dmi'
+ icon_state = "hierophant_telegraph"
+ pixel_x = -32
+ pixel_y = -32
+ duration = 3
+
+/obj/effect/overlay/temp/hierophant/telegraph/diagonal
+ icon_state = "hierophant_telegraph_diagonal"
+
+/obj/effect/overlay/temp/hierophant/telegraph/cardinal
+ icon_state = "hierophant_telegraph_cardinal"
+
+/obj/effect/overlay/temp/hierophant/telegraph/teleport
+ icon_state = "hierophant_telegraph_teleport"
+ duration = 9
+
+/obj/effect/overlay/temp/hierophant/blast
+ icon_state = "hierophant_blast"
+ name = "vortex blast"
+ luminosity = 1
+ desc = "Get out of the way!"
+ duration = 9
+ var/damage = 10 //how much damage do we do?
+ var/list/hit_things = list() //we hit these already, ignore them
+ var/friendly_fire_check = FALSE
+ var/bursting = FALSE //if we're bursting and need to hit anyone crossing us
+
+/obj/effect/overlay/temp/hierophant/blast/New(loc, new_caster, friendly_fire)
+ ..()
+ friendly_fire_check = friendly_fire
+ if(new_caster)
+ hit_things += new_caster
+ if(istype(loc, /turf/closed/mineral)) //drill mineral turfs
+ var/turf/closed/mineral/M = loc
+ M.gets_drilled(caster)
+ addtimer(src, "blast", 0)
+
+/obj/effect/overlay/temp/hierophant/blast/proc/blast()
+ var/turf/T = get_turf(src)
+ if(!T)
+ return
+ playsound(T,'sound/magic/Blind.ogg', 125, 1, -5) //make a sound
+ sleep(6) //wait a little
+ bursting = TRUE
+ do_damage(T) //do damage and mark us as bursting
+ sleep(1.3) //slightly forgiving; the burst animation is 1.5 deciseconds
+ bursting = FALSE //we no longer damage crossers
+
+/obj/effect/overlay/temp/hierophant/blast/Crossed(atom/movable/AM)
+ ..()
+ if(bursting)
+ do_damage(get_turf(src))
+
+/obj/effect/overlay/temp/hierophant/blast/proc/do_damage(turf/T)
+ for(var/mob/living/L in T.contents - hit_things) //find and damage mobs...
+ hit_things += L
+ if((friendly_fire_check && caster && caster.faction_check(L)) || L.stat == DEAD)
+ continue
+ if(L.client)
+ flash_color(L.client, "#660099", 1)
+ playsound(L,'sound/weapons/sear.ogg', 50, 1, -4)
+ L << "You're struck by a [name]!"
+ var/limb_to_hit = L.get_bodypart(pick("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg"))
+ var/armor = L.run_armor_check(limb_to_hit, "melee", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 50, "Your armor was penetrated by [src]!")
+ L.apply_damage(damage, BURN, limb_to_hit, armor)
+ if(ismegafauna(L) || istype(L, /mob/living/simple_animal/hostile/asteroid))
+ L.adjustBruteLoss(damage)
+ add_logs(caster, L, "struck with a [name]")
+ for(var/obj/mecha/M in T.contents - hit_things) //and mechs.
+ hit_things += M
+ if(M.occupant)
+ if(friendly_fire_check && caster && caster.faction_check(M.occupant))
+ continue
+ M.occupant << "Your [M.name] is struck by a [name]!"
+ playsound(M,'sound/weapons/sear.ogg', 50, 1, -4)
+ M.take_damage(damage, "fire", 0)
+
+/obj/effect/hierophant
+ name = "hierophant rune"
+ desc = "A powerful magic mark allowing whomever attunes themself to it to return to it at will."
+ icon = 'icons/obj/rune.dmi'
+ icon_state = "hierophant"
+ layer = LOW_OBJ_LAYER
+ anchored = TRUE
+ color = "#CC00FF"
+
+/obj/effect/hierophant/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/weapon/hierophant_staff))
+ var/obj/item/weapon/hierophant_staff/H = I
+ if(H.rune == src)
+ user << "You start removing your hierophant rune..."
+ H.timer = world.time + 51
+ if(do_after(user, 50, target = src))
+ playsound(src,'sound/magic/Blind.ogg', 200, 1, -4)
+ PoolOrNew(/obj/effect/overlay/temp/hierophant/telegraph/teleport, list(get_turf(src), user))
+ user << "You touch the rune with the staff, dispelling it!"
+ H.rune = null
+ user.update_action_buttons_icon()
+ qdel(src)
+ else
+ H.timer = world.time
+ else
+ user << "You touch the rune with the staff, but nothing happens."
+
+ else
+ ..()
+
+/obj/item/device/gps/internal/hierophant
+ icon_state = null
+ gpstag = "Zealous Signal"
+ desc = "Heed its words."
+ invisibility = 100
+
+/turf/open/indestructible/hierophant
+ icon_state = "hierophant1"
+ initial_gas_mix = "o2=14;n2=23;TEMP=300"
+ desc = "A floor with a square pattern. It's faintly cool to the touch."
+
+/turf/open/indestructible/hierophant/New()
+ ..()
+ if(prob(50))
+ icon_state = "hierophant2"
+
+/turf/closed/indestructible/riveted/hierophant
+ name = "wall"
+ desc = "A wall made out of smooth, cold stone."
+ icon = 'icons/turf/walls/hierophant_wall.dmi'
+ icon_state = "hierophant"
+ smooth = SMOOTH_TRUE
+
+#undef MEDAL_PREFIX
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
index b81f0a77789..fa7e0330f24 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
@@ -110,6 +110,8 @@ Difficulty: Medium
L.update_transform()
update_transform()
+ L.faction = faction.Copy()
+
L.GiveTarget(target)
visible_message("[src] splits in twain!")
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
index 45a0f519989..df5897d9f65 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
@@ -223,9 +223,8 @@
A.admin_spawned = admin_spawned
A.GiveTarget(target)
A.friends = friends
- A.faction = faction
+ A.faction = faction.Copy()
ranged_cooldown = world.time + ranged_cooldown_time
- return
/mob/living/simple_animal/hostile/asteroid/hivelord/AttackingTarget()
OpenFire()
@@ -244,7 +243,6 @@
actions_types = list(/datum/action/item_action/organ_action/use)
var/inert = 0
var/preserved = 0
- var/list/spawned_brood = list()
/obj/item/organ/hivelord_core/New()
..()
@@ -274,36 +272,13 @@
update_icon()
/obj/item/organ/hivelord_core/ui_action_click()
- var/spawn_amount = 1
- if(!inert)
- spawn_amount++
-
- for(var/a in spawned_brood)
- if(!istype(a, /mob/living/simple_animal/hostile/asteroid/hivelordbrood) || qdeleted(a))
- spawned_brood -= a
- continue
- spawn_amount -= spawned_brood.len
-
- for(var/i = 1 to spawn_amount)
- var/mob/living/simple_animal/hostile/asteroid/hivelordbrood/blood/B = new (owner.loc)
- B.link_host(owner)
- spawned_brood |= B
-
+ owner.revive(full_heal = 1)
+ qdel(src)
/obj/item/organ/hivelord_core/on_life()
..()
- if(owner)
- owner.adjustBruteLoss(-1)
- owner.adjustFireLoss(-1)
- owner.adjustOxyLoss(-2)
- if(ishuman(owner))
- var/mob/living/carbon/human/H = owner
- CHECK_DNA_AND_SPECIES(H)
- if(NOBLOOD in H.dna.species.specflags)
- return
-
- if(H.blood_volume && H.blood_volume < BLOOD_VOLUME_NORMAL)
- H.blood_volume += 2 // Fast blood regen
+ if(owner.health < HEALTH_THRESHOLD_CRIT)
+ ui_action_click()
/obj/item/organ/hivelord_core/afterattack(atom/target, mob/user, proximity_flag)
if(proximity_flag && ishuman(target))
@@ -733,6 +708,7 @@
speak_emote = list("telepathically cries")
attack_sound = 'sound/weapons/bladeslice.ogg'
stat_attack = 1
+ flying = TRUE
robust_searching = 1
loot = list()
butcher_results = list(/obj/item/weapon/ore/diamond = 2, /obj/item/stack/sheet/sinew = 2, /obj/item/stack/sheet/bone = 1)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index c30137a2dae..4ef37cae914 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -412,8 +412,9 @@ var/next_mob_id = 0
*/
/mob/verb/memory()
- set name = "Notes"
+ set name = "Notes Memory"
set category = "IC"
+ set desc = "View your character's notes memory."
if(mind)
mind.show_memory(src)
else
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 5cbc3b370bc..919e995bca8 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -303,9 +303,6 @@
break
. = dense_object_backup
-/mob/proc/mob_has_gravity(turf/T)
- return has_gravity(src, T)
-
/mob/proc/mob_negates_gravity()
return 0
diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm
index ecfbb77e79a..516293bfc27 100644
--- a/code/modules/modular_computers/computers/item/computer.dm
+++ b/code/modules/modular_computers/computers/item/computer.dm
@@ -148,6 +148,9 @@
return attack_self(M)
return
+/obj/item/device/modular_computer/attack_ai(mob/user)
+ return attack_self(user)
+
/obj/item/device/modular_computer/attack_ghost(mob/dead/observer/user)
if(enabled)
ui_interact(user)
diff --git a/code/modules/modular_computers/computers/status_icons.dmi b/code/modules/modular_computers/computers/status_icons.dmi
deleted file mode 100644
index 52127ec4842..00000000000
Binary files a/code/modules/modular_computers/computers/status_icons.dmi and /dev/null differ
diff --git a/code/modules/ninja/energy_katana.dm b/code/modules/ninja/energy_katana.dm
index 354d2f4db97..75490674b9a 100644
--- a/code/modules/ninja/energy_katana.dm
+++ b/code/modules/ninja/energy_katana.dm
@@ -6,6 +6,7 @@
force = 40
throwforce = 20
armour_penetration = 50
+ unacidable = 1
var/datum/effect_system/spark_spread/spark_system
/obj/item/weapon/katana/energy/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
@@ -37,7 +38,7 @@
/obj/item/weapon/katana/energy/proc/returnToOwner(mob/living/carbon/human/user, doSpark = 1, caught = 0)
if(!istype(user))
return
- loc = get_turf(src)
+ forceMove(get_turf(user))
if(doSpark)
spark_system.start()
@@ -50,7 +51,6 @@
else if(user.equip_to_slot_if_possible(src, slot_belt, 0, 1, 1))
msg = "Your Energy Katana teleports back to you, sheathing itself as it does so!"
else
- loc = get_turf(user)
msg = "Your Energy Katana teleports to your location!"
if(caught)
diff --git a/code/modules/ninja/suit/gloves.dm b/code/modules/ninja/suit/gloves.dm
index 51b18f4c43a..5e441da8472 100644
--- a/code/modules/ninja/suit/gloves.dm
+++ b/code/modules/ninja/suit/gloves.dm
@@ -31,6 +31,7 @@
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
strip_delay = 120
+ unacidable = 1
var/draining = 0
var/candrain = 0
var/mindrain = 200
diff --git a/code/modules/ninja/suit/head.dm b/code/modules/ninja/suit/head.dm
index 5707a1bd809..cb4921fd7df 100644
--- a/code/modules/ninja/suit/head.dm
+++ b/code/modules/ninja/suit/head.dm
@@ -8,4 +8,5 @@
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 25)
strip_delay = 12
unacidable = 1
- blockTracking = 1//Roughly the only unique thing about this helmet.
\ No newline at end of file
+ blockTracking = 1//Roughly the only unique thing about this helmet.
+ flags_inv = HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
\ No newline at end of file
diff --git a/code/modules/ninja/suit/mask.dm b/code/modules/ninja/suit/mask.dm
index f5c5b4dbd4c..ca549aab8e6 100644
--- a/code/modules/ninja/suit/mask.dm
+++ b/code/modules/ninja/suit/mask.dm
@@ -16,3 +16,4 @@ Contents:
icon_state = "s-ninja"
item_state = "s-ninja_mask"
strip_delay = 120
+ unacidable = 1
diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm
index b77c67970e8..f76f974e647 100644
--- a/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm
+++ b/code/modules/ninja/suit/n_suit_verbs/ninja_adrenaline.dm
@@ -23,5 +23,6 @@
reagents.trans_id_to(H, "radium", a_transfer)
H << "You are beginning to feel the after-effect of the injection."
a_boost--
+ H << "There are [a_boost] adrenaline boosts remaining."
s_coold = 3
return
\ No newline at end of file
diff --git a/code/modules/ninja/suit/shoes.dm b/code/modules/ninja/suit/shoes.dm
index 732f8a37e8d..ca5761014bd 100644
--- a/code/modules/ninja/suit/shoes.dm
+++ b/code/modules/ninja/suit/shoes.dm
@@ -6,6 +6,7 @@
item_state = "secshoes"
permeability_coefficient = 0.01
flags = NOSLIP
+ unacidable = 1
armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 30, bio = 30, rad = 30)
strip_delay = 120
cold_protection = FEET
diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm
index 80b96c18152..5ec232ea1ed 100644
--- a/code/modules/power/gravitygenerator.dm
+++ b/code/modules/power/gravitygenerator.dm
@@ -372,7 +372,7 @@ var/const/GRAV_NEEDS_WRENCH = 3
for(var/mob/M in mob_list)
if(M.z != z)
continue
- M.update_gravity(M.mob_has_gravity())
+ M.update_gravity(M.has_gravity())
if(M.client)
shake_camera(M, 15, 1)
M.playsound_local(T, 'sound/effects/alert.ogg', 100, 1, 0.5)
diff --git a/code/modules/power/singularity/narsie.dm b/code/modules/power/singularity/narsie.dm
index 0c93c9835d0..6c9c98da31d 100644
--- a/code/modules/power/singularity/narsie.dm
+++ b/code/modules/power/singularity/narsie.dm
@@ -50,7 +50,7 @@
eat()
if(!target || prob(5))
pickcultist()
- if(istype(target, /obj/structure/clockwork/massive/ratvar))
+ if(istype(target, /obj/structure/destructible/clockwork/massive/ratvar))
move(get_dir(src, target)) //Oh, it's you again.
else
move()
@@ -86,7 +86,7 @@
/obj/singularity/narsie/proc/pickcultist() //Narsie rewards her cultists with being devoured first, then picks a ghost to follow.
var/list/cultists = list()
var/list/noncultists = list()
- for(var/obj/structure/clockwork/massive/ratvar/enemy in poi_list) //Prioritize killing Ratvar
+ for(var/obj/structure/destructible/clockwork/massive/ratvar/enemy in poi_list) //Prioritize killing Ratvar
if(enemy.z != z)
continue
acquire(enemy)
diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm
index 9ce067c1575..107b9c68197 100644
--- a/code/modules/power/singularity/singularity.dm
+++ b/code/modules/power/singularity/singularity.dm
@@ -416,11 +416,9 @@
/obj/singularity/proc/pulse()
-
for(var/obj/machinery/power/rad_collector/R in rad_collectors)
- if(get_dist(R, src) <= 15) // Better than using orange() every process
+ if(R.z == z && get_dist(R, src) <= 15) // Better than using orange() every process
R.receive_pulse(energy)
- return
/obj/singularity/singularity_act()
var/gain = (energy/2)
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index 0d7d5519211..c0c108ffe41 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -86,15 +86,15 @@
qdel(src)
/obj/machinery/power/supermatter_shard/process()
- var/turf/L = loc
+ var/turf/T = loc
- if(isnull(L)) // We have a null turf...something is wrong, stop processing this entity.
+ if(isnull(T)) // We have a null turf...something is wrong, stop processing this entity.
return PROCESS_KILL
- if(!istype(L)) //We are in a crate or somewhere that isn't turf, if we return to turf resume processing but for now.
+ if(!istype(T)) //We are in a crate or somewhere that isn't turf, if we return to turf resume processing but for now.
return //Yeah just stop.
- if(istype(L, /turf/open/space)) // Stop processing this stuff if we've been ejected.
+ if(istype(T, /turf/open/space)) // Stop processing this stuff if we've been ejected.
return
if(damage > warning_point) // while the core is still damaged and it's still worth noting its status
@@ -118,18 +118,20 @@
lastwarning = world.timeofday
if(damage > explosion_point)
- for(var/mob/living/mob in living_mob_list)
- if(istype(mob, /mob/living/carbon/human))
- //Hilariously enough, running into a closet should make you get hit the hardest.
- var/mob/living/carbon/human/H = mob
- H.hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) )
- var/rads = DETONATION_RADS * sqrt( 1 / (get_dist(mob, src) + 1) )
- mob.rad_act(rads)
+ for(var/mob in living_mob_list)
+ var/mob/living/L = mob
+ if(istype(L) && L.z == z)
+ if(ishuman(mob))
+ //Hilariously enough, running into a closet should make you get hit the hardest.
+ var/mob/living/carbon/human/H = mob
+ H.hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) )
+ var/rads = DETONATION_RADS * sqrt( 1 / (get_dist(L, src) + 1) )
+ L.rad_act(rads)
explode()
//Ok, get the air from the turf
- var/datum/gas_mixture/env = L.return_air()
+ var/datum/gas_mixture/env = T.return_air()
var/datum/gas_mixture/removed
@@ -278,7 +280,7 @@
/obj/machinery/power/supermatter_shard/proc/transfer_energy()
for(var/obj/machinery/power/rad_collector/R in rad_collectors)
- if(get_dist(R, src) <= 15) // Better than using orange() every process
+ if(R.z == z && get_dist(R, src) <= 15) //Better than using orange() every process
R.receive_pulse(power/10)
/obj/machinery/power/supermatter_shard/attackby(obj/item/W, mob/living/user, params)
diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm
index ce5682ecb73..6c41ca751d7 100644
--- a/code/modules/projectiles/projectile/energy.dm
+++ b/code/modules/projectiles/projectile/energy.dm
@@ -177,14 +177,15 @@
icon_state = "purple_laser"
var/chain
-/obj/item/ammo_casing/energy/shock_revolver/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
+/obj/item/projectile/energy/shock_revolver/fire(setAngle)
+ if(firer)
+ chain = Beam(firer, icon_state = "lightning[rand(1, 12)]", icon = 'icons/effects/effects.dmi', time = INFINITY, maxdistance = INFINITY)
..()
- var/obj/item/projectile/hook/P = BB
- spawn(1)
- P.chain = P.Beam(user,icon_state="purple_lightning",icon = 'icons/effects/effects.dmi',time=1000, maxdistance = 30)
/obj/item/projectile/energy/shock_revolver/on_hit(atom/target)
. = ..()
if(isliving(target))
tesla_zap(src, 3, 10000)
+
+/obj/item/projectile/energy/shock_revolver/Destroy()
qdel(chain)
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index 62f8a1ceec0..bdc42b7c03c 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -12,7 +12,7 @@ var/const/INJECT = 5 //injection
var/list/datum/reagent/reagent_list = new/list()
var/total_volume = 0
var/maximum_volume = 100
- var/atom/my_atom = null
+ var/datum/my_atom = null
var/chem_temp = 150
var/last_tick = 1
var/addiction_tick = 1
@@ -61,30 +61,32 @@ var/const/INJECT = 5 //injection
/datum/reagents/Destroy()
. = ..()
STOP_PROCESSING(SSobj, src)
- for(var/reagent in reagent_list)
+ var/list/cached_reagents = reagent_list
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
qdel(R)
- reagent_list.Cut()
- reagent_list = null
+ cached_reagents.Cut()
+ cached_reagents = null
if(my_atom && my_atom.reagents == src)
my_atom.reagents = null
/datum/reagents/proc/remove_any(amount = 1)
+ var/list/cached_reagents = reagent_list
var/total_transfered = 0
var/current_list_element = 1
- current_list_element = rand(1, reagent_list.len)
+ current_list_element = rand(1, cached_reagents.len)
while(total_transfered != amount)
if(total_transfered >= amount)
break
- if(total_volume <= 0 || !reagent_list.len)
+ if(total_volume <= 0 || !cached_reagents.len)
break
- if(current_list_element > reagent_list.len)
+ if(current_list_element > cached_reagents.len)
current_list_element = 1
- var/datum/reagent/R = reagent_list[current_list_element]
+ var/datum/reagent/R = cached_reagents[current_list_element]
remove_reagent(R.id, 1)
current_list_element++
@@ -95,9 +97,10 @@ var/const/INJECT = 5 //injection
return total_transfered
/datum/reagents/proc/remove_all(amount = 1)
+ var/list/cached_reagents = reagent_list
if(total_volume > 0)
var/part = amount / total_volume
- for(var/reagent in reagent_list)
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
remove_reagent(R.id, R.volume * part)
@@ -106,9 +109,10 @@ var/const/INJECT = 5 //injection
return amount
/datum/reagents/proc/get_master_reagent_name()
+ var/list/cached_reagents = reagent_list
var/name
var/max_volume = 0
- for(var/reagent in reagent_list)
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
if(R.volume > max_volume)
max_volume = R.volume
@@ -117,9 +121,10 @@ var/const/INJECT = 5 //injection
return name
/datum/reagents/proc/get_master_reagent_id()
+ var/list/cached_reagents = reagent_list
var/id
var/max_volume = 0
- for(var/reagent in reagent_list)
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
if(R.volume > max_volume)
max_volume = R.volume
@@ -128,6 +133,8 @@ var/const/INJECT = 5 //injection
return id
/datum/reagents/proc/trans_to(obj/target, amount=1, multiplier=1, preserve_data=1, no_react = 0)//if preserve_data=0, the reagents data will be lost. Usefull if you use data for some strange stuff and don't want it to be transferred.
+ var/list/cached_reagents = reagent_list
+
if(!target || !total_volume)
return
var/datum/reagents/R
@@ -140,7 +147,7 @@ var/const/INJECT = 5 //injection
amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume)
var/part = amount / src.total_volume
var/trans_data = null
- for(var/reagent in reagent_list)
+ for(var/reagent in cached_reagents)
var/datum/reagent/T = reagent
var/transfer_amount = T.volume * part
if(preserve_data)
@@ -156,6 +163,7 @@ var/const/INJECT = 5 //injection
return amount
/datum/reagents/proc/copy_to(obj/target, amount=1, multiplier=1, preserve_data=1)
+ var/list/cached_reagents = reagent_list
if(!target)
return
if(!target.reagents || src.total_volume<=0)
@@ -164,7 +172,7 @@ var/const/INJECT = 5 //injection
amount = min(min(amount, total_volume), R.maximum_volume-R.total_volume)
var/part = amount / total_volume
var/trans_data = null
- for(var/reagent in reagent_list)
+ for(var/reagent in cached_reagents)
var/datum/reagent/T = reagent
var/copy_amount = T.volume * part
if(preserve_data)
@@ -178,6 +186,7 @@ var/const/INJECT = 5 //injection
return amount
/datum/reagents/proc/trans_id_to(obj/target, reagent, amount=1, preserve_data=1)//Not sure why this proc didn't exist before. It does now! /N
+ var/list/cached_reagents = reagent_list
if (!target)
return
if (!target.reagents || src.total_volume<=0 || !src.get_reagent_amount(reagent))
@@ -188,58 +197,28 @@ var/const/INJECT = 5 //injection
amount = src.get_reagent_amount(reagent)
amount = min(amount, R.maximum_volume-R.total_volume)
var/trans_data = null
- for (var/datum/reagent/current_reagent in src.reagent_list)
+ for (var/CR in cached_reagents)
+ var/datum/reagent/current_reagent = CR
if(current_reagent.id == reagent)
if(preserve_data)
trans_data = current_reagent.data
R.add_reagent(current_reagent.id, amount, trans_data, src.chem_temp)
- src.remove_reagent(current_reagent.id, amount, 1)
+ remove_reagent(current_reagent.id, amount, 1)
break
src.update_total()
R.update_total()
R.handle_reactions()
- //src.handle_reactions() Don't need to handle reactions on the source since you're (presumably isolating and) transferring a specific reagent.
return amount
-/*
- if (!target) return
- var/total_transfered = 0
- var/current_list_element = 1
- var/datum/reagents/R = target.reagents
- var/trans_data = null
- //if(R.total_volume + amount > R.maximum_volume) return 0
-
- current_list_element = rand(1,reagent_list.len) //Eh, bandaid fix.
-
- while(total_transfered != amount)
- if(total_transfered >= amount) break //Better safe than sorry.
- if(total_volume <= 0 || !reagent_list.len) break
- if(R.total_volume >= R.maximum_volume) break
-
- if(current_list_element > reagent_list.len) current_list_element = 1
- var/datum/reagent/current_reagent = reagent_list[current_list_element]
- if(preserve_data)
- trans_data = current_reagent.data
- R.add_reagent(current_reagent.id, (1 * multiplier), trans_data)
- src.remove_reagent(current_reagent.id, 1)
-
- current_list_element++
- total_transfered++
- src.update_total()
- R.update_total()
- R.handle_reactions()
- handle_reactions()
-
- return total_transfered
-*/
-
/datum/reagents/proc/metabolize(mob/living/carbon/C, can_overdose = 0)
+ var/list/cached_reagents = reagent_list
+ var/list/cached_addictions = addiction_list
if(C)
chem_temp = C.bodytemperature
handle_reactions()
var/need_mob_update = 0
- for(var/reagent in reagent_list)
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
if(!R.holder)
continue
@@ -253,13 +232,13 @@ var/const/INJECT = 5 //injection
R.overdosed = 1
need_mob_update += R.overdose_start(C)
if(R.addiction_threshold)
- if(R.volume >= R.addiction_threshold && !is_type_in_list(R, addiction_list))
+ if(R.volume >= R.addiction_threshold && !is_type_in_list(R, cached_addictions))
var/datum/reagent/new_reagent = new R.type()
- addiction_list.Add(new_reagent)
+ cached_addictions.Add(new_reagent)
if(R.overdosed)
need_mob_update += R.overdose_process(C)
- if(is_type_in_list(R,addiction_list))
- for(var/addiction in addiction_list)
+ if(is_type_in_list(R,cached_addictions))
+ for(var/addiction in cached_addictions)
var/datum/reagent/A = addiction
if(istype(R, A))
A.addiction_stage = -15 // you're satisfied for a good while.
@@ -268,7 +247,7 @@ var/const/INJECT = 5 //injection
if(can_overdose)
if(addiction_tick == 6)
addiction_tick = 1
- for(var/addiction in addiction_list)
+ for(var/addiction in cached_addictions)
var/datum/reagent/R = addiction
if(C && R)
R.addiction_stage++
@@ -283,7 +262,7 @@ var/const/INJECT = 5 //injection
need_mob_update += R.addiction_act_stage4(C)
if(40 to INFINITY)
C << "You feel like you've gotten over your need for [R.name]."
- addiction_list.Remove(R)
+ cached_addictions.Remove(R)
addiction_tick++
if(C && need_mob_update) //some of the metabolized reagents had effects on the mob that requires some updates.
C.updatehealth()
@@ -292,11 +271,12 @@ var/const/INJECT = 5 //injection
update_total()
/datum/reagents/process()
+ var/list/cached_reagents = reagent_list
if(flags & REAGENT_NOREACT)
STOP_PROCESSING(SSobj, src)
return
- for(var/reagent in reagent_list)
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
R.on_tick()
@@ -311,34 +291,41 @@ var/const/INJECT = 5 //injection
flags |= REAGENT_NOREACT
/datum/reagents/proc/conditional_update_move(atom/A, Running = 0)
- for(var/reagent in reagent_list)
+ var/list/cached_reagents = reagent_list
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
R.on_move (A, Running)
update_total()
/datum/reagents/proc/conditional_update(atom/A)
- for(var/reagent in reagent_list)
+ var/list/cached_reagents = reagent_list
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
R.on_update (A)
update_total()
/datum/reagents/proc/handle_reactions()
+ var/list/cached_reagents = reagent_list
+ var/list/cached_reactions = chemical_reactions_list
+ var/datum/cached_my_atom = my_atom
if(flags & REAGENT_NOREACT)
return //Yup, no reactions here. No siree.
var/reaction_occured = 0
do
reaction_occured = 0
- for(var/reagent in reagent_list)
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
- for(var/reaction in chemical_reactions_list[R.id]) // Was a big list but now it should be smaller since we filtered it with our reagent id
+ for(var/reaction in cached_reactions[R.id]) // Was a big list but now it should be smaller since we filtered it with our reagent id
if(!reaction)
continue
var/datum/chemical_reaction/C = reaction
- var/total_required_reagents = C.required_reagents.len
+ var/list/cached_required_reagents = C.required_reagents
+ var/total_required_reagents = cached_required_reagents.len
var/total_matching_reagents = 0
- var/total_required_catalysts = C.required_catalysts.len
+ var/list/cached_required_catalysts = C.required_catalysts
+ var/total_required_catalysts = cached_required_catalysts.len
var/total_matching_catalysts= 0
var/matching_container = 0
var/matching_other = 0
@@ -347,32 +334,39 @@ var/const/INJECT = 5 //injection
var/is_cold_recipe = C.is_cold_recipe
var/meets_temp_requirement = 0
- for(var/B in C.required_reagents)
- if(!has_reagent(B, C.required_reagents[B]))
+ var/list/cached_results = C.results
+
+ for(var/B in cached_required_reagents)
+ if(!has_reagent(B, cached_required_reagents[B]))
break
total_matching_reagents++
- multipliers += round(get_reagent_amount(B) / C.required_reagents[B])
- for(var/B in C.required_catalysts)
- if(!has_reagent(B, C.required_catalysts[B]))
+ multipliers += round(get_reagent_amount(B) / cached_required_reagents[B])
+ for(var/B in cached_required_catalysts)
+ if(!has_reagent(B, cached_required_catalysts[B]))
break
total_matching_catalysts++
-
- if(!C.required_container)
- matching_container = 1
-
- else
- if(my_atom.type == C.required_container)
+ if(cached_my_atom)
+ if(!C.required_container)
matching_container = 1
- if (isliving(my_atom)) //Makes it so certain chemical reactions don't occur in mobs
- if (C.mob_react)
- return
- if(!C.required_other)
- matching_other = 1
- else if(istype(my_atom, /obj/item/slime_extract))
- var/obj/item/slime_extract/M = my_atom
+ else
+ if(cached_my_atom.type == C.required_container)
+ matching_container = 1
+ if (isliving(cached_my_atom)) //Makes it so certain chemical reactions don't occur in mobs
+ if (C.mob_react)
+ return
+ if(!C.required_other)
+ matching_other = 1
- if(M.Uses > 0) // added a limit to slime cores -- Muskets requested this
+ else if(istype(cached_my_atom, /obj/item/slime_extract))
+ var/obj/item/slime_extract/M = cached_my_atom
+
+ if(M.Uses > 0) // added a limit to slime cores -- Muskets requested this
+ matching_other = 1
+ else
+ if(!C.required_container)
+ matching_container = 1
+ if(!C.required_other)
matching_other = 1
if(required_temp == 0 || (is_cold_recipe && chem_temp <= required_temp) || (!is_cold_recipe && chem_temp >= required_temp))
@@ -380,30 +374,30 @@ var/const/INJECT = 5 //injection
if(total_matching_reagents == total_required_reagents && total_matching_catalysts == total_required_catalysts && matching_container && matching_other && meets_temp_requirement)
var/multiplier = min(multipliers)
- for(var/B in C.required_reagents)
- remove_reagent(B, (multiplier * C.required_reagents[B]), safety = 1)
+ for(var/B in cached_required_reagents)
+ remove_reagent(B, (multiplier * cached_required_reagents[B]), safety = 1)
for(var/P in C.results)
- feedback_add_details("chemical_reaction", "[P]|[C.results[P]*multiplier]")
+ feedback_add_details("chemical_reaction", "[P]|[cached_results[P]*multiplier]")
multiplier = max(multiplier, 1) //this shouldnt happen ...
- add_reagent(P, C.results[P]*multiplier, null, chem_temp)
+ add_reagent(P, cached_results[P]*multiplier, null, chem_temp)
var/list/seen = viewers(4, get_turf(my_atom))
-
- if(!istype(my_atom, /mob)) // No bubbling mobs
- if(C.mix_sound)
- playsound(get_turf(my_atom), C.mix_sound, 80, 1)
- for(var/mob/M in seen)
- M << "\icon[my_atom] [C.mix_message]"
-
- if(istype(my_atom, /obj/item/slime_extract))
- var/obj/item/slime_extract/ME2 = my_atom
- ME2.Uses--
- if(ME2.Uses <= 0) // give the notification that the slime core is dead
+ if(cached_my_atom)
+ if(!ismob(cached_my_atom)) // No bubbling mobs
+ if(C.mix_sound)
+ playsound(get_turf(cached_my_atom), C.mix_sound, 80, 1)
for(var/mob/M in seen)
- M << "\icon[my_atom] \The [my_atom]'s power is consumed in the reaction."
- ME2.name = "used slime extract"
- ME2.desc = "This extract has been used up."
+ M << "\icon[my_atom] [C.mix_message]"
+
+ if(istype(cached_my_atom, /obj/item/slime_extract))
+ var/obj/item/slime_extract/ME2 = my_atom
+ ME2.Uses--
+ if(ME2.Uses <= 0) // give the notification that the slime core is dead
+ for(var/mob/M in seen)
+ M << "\icon[my_atom] \The [my_atom]'s power is consumed in the reaction."
+ ME2.name = "used slime extract"
+ ME2.desc = "This extract has been used up."
C.on_reaction(src, multiplier)
reaction_occured = 1
@@ -414,26 +408,29 @@ var/const/INJECT = 5 //injection
return 0
/datum/reagents/proc/isolate_reagent(reagent)
- for(var/_reagent in reagent_list)
+ var/list/cached_reagents = reagent_list
+ for(var/_reagent in cached_reagents)
var/datum/reagent/R = _reagent
if(R.id != reagent)
del_reagent(R.id)
update_total()
/datum/reagents/proc/del_reagent(reagent)
- for(var/_reagent in reagent_list)
+ var/list/cached_reagents = reagent_list
+ for(var/_reagent in cached_reagents)
var/datum/reagent/R = _reagent
if(R.id == reagent)
- if(istype(my_atom, /mob/living))
+ if(my_atom && istype(my_atom, /mob/living))
var/mob/living/M = my_atom
R.on_mob_delete(M)
qdel(R)
reagent_list -= R
update_total()
- my_atom.on_reagent_change()
- check_ignoreslow(my_atom)
- check_gofast(my_atom)
- check_goreallyfast(my_atom)
+ if(my_atom)
+ my_atom.on_reagent_change()
+ check_ignoreslow(my_atom)
+ check_gofast(my_atom)
+ check_goreallyfast(my_atom)
return 1
/datum/reagents/proc/check_ignoreslow(mob/M)
@@ -458,8 +455,9 @@ var/const/INJECT = 5 //injection
M.status_flags &= ~GOTTAGOREALLYFAST
/datum/reagents/proc/update_total()
+ var/list/cached_reagents = reagent_list
total_volume = 0
- for(var/reagent in reagent_list)
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
if(R.volume < 0.1)
del_reagent(R.id)
@@ -469,44 +467,54 @@ var/const/INJECT = 5 //injection
return 0
/datum/reagents/proc/clear_reagents()
- for(var/reagent in reagent_list)
+ var/list/cached_reagents = reagent_list
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
del_reagent(R.id)
return 0
/datum/reagents/proc/reaction(atom/A, method = TOUCH, volume_modifier = 1, show_message = 1)
+ var/react_type
if(isliving(A))
- var/touch_protection = 0
- if(method == VAPOR)
- var/mob/living/L = A
- touch_protection = L.get_permeability_protection()
- for(var/reagent in reagent_list)
- var/datum/reagent/R = reagent
- R.reaction_mob(A, method, R.volume * volume_modifier, show_message, touch_protection)
+ react_type = "LIVING"
else if(isturf(A))
- for(var/reagent in reagent_list)
- var/datum/reagent/R = reagent
- R.reaction_turf(A, R.volume * volume_modifier, show_message)
+ react_type = "TURF"
else if(isobj(A))
- for(var/reagent in reagent_list)
- var/datum/reagent/R = reagent
- R.reaction_obj(A, R.volume * volume_modifier, show_message)
+ react_type = "OBJ"
+ else
+ return
+ var/list/cached_reagents = reagent_list
+ for(var/reagent in cached_reagents)
+ var/datum/reagent/R = reagent
+ switch(react_type)
+ if("LIVING")
+ var/touch_protection = 0
+ if(method == VAPOR)
+ var/mob/living/L = A
+ touch_protection = L.get_permeability_protection()
+ R.reaction_mob(A, method, R.volume * volume_modifier, show_message, touch_protection)
+ if("TURF")
+ R.reaction_turf(A, R.volume * volume_modifier, show_message)
+ if("OBJ")
+ R.reaction_obj(A, R.volume * volume_modifier, show_message)
/datum/reagents/proc/add_reagent(reagent, amount, list/data=null, reagtemp = 300, no_react = 0)
if(!isnum(amount) || !amount)
return 1
+ var/list/cached_reagents = reagent_list
update_total()
if(total_volume + amount > maximum_volume)
amount = (maximum_volume - total_volume) //Doesnt fit in. Make it disappear. Shouldnt happen. Will happen.
chem_temp = round(((amount * reagtemp) + (total_volume * chem_temp)) / (total_volume + amount)) //equalize with new chems
- for(var/A in reagent_list)
+ for(var/A in cached_reagents)
var/datum/reagent/R = A
if (R.id == reagent)
R.volume += amount
update_total()
- my_atom.on_reagent_change()
+ if(my_atom)
+ my_atom.on_reagent_change()
R.on_merge(data)
if(!no_react)
handle_reactions()
@@ -516,7 +524,7 @@ var/const/INJECT = 5 //injection
if(D)
var/datum/reagent/R = new D.type(data)
- reagent_list += R
+ cached_reagents += R
R.holder = src
R.volume = amount
if(data)
@@ -524,7 +532,8 @@ var/const/INJECT = 5 //injection
R.on_new(data)
update_total()
- my_atom.on_reagent_change()
+ if(my_atom)
+ my_atom.on_reagent_change()
if(!no_react)
handle_reactions()
return 0
@@ -549,20 +558,24 @@ var/const/INJECT = 5 //injection
if(!isnum(amount))
return 1
- for(var/A in reagent_list)
+ var/list/cached_reagents = reagent_list
+
+ for(var/A in cached_reagents)
var/datum/reagent/R = A
if (R.id == reagent)
R.volume -= amount
update_total()
if(!safety)//So it does not handle reactions when it need not to
handle_reactions()
- my_atom.on_reagent_change()
+ if(my_atom)
+ my_atom.on_reagent_change()
return 0
return 1
/datum/reagents/proc/has_reagent(reagent, amount = -1)
- for(var/_reagent in reagent_list)
+ var/list/cached_reagents = reagent_list
+ for(var/_reagent in cached_reagents)
var/datum/reagent/R = _reagent
if (R.id == reagent)
if(!amount)
@@ -576,7 +589,8 @@ var/const/INJECT = 5 //injection
return 0
/datum/reagents/proc/get_reagent_amount(reagent)
- for(var/_reagent in reagent_list)
+ var/list/cached_reagents = reagent_list
+ for(var/_reagent in cached_reagents)
var/datum/reagent/R = _reagent
if (R.id == reagent)
return R.volume
@@ -585,7 +599,8 @@ var/const/INJECT = 5 //injection
/datum/reagents/proc/get_reagents()
var/list/names = list()
- for(var/reagent in reagent_list)
+ var/list/cached_reagents = reagent_list
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
names += R.name
@@ -593,10 +608,10 @@ var/const/INJECT = 5 //injection
/datum/reagents/proc/remove_all_type(reagent_type, amount, strict = 0, safety = 1) // Removes all reagent of X type. @strict set to 1 determines whether the childs of the type are included.
if(!isnum(amount)) return 1
-
+ var/list/cached_reagents = reagent_list
var/has_removed_reagent = 0
- for(var/reagent in reagent_list)
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
var/matches = 0
// Switch between how we check the reagent type
@@ -615,14 +630,16 @@ var/const/INJECT = 5 //injection
//two helper functions to preserve data across reactions (needed for xenoarch)
/datum/reagents/proc/get_data(reagent_id)
- for(var/reagent in reagent_list)
+ var/list/cached_reagents = reagent_list
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
if(R.id == reagent_id)
//world << "proffering a data-carrying reagent ([reagent_id])"
return R.data
/datum/reagents/proc/set_data(reagent_id, new_data)
- for(var/reagent in reagent_list)
+ var/list/cached_reagents = reagent_list
+ for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
if(R.id == reagent_id)
//world << "reagent data set ([reagent_id])"
@@ -650,7 +667,8 @@ var/const/INJECT = 5 //injection
return trans_data
/datum/reagents/proc/get_reagent(type)
- . = locate(type) in reagent_list
+ var/list/cached_reagents = reagent_list
+ . = locate(type) in cached_reagents
///////////////////////////////////////////////////////////////////////////////////
@@ -658,7 +676,7 @@ var/const/INJECT = 5 //injection
// Convenience proc to create a reagents holder for an atom
// Max vol is maximum volume of holder
-/atom/proc/create_reagents(max_vol)
+/datum/proc/create_reagents(max_vol)
if(reagents)
qdel(reagents)
reagents = new/datum/reagents(max_vol)
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index ace882be22e..ff9eb7197d6 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -443,7 +443,7 @@
/datum/reagent/oxygen
name = "Oxygen"
id = "oxygen"
- description = "A colorless, odorless gas."
+ description = "A colorless, odorless gas. Grows on trees but is still pretty valuable."
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
@@ -460,14 +460,14 @@
/datum/reagent/copper
name = "Copper"
id = "copper"
- description = "A highly ductile metal."
+ description = "A highly ductile metal. Things made out of copper aren't very durable, but it makes a decent material for electrical wiring."
reagent_state = SOLID
color = "#6E3B08" // rgb: 110, 59, 8
/datum/reagent/nitrogen
name = "Nitrogen"
id = "nitrogen"
- description = "A colorless, odorless, tasteless gas."
+ description = "A colorless, odorless, tasteless gas. A simple asphyxiant that can silently displace vital oxygen."
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
@@ -498,7 +498,7 @@
/datum/reagent/mercury
name = "Mercury"
id = "mercury"
- description = "A chemical element."
+ description = "A curious metal that's a liquid at room temperature. Neurodegenerative and very bad for the mind."
color = "#484848" // rgb: 72, 72, 72
/datum/reagent/mercury/on_mob_life(mob/living/M)
@@ -512,14 +512,14 @@
/datum/reagent/sulfur
name = "Sulfur"
id = "sulfur"
- description = "A chemical element."
+ description = "A sickly yellow solid mostly known for its nasty smell. It's actually much more helpful than it looks in biochemisty."
reagent_state = SOLID
color = "#BF8C00" // rgb: 191, 140, 0
/datum/reagent/carbon
name = "Carbon"
id = "carbon"
- description = "A chemical element."
+ description = "A crumbly black solid that, while unexciting on an physical level, forms the base of all known life. Kind of a big deal."
reagent_state = SOLID
color = "#1C1300" // rgb: 30, 20, 0
@@ -532,7 +532,7 @@
/datum/reagent/chlorine
name = "Chlorine"
id = "chlorine"
- description = "A chemical element."
+ description = "A pale yellow gas that's well known as an oxidizer. While it forms many harmless molecules in its elemental form it is far from harmless."
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
@@ -544,7 +544,7 @@
/datum/reagent/fluorine
name = "Fluorine"
id = "fluorine"
- description = "A highly-reactive chemical element."
+ description = "A comically-reactive chemical element. The universe does not want this stuff to exist in this form in the slightest."
reagent_state = GAS
color = "#808080" // rgb: 128, 128, 128
@@ -556,21 +556,21 @@
/datum/reagent/sodium
name = "Sodium"
id = "sodium"
- description = "A chemical element."
+ description = "A soft silver metal that can easily be cut with a knife. It's not salt just yet, so refrain from putting in on your chips."
reagent_state = SOLID
color = "#808080" // rgb: 128, 128, 128
/datum/reagent/phosphorus
name = "Phosphorus"
id = "phosphorus"
- description = "A chemical element."
+ description = "A ruddy red powder that burns readily. Though it comes in many colors, the general theme is always the same."
reagent_state = SOLID
color = "#832828" // rgb: 131, 40, 40
/datum/reagent/lithium
name = "Lithium"
id = "lithium"
- description = "A chemical element."
+ description = "A silver metal, it's claim to fame is its remarkably low density. Using it is a bit too effective in calming oneself down."
reagent_state = SOLID
color = "#808080" // rgb: 128, 128, 128
@@ -863,7 +863,7 @@
name = "Carbon Dioxide"
id = "co2"
reagent_state = GAS
- description = "A gas commonly produced by burning carbon fuels."
+ description = "A gas commonly produced by burning carbon fuels. You're constantly producing this in your lungs."
color = "#B0B0B0" // rgb : 192, 192, 192
/datum/reagent/carbondioxide/reaction_obj(obj/O, reac_volume)
@@ -1008,21 +1008,14 @@
/datum/reagent/iodine
name = "Iodine"
id = "iodine"
- description = "A slippery solution."
- reagent_state = LIQUID
- color = "#C8A5DC"
-
-/datum/reagent/fluorine
- name = "Fluorine"
- id = "fluorine"
- description = "A slippery solution."
+ description = "Commonly added to table salt as a nutrient. On its own it tastes far less pleasing."
reagent_state = LIQUID
color = "#C8A5DC"
/datum/reagent/carpet
name = "Carpet"
id = "carpet"
- description = "A slippery solution."
+ description = "For those that need a more creative way to roll out a red carpet."
reagent_state = LIQUID
color = "#C8A5DC"
@@ -1036,35 +1029,35 @@
/datum/reagent/bromine
name = "Bromine"
id = "bromine"
- description = "A slippery solution."
+ description = "A brownish liquid that's highly reactive. Useful for stopping free radicals, but not intended for human consumption."
reagent_state = LIQUID
color = "#C8A5DC"
/datum/reagent/phenol
name = "Phenol"
id = "phenol"
- description = "Used for certain medical recipes."
+ description = "An aromatic ring of carbon with a hydroxyl group. A useful precursor to some medicines, but has no healing properties on its own."
reagent_state = LIQUID
color = "#C8A5DC"
/datum/reagent/ash
name = "Ash"
id = "ash"
- description = "Basic ingredient in a couple of recipes."
+ description = "Supposedly pheonixes rise from these, but you've never seen it."
reagent_state = LIQUID
color = "#C8A5DC"
/datum/reagent/acetone
name = "Acetone"
id = "acetone"
- description = "Common ingredient in other recipes."
+ description = "A slick, slightly carcinogenic liquid. Has a multitude of mundane uses in everyday life."
reagent_state = LIQUID
color = "#C8A5DC"
/datum/reagent/colorful_reagent
name = "Colorful Reagent"
id = "colorful_reagent"
- description = "A solution."
+ description = "Thoroughly sample the rainbow."
reagent_state = LIQUID
color = "#C8A5DC"
var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d11141","#00b159","#00aedb","#f37735","#ffc425","#008744","#0057e7","#d62d20","#ffa700")
@@ -1094,7 +1087,7 @@
/datum/reagent/hair_dye
name = "Quantum Hair Dye"
id = "hair_dye"
- description = "A solution."
+ description = "Has a high chance of making you look like a mad scientist."
reagent_state = LIQUID
color = "#C8A5DC"
var/list/potential_colors = list("0ad","a0f","f73","d14","d14","0b5","0ad","f73","fc2","084","05e","d22","fa0") // fucking hair code
@@ -1142,21 +1135,21 @@
/datum/reagent/saltpetre
name = "Saltpetre"
id = "saltpetre"
- description = "Volatile."
+ description = "Volatile. Controversial. Third Thing."
reagent_state = LIQUID
color = "#60A584" // rgb: 96, 165, 132
/datum/reagent/lye
name = "Lye"
id = "lye"
- description = "Also known as sodium hydroxide."
+ description = "Also known as sodium hydroxide. As a profession making this is somewhat underwhelming."
reagent_state = LIQUID
color = "#FFFFD6" // very very light yellow
/datum/reagent/drying_agent
name = "Drying agent"
id = "drying_agent"
- description = "Can be used to dry things."
+ description = "A desiccant. Can be used to dry things."
reagent_state = LIQUID
color = "#A70FFF"
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index ec86f0817f5..5ed872fc0ff 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -49,6 +49,8 @@
/obj/structure/reagent_dispensers/proc/boom()
+ visible_message("\The [src] ruptures!")
+ chem_splash(loc, 5, list(reagents))
qdel(src)
/obj/structure/reagent_dispensers/watertank
@@ -56,20 +58,11 @@
desc = "A water tank."
icon_state = "water"
-/obj/structure/reagent_dispensers/waterank/bullet_act(obj/item/projectile/Proj)
+/obj/structure/reagent_dispensers/bullet_act(obj/item/projectile/Proj)
..()
if(tank_volume && istype(Proj) && !Proj.nodamage && ((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE)))
boom()
-/obj/structure/reagent_dispensers/watertank/boom()
- playsound(src.loc, 'sound/effects/spray2.ogg', 50, 1, -6)
- PoolOrNew(/obj/effect/particle_effect/water, loc)
- for(var/turf/open/T in view(5,loc))
- T.MakeSlippery(min_wet_time = 20, wet_time_to_add = 15)
- for(var/mob/living/L in T)
- L.adjust_fire_stacks(-20)
- qdel(src)
-
/obj/structure/reagent_dispensers/watertank/blob_act(obj/effect/blob/B)
if(prob(50))
PoolOrNew(/obj/effect/particle_effect/water, loc)
diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm
index 2e364b7e72f..8b304469259 100644
--- a/code/modules/research/designs.dm
+++ b/code/modules/research/designs.dm
@@ -37,7 +37,7 @@ other types of metals and chemistry for reagents).
var/build_path = null //The file path of the object that gets created
var/list/make_reagents = list() //Reagents produced. Format: "id" = amount. Currently only supported by the biogenerator.
var/list/category = null //Primarily used for Mech Fabricators, but can be used for anything
- var/list/reagents = list() //List of reagents. Format: "id" = amount.
+ var/list/reagents_list = list() //List of reagents. Format: "id" = amount.
var/maxstack = 1
diff --git a/code/modules/research/designs/comp_board_designs.dm b/code/modules/research/designs/comp_board_designs.dm
index 60b921056de..ac400b4780a 100644
--- a/code/modules/research/designs/comp_board_designs.dm
+++ b/code/modules/research/designs/comp_board_designs.dm
@@ -7,7 +7,7 @@
req_tech = list("programming" = 1)
build_type = IMPRINTER
materials = list(MAT_GLASS = 1000)
- reagents = list("sacid" = 20)
+ reagents_list = list("sacid" = 20)
build_path = /obj/item/weapon/circuitboard/computer/arcade/battle
category = list("Computer Boards")
diff --git a/code/modules/research/designs/computer_part_designs.dm b/code/modules/research/designs/computer_part_designs.dm
index dc6c69ad461..cd7452d6f10 100644
--- a/code/modules/research/designs/computer_part_designs.dm
+++ b/code/modules/research/designs/computer_part_designs.dm
@@ -64,7 +64,7 @@
req_tech = list("programming" = 2, "engineering" = 1)
build_type = IMPRINTER
materials = list(MAT_METAL = 250, MAT_GLASS = 100)
- reagents = list("sacid" = 20)
+ reagents_list = list("sacid" = 20)
build_path = /obj/item/weapon/computer_hardware/network_card
category = list("Computer Parts")
@@ -74,7 +74,7 @@
req_tech = list("programming" = 4, "engineering" = 2)
build_type = IMPRINTER
materials = list(MAT_METAL = 500, MAT_GLASS = 200)
- reagents = list("sacid" = 20)
+ reagents_list = list("sacid" = 20)
build_path = /obj/item/weapon/computer_hardware/network_card/advanced
category = list("Computer Parts")
@@ -84,7 +84,7 @@
req_tech = list("programming" = 5, "engineering" = 3)
build_type = IMPRINTER
materials = list(MAT_METAL = 2500, MAT_GLASS = 400)
- reagents = list("sacid" = 20)
+ reagents_list = list("sacid" = 20)
build_path = /obj/item/weapon/computer_hardware/network_card/wired
category = list("Computer Parts")
@@ -96,7 +96,7 @@
req_tech = list("programming" = 1)
build_type = IMPRINTER
materials = list(MAT_GLASS = 800)
- reagents = list("sacid" = 20)
+ reagents_list = list("sacid" = 20)
build_path = /obj/item/weapon/computer_hardware/hard_drive/portable
category = list("Computer Parts")
@@ -106,7 +106,7 @@
req_tech = list("programming" = 2)
build_type = IMPRINTER
materials = list(MAT_GLASS = 1600)
- reagents = list("sacid" = 20)
+ reagents_list = list("sacid" = 20)
build_path = /obj/item/weapon/computer_hardware/hard_drive/portable/advanced
category = list("Computer Parts")
@@ -116,7 +116,7 @@
req_tech = list("programming" = 4)
build_type = IMPRINTER
materials = list(MAT_GLASS = 3200)
- reagents = list("sacid" = 20)
+ reagents_list = list("sacid" = 20)
build_path = /obj/item/weapon/computer_hardware/hard_drive/portable/super
category = list("Computer Parts")
@@ -216,7 +216,7 @@
req_tech = list("programming" = 3, "engineering" = 2)
build_type = IMPRINTER
materials = list(MAT_GLASS = 1600)
- reagents = list("sacid" = 20)
+ reagents_list = list("sacid" = 20)
build_path = /obj/item/weapon/computer_hardware/processor_unit
category = list("Computer Parts")
@@ -226,7 +226,7 @@
req_tech = list("programming" = 2, "engineering" = 2)
build_type = IMPRINTER
materials = list(MAT_GLASS = 800)
- reagents = list("sacid" = 20)
+ reagents_list = list("sacid" = 20)
build_path = /obj/item/weapon/computer_hardware/processor_unit/small
category = list("Computer Parts")
@@ -236,7 +236,7 @@
req_tech = list("programming" = 5, "engineering" = 4)
build_type = IMPRINTER
materials = list(MAT_GLASS= 6400, MAT_GOLD = 2000)
- reagents = list("sacid" = 40)
+ reagents_list = list("sacid" = 40)
build_path = /obj/item/weapon/computer_hardware/processor_unit/photonic
category = list("Computer Parts")
@@ -246,6 +246,6 @@
req_tech = list("programming" = 4, "engineering" = 3)
build_type = IMPRINTER
materials = list(MAT_GLASS = 3200, MAT_GOLD = 1000)
- reagents = list("sacid" = 20)
+ reagents_list = list("sacid" = 20)
build_path = /obj/item/weapon/computer_hardware/processor_unit/photonic/small
category = list("Computer Parts")
\ No newline at end of file
diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm
index 36ade8b17ca..05fcc6cde92 100644
--- a/code/modules/research/designs/weapon_designs.dm
+++ b/code/modules/research/designs/weapon_designs.dm
@@ -69,7 +69,7 @@
req_tech = list("combat" = 5, "materials" = 5, "biotech" = 6, "plasmatech" = 7)
build_type = PROTOLATHE
materials = list(MAT_GOLD = 5000,MAT_URANIUM = 10000)
- reagents = list("mutagen" = 40)
+ reagents_list = list("mutagen" = 40)
build_path = /obj/item/weapon/gun/energy/decloner
category = list("Weapons")
@@ -110,7 +110,7 @@
req_tech = list("materials" = 2, "biotech" = 4)
build_type = PROTOLATHE
materials = list(MAT_METAL = 2000, MAT_GLASS = 500)
- reagents = list("radium" = 20)
+ reagents_list = list("radium" = 20)
build_path = /obj/item/weapon/gun/energy/floragun
category = list("Weapons")
diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm
index 1930b09d148..76a956259bf 100644
--- a/code/modules/research/rdconsole.dm
+++ b/code/modules/research/rdconsole.dm
@@ -256,7 +256,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
var/datum/design/D = files.known_designs[href_list["copy_design_ID"]]
if(D)
var/autolathe_friendly = 1
- if(D.reagents.len)
+ if(D.reagents_list.len)
autolathe_friendly = 0
D.category -= "Imported"
else
@@ -426,16 +426,16 @@ won't update every console in existence) but it's more of a hassle to do. Also,
enough_materials = 0
g2g = 0
else
- for(var/R in being_built.reagents)
- if(!linked_lathe.reagents.has_reagent(R, being_built.reagents[R]*coeff))
+ for(var/R in being_built.reagents_list)
+ if(!linked_lathe.reagents.has_reagent(R, being_built.reagents_list[R]*coeff))
linked_lathe.say("Not enough reagents to complete prototype.")
enough_materials = 0
g2g = 0
if(enough_materials)
linked_lathe.materials.use_amount(efficient_mats, amount)
- for(var/R in being_built.reagents)
- linked_lathe.reagents.remove_reagent(R, being_built.reagents[R]*coeff)
+ for(var/R in being_built.reagents_list)
+ linked_lathe.reagents.remove_reagent(R, being_built.reagents_list[R]*coeff)
var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes.
spawn(32*coeff*amount**0.8)
@@ -499,16 +499,16 @@ won't update every console in existence) but it's more of a hassle to do. Also,
enough_materials = 0
g2g = 0
else
- for(var/R in being_built.reagents)
- if(!linked_imprinter.reagents.has_reagent(R, being_built.reagents[R]/coeff))
+ for(var/R in being_built.reagents_list)
+ if(!linked_imprinter.reagents.has_reagent(R, being_built.reagents_list[R]/coeff))
linked_imprinter.say("Not enough reagents to complete prototype.")
enough_materials = 0
g2g = 0
if(enough_materials)
linked_imprinter.materials.use_amount(efficient_mats)
- for(var/R in being_built.reagents)
- linked_imprinter.reagents.remove_reagent(R, being_built.reagents[R]/coeff)
+ for(var/R in being_built.reagents_list)
+ linked_imprinter.reagents.remove_reagent(R, being_built.reagents_list[R]/coeff)
var/P = being_built.build_path //lets save these values before the spawn() just in case. Nobody likes runtimes.
spawn(16)
@@ -727,7 +727,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
if(D.build_type & MECHFAB) dat += "Exosuit Fabricator
"
if(D.build_type & BIOGENERATOR) dat += "Biogenerator
"
dat += "Required Materials:
"
- var/all_mats = D.materials + D.reagents
+ var/all_mats = D.materials + D.reagents_list
for(var/M in all_mats)
dat += "* [CallMaterialName(M)] x [all_mats[M]]
"
dat += "Operations: Upload to Database Clear Slot"
@@ -848,7 +848,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
var/c = 50
var/t
- var/all_materials = D.materials + D.reagents
+ var/all_materials = D.materials + D.reagents_list
for(var/M in all_materials)
t = linked_lathe.check_mat(D, M)
temp_material += " | "
@@ -882,7 +882,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
var/temp_material
var/c = 50
var/t
- var/all_materials = D.materials + D.reagents
+ var/all_materials = D.materials + D.reagents_list
for(var/M in all_materials)
t = linked_lathe.check_mat(D, M)
temp_material += " | "
@@ -967,7 +967,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
var/temp_materials
var/check_materials = 1
- var/all_materials = D.materials + D.reagents
+ var/all_materials = D.materials + D.reagents_list
for(var/M in all_materials)
temp_materials += " | "
@@ -993,7 +993,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
for(var/datum/design/D in matching_designs)
var/temp_materials
var/check_materials = 1
- var/all_materials = D.materials + D.reagents
+ var/all_materials = D.materials + D.reagents_list
for(var/M in all_materials)
temp_materials += " | "
if (!linked_imprinter.check_mat(D, M))
diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm
index 5534256453f..cc5f39f8672 100644
--- a/code/modules/research/xenobiology/xenobiology.dm
+++ b/code/modules/research/xenobiology/xenobiology.dm
@@ -239,7 +239,7 @@
user.mind.transfer_to(SM)
SM.languages_spoken = user.languages_spoken
SM.languages_understood = user.languages_understood
- SM.faction = user.faction
+ SM.faction = user.faction.Copy()
SM.sentience_act() //Same deal here as with sentience
user.death()
SM << "In a quick flash, you feel your consciousness flow into [SM]!"
diff --git a/code/modules/ruins/ruin_areas.dm b/code/modules/ruins/ruin_areas.dm
index 817adb8f5ad..b0444fe9b97 100644
--- a/code/modules/ruins/ruin_areas.dm
+++ b/code/modules/ruins/ruin_areas.dm
@@ -19,6 +19,8 @@
//Areas
+/area/ruin/unpowered/hierophant
+ name = "Hierophant's Arena"
/area/ruin/unpowered/no_grav/way_home
name = "\improper Salvation"
diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm
new file mode 100644
index 00000000000..77e69582ef0
--- /dev/null
+++ b/code/modules/station_goals/bsa.dm
@@ -0,0 +1,321 @@
+// Crew has to build a bluespace cannon
+// Cargo orders part for high price
+// Requires high amount of power
+// Requires high level stock parts
+/datum/station_goal/bluespace_cannon
+ name = "Bluespace Artillery"
+
+/datum/station_goal/bluespace_cannon/get_report()
+ return {"Our military presence is inadequate in your sector.
+ We need you to construct BSA-[rand(0-99)] Artillery position aboard your station.
+
+ Base parts should be availible for shipping by your cargo shuttle.
+ -Nanotrasen Naval Command"}
+
+/datum/station_goal/bluespace_cannon/on_report()
+ //Unlock BSA parts
+ var/datum/supply_pack/misc/bsa/P = SSshuttle.supply_packs[/datum/supply_pack/misc/bsa]
+ P.special_enabled = TRUE
+
+/datum/station_goal/bluespace_cannon/check_completion()
+ if(..())
+ return TRUE
+ var/obj/machinery/bsa/full/B = locate()
+ if(B && !B.stat)
+ return TRUE
+ return FALSE
+
+/obj/machinery/bsa
+ icon = 'icons/obj/machines/particle_accelerator.dmi'
+ density = 1
+ anchored = 1
+
+/obj/machinery/bsa/back
+ name = "Bluespace Artillery Generator"
+ desc = "Generates cannon pulse. Needs to be linked with a fusor. "
+ icon_state = "power_box"
+
+/obj/machinery/bsa/back/attackby(obj/item/weapon/W, mob/user, params)
+ if(istype(W, /obj/item/device/multitool))
+ var/obj/item/device/multitool/M = W
+ M.buffer = src
+ user << "You store linkage information in [W]'s buffer."
+ else
+ return ..()
+
+/obj/machinery/bsa/front
+ name = "Bluespace Artillery Bore"
+ desc = "Do not stand in front of cannon during operation. Needs to be linked with a fusor."
+ icon_state = "emitter_center"
+
+/obj/machinery/bsa/front/attackby(obj/item/weapon/W, mob/user, params)
+ if(istype(W, /obj/item/device/multitool))
+ var/obj/item/device/multitool/M = W
+ M.buffer = src
+ user << "You store linkage information in [W]'s buffer."
+ else
+ return ..()
+
+/obj/machinery/bsa/middle
+ name = "Bluespace Artillery Fusor"
+ desc = "Contents classifed by Nanotrasen Naval Command. Needs to be linked with the other BSA parts using multitool."
+ icon_state = "fuel_chamber"
+ var/obj/machinery/bsa/back/back
+ var/obj/machinery/bsa/front/front
+
+/obj/machinery/bsa/middle/attackby(obj/item/weapon/W, mob/user, params)
+ if(istype(W, /obj/item/device/multitool))
+ var/obj/item/device/multitool/M = W
+ if(M.buffer)
+ if(istype(M.buffer,/obj/machinery/bsa/back))
+ back = M.buffer
+ M.buffer = null
+ user << "You link [src] with [back]."
+ else if(istype(M.buffer,/obj/machinery/bsa/front))
+ front = M.buffer
+ M.buffer = null
+ user << "You link [src] with [front]."
+ else
+ return ..()
+
+/obj/machinery/bsa/middle/proc/check_completion()
+ if(!front || !back)
+ return "No linked parts detected!"
+ if(front.y != y || back.y != y || !(front.x > x && back.x < x || front.x < x && back.x > x) || front.z != z || back.z != z)
+ return "Parts misaligned!"
+ if(!has_space())
+ return "Not enough free space!"
+
+/obj/machinery/bsa/middle/proc/has_space()
+ var/cannon_dir = get_cannon_direction()
+ var/x_min
+ var/x_max
+ switch(cannon_dir)
+ if(EAST)
+ x_min = x - 4 //replace with defines later
+ x_max = x + 6
+ if(WEST)
+ x_min = x + 4
+ x_max = x - 6
+
+ for(var/turf/T in block(locate(x_min,y-1,z),locate(x_max,y+1,z)))
+ if(T.density || istype(T, /turf/open/space))
+ return FALSE
+ return TRUE
+
+/obj/machinery/bsa/middle/proc/get_cannon_direction()
+ if(front.x > x && back.x < x)
+ return EAST
+ else if(front.x < x && back.x > x)
+ return WEST
+
+
+/obj/machinery/bsa/full
+ name = "Bluespace Artillery"
+ desc = "Long range bluespace artillery."
+ icon = 'icons/obj/lavaland/cannon.dmi'
+ icon_state = "orbital_cannon1"
+ unsecuring_tool = null
+ var/static/image/top_layer = null
+ var/ex_power = 3
+ var/power_used_per_shot = 2000000 //enough to kil standard apc - todo : make this use wires instead and scale explosion power with it
+ pixel_y = -32
+ pixel_x = -192
+ bound_width = 352
+ bound_x = -192
+ appearance_flags = NONE //Removes default TILE_BOUND
+
+/obj/machinery/bsa/full/proc/get_front_turf()
+ switch(dir)
+ if(WEST)
+ return locate(x - 6,y,z)
+ if(EAST)
+ return locate(x + 4,y,z)
+ return get_turf(src)
+
+/obj/machinery/bsa/full/proc/get_back_turf()
+ switch(dir)
+ if(WEST)
+ return locate(x + 4,y,z)
+ if(EAST)
+ return locate(x - 6,y,z)
+ return get_turf(src)
+
+/obj/machinery/bsa/full/proc/get_target_turf()
+ switch(dir)
+ if(WEST)
+ return locate(1,y,z)
+ if(EAST)
+ return locate(world.maxx,y,z)
+ return get_turf(src)
+
+/obj/machinery/bsa/full/New(loc,cannon_direction = WEST)
+ ..()
+ switch(cannon_direction)
+ if(WEST)
+ dir = WEST
+ pixel_x = -192
+ top_layer = image("icons/obj/lavaland/orbital_cannon.dmi", "top_west")
+ top_layer.layer = ABOVE_MOB_LAYER
+ icon_state = "cannon_west"
+ if(EAST)
+ dir = EAST
+ top_layer = image("icons/obj/lavaland/orbital_cannon.dmi", "top_east")
+ top_layer.layer = ABOVE_MOB_LAYER
+ icon_state = "cannon_east"
+ add_overlay(top_layer)
+
+/obj/machinery/bsa/full/proc/fire()
+ var/turf/point = get_front_turf()
+ for(var/turf/T in getline(get_step(point,dir),get_target_turf()))
+ T.ex_act(1)
+ point.Beam(get_target_turf(),icon_state="bsa_beam",icon='icons/effects/beam.dmi',time=50,maxdistance = world.maxx) //ZZZAP
+
+
+/obj/structure/filler
+ name = "big machinery part"
+ density = 1
+ anchored = 1
+ invisibility = INVISIBILITY_ABSTRACT
+ var/obj/machinery/parent
+
+/obj/structure/filler/ex_act()
+ return
+
+/obj/item/weapon/circuitboard/machine/bsa/back
+ name = "circuit board (Bluespace Artillery Generator)"
+ build_path = /obj/machinery/bsa/back
+ origin_tech = "engineering=2;combat=2;bluespace=2" //No freebies!
+ req_components = list(
+ /obj/item/weapon/stock_parts/capacitor/quadratic = 5,
+ /obj/item/stack/cable_coil = 2)
+
+/obj/item/weapon/circuitboard/machine/bsa/middle
+ name = "circuit board (Bluespace Artillery Fusor)"
+ build_path = /obj/machinery/bsa/middle
+ origin_tech = "engineering=2;combat=2;bluespace=2"
+ req_components = list(
+ /obj/item/weapon/ore/bluespace_crystal = 20,
+ /obj/item/stack/cable_coil = 2)
+
+/obj/item/weapon/circuitboard/machine/bsa/front
+ name = "circuit board (Bluespace Artillery Bore)"
+ build_path = /obj/machinery/bsa/front
+ origin_tech = "engineering=2;combat=2;bluespace=2"
+ req_components = list(
+ /obj/item/weapon/stock_parts/manipulator/femto = 5,
+ /obj/item/stack/cable_coil = 2)
+
+/obj/item/weapon/circuitboard/machine/computer/bsa_control
+ name = "circuit board (Bluespace Artillery Controls)"
+ build_path = /obj/machinery/computer/bsa_control
+ origin_tech = "engineering=2;combat=2;bluespace=2"
+
+/obj/machinery/computer/bsa_control
+ name = "Bluespace Artillery Control"
+ var/obj/machinery/bsa/full/cannon
+ var/ready = FALSE
+ var/notice
+ var/target
+ use_power = 0
+ circuit = /obj/machinery/computer/bsa_control
+ icon = 'icons/obj/machines/particle_accelerator.dmi'
+ icon_state = "control_boxp"
+ var/area_aim = FALSE //should also show areas for targeting
+
+/obj/machinery/computer/bsa_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
+ datum/tgui/master_ui = null, datum/ui_state/state = physical_state)
+ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "bsa", name, 400, 305, master_ui, state)
+ ui.open()
+
+/obj/machinery/computer/bsa_control/ui_data()
+ var/list/data = list()
+ data["ready"] = ready
+ data["connected"] = cannon
+ data["notice"] = notice
+ if(target)
+ data["target"] = get_target_name()
+ return data
+
+/obj/machinery/computer/bsa_control/ui_act(action, params)
+ if(..())
+ return
+ switch(action)
+ if("build")
+ cannon = deploy()
+ . = TRUE
+ if("fire")
+ fire(usr)
+ . = TRUE
+ if("recalibrate")
+ calibrate(usr)
+ . = TRUE
+ update_icon()
+
+/obj/machinery/computer/bsa_control/proc/calibrate(mob/user)
+ var/list/gps_locators = list()
+ for(var/obj/item/device/gps/G in GPS_list) //nulls on the list somehow
+ gps_locators[G.gpstag] = G
+
+ var/list/options = gps_locators
+ if(area_aim)
+ options += teleportlocs
+ var/V = input(user,"Select target", "Select target",null) in options|null
+ target = options[V]
+
+
+/obj/machinery/computer/bsa_control/proc/get_target_name()
+ if(istype(target,/area))
+ var/area/A = target
+ return A.name
+ else if(istype(target,/obj/item/device/gps))
+ var/obj/item/device/gps/G = target
+ return G.gpstag
+
+/obj/machinery/computer/bsa_control/proc/get_impact_turf()
+ if(istype(target,/area))
+ return pick(get_area_turfs(target))
+ else if(istype(target,/obj/item/device/gps))
+ return get_turf(target)
+
+/obj/machinery/computer/bsa_control/proc/fire(mob/user)
+ if(cannon.stat)
+ notice = "Cannon unpowered!"
+ return
+ notice = null
+ cannon.use_power(cannon.power_used_per_shot)
+ cannon.fire()
+ ready = FALSE
+ var/turf/bullseye = get_impact_turf()
+ message_admins("[key_name_admin(usr)] has launched an artillery strike.")
+ explosion(bullseye,cannon.ex_power,cannon.ex_power*2,cannon.ex_power*4)
+ addtimer(src,"ready_cannon",600)
+
+/obj/machinery/computer/bsa_control/proc/ready_cannon()
+ ready = TRUE
+
+/obj/machinery/computer/bsa_control/proc/deploy(force=FALSE)
+ var/obj/machinery/bsa/full/prebuilt = locate() in range(7) //In case of adminspawn
+ if(prebuilt)
+ ready = TRUE
+ return prebuilt
+
+ var/obj/machinery/bsa/middle/centerpiece = locate() in range(7)
+ if(!centerpiece)
+ notice = "No BSA parts detected nearby."
+ return null
+ notice = centerpiece.check_completion()
+ if(notice)
+ return null
+ //Totally nanite construction system not an immersion breaking spawning
+ var/datum/effect_system/smoke_spread/s = new
+ s.set_up(4, 1, get_turf(centerpiece), 0)
+ s.start()
+ var/obj/machinery/bsa/full/cannon = new(get_turf(centerpiece),cannon_direction=centerpiece.get_cannon_direction())
+ qdel(centerpiece.front)
+ qdel(centerpiece.back)
+ qdel(centerpiece)
+ ready = TRUE
+ return cannon
diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm
new file mode 100644
index 00000000000..6de3312238f
--- /dev/null
+++ b/code/modules/station_goals/dna_vault.dm
@@ -0,0 +1,276 @@
+//Crew has to create dna vault
+// Cargo can order DNA samplers + DNA vault boards
+// DNA vault requires x animals ,y plants, z human dna
+// DNA vaults require high tier stock parts and cold
+// After completion each crewmember can receive single upgrade chosen out of 2 for the mob.
+#define VAULT_TOXIN "Toxin Adaptation"
+#define VAULT_NOBREATH "Lung Enhancement"
+#define VAULT_FIREPROOF "Thermal Regulation"
+#define VAULT_STUNTIME "Neural Repathing"
+#define VAULT_ARMOUR "Bone Reinforcment"
+
+/datum/station_goal/dna_vault
+ name = "DNA Vault"
+ var/animal_count
+ var/human_count
+ var/plant_count
+
+/datum/station_goal/dna_vault/New()
+ ..()
+ animal_count = rand(15,20) //might be too few given ~15 roundstart stationside ones
+ human_count = rand(round(0.75 * ticker.totalPlayersReady) , ticker.totalPlayersReady) // 75%+ roundstart population.
+ var/non_standard_plants = non_standard_plants_count()
+ plant_count = rand(round(0.7 * non_standard_plants),round(0.9 * non_standard_plants))
+
+/datum/station_goal/dna_vault/proc/non_standard_plants_count()
+ . = 0
+ for(var/T in subtypesof(/obj/item/seeds)) //put a cache if it's used anywhere else
+ var/obj/item/seeds/S = T
+ if(initial(S.rarity) > 0)
+ .++
+
+/datum/station_goal/dna_vault/get_report()
+ return {"Our long term prediction systems say there's 99% chance of system-wide cataclysm in near future.
+ We need you to construct DNA Vault aboard your station.
+
+ DNA Vault needs to contain samples of:
+ [animal_count] unique animal data
+ [plant_count] unique non-standard plant data
+ [human_count] unique sapient humanoid DNA data
+
+ Base vault parts should be availible for shipping by your cargo shuttle."}
+
+
+/datum/station_goal/dna_vault/on_report()
+ var/datum/supply_pack/P = SSshuttle.supply_packs[/datum/supply_pack/misc/dna_vault]
+ P.special_enabled = TRUE
+
+ P = SSshuttle.supply_packs[/datum/supply_pack/misc/dna_probes]
+ P.special_enabled = TRUE
+
+/datum/station_goal/dna_vault/check_completion()
+ if(..())
+ return TRUE
+ for(var/obj/machinery/dna_vault/V in machines)
+ if(V.animals.len >= animal_count && V.plants.len >= plant_count && V.dna >= human_count)
+ return TRUE
+ return FALSE
+
+
+/obj/item/device/dna_probe
+ name = "DNA Sampler"
+ desc = "Can be used to take chemical and genetic samples of pretty much anything."
+ icon = 'icons/obj/syringe.dmi'
+ item_state = "hypo"
+ icon_state = "hypo"
+ flags = NOBLUDGEON
+ var/list/animals = list()
+ var/list/plants = list()
+ var/list/dna = list()
+
+/obj/item/device/dna_probe/proc/clear_data()
+ animals = list()
+ plants = list()
+ dna = list()
+
+var/list/non_simple_animals = typecacheof(list(/mob/living/carbon/monkey,/mob/living/carbon/alien))
+
+/obj/item/device/dna_probe/afterattack(atom/target, mob/user, proximity)
+ ..()
+ if(!proximity || !target)
+ return
+ //tray plants
+ if(istype(target,/obj/machinery/hydroponics))
+ var/obj/machinery/hydroponics/H = target
+ if(!H.myseed)
+ return
+ if(!H.harvest)// So it's bit harder.
+ user << "Plants needs to be ready to harvest to perform full data scan." //Because space dna is actually magic
+ return
+ if(plants[H.myseed.type])
+ user << "Plant data already present in local storage."
+ return
+ plants[H.myseed.type] = 1
+ user << "Plant data added to local storage."
+
+ //animals
+ if(isanimal(target) || is_type_in_typecache(target,non_simple_animals))
+ if(isanimal(target))
+ var/mob/living/simple_animal/A = target
+ if(!A.healable)//simple approximation of being animal not a robot or similar
+ user << "No compatibile DNA detected"
+ return
+ if(animals[target.type])
+ user << "Animal data already present in local storage."
+ return
+ animals[target.type] = 1
+ user << "Animal data added to local storage."
+
+ //humans
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ if(dna[H.dna.uni_identity])
+ user << "Humanoid data already present in local storage."
+ return
+ dna[H.dna.uni_identity] = 1
+ user << "Humanoid data added to local storage."
+
+
+/obj/item/weapon/circuitboard/machine/dna_vault
+ name = "circuit board (DNA Vault)"
+ build_path = /obj/machinery/dna_vault
+ origin_tech = "engineering=2;combat=2;bluespace=2" //No freebies!
+ req_components = list(
+ /obj/item/weapon/stock_parts/capacitor/quadratic = 5,
+ /obj/item/stack/cable_coil = 2)
+
+/obj/machinery/dna_vault
+ name = "DNA Vault"
+ desc = "Break glass in case of apocalypse."
+ icon = 'icons/obj/machines/dna_vault.dmi'
+ icon_state = "vault"
+ density = 1
+ anchored = 1
+ idle_power_usage = 5000
+ pixel_x = -32
+ pixel_y = -64
+ luminosity = 1
+
+ //High defaults so it's not completed automatically if there's no station goal
+ var/animals_max = 100
+ var/plants_max = 100
+ var/dna_max = 100
+ var/list/animals = list()
+ var/list/plants = list()
+ var/list/dna = list()
+
+ var/completed = FALSE
+ var/list/power_lottery = list()
+
+ var/list/obj/structure/fillers = list()
+
+/obj/machinery/dna_vault/New()
+ //TODO: Replace this,bsa and gravgen with some big machinery datum
+ var/list/occupied = list()
+ for(var/direct in list(EAST,WEST,SOUTHEAST,SOUTHWEST))
+ occupied += get_step(src,direct)
+ occupied += locate(x+1,y-2,z)
+ occupied += locate(x-1,y-2,z)
+
+ for(var/T in occupied)
+ var/obj/structure/filler/F = new(T)
+ F.parent = src
+ fillers += F
+
+ if(ticker.mode)
+ for(var/datum/station_goal/dna_vault/G in ticker.mode.station_goals)
+ animals_max = G.animal_count
+ plants_max = G.plant_count
+ dna_max = G.human_count
+ break
+
+/obj/machinery/dna_vault/Destroy()
+ for(var/V in fillers)
+ var/obj/structure/filler/filler = V
+ filler.parent = null
+ qdel(filler)
+ . = ..()
+
+
+/obj/machinery/dna_vault/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = physical_state)
+ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ roll_powers(user)
+ ui = new(user, src, ui_key, "dna_vault", name, 350, 400, master_ui, state)
+ ui.open()
+
+
+/obj/machinery/dna_vault/proc/roll_powers(mob/user)
+ if(user in power_lottery)
+ return
+ var/list/L = list()
+ var/list/possible_powers = list(VAULT_TOXIN,VAULT_NOBREATH,VAULT_FIREPROOF,VAULT_STUNTIME,VAULT_ARMOUR)
+ L += pick_n_take(possible_powers)
+ L += pick_n_take(possible_powers)
+ power_lottery[user] = L
+
+/obj/machinery/dna_vault/ui_data(mob/user) //TODO Make it % bars maybe
+ var/list/data = list()
+ data["plants"] = plants.len
+ data["plants_max"] = plants_max
+ data["animals"] = animals.len
+ data["animals_max"] = animals_max
+ data["dna"] = dna.len
+ data["dna_max"] = dna_max
+ data["completed"] = completed
+ data["used"] = TRUE
+ data["choiceA"] = ""
+ data["choiceB"] = ""
+ if(user && completed)
+ var/list/L = power_lottery[user]
+ if(L && L.len)
+ data["used"] = FALSE
+ data["choiceA"] = L[1]
+ data["choiceB"] = L[2]
+ return data
+
+/obj/machinery/dna_vault/ui_act(action, params)
+ if(..())
+ return
+ switch(action)
+ if("gene")
+ upgrade(usr,params["choice"])
+ . = TRUE
+
+/obj/machinery/dna_vault/proc/check_goal()
+ if(plants.len >= plants_max && animals.len >= animals_max && dna.len >= dna_max)
+ completed = TRUE
+
+
+/obj/machinery/dna_vault/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/device/dna_probe))
+ var/obj/item/device/dna_probe/P = I
+ var/uploaded = 0
+ for(var/plant in P.plants)
+ if(!plants[plant])
+ uploaded++
+ plants[plant] = 1
+ for(var/animal in P.animals)
+ if(!animals[animal])
+ uploaded++
+ animals[animal] = 1
+ for(var/ui in P.dna)
+ if(!dna[ui])
+ uploaded++
+ dna[ui] = 1
+ check_goal()
+ user << "[uploaded] new datapoints uploaded."
+ else
+ return ..()
+
+
+
+/obj/machinery/dna_vault/proc/upgrade(mob/living/carbon/human/H,upgrade_type)
+ if(!(upgrade_type in power_lottery[H]))
+ return
+ var/datum/species/S = H.dna.species
+ switch(upgrade_type)
+ if(VAULT_TOXIN)
+ H << "You feel resistant to airborne toxins."
+ S.tox_breath_dam_min = 0
+ S.tox_breath_dam_max = 0
+ S.specflags |= VIRUSIMMUNE
+ if(VAULT_NOBREATH)
+ H << "Your lungs feel great."
+ S.specflags |= NOBREATH
+ if(VAULT_FIREPROOF)
+ H << "Your feel fireproof."
+ S.burnmod = 0.5
+ S.heatmod = 0
+ if(VAULT_STUNTIME)
+ H << "Nothing can keep you down for long."
+ S.stunmod = 0.5
+ if(VAULT_ARMOUR)
+ H << "Your feel tough."
+ S.armor = 30
+ power_lottery[H] = list()
\ No newline at end of file
diff --git a/code/modules/station_goals/shield.dm b/code/modules/station_goals/shield.dm
new file mode 100644
index 00000000000..357cc426e15
--- /dev/null
+++ b/code/modules/station_goals/shield.dm
@@ -0,0 +1,181 @@
+//Station Shield
+// A chain of satellites encircles the station
+// Satellites be actived to generate a shield that will block unorganic matter from passing it.
+/datum/station_goal/station_shield
+ name = "Station Shield"
+ var/coverage_goal = 500
+
+/datum/station_goal/station_shield/get_report()
+ return {"The station is located in a zone full of space debris.
+ We have a prototype shielding system you will deploy to reduce collision related accidents.
+
+ You can order the satellites and control systems through cargo shuttle.
+ "}
+
+
+/datum/station_goal/station_shield/on_report()
+ //Unlock
+ var/datum/supply_pack/P = SSshuttle.supply_packs[/datum/supply_pack/misc/shield_sat]
+ P.special_enabled = TRUE
+
+ P = SSshuttle.supply_packs[/datum/supply_pack/misc/shield_sat_control]
+ P.special_enabled = TRUE
+
+/datum/station_goal/station_shield/check_completion()
+ if(..())
+ return TRUE
+ if(get_coverage() >= coverage_goal)
+ return TRUE
+ return FALSE
+
+/datum/station_goal/proc/get_coverage()
+ var/list/coverage = list()
+ for(var/obj/machinery/satellite/meteor_shield/A in machines)
+ if(!A.active || A.z != ZLEVEL_STATION)
+ continue
+ coverage |= view(A.kill_range,A)
+ return coverage.len
+
+/obj/item/weapon/circuitboard/machine/computer/sat_control
+ name = "circuit board (Satellite Network Control)"
+ build_path = /obj/machinery/computer/sat_control
+ origin_tech = "engineering=3"
+
+/obj/machinery/computer/sat_control
+ name = "Satellite control"
+ desc = "Used to control the satellite network."
+ circuit = /obj/item/weapon/circuitboard/machine/computer/sat_control
+ var/notice
+
+/obj/machinery/computer/sat_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, \
+ datum/tgui/master_ui = null, datum/ui_state/state = physical_state)
+ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "sat_control", name, 400, 305, master_ui, state)
+ ui.open()
+
+/obj/machinery/computer/sat_control/ui_act(action, params)
+ if(..())
+ return
+ switch(action)
+ if("toggle")
+ toggle(text2num(params["id"]))
+ . = TRUE
+
+/obj/machinery/computer/sat_control/proc/toggle(id)
+ for(var/obj/machinery/satellite/S in machines)
+ if(S.id == id && S.z == z)
+ S.toggle()
+
+/obj/machinery/computer/sat_control/ui_data()
+ var/list/data = list()
+
+ data["satellites"] = list()
+ for(var/obj/machinery/satellite/S in machines)
+ data["satellites"] += list(list(
+ "id" = S.id,
+ "active" = S.active,
+ "mode" = S.mode
+ ))
+ data["notice"] = notice
+
+
+ var/datum/station_goal/station_shield/G = locate() in ticker.mode.station_goals
+ if(G)
+ data["meteor_shield"] = 1
+ data["meteor_shield_coverage"] = G.get_coverage()
+ data["meteor_shield_coverage_max"] = G.coverage_goal
+ return data
+
+
+/obj/machinery/satellite
+ name = "Defunct Satellite"
+ desc = ""
+ icon = 'icons/obj/machines/satellite.dmi'
+ icon_state = "sat_inactive"
+ var/mode = "NTPROBEV0.8"
+ var/active = FALSE
+ density = 1
+ var/static/gid = 0
+ var/id = 0
+
+/obj/machinery/satellite/New()
+ ..()
+ id = gid++
+
+/obj/machinery/satellite/interact(mob/user)
+ toggle(user)
+
+/obj/machinery/satellite/proc/toggle(mob/user)
+ if(!active && !isinspace())
+ if(user)
+ user << "You can only active the [src] in space."
+ return FALSE
+ if(user)
+ user << "You [active ? "deactivate": "activate"] the [src]"
+ active = !active
+ if(active)
+ animate(src, pixel_y = 2, time = 10, loop = -1)
+ anchored = 1
+ else
+ animate(src, pixel_y = 0, time = 10)
+ anchored = 0
+ update_icon()
+
+/obj/machinery/satellite/update_icon()
+ icon_state = active ? "sat_active" : "sat_inactive"
+
+/obj/machinery/satellite/attackby(obj/item/I, mob/user, params)
+ if(istype(I, /obj/item/device/multitool))
+ user << "// NTSAT-[id] // Mode : [active ? "PRIMARY" : "STANDBY"] //[emagged ? "DEBUG_MODE //" : ""]"
+ else
+ return ..()
+
+/obj/machinery/satellite/meteor_shield
+ name = "Meteor Shield Satellite"
+ desc = "Meteor Point Defense Satellite"
+ mode = "M-SHIELD"
+ var/kill_range = 10
+
+/obj/machinery/satellite/meteor_shield/proc/space_los(meteor)
+ for(var/turf/T in getline(src,meteor))
+ if(!istype(T, /turf/open/space))
+ return FALSE
+ return TRUE
+
+/obj/machinery/satellite/meteor_shield/process()
+ if(!active)
+ return
+ for(var/obj/effect/meteor/M in meteor_list)
+ if(M.z != z)
+ continue
+ if(get_dist(M,src) > kill_range)
+ continue
+ if(!emagged && space_los(M))
+ Beam(get_turf(M),time=5,maxdistance=kill_range)
+ qdel(M)
+
+/obj/machinery/satellite/meteor_shield/toggle(user)
+ if(!..(user))
+ return FALSE
+ if(emagged)
+ if(active)
+ change_meteor_chance(2)
+ else
+ change_meteor_chance(0.5)
+
+/obj/machinery/satellite/meteor_shield/proc/change_meteor_chance(mod)
+ var/datum/round_event_control/E = locate(/datum/round_event_control/meteor_wave) in SSevent.control
+ if(E)
+ E.weight *= mod
+
+/obj/machinery/satellite/meteor_shield/Destroy()
+ . = ..()
+ if(active && emagged)
+ change_meteor_chance(0.5)
+
+/obj/machinery/satellite/meteor_shield/emag_act()
+ if(!emagged)
+ emagged = 1
+ if(active)
+ change_meteor_chance(2)
diff --git a/code/modules/station_goals/station_goal.dm b/code/modules/station_goals/station_goal.dm
new file mode 100644
index 00000000000..daf6ee7dd1f
--- /dev/null
+++ b/code/modules/station_goals/station_goal.dm
@@ -0,0 +1,64 @@
+//TODO
+// Admin button to override with your own
+// Sabotage objective for tators
+// Multiple goals with less impact but more department focused
+
+/datum/station_goal
+ var/name = "Generic Goal"
+ var/weight = 1 //In case of multiple goals later.
+ var/required_crew = 10
+ var/list/gamemode_blacklist = list()
+ var/completed = FALSE
+ var/report_message = "Complete this goal."
+
+/datum/station_goal/proc/send_report()
+ priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", 'sound/AI/commandreport.ogg')
+ print_command_report(get_report(),"Nanotrasen Directive [pick(phonetic_alphabet)] \Roman[rand(1,50)]")
+ on_report()
+
+/datum/station_goal/proc/on_report()
+ //Additional unlocks/changes go here
+ return
+
+/datum/station_goal/proc/get_report()
+ return report_message
+
+/datum/station_goal/proc/check_completion()
+ return completed
+
+/datum/station_goal/proc/print_result()
+ if(check_completion())
+ world << "Station Goal : [name] : Completed!"
+ else
+ world << "Station Goal : [name] : Failed!"
+
+/datum/station_goal/Destroy()
+ ticker.mode.station_goals -= src
+ . = ..()
+
+/datum/station_goal/Topic(href, href_list)
+ ..()
+
+ if(!check_rights(R_ADMIN))
+ return
+
+ if(href_list["announce"])
+ on_report()
+ send_report()
+ else if(href_list["remove"])
+ qdel(src)
+
+/*
+//Crew has to create alien intelligence detector
+// Requires a lot of minerals
+// Dish requires a lot of power
+// Needs five? AI's for decoding purposes
+/datum/station_goal/seti
+ name = "SETI Project"
+
+//Crew Sweep
+//Blood samples and special scans of amount of people on roundstart manifest.
+//Should keep sec busy.
+//Maybe after completion you'll get some ling detecting gear or some station wide DNA scan ?
+
+*/
\ No newline at end of file
diff --git a/code/modules/tgui/states.dm b/code/modules/tgui/states.dm
index ee21dfd1206..50b73da7bc2 100644
--- a/code/modules/tgui/states.dm
+++ b/code/modules/tgui/states.dm
@@ -26,7 +26,7 @@
. = max(., UI_INTERACTIVE)
// Regular ghosts can always at least view if in range.
- if(get_dist(src_object, src) < user.client.view)
+ if(get_dist(src_object, user) < user.client.view)
. = max(., UI_UPDATE)
// Check if the state allows interaction
diff --git a/code/modules/tgui/subsystem.dm b/code/modules/tgui/subsystem.dm
index 81c67c67d1c..c623e3c39ae 100644
--- a/code/modules/tgui/subsystem.dm
+++ b/code/modules/tgui/subsystem.dm
@@ -182,8 +182,15 @@
processing_uis.Remove(ui) // Remove it from the list of processing UIs.
if(ui.user) // If the user exists, remove it from them too.
ui.user.open_uis.Remove(ui)
- var/list/uis = open_uis[src_object_key][ui.ui_key] // Remove it from the list of open UIs.
+ var/Ukey = ui.ui_key
+ var/list/uis = open_uis[src_object_key][Ukey] // Remove it from the list of open UIs.
uis.Remove(ui)
+ if(!uis.len)
+ var/list/uiobj = open_uis[src_object_key]
+ uiobj.Remove(Ukey)
+ if(!uiobj.len)
+ open_uis.Remove(src_object_key)
+
return 1 // Let the caller know we did it.
/**
diff --git a/code/modules/uplink/uplink_item.dm b/code/modules/uplink/uplink_item.dm
index db0d86a9863..75c136ea925 100644
--- a/code/modules/uplink/uplink_item.dm
+++ b/code/modules/uplink/uplink_item.dm
@@ -521,6 +521,7 @@ var/list/uplink_items = list() // Global list so we only initialize this once.
deflecting all ranged weapon fire, but you also refuse to use dishonorable ranged weaponry."
item = /obj/item/weapon/sleeping_carp_scroll
cost = 17
+ surplus = 0
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/gang)
/datum/uplink_item/stealthy_weapons/throwingweapons
@@ -799,7 +800,7 @@ var/list/uplink_items = list() // Global list so we only initialize this once.
name = "Military Belt"
desc = "A robust seven-slot red belt that is capable of holding all manner of tatical equipment."
item = /obj/item/weapon/storage/belt/military
- cost = 3
+ cost = 1
exclude_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/device_tools/medkit
@@ -1111,7 +1112,7 @@ var/list/uplink_items = list() // Global list so we only initialize this once.
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/gang)
/datum/uplink_item/badass/surplus/spawn_item(turf/loc, obj/item/device/uplink/U)
- var/list/uplink_items = get_uplink_items()
+ var/list/uplink_items = get_uplink_items(ticker.mode)
var/crate_value = 50
var/obj/structure/closet/crate/C = new(loc)
@@ -1138,7 +1139,7 @@ var/list/uplink_items = list() // Global list so we only initialize this once.
cost = 0
/datum/uplink_item/badass/random/spawn_item(turf/loc, obj/item/device/uplink/U)
- var/list/uplink_items = get_uplink_items()
+ var/list/uplink_items = get_uplink_items(ticker.mode)
var/list/possible_items = list()
for(var/category in uplink_items)
for(var/item in uplink_items[category])
diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm
index 9c9a53cd9e1..ac8fdaa8b6b 100644
--- a/code/modules/vehicles/vehicle.dm
+++ b/code/modules/vehicles/vehicle.dm
@@ -129,7 +129,7 @@
/obj/vehicle/Process_Spacemove(direction)
- if(has_gravity(src))
+ if(has_gravity())
return 1
if(pulledby)
diff --git a/config/admins.txt b/config/admins.txt
index 6f2e44a9c3f..46be5e597e5 100644
--- a/config/admins.txt
+++ b/config/admins.txt
@@ -8,7 +8,6 @@
# NOTE: syntax was changed to allow hyphenation of ranknames, since spaces are stripped. #
###############################################################################################
Optimumtact = Host
-kevinz000 = Host
kingofkosmos = Game Master
MrStonedOne = Game Master
microscopics = Game Master
@@ -118,4 +117,5 @@ TechnoAlchemist = Game Master
Aloraydrel = Game Master
Quiltyquilty = Game Master
SnipeDragon = Game Master
-Fjeld = Game Master
\ No newline at end of file
+Fjeld = Game Master
+kevinz000 = Game Master
diff --git a/config/sillytips.txt b/config/sillytips.txt
index c804c3d9b43..513b91142be 100644
--- a/config/sillytips.txt
+++ b/config/sillytips.txt
@@ -8,6 +8,9 @@ Just like real life the entropy of the game can only increase with time. If thin
Completing your objectives is good practice, but the best antagonists will strive to do more than the bare minimum to really leave an impression.
The more obscure and underused a game mechanic is, the less likely your victims are to be able to deal with it.
Space is cold and it will quickly freeze you to death if you don't protect yourself. This isn't how thermodynamics really works but just go with it.
+Blobs are weak to fire! Use a flame thrower for maximum damage!
+Flash bangs can weaken blob tiles, allowing for you to easily destroy them.
+Freon is great against the blob, as it freezes the blob making it able to be shattered into a million pieces if you hit it correctly!
Cleanbot.
The wizard is supposed to be extremely strong in one on one combat, stop getting mad about it.
Sometimes a round will just be a bust. C'est la vie.
diff --git a/html/changelog.html b/html/changelog.html
index 005e0ea5582..e5ee7fea60f 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -55,6 +55,137 @@
-->
+
09 September 2016
+
Ergovisavi updated:
+
+ - Adds new loot for the colossus, the "Anomalous Crystal"
+ - Enabled colossus spawning again
+
+
Joan, Ausops updated:
+
+ - Added some very fancy tables, constructed by adding carpet tiles to a standard table frame.
+
+
MrStonedOne updated:
+
+ - Blessed our beloved code with dark magic.
+
+
Shadowlight213 updated:
+
+ - Radiation storm direct tox loss removed
+ - Radiation storms now cause a radiation alert to appear for the duration
+
+
+
08 September 2016
+
Jordie0608 updated:
+
+ - Notes can now be tagged as secret to be hidden from player viewed notes.
+
+
Lzimann updated:
+
+ - Legion implants now have a full heal when implanted instead of passive heal + spawn tentacles. The healing also goes off when you enter crit.
+
+
Yackemflam updated:
+
+ - You can now buy a box for a chance to mess with the stations meta for ops.
+
+
+
07 September 2016
+
A-t48 updated:
+
+ - you can now scrub freon and water vapor
+ - you can now label canisters as freon and water vapor
+
+
AnturK updated:
+
+ - Watch out for special instructions from Centcom in the intercept report.
+
+
Cheridan updated:
+
+ - Brain damage no longer causes machines to be inoperable.
+
+
Ergovisavi updated:
+
+ - Stops ash drakes from swooping across zlevels
+
+
Impisi updated:
+
+ - Increased chances of Modular Receiver drop in Maintenance
+
+
Incoming5643 updated:
+
+ - Wizards can no longer purchase the Cursed Heart from their spellbook.
+
+
Joan updated:
+
+ - The lava staff now has a short delay before creating lava, with a visible indicator.
+ - The lava staff's cooldown is now somewhat shorter, and turning lava back into basalt has a much shorter cooldown and no delay.
+
+
Lzimann updated:
+
+ - Stunprods no longer fit in your backpack, they go on your back now.
+
+
MrStonedOne updated:
+
+ - Fixed lava sometimes doing massive amounts of damage.
+ - AFK players will no longer default to continue playing during restart votes.
+
+
XDTM updated:
+
+ - Cloners now preserve your genetic mutations.
+
+
pubby updated:
+
+ - Changed military belt TC cost from 3 -> 1
+ - Update ingredient boxes to have more useful ingredients
+
+
+
04 September 2016
+
A-t48 updated:
+
+ - Radiation storms no longer spam "Your armor softened the blow."
+ - Radiation always gives a message that you are being irradiated, regardless of armor level (only an issue if you stripped off all clothing)
+ - Radiation now displays a message appropriate for all mob types (no longer references clothes).
+
+
Gun Hog updated:
+
+ - Ghosts may now read an AI or Cyborg's laws by examining them.
+
+
Joan updated:
+
+ - The talisman of construction now has 25 uses, each of which can convert a sheet of plasteel to a sheet of runed metal. It can still convert metal into construct shells, and requires no specific amount of uses to do so.
+ - Added the 'Drain Life' rune to the runes cultists can make. It will drain life from all creatures on the rune, healing the invoker.
+ - The 'Astral Communion' rune has a new sprite, made by WJohnston.
+ - You can no longer use telekinesis to hit people with items they're holding, items inside items they're holding, items embedded in them, items actually implanted in them, or items they're wearing.
+
+
MMMiracles updated:
+
+ - A set of combat gear for bears has been added, see your local russian for more information.
+
+
XDTM updated:
+
+ - Nanotrasen has now stocked the DNA Manipulators with potassium iodide instead of epinephrine as rejuvenators.
+
+
+
02 September 2016
+
A-t48 updated:
+
+ - Fixed cyborgs being able to use Power Warning emote when broken.
+
+
Iamgoofball updated:
+
+ - Freon has been reworked completely.
+ - Water Vapor has been added to the Janitor's Closet.
+
+
RemieRichards updated:
+
+ - Cutting bedsheets with a sharp object/wirecutters no longer puts the resulting cloth INSIDE OF YOU if you're holding it, what a bug.
+
+
bgobandit updated:
+
+ - You can hide small items in urinals now. Use a screwdriver to screw open the drain enclosure.
+ - Every space urinal comes complete with space urinal cake. Do not eat.
+
+
01 September 2016
Cruix updated:
@@ -1032,189 +1163,6 @@
- When a player uses a communication console to ask for the codes to the self destruct, for better or for worse, the admins can set them with a single click. Whether the admins a) click the button b) actually give the random person the codes, is another thing entirely.
- Servants of Ratvar get an alert if they have no tinkerer's caches constructed. Because it's important that they should.
-
-
06 July 2016
-
Cruix updated:
-
- - Vending machine restocking units now work.
-
-
Joan updated:
-
- - Servants should now be more aware of when scripture tiers are locked or unlocked.
- - Judicial Explosions from a Judicial Visor now mute for about 10 seconds.
-
-
MrStonedOne updated:
-
- - Instant Runoff Voting polls are now available.
-
-
RemieRichards updated:
-
- - Fixes accidental buff to botany, all modifiers should now be at the point they were at pre-bees (this does not remove, nerf or alter bees)
-
-
Xhuis updated:
-
- - The Necropolis gate now looks as regal as it should. Credit goes to KorPhaeron for turf and wall sprites.
- - Ash storms are actually damaging now.
-
-
coiax updated:
-
- - Gulag prisoners can no longer duplicate their mining efforts through window breaking on the shuttle.
- - Fixes pickaxes inside walls on lavaland, along with lava having eaten one of the storage units.
- - More fire extinguishers for lavaland mining base.
- - You can now reload your gun in CTF.
- - Dying in CTF will spawn a short lived ammo pickup, which you can walk over to reload all your weapons.
- - If reduced to critical status in CTF, you will automatically die, so you no longer have to succumb or be coup de graced. If you are conscious, you will now heal slowly if some damage got through your shield and didn't crit you.
- - The tesla now dusts all carbon mobs on the turf that it moves to, grounding rod or no.
-
-
coiax, Niknakflak updated:
-
- - Added fireplaces, fuel with logs or paper and set on fire and enjoy that warm comforting glow.
- - Cardboard cutouts are now flammable.
- - Cigarettes, fireplaces and candles now share a pool of possible igniters. So you can now esword that candle on, but turn it on first.
- - Eswords will ignite plasma in the air if turned on.
-
-
kevinz000 updated:
-
- - Kudzu is no longer unstoppable
-
-
optional name here updated:
-
- - Suit Storage Units can now disinfect items other than living and dead creatures.
-
-
-
04 July 2016
-
Gun Hog updated:
-
- - The Space Wizard Federation has finally begun teaching its pupils how to properly aim the Fireball spell!
- - Fireball spells, including the Devil version, are now aimed via mouse click. It is recommended to avoid firing at anything too close, as the user can still blow himself up!
-
-
Joan updated:
-
- - Mecha are no longer immune to ocular wardens.
-
-
Lzimann updated:
-
- - Throwing active stunbatons now has a chance to stun whoever it hits!
-
-
MMMiracles updated:
-
- - Adds space ruins. Balance not included.
- - Simple mob ghosts actually work now.
- - Puzzle1 ruin removed due to issues with projectiles.
-
-
X-TheDark updated:
-
- - Switching mobs/ghosting/etc related actions during the round will now no longer reset your hotkey settings.
-
-
Xhuis updated:
-
- - Ash storms can now occur again.
-
-
bgobandit updated:
-
- - Bluespace polycrystals, basically stacks of bluespace crystals, have been added. The ore redemptor accepts them now.
- - The ore redemptor machine should be less spammy now.
-
-
coiax updated:
-
- - The zone of hyperspace that a shuttle travels in is dynamically determined when a shuttle begins charging its engines. This is signified by the shuttle mode IGN. All shuttles must now charge engines before launching. This time is already included in the emergency shuttle timer.
- - The cargo shuttle can only be loaned to Centcom while at Centcom.
- - Immovable rods now notify ghosts when created, allowing them to orbit it and follow their path of destruction through the station.
- - Fixed bugs where no meteors would come or go from the south. Seriously, that was a real bug. Meteor showers are now about 33% stronger as a result.
-
-
-
03 July 2016
-
Cruix updated:
-
- - Hand labelers can now label storage containers.
- - You can now properly resist out of wrapped lockers.
- - You can now resist out of morgues if you are in a bodybag.
- - Mechs can no longer spam doors they do not have access to.
-
-
Joan updated:
-
- - Clock Cult can now happen at 24 players, same as cult.
- - Clock Cult player scaling is lower; 3 people, plus one for every 15 players above 30, from 1 for every 10 players with a player minimum of 30.
- - Guvax now invokes 1 second faster(5 seconds), but is 0.75 seconds slower for each scripture-valid servant above 5, up to a maximum of 15 seconds.
- - Clockwork Slabs generate components 20 seconds slower for each scripture-valid servant above 5, up to a maximum of 1 component every 5 minutes.
- - Tinkerer's Daemons that would be useless cannot be made.
-
-
-
02 July 2016
-
Joan updated:
-
- - Clockwork Proselytizers can now reform stored alloy into usable component alloy when used in-hand.
- - Mending motors start with 2500W of power in alloy, from 5000. Sigils of Transmission start with 2500W of power, from 4000. Clockwork Proselytizers start with 90 alloy, from 100.
- - Umbras have been removed.
- - Revenants have been readded, though they are now vulnerable to salt piles.
-
-
MMMiracles updated:
-
- - Added the power fist, a gauntlet with a piston-powered ram attached to the top for traitors to punch people across the station. Punch people into walls for added fun.
-
-
incoming5643 updated:
-
- - Nuke ops can now harness the power of METAL BOXES: special versions of cardboard boxes that can take a lot of abuse and can fit the whole team if need be. They're not nearly as light as their cardboard brothers though...
-
-
kevinz000 updated:
-
- - Some new emojis have been added to OOC for your enjoyment. Try them out.
- - New emojis are : coffee, trophy, tea, gear, supermatter, forceweapon, gift, kudzu, dosh, chrono, nya, and tophat. Type :nameofemoji: in OOC to use.
-
-
-
01 July 2016
-
Flavo updated:
-
- - fixed a bug where lights would not update.
-
-
Joan updated:
-
- - Clockwork Slabs now use an action button to communicate instead of the "Report" option in the menu after using a slab.
- - Clockwork Slabs now fit in pockets, the belt slot, or in the suit storage slot(if wearing clockwork armor), where they can be used as hands-free communication.
- - Clockwork items with action buttons have a new, clockwork-y background.
- - Judicial Visors now tell the user how many targets the Judicial Blast struck.
- - Judicial Markers now have sounds when appearing and exploding.
- - Wet turfs should remain that way for slightly longer than 5 seconds now.
- - Drones and Swarmers should now sound more robotic.
- - Ratvarian Spears will stun cyborgs and cultists for twice as long when thrown; on cyborgs, this should be long enough to use Guvax on them.
- - Removed the Justicar's Gavel application scripture.
- - Vitality Matrices will drain and heal 50% faster, and the base cost to revive is 20% lower; 20, from 25.
- - Vitality Matrices will not revive or heal corpses unless they can grab the ghost of the corpse, and will immediately grab the ghost when reviving.
- - Swarmers consuming swarmer shells now refunds the swarmer the entire cost of the shell instead of 2% of the shell's cost.
- - Application scriptures require at least 75 CV, from 50.
- - Revenant scriptures require at least 4 Caches, from 3, and at least 150 CV, from 100.
- - Judgement scripture requires at least 12 servants, from 10, 5 Caches, from 3, and at least 250 CV, from 100.
- - Script and Application scripture have had their component costs and requirements tweaked to reduce overuse of certain components.
- - Invoke times for a few scriptures that were instant are now very short instead.
-
-
Kor updated:
-
- - Holoparasites are no longer in the uplink
-
-
NikNak updated:
-
- - Showcases are now movable and deconstructable. Wrench them to unanchor and then screwdriver and crowbar to deconstruct.
-
-
Papa Bones updated:
-
- - Security now has energy bolas available to them in their vending machines, check them out!
-
-
bobdobbington updated:
-
- - Added skub to the AutoDrobe as a premium item.
-
-
coiax updated:
-
- - The CTF arena regenerates every round, and the blue team now shoot blue lasers.
- - Adds some descriptions to alien surgery tools
- - The agent vest can be locked and unlocked (toggling the NODROP flag)
- - An abductor team can spend data points to purchase an agent vest (note that only abductor agents are trained in their use)
- - The nuke disk reappears on the station in far more random locations, but tends to re-materialise in safe pressurised areas that aren't on fire.
-
-
name: Lzimann updated:
-
- - Mulebots with pAI cards no longer stun people
-
GoonStation 13 Development Team
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index c86cc668c44..b38c0a146bf 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -6917,3 +6917,91 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- tweak: Putting packagewrap or hand labeler in a backpack is now done by clicking
and dragging.
- bugfix: You can now wrap backpacks and other storage items with packagewrap.
+2016-09-02:
+ A-t48:
+ - bugfix: Fixed cyborgs being able to use Power Warning emote when broken.
+ Iamgoofball:
+ - experiment: Freon has been reworked completely.
+ - rscadd: Water Vapor has been added to the Janitor's Closet.
+ RemieRichards:
+ - bugfix: Cutting bedsheets with a sharp object/wirecutters no longer puts the resulting
+ cloth INSIDE OF YOU if you're holding it, what a bug.
+ bgobandit:
+ - tweak: You can hide small items in urinals now. Use a screwdriver to screw open
+ the drain enclosure.
+ - rscadd: Every space urinal comes complete with space urinal cake. Do not eat.
+2016-09-04:
+ A-t48:
+ - bugfix: Radiation storms no longer spam "Your armor softened the blow."
+ - bugfix: Radiation always gives a message that you are being irradiated, regardless
+ of armor level (only an issue if you stripped off all clothing)
+ - bugfix: Radiation now displays a message appropriate for all mob types (no longer
+ references clothes).
+ Gun Hog:
+ - rscadd: Ghosts may now read an AI or Cyborg's laws by examining them.
+ Joan:
+ - rscadd: The talisman of construction now has 25 uses, each of which can convert
+ a sheet of plasteel to a sheet of runed metal. It can still convert metal into
+ construct shells, and requires no specific amount of uses to do so.
+ - rscadd: Added the 'Drain Life' rune to the runes cultists can make. It will drain
+ life from all creatures on the rune, healing the invoker.
+ - imageadd: The 'Astral Communion' rune has a new sprite, made by WJohnston.
+ - rscdel: You can no longer use telekinesis to hit people with items they're holding,
+ items inside items they're holding, items embedded in them, items actually implanted
+ in them, or items they're wearing.
+ MMMiracles:
+ - rscadd: A set of combat gear for bears has been added, see your local russian
+ for more information.
+ XDTM:
+ - tweak: Nanotrasen has now stocked the DNA Manipulators with potassium iodide instead
+ of epinephrine as rejuvenators.
+2016-09-07:
+ A-t48:
+ - bugfix: you can now scrub freon and water vapor
+ - bugfix: you can now label canisters as freon and water vapor
+ AnturK:
+ - rscadd: Watch out for special instructions from Centcom in the intercept report.
+ Cheridan:
+ - tweak: Brain damage no longer causes machines to be inoperable.
+ Ergovisavi:
+ - bugfix: Stops ash drakes from swooping across zlevels
+ Impisi:
+ - tweak: Increased chances of Modular Receiver drop in Maintenance
+ Incoming5643:
+ - rscdel: Wizards can no longer purchase the Cursed Heart from their spellbook.
+ Joan:
+ - experiment: The lava staff now has a short delay before creating lava, with a
+ visible indicator.
+ - tweak: The lava staff's cooldown is now somewhat shorter, and turning lava back
+ into basalt has a much shorter cooldown and no delay.
+ Lzimann:
+ - tweak: Stunprods no longer fit in your backpack, they go on your back now.
+ MrStonedOne:
+ - bugfix: Fixed lava sometimes doing massive amounts of damage.
+ - tweak: AFK players will no longer default to continue playing during restart votes.
+ XDTM:
+ - bugfix: Cloners now preserve your genetic mutations.
+ pubby:
+ - tweak: Changed military belt TC cost from 3 -> 1
+ - tweak: Update ingredient boxes to have more useful ingredients
+2016-09-08:
+ Jordie0608:
+ - rscadd: Notes can now be tagged as secret to be hidden from player viewed notes.
+ Lzimann:
+ - tweak: Legion implants now have a full heal when implanted instead of passive
+ heal + spawn tentacles. The healing also goes off when you enter crit.
+ Yackemflam:
+ - rscadd: You can now buy a box for a chance to mess with the stations meta for
+ ops.
+2016-09-09:
+ Ergovisavi:
+ - rscadd: Adds new loot for the colossus, the "Anomalous Crystal"
+ - tweak: Enabled colossus spawning again
+ Joan, Ausops:
+ - rscadd: Added some very fancy tables, constructed by adding carpet tiles to a
+ standard table frame.
+ MrStonedOne:
+ - experiment: Blessed our beloved code with dark magic.
+ Shadowlight213:
+ - tweak: Radiation storm direct tox loss removed
+ - tweak: Radiation storms now cause a radiation alert to appear for the duration
diff --git a/html/changelogs/AutoChangeLog-pr-20175.yml b/html/changelogs/AutoChangeLog-pr-20175.yml
deleted file mode 100644
index 54ad26b7639..00000000000
--- a/html/changelogs/AutoChangeLog-pr-20175.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "bgobandit"
-delete-after: True
-changes:
- - tweak: "You can hide small items in urinals now. Use a screwdriver to screw open the drain enclosure."
- - rscadd: "Every space urinal comes complete with space urinal cake. Do not eat."
diff --git a/html/changelogs/AutoChangeLog-pr-20249.yml b/html/changelogs/AutoChangeLog-pr-20249.yml
deleted file mode 100644
index 059a1f969c2..00000000000
--- a/html/changelogs/AutoChangeLog-pr-20249.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "A-t48"
-delete-after: True
-changes:
- - bugfix: "Fixed cyborgs being able to use Power Warning emote when broken."
diff --git a/html/changelogs/AutoChangeLog-pr-20395.yml b/html/changelogs/AutoChangeLog-pr-20395.yml
new file mode 100644
index 00000000000..079783c4ca8
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-20395.yml
@@ -0,0 +1,5 @@
+author: "Shadowlight213"
+delete-after: True
+changes:
+ - rscdel: "The surplus crate and random item will now only contain items allowed by the gamemode"
+ - rscdel: "removes sleeping carp scroll from surplus crates"
diff --git a/html/changelogs/AutoChangeLog-pr-20402.yml b/html/changelogs/AutoChangeLog-pr-20402.yml
new file mode 100644
index 00000000000..e1cc68b7f55
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-20402.yml
@@ -0,0 +1,5 @@
+author: "Joan"
+delete-after: True
+changes:
+ - rscadd: "Cult structures can once again be constructed with runed metal."
+ - experiment: "Cult structures can now take damage and be destroyed. Artificers can repair them if they're damaged."
diff --git a/icons/effects/96x96.dmi b/icons/effects/96x96.dmi
index ce4f24553e3..01a40107540 100644
Binary files a/icons/effects/96x96.dmi and b/icons/effects/96x96.dmi differ
diff --git a/icons/effects/beam.dmi b/icons/effects/beam.dmi
index 7434915c0eb..d41b9403fa2 100644
Binary files a/icons/effects/beam.dmi and b/icons/effects/beam.dmi differ
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index 684a6a98cca..01e00f7163f 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/effects/tile_effects.dmi b/icons/effects/tile_effects.dmi
index 2a627378203..0bd03133ea1 100644
Binary files a/icons/effects/tile_effects.dmi and b/icons/effects/tile_effects.dmi differ
diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi
index 03e67a1c927..91bc9ca9828 100644
Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ
diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi
index 980c95fa776..cb872b63406 100644
Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index 01a368a92f5..3bfc1504ed8 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/belt.dmi b/icons/mob/belt.dmi
index 99129883b4e..974d473eacd 100644
Binary files a/icons/mob/belt.dmi and b/icons/mob/belt.dmi differ
diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi
index 2366cb7b33a..4fd8e88842f 100644
Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ
diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi
index bf71f3c3e40..438f41daca2 100644
Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ
diff --git a/icons/mob/lavaland/hierophant.dmi b/icons/mob/lavaland/hierophant.dmi
new file mode 100644
index 00000000000..d05bc3bd62d
Binary files /dev/null and b/icons/mob/lavaland/hierophant.dmi differ
diff --git a/icons/obj/atmos.dmi b/icons/obj/atmos.dmi
index c70d01ab2e1..d2bb36cc0bf 100644
Binary files a/icons/obj/atmos.dmi and b/icons/obj/atmos.dmi differ
diff --git a/icons/obj/clothing/belts.dmi b/icons/obj/clothing/belts.dmi
index a94697f55f2..ec2ca29fa8c 100644
Binary files a/icons/obj/clothing/belts.dmi and b/icons/obj/clothing/belts.dmi differ
diff --git a/icons/obj/guns/magic.dmi b/icons/obj/guns/magic.dmi
index 45e7b49f4e1..05c8aa7794f 100644
Binary files a/icons/obj/guns/magic.dmi and b/icons/obj/guns/magic.dmi differ
diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi
index 226ff760a5a..62f5dd37112 100644
Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ
diff --git a/icons/obj/lavaland/artefacts.dmi b/icons/obj/lavaland/artefacts.dmi
index 9123949dc7c..45927256e35 100644
Binary files a/icons/obj/lavaland/artefacts.dmi and b/icons/obj/lavaland/artefacts.dmi differ
diff --git a/icons/obj/lavaland/ash_flora.dmi b/icons/obj/lavaland/ash_flora.dmi
new file mode 100644
index 00000000000..d58541612d2
Binary files /dev/null and b/icons/obj/lavaland/ash_flora.dmi differ
diff --git a/icons/obj/lavaland/cannon.dmi b/icons/obj/lavaland/cannon.dmi
new file mode 100644
index 00000000000..82efad1bc5e
Binary files /dev/null and b/icons/obj/lavaland/cannon.dmi differ
diff --git a/icons/obj/machines/dna_vault.dmi b/icons/obj/machines/dna_vault.dmi
new file mode 100644
index 00000000000..35503336d42
Binary files /dev/null and b/icons/obj/machines/dna_vault.dmi differ
diff --git a/icons/obj/machines/satellite.dmi b/icons/obj/machines/satellite.dmi
new file mode 100644
index 00000000000..efe3dade763
Binary files /dev/null and b/icons/obj/machines/satellite.dmi differ
diff --git a/icons/obj/rune.dmi b/icons/obj/rune.dmi
index a6a03098b05..748ea4541c4 100644
Binary files a/icons/obj/rune.dmi and b/icons/obj/rune.dmi differ
diff --git a/icons/obj/smooth_structures/fancy_table.dmi b/icons/obj/smooth_structures/fancy_table.dmi
new file mode 100644
index 00000000000..a57b165f4ac
Binary files /dev/null and b/icons/obj/smooth_structures/fancy_table.dmi differ
diff --git a/icons/obj/status_display.dmi b/icons/obj/status_display.dmi
index 76f18ba5e65..2c407ce049f 100644
Binary files a/icons/obj/status_display.dmi and b/icons/obj/status_display.dmi differ
diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi
index daae938fbd2..ea17810bb88 100644
Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ
diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi
index 993c6dc509b..dcc0ffb5ce8 100644
Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ
diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi
index afff7e175bb..260540db932 100644
Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ
diff --git a/icons/turf/mining.dmi b/icons/turf/mining.dmi
index 62404dd5551..66c07a8146c 100644
Binary files a/icons/turf/mining.dmi and b/icons/turf/mining.dmi differ
diff --git a/icons/turf/walls/hierophant_wall.dmi b/icons/turf/walls/hierophant_wall.dmi
new file mode 100644
index 00000000000..8482970eaf0
Binary files /dev/null and b/icons/turf/walls/hierophant_wall.dmi differ
diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm
index cd5f268c7d4..797a77653a8 100644
--- a/interface/stylesheet.dm
+++ b/interface/stylesheet.dm
@@ -71,6 +71,8 @@ h1.alert, h2.alert {color: #000000;}
.cultlarge {color: #960000; font-weight: bold; font-size: 3;}
.narsie {color: #960000; font-weight: bold; font-size: 15;}
.colossus {color: #7F282A; font-size: 5;}
+.hierophant {color: #660099; font-weight: bold; font-size: 4;}
+.hierophant_warning {color: #660099; font-weight: bold; font-style: italic;}
.purple {color: #5e2d79;}
.holoparasite {color: #35333a;}
.holoparasitebold {color: #35333a; font-weight: bold;}
diff --git a/tgstation.dme b/tgstation.dme
index 3487e60a3af..57e25379006 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -746,6 +746,7 @@
#include "code\game\objects\structures\artstuff.dm"
#include "code\game\objects\structures\barsigns.dm"
#include "code\game\objects\structures\bedsheet_bin.dm"
+#include "code\game\objects\structures\destructible_structures.dm"
#include "code\game\objects\structures\displaycase.dm"
#include "code\game\objects\structures\door_assembly.dm"
#include "code\game\objects\structures\dresser.dm"
@@ -1275,6 +1276,7 @@
#include "code\modules\mining\laborcamp\laborminerals.dm"
#include "code\modules\mining\laborcamp\laborshuttle.dm"
#include "code\modules\mining\laborcamp\laborstacker.dm"
+#include "code\modules\mining\lavaland\ash_flora.dm"
#include "code\modules\mining\lavaland\lavaland_areas.dm"
#include "code\modules\mining\lavaland\necropolis_chests.dm"
#include "code\modules\mining\lavaland\ruins\gym.dm"
@@ -1392,6 +1394,7 @@
#include "code\modules\mob\living\carbon\monkey\punpun.dm"
#include "code\modules\mob\living\carbon\monkey\update_icons.dm"
#include "code\modules\mob\living\silicon\death.dm"
+#include "code\modules\mob\living\silicon\examine.dm"
#include "code\modules\mob\living\silicon\laws.dm"
#include "code\modules\mob\living\silicon\login.dm"
#include "code\modules\mob\living\silicon\say.dm"
@@ -1505,6 +1508,7 @@
#include "code\modules\mob\living\simple_animal\hostile\megafauna\bubblegum.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\colossus.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\dragon.dm"
+#include "code\modules\mob\living\simple_animal\hostile\megafauna\hierophant.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\legion.dm"
#include "code\modules\mob\living\simple_animal\hostile\megafauna\megafauna.dm"
#include "code\modules\mob\living\simple_animal\hostile\retaliate\bat.dm"
@@ -1816,6 +1820,10 @@
#include "code\modules\spells\spell_types\trigger.dm"
#include "code\modules\spells\spell_types\turf_teleport.dm"
#include "code\modules\spells\spell_types\wizard.dm"
+#include "code\modules\station_goals\bsa.dm"
+#include "code\modules\station_goals\dna_vault.dm"
+#include "code\modules\station_goals\shield.dm"
+#include "code\modules\station_goals\station_goal.dm"
#include "code\modules\stock_market\articles.dm"
#include "code\modules\stock_market\computer.dm"
#include "code\modules\stock_market\events.dm"
diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js
index 72849e255ec..ec8b0ce7eed 100644
--- a/tgui/assets/tgui.js
+++ b/tgui/assets/tgui.js
@@ -1,15 +1,16 @@
-require=function t(e,n,a){function r(o,s){if(!n[o]){if(!e[o]){var u="function"==typeof require&&require;if(!s&&u)return u(o,!0);if(i)return i(o,!0);var p=Error("Cannot find module '"+o+"'");throw p.code="MODULE_NOT_FOUND",p}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;o2?p[2]:void 0,l=Math.min((void 0===c?o:r(c,o))-u,o-s),f=1;for(s>u&&u+l>s&&(f=-1,u+=l-1,s+=l-1);l-- >0;)u in n?n[s]=n[u]:delete n[s],s+=f,u+=f;return n}},{76:76,79:79,80:80}],6:[function(t,e,n){"use strict";var a=t(80),r=t(76),i=t(79);e.exports=[].fill||function(t){for(var e=a(this),n=i(e.length),o=arguments,s=o.length,u=r(s>1?o[1]:void 0,n),p=s>2?o[2]:void 0,c=void 0===p?n:r(p,n);c>u;)e[u++]=t;return e}},{76:76,79:79,80:80}],7:[function(t,e,n){var a=t(78),r=t(79),i=t(76);e.exports=function(t){return function(e,n,o){var s,u=a(e),p=r(u.length),c=i(o,p);if(t&&n!=n){for(;p>c;)if(s=u[c++],s!=s)return!0}else for(;p>c;c++)if((t||c in u)&&u[c]===n)return t||c;return!t&&-1}}},{76:76,78:78,79:79}],8:[function(t,e,n){var a=t(17),r=t(34),i=t(80),o=t(79),s=t(9);e.exports=function(t){var e=1==t,n=2==t,u=3==t,p=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(p)return!1;return c?-1:u||p?p:w}}},{17:17,34:34,79:79,80:80,9:9}],9:[function(t,e,n){var a=t(38),r=t(36),i=t(83)("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)}},{36:36,38:38,83:83}],10:[function(t,e,n){var a=t(11),r=t(83)("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}},{11:11,83:83}],11:[function(t,e,n){var a={}.toString;e.exports=function(t){return a.call(t).slice(8,-1)}},{}],12:[function(t,e,n){"use strict";var a=t(46),r=t(31),i=t(60),o=t(17),s=t(69),u=t(18),p=t(27),c=t(42),l=t(44),f=t(82)("id"),d=t(30),h=t(38),m=t(65),v=t(19),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&&p(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 u(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)}}},{17:17,18:18,19:19,27:27,30:30,31:31,38:38,42:42,44:44,46:46,60:60,65:65,69:69,82:82}],13:[function(t,e,n){var a=t(27),r=t(10);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}}},{10:10,27:27}],14:[function(t,e,n){"use strict";var a=t(31),r=t(60),i=t(4),o=t(38),s=t(69),u=t(27),p=t(8),c=t(30),l=t(82)("weak"),f=Object.isExtensible||o,d=p(5),h=p(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&&u(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}},{27:27,30:30,31:31,38:38,4:4,60:60,69:69,8:8,82:82}],15:[function(t,e,n){"use strict";var a=t(29),r=t(22),i=t(61),o=t(60),s=t(27),u=t(69),p=t(38),c=t(24),l=t(43),f=t(66);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&&!p(t)?!1:e.call(this,0===t?0:t)}:"has"==t?function(t){return m&&!p(t)?!1:e.call(this,0===t?0:t)}:"get"==t?function(t){return m&&!p(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,E=c(function(){k.has(1)}),C=l(function(t){new g(t)});C||(g=e(function(e,n){u(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)}),(E||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}},{22:22,24:24,27:27,29:29,38:38,43:43,60:60,61:61,66:66,69:69}],16:[function(t,e,n){var a=e.exports={version:"1.2.6"};"number"==typeof __e&&(__e=a)},{}],17:[function(t,e,n){var a=t(2);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)}}},{2:2}],18:[function(t,e,n){e.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},{}],19:[function(t,e,n){e.exports=!t(24)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},{24:24}],20:[function(t,e,n){var a=t(38),r=t(29).document,i=a(r)&&a(r.createElement);e.exports=function(t){return i?r.createElement(t):{}}},{29:29,38:38}],21:[function(t,e,n){var a=t(46);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}},{46:46}],22:[function(t,e,n){var a=t(29),r=t(16),i=t(31),o=t(61),s=t(17),u="prototype",p=function(t,e,n){var c,l,f,d,h=t&p.F,m=t&p.G,v=t&p.S,g=t&p.P,b=t&p.B,y=m?a:v?a[e]||(a[e]={}):(a[e]||{})[u],_=m?r:r[e]||(r[e]={}),x=_[u]||(_[u]={});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,p.F=1,p.G=2,p.S=4,p.P=8,p.B=16,p.W=32,e.exports=p},{16:16,17:17,29:29,31:31,61:61}],23:[function(t,e,n){var a=t(83)("match");e.exports=function(t){var e=/./;try{"/./"[t](e)}catch(n){try{return e[a]=!1,!"/./"[t](e)}catch(r){}}return!0}},{83:83}],24:[function(t,e,n){e.exports=function(t){try{return!!t()}catch(e){return!0}}},{}],25:[function(t,e,n){"use strict";var a=t(31),r=t(61),i=t(24),o=t(18),s=t(83);e.exports=function(t,e,n){var u=s(t),p=""[t];i(function(){var e={};return e[u]=function(){return 7},7!=""[t](e)})&&(r(String.prototype,t,n(o,u,p)),a(RegExp.prototype,u,2==e?function(t,e){return p.call(t,this,e)}:function(t){return p.call(t,this)}))}},{18:18,24:24,31:31,61:61,83:83}],26:[function(t,e,n){"use strict";var a=t(4);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}},{4:4}],27:[function(t,e,n){var a=t(17),r=t(40),i=t(35),o=t(4),s=t(79),u=t(84);e.exports=function(t,e,n,p){var c,l,f,d=u(t),h=a(n,p,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)}},{17:17,35:35,4:4,40:40,79:79,84:84}],28:[function(t,e,n){var a=t(78),r=t(46).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))}},{46:46,78:78}],29:[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)},{}],30:[function(t,e,n){var a={}.hasOwnProperty;e.exports=function(t,e){return a.call(t,e)}},{}],31:[function(t,e,n){var a=t(46),r=t(59);e.exports=t(19)?function(t,e,n){return a.setDesc(t,e,r(1,n))}:function(t,e,n){return t[e]=n,t}},{19:19,46:46,59:59}],32:[function(t,e,n){e.exports=t(29).document&&document.documentElement},{29:29}],33:[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)}},{}],34:[function(t,e,n){var a=t(11);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==a(t)?t.split(""):Object(t)}},{11:11}],35:[function(t,e,n){var a=t(45),r=t(83)("iterator"),i=Array.prototype;e.exports=function(t){return void 0!==t&&(a.Array===t||i[r]===t)}},{45:45,83:83}],36:[function(t,e,n){var a=t(11);e.exports=Array.isArray||function(t){return"Array"==a(t)}},{11:11}],37:[function(t,e,n){var a=t(38),r=Math.floor;e.exports=function(t){return!a(t)&&isFinite(t)&&r(t)===t}},{38:38}],38:[function(t,e,n){e.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},{}],39:[function(t,e,n){var a=t(38),r=t(11),i=t(83)("match");e.exports=function(t){var e;return a(t)&&(void 0!==(e=t[i])?!!e:"RegExp"==r(t))}},{11:11,38:38,83:83}],40:[function(t,e,n){var a=t(4);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}}},{4:4}],41:[function(t,e,n){"use strict";var a=t(46),r=t(59),i=t(66),o={};t(31)(o,t(83)("iterator"),function(){return this}),e.exports=function(t,e,n){t.prototype=a.create(o,{next:r(1,n)}),i(t,e+" Iterator")}},{31:31,46:46,59:59,66:66,83:83}],42:[function(t,e,n){"use strict";var a=t(48),r=t(22),i=t(61),o=t(31),s=t(30),u=t(45),p=t(41),c=t(66),l=t(46).getProto,f=t(83)("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){p(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)}},E=e+" Iterator",C=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,E,!0),!a&&s(A,h)&&o(M,f,g),C&&O.name!==v&&(S=!0,T=function(){return O.call(this)})}if(a&&!x||!d&&!S&&A[f]||o(A,f,T),u[e]=T,u[E]=g,y)if(w={values:C?T:P(v),keys:_?T:P(m),entries:C?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}},{22:22,30:30,31:31,41:41,45:45,46:46,48:48,61:61,66:66,83:83}],43:[function(t,e,n){var a=t(83)("iterator"),r=!1;try{var i=[7][a]();i["return"]=function(){r=!0},Array.from(i,function(){throw 2})}catch(o){}e.exports=function(t,e){if(!e&&!r)return!1;var n=!1;try{var i=[7],o=i[a]();o.next=function(){return{done:n=!0}},i[a]=function(){return o},t(i)}catch(s){}return n}},{83:83}],44:[function(t,e,n){e.exports=function(t,e){return{value:e,done:!!t}}},{}],45:[function(t,e,n){e.exports={}},{}],46:[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}},{}],47:[function(t,e,n){var a=t(46),r=t(78);e.exports=function(t,e){for(var n,i=r(t),o=a.getKeys(i),s=o.length,u=0;s>u;)if(i[n=o[u++]]===e)return n}},{46:46,78:78}],48:[function(t,e,n){e.exports=!1},{}],49:[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}},{}],50:[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)}},{}],51:[function(t,e,n){e.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:0>t?-1:1}},{}],52:[function(t,e,n){var a,r,i,o=t(29),s=t(75).set,u=o.MutationObserver||o.WebKitMutationObserver,p=o.process,c=o.Promise,l="process"==t(11)(p),f=function(){var t,e,n;for(l&&(t=p.domain)&&(p.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(){p.nextTick(f)};else if(u){var d=1,h=document.createTextNode("");new u(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&&p.domain};r&&(r.next=e),a||(a=e,i()),r=e}},{11:11,29:29,75:75}],53:[function(t,e,n){var a=t(46),r=t(80),i=t(34);e.exports=t(24)(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,u=1,p=a.getKeys,c=a.getSymbols,l=a.isEnum;s>u;)for(var f,d=i(o[u++]),h=c?p(d).concat(c(d)):p(d),m=h.length,v=0;m>v;)l.call(d,f=h[v++])&&(n[f]=d[f]);return n}:Object.assign},{24:24,34:34,46:46,80:80}],54:[function(t,e,n){var a=t(22),r=t(16),i=t(24);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)}},{16:16,22:22,24:24}],55:[function(t,e,n){var a=t(46),r=t(78),i=a.isEnum;e.exports=function(t){return function(e){for(var n,o=r(e),s=a.getKeys(o),u=s.length,p=0,c=[];u>p;)i.call(o,n=s[p++])&&c.push(t?[n,o[n]]:o[n]);return c}}},{46:46,78:78}],56:[function(t,e,n){var a=t(46),r=t(4),i=t(29).Reflect;e.exports=i&&i.ownKeys||function(t){var e=a.getNames(r(t)),n=a.getSymbols;return n?e.concat(n(t)):e}},{29:29,4:4,46:46}],57:[function(t,e,n){"use strict";var a=t(58),r=t(33),i=t(2);e.exports=function(){for(var t=i(this),e=arguments.length,n=Array(e),o=0,s=a._,u=!1;e>o;)(n[o]=arguments[o++])===s&&(u=!0);return function(){var a,i=this,o=arguments,p=o.length,c=0,l=0;if(!u&&!p)return r(t,n,i);if(a=n.slice(),u)for(;e>c;c++)a[c]===s&&(a[c]=o[l++]);for(;p>l;)a.push(o[l++]);return r(t,a,i)}}},{2:2,33:33,58:58}],58:[function(t,e,n){e.exports=t(29)},{29:29}],59:[function(t,e,n){e.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},{}],60:[function(t,e,n){var a=t(61);e.exports=function(t,e){for(var n in e)a(t,n,e[n]);return t}},{61:61}],61:[function(t,e,n){var a=t(29),r=t(31),i=t(82)("src"),o="toString",s=Function[o],u=(""+s).split(o);t(16).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]:u.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)})},{16:16,29:29,31:31,82:82}],62:[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)}}},{}],63:[function(t,e,n){e.exports=Object.is||function(t,e){return t===e?0!==t||1/t===1/e:t!=t&&e!=e}},{}],64:[function(t,e,n){var a=t(46).getDesc,r=t(38),i=t(4),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(17)(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}},{17:17,38:38,4:4,46:46}],65:[function(t,e,n){"use strict";var a=t(29),r=t(46),i=t(19),o=t(83)("species");e.exports=function(t){var e=a[t];i&&e&&!e[o]&&r.setDesc(e,o,{configurable:!0,get:function(){return this}})}},{19:19,29:29,46:46,83:83}],66:[function(t,e,n){var a=t(46).setDesc,r=t(30),i=t(83)("toStringTag");e.exports=function(t,e,n){t&&!r(t=n?t:t.prototype,i)&&a(t,i,{configurable:!0,value:e})}},{30:30,46:46,83:83}],67:[function(t,e,n){var a=t(29),r="__core-js_shared__",i=a[r]||(a[r]={});e.exports=function(t){return i[t]||(i[t]={})}},{29:29}],68:[function(t,e,n){var a=t(4),r=t(2),i=t(83)("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)}},{2:2,4:4,83:83}],69:[function(t,e,n){e.exports=function(t,e,n){if(!(t instanceof e))throw TypeError(n+": use the 'new' operator!");return t}},{}],70:[function(t,e,n){var a=t(77),r=t(18);e.exports=function(t){return function(e,n){var i,o,s=r(e)+"",u=a(n),p=s.length;return 0>u||u>=p?t?"":void 0:(i=s.charCodeAt(u),55296>i||i>56319||u+1===p||(o=s.charCodeAt(u+1))<56320||o>57343?t?s.charAt(u):i:t?s.slice(u,u+2):(i-55296<<10)+(o-56320)+65536)}}},{18:18,77:77}],71:[function(t,e,n){var a=t(39),r=t(18);e.exports=function(t,e,n){if(a(e))throw TypeError("String#"+n+" doesn't accept regex!");return r(t)+""}},{18:18,39:39}],72:[function(t,e,n){var a=t(79),r=t(73),i=t(18);e.exports=function(t,e,n,o){var s=i(t)+"",u=s.length,p=void 0===n?" ":n+"",c=a(e);if(u>=c)return s;""==p&&(p=" ");var l=c-u,f=r.call(p,Math.ceil(l/p.length));return f.length>l&&(f=f.slice(0,l)),o?f+s:s+f}},{18:18,73:73,79:79}],73:[function(t,e,n){"use strict";var a=t(77),r=t(18);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}},{18:18,77:77}],74:[function(t,e,n){var a=t(22),r=t(18),i=t(24),o=" \n\x0B\f\r \u2028\u2029\ufeff",s="["+o+"]",u="
",p=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]()||u[t]()!=u}),"String",n)},f=l.trim=function(t,e){return t=r(t)+"",1&e&&(t=t.replace(p,"")),2&e&&(t=t.replace(c,"")),t};e.exports=l},{18:18,22:22,24:24}],75:[function(t,e,n){var a,r,i,o=t(17),s=t(33),u=t(32),p=t(20),c=t(29),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(11)(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 p("script")?function(t){u.appendChild(p("script"))[g]=function(){u.removeChild(this),b.call(t)}}:function(t){setTimeout(o(b,t,1),0)}),e.exports={set:f,clear:d}},{11:11,17:17,20:20,29:29,32:32,33:33}],76:[function(t,e,n){var a=t(77),r=Math.max,i=Math.min;e.exports=function(t,e){return t=a(t),0>t?r(t+e,0):i(t,e)}},{77:77}],77:[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)}},{}],78:[function(t,e,n){var a=t(34),r=t(18);e.exports=function(t){return a(r(t))}},{18:18,34:34}],79:[function(t,e,n){var a=t(77),r=Math.min;e.exports=function(t){return t>0?r(a(t),9007199254740991):0}},{77:77}],80:[function(t,e,n){var a=t(18);e.exports=function(t){return Object(a(t))}},{18:18}],81:[function(t,e,n){var a=t(38);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")}},{38:38}],82:[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))}},{}],83:[function(t,e,n){var a=t(67)("wks"),r=t(82),i=t(29).Symbol;e.exports=function(t){return a[t]||(a[t]=i&&i[t]||(i||r)("Symbol."+t))}},{29:29,67:67,82:82}],84:[function(t,e,n){var a=t(10),r=t(83)("iterator"),i=t(45);e.exports=t(16).getIteratorMethod=function(t){return void 0!=t?t[r]||t["@@iterator"]||i[a(t)]:void 0}},{10:10,16:16,45:45,83:83}],85:[function(t,e,n){"use strict";var a,r=t(46),i=t(22),o=t(19),s=t(59),u=t(32),p=t(20),c=t(30),l=t(11),f=t(33),d=t(24),h=t(4),m=t(2),v=t(38),g=t(80),b=t(78),y=t(77),_=t(76),x=t(79),w=t(34),k=t(82)("__proto__"),P=t(8),E=t(7)(!1),C=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(p("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(!C.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"),F=L.length,D=function(){var t,e=p("iframe"),n=F,a=">";for(e.style.display="none",u.appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write("i;)c(r,a=t[i++])&&(~E(o,a)||o.push(a));return o}},B=function(){};i(i.S,"Object",{getPrototypeOf:r.getProto=r.getProto||function(t){return t=g(t),c(t,k)?t[k]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?C:null},getOwnPropertyNames:r.getNames=r.getNames||I(N,N.length,!0),create:r.create=r.create||function(t,e){var n;return null!==t?(B.prototype=h(t),n=new B,B.prototype=null,n[k]=t):n=D(),void 0===e?n:R(n,e)},keys:r.getKeys=r.getKeys||I(L,F,!1)});var q=function(t,e,n){if(!(e in j)){for(var a=[],r=0;e>r;r++)a[r]="a["+r+"]";j[e]=Function("F,a","return new F("+a.join(",")+")")}return j[e](t,n)};i(i.P,"Function",{bind:function(t){var e=m(this),n=A.call(arguments,1),a=function(){var r=n.concat(A.call(arguments));return this instanceof a?q(e,r.length,r):f(e,r,t)};return v(e.prototype)&&(a.prototype=e.prototype),a}}),i(i.P+i.F*d(function(){u&&A.call(u)}),"Array",{slice:function(t,e){var n=x(this.length),a=l(this);if(e=void 0===e?n:e,"Array"==a)return A.call(this,t,e);for(var r=_(t,n),i=_(e,n),o=x(i-r),s=Array(o),u=0;o>u;u++)s[u]="String"==a?this.charAt(r+u):this[r+u];return s}}),i(i.P+i.F*(w!=Object),"Array",{join:function(t){return O.call(w(this),void 0===t?",":t)}}),i(i.S,"Array",{isArray:t(36)});var G=function(t){return function(e,n){m(e);var a=w(this),r=x(a.length),i=t?r-1:0,o=t?-1:1;if(arguments.length<2)for(;;){if(i in a){n=a[i],i+=o;break}if(i+=o,t?0>i:i>=r)throw TypeError("Reduce of empty array with no initial value")}for(;t?i>=0:r>i;i+=o)i in a&&(n=e(n,a[i],i,this));return n}},U=function(t){return function(e){return t(this,e,arguments[1])}};i(i.P,"Array",{forEach:r.each=r.each||U(P(0)),map:U(P(1)),filter:U(P(2)),some:U(P(3)),every:U(P(4)),reduce:G(!1),reduceRight:G(!0),indexOf:U(E),lastIndexOf:function(t,e){var n=b(this),a=x(n.length),r=a-1;for(arguments.length>1&&(r=Math.min(r,y(e))),0>r&&(r=x(a+r));r>=0;r--)if(r in n&&n[r]===t)return r;return-1}}),i(i.S,"Date",{now:function(){return+new Date}});var V=function(t){return t>9?t:"0"+t};i(i.P+i.F*(d(function(){return"0385-07-25T07:06:39.999Z"!=new Date(-5e13-1).toISOString()})||!d(function(){new Date(NaN).toISOString()})),"Date",{toISOString:function(){if(!isFinite(this))throw RangeError("Invalid time value");var t=this,e=t.getUTCFullYear(),n=t.getUTCMilliseconds(),a=0>e?"-":e>9999?"+":"";return a+("00000"+Math.abs(e)).slice(a?-6:-4)+"-"+V(t.getUTCMonth()+1)+"-"+V(t.getUTCDate())+"T"+V(t.getUTCHours())+":"+V(t.getUTCMinutes())+":"+V(t.getUTCSeconds())+"."+(n>99?n:"0"+V(n))+"Z"}})},{11:11,19:19,2:2,20:20,22:22,24:24,30:30,32:32,33:33,34:34,36:36,38:38,4:4,46:46,59:59,7:7,76:76,77:77,78:78,79:79,8:8,80:80,82:82}],86:[function(t,e,n){var a=t(22);a(a.P,"Array",{copyWithin:t(5)}),t(3)("copyWithin")},{22:22,3:3,5:5}],87:[function(t,e,n){var a=t(22);a(a.P,"Array",{fill:t(6)}),t(3)("fill")},{22:22,3:3,6:6}],88:[function(t,e,n){"use strict";var a=t(22),r=t(8)(6),i="findIndex",o=!0;i in[]&&Array(1)[i](function(){o=!1}),a(a.P+a.F*o,"Array",{findIndex:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0)}}),t(3)(i)},{22:22,3:3,8:8}],89:[function(t,e,n){"use strict";var a=t(22),r=t(8)(5),i="find",o=!0;i in[]&&Array(1)[i](function(){o=!1}),a(a.P+a.F*o,"Array",{find:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0)}}),t(3)(i)},{22:22,3:3,8:8}],90:[function(t,e,n){"use strict";var a=t(17),r=t(22),i=t(80),o=t(40),s=t(35),u=t(79),p=t(84);r(r.S+r.F*!t(43)(function(t){Array.from(t)}),"Array",{from:function(t){var e,n,r,c,l=i(t),f="function"==typeof this?this:Array,d=arguments,h=d.length,m=h>1?d[1]:void 0,v=void 0!==m,g=0,b=p(l);if(v&&(m=a(m,h>2?d[2]:void 0,2)),void 0==b||f==Array&&s(b))for(e=u(l.length),n=new f(e);e>g;g++)n[g]=v?m(l[g],g):l[g];else for(c=b.call(l),n=new f;!(r=c.next()).done;g++)n[g]=v?o(c,m,[r.value,g],!0):r.value;return n.length=g,n}})},{17:17,22:22,35:35,40:40,43:43,79:79,80:80,84:84}],91:[function(t,e,n){"use strict";var a=t(3),r=t(44),i=t(45),o=t(78);e.exports=t(42)(Array,"Array",function(t,e){this._t=o(t),this._i=0,this._k=e},function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,r(1)):"keys"==e?r(0,n):"values"==e?r(0,t[n]):r(0,[n,t[n]])},"values"),i.Arguments=i.Array,a("keys"),a("values"),a("entries")},{3:3,42:42,44:44,45:45,78:78}],92:[function(t,e,n){"use strict";var a=t(22);a(a.S+a.F*t(24)(function(){function t(){}return!(Array.of.call(t)instanceof t)}),"Array",{of:function(){for(var t=0,e=arguments,n=e.length,a=new("function"==typeof this?this:Array)(n);n>t;)a[t]=e[t++];return a.length=n,a}})},{22:22,24:24}],93:[function(t,e,n){t(65)("Array")},{65:65}],94:[function(t,e,n){"use strict";var a=t(46),r=t(38),i=t(83)("hasInstance"),o=Function.prototype;i in o||a.setDesc(o,i,{value:function(t){if("function"!=typeof this||!r(t))return!1;if(!r(this.prototype))return t instanceof this;for(;t=a.getProto(t);)if(this.prototype===t)return!0;return!1}})},{38:38,46:46,83:83}],95:[function(t,e,n){var a=t(46).setDesc,r=t(59),i=t(30),o=Function.prototype,s=/^\s*function ([^ (]*)/,u="name";u in o||t(19)&&a(o,u,{configurable:!0,get:function(){var t=(""+this).match(s),e=t?t[1]:"";return i(this,u)||a(this,u,r(5,e)),e}})},{19:19,30:30,46:46,59:59}],96:[function(t,e,n){"use strict";var a=t(12);t(15)("Map",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{get:function(t){var e=a.getEntry(this,t);return e&&e.v},set:function(t,e){return a.def(this,0===t?0:t,e)}},a,!0)},{12:12,15:15}],97:[function(t,e,n){var a=t(22),r=t(50),i=Math.sqrt,o=Math.acosh;a(a.S+a.F*!(o&&710==Math.floor(o(Number.MAX_VALUE))),"Math",{acosh:function(t){return(t=+t)<1?NaN:t>94906265.62425156?Math.log(t)+Math.LN2:r(t-1+i(t-1)*i(t+1))}})},{22:22,50:50}],98:[function(t,e,n){function a(t){return isFinite(t=+t)&&0!=t?0>t?-a(-t):Math.log(t+Math.sqrt(t*t+1)):t}var r=t(22);r(r.S,"Math",{asinh:a})},{22:22}],99:[function(t,e,n){var a=t(22);a(a.S,"Math",{atanh:function(t){return 0==(t=+t)?t:Math.log((1+t)/(1-t))/2}})},{22:22}],100:[function(t,e,n){var a=t(22),r=t(51);a(a.S,"Math",{cbrt:function(t){return r(t=+t)*Math.pow(Math.abs(t),1/3)}})},{22:22,51:51}],101:[function(t,e,n){var a=t(22);a(a.S,"Math",{clz32:function(t){return(t>>>=0)?31-Math.floor(Math.log(t+.5)*Math.LOG2E):32}})},{22:22}],102:[function(t,e,n){var a=t(22),r=Math.exp;a(a.S,"Math",{cosh:function(t){return(r(t=+t)+r(-t))/2}})},{22:22}],103:[function(t,e,n){var a=t(22);a(a.S,"Math",{expm1:t(49)})},{22:22,49:49}],104:[function(t,e,n){var a=t(22),r=t(51),i=Math.pow,o=i(2,-52),s=i(2,-23),u=i(2,127)*(2-s),p=i(2,-126),c=function(t){return t+1/o-1/o};a(a.S,"Math",{fround:function(t){var e,n,a=Math.abs(t),i=r(t);return p>a?i*c(a/p/s)*p*s:(e=(1+s/o)*a,n=e-(e-a),n>u||n!=n?i*(1/0):i*n)}})},{22:22,51:51}],105:[function(t,e,n){var a=t(22),r=Math.abs;a(a.S,"Math",{hypot:function(t,e){for(var n,a,i=0,o=0,s=arguments,u=s.length,p=0;u>o;)n=r(s[o++]),n>p?(a=p/n,i=i*a*a+1,p=n):n>0?(a=n/p,i+=a*a):i+=n;return p===1/0?1/0:p*Math.sqrt(i)}})},{22:22}],106:[function(t,e,n){var a=t(22),r=Math.imul;a(a.S+a.F*t(24)(function(){return-5!=r(4294967295,5)||2!=r.length}),"Math",{imul:function(t,e){var n=65535,a=+t,r=+e,i=n&a,o=n&r;return 0|i*o+((n&a>>>16)*o+i*(n&r>>>16)<<16>>>0)}})},{22:22,24:24}],107:[function(t,e,n){var a=t(22);a(a.S,"Math",{log10:function(t){return Math.log(t)/Math.LN10}})},{22:22}],108:[function(t,e,n){var a=t(22);a(a.S,"Math",{log1p:t(50)})},{22:22,50:50}],109:[function(t,e,n){var a=t(22);a(a.S,"Math",{log2:function(t){return Math.log(t)/Math.LN2}})},{22:22}],110:[function(t,e,n){var a=t(22);a(a.S,"Math",{sign:t(51)})},{22:22,51:51}],111:[function(t,e,n){var a=t(22),r=t(49),i=Math.exp;a(a.S+a.F*t(24)(function(){return-2e-17!=!Math.sinh(-2e-17)}),"Math",{sinh:function(t){return Math.abs(t=+t)<1?(r(t)-r(-t))/2:(i(t-1)-i(-t-1))*(Math.E/2)}})},{22:22,24:24,49:49}],112:[function(t,e,n){var a=t(22),r=t(49),i=Math.exp;a(a.S,"Math",{tanh:function(t){var e=r(t=+t),n=r(-t);return e==1/0?1:n==1/0?-1:(e-n)/(i(t)+i(-t))}})},{22:22,49:49}],113:[function(t,e,n){var a=t(22);a(a.S,"Math",{trunc:function(t){return(t>0?Math.floor:Math.ceil)(t)}})},{22:22}],114:[function(t,e,n){"use strict";var a=t(46),r=t(29),i=t(30),o=t(11),s=t(81),u=t(24),p=t(74).trim,c="Number",l=r[c],f=l,d=l.prototype,h=o(a.create(d))==c,m="trim"in String.prototype,v=function(t){
-var e=s(t,!1);if("string"==typeof e&&e.length>2){e=m?e.trim():p(e,3);var n,a,r,i=e.charCodeAt(0);if(43===i||45===i){if(n=e.charCodeAt(2),88===n||120===n)return NaN}else if(48===i){switch(e.charCodeAt(1)){case 66:case 98:a=2,r=49;break;case 79:case 111:a=8,r=55;break;default:return+e}for(var o,u=e.slice(2),c=0,l=u.length;l>c;c++)if(o=u.charCodeAt(c),48>o||o>r)return NaN;return parseInt(u,a)}}return+e};l(" 0o1")&&l("0b1")&&!l("+0x1")||(l=function(t){var e=arguments.length<1?0:t,n=this;return n instanceof l&&(h?u(function(){d.valueOf.call(n)}):o(n)!=c)?new f(v(e)):v(e)},a.each.call(t(19)?a.getNames(f):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),function(t){i(f,t)&&!i(l,t)&&a.setDesc(l,t,a.getDesc(f,t))}),l.prototype=d,d.constructor=l,t(61)(r,c,l))},{11:11,19:19,24:24,29:29,30:30,46:46,61:61,74:74,81:81}],115:[function(t,e,n){var a=t(22);a(a.S,"Number",{EPSILON:Math.pow(2,-52)})},{22:22}],116:[function(t,e,n){var a=t(22),r=t(29).isFinite;a(a.S,"Number",{isFinite:function(t){return"number"==typeof t&&r(t)}})},{22:22,29:29}],117:[function(t,e,n){var a=t(22);a(a.S,"Number",{isInteger:t(37)})},{22:22,37:37}],118:[function(t,e,n){var a=t(22);a(a.S,"Number",{isNaN:function(t){return t!=t}})},{22:22}],119:[function(t,e,n){var a=t(22),r=t(37),i=Math.abs;a(a.S,"Number",{isSafeInteger:function(t){return r(t)&&i(t)<=9007199254740991}})},{22:22,37:37}],120:[function(t,e,n){var a=t(22);a(a.S,"Number",{MAX_SAFE_INTEGER:9007199254740991})},{22:22}],121:[function(t,e,n){var a=t(22);a(a.S,"Number",{MIN_SAFE_INTEGER:-9007199254740991})},{22:22}],122:[function(t,e,n){var a=t(22);a(a.S,"Number",{parseFloat:parseFloat})},{22:22}],123:[function(t,e,n){var a=t(22);a(a.S,"Number",{parseInt:parseInt})},{22:22}],124:[function(t,e,n){var a=t(22);a(a.S+a.F,"Object",{assign:t(53)})},{22:22,53:53}],125:[function(t,e,n){var a=t(38);t(54)("freeze",function(t){return function(e){return t&&a(e)?t(e):e}})},{38:38,54:54}],126:[function(t,e,n){var a=t(78);t(54)("getOwnPropertyDescriptor",function(t){return function(e,n){return t(a(e),n)}})},{54:54,78:78}],127:[function(t,e,n){t(54)("getOwnPropertyNames",function(){return t(28).get})},{28:28,54:54}],128:[function(t,e,n){var a=t(80);t(54)("getPrototypeOf",function(t){return function(e){return t(a(e))}})},{54:54,80:80}],129:[function(t,e,n){var a=t(38);t(54)("isExtensible",function(t){return function(e){return a(e)?t?t(e):!0:!1}})},{38:38,54:54}],130:[function(t,e,n){var a=t(38);t(54)("isFrozen",function(t){return function(e){return a(e)?t?t(e):!1:!0}})},{38:38,54:54}],131:[function(t,e,n){var a=t(38);t(54)("isSealed",function(t){return function(e){return a(e)?t?t(e):!1:!0}})},{38:38,54:54}],132:[function(t,e,n){var a=t(22);a(a.S,"Object",{is:t(63)})},{22:22,63:63}],133:[function(t,e,n){var a=t(80);t(54)("keys",function(t){return function(e){return t(a(e))}})},{54:54,80:80}],134:[function(t,e,n){var a=t(38);t(54)("preventExtensions",function(t){return function(e){return t&&a(e)?t(e):e}})},{38:38,54:54}],135:[function(t,e,n){var a=t(38);t(54)("seal",function(t){return function(e){return t&&a(e)?t(e):e}})},{38:38,54:54}],136:[function(t,e,n){var a=t(22);a(a.S,"Object",{setPrototypeOf:t(64).set})},{22:22,64:64}],137:[function(t,e,n){"use strict";var a=t(10),r={};r[t(83)("toStringTag")]="z",r+""!="[object z]"&&t(61)(Object.prototype,"toString",function(){return"[object "+a(this)+"]"},!0)},{10:10,61:61,83:83}],138:[function(t,e,n){"use strict";var a,r=t(46),i=t(48),o=t(29),s=t(17),u=t(10),p=t(22),c=t(38),l=t(4),f=t(2),d=t(69),h=t(27),m=t(64).set,v=t(63),g=t(83)("species"),b=t(68),y=t(52),_="Promise",x=o.process,w="process"==u(x),k=o[_],P=function(){},E=function(t){var e,n=new k(P);return t&&(n.constructor=function(t){t(P,P)}),(e=k.resolve(n))["catch"](P),e===n},C=function(){function e(t){var n=new k(t);return m(n,e.prototype),n}var n=!1;try{if(n=k&&k.resolve&&E(),m(e,k),e.prototype=r.create(k.prototype,{constructor:{value:e}}),e.resolve(5).then(function(){})instanceof e||(n=!1),n&&t(19)){var a=!1;k.resolve(r.setDesc({},"then",{get:function(){a=!0}})),n=a}}catch(i){n=!1}return n}(),S=function(t,e){return i&&t===k&&e===a?!0:v(t,e)},A=function(t){var e=l(t)[g];return void 0!=e?e:t},O=function(t){var e;return c(t)&&"function"==typeof(e=t.then)?e:!1},T=function(t){var e,n;this.promise=new t(function(t,a){if(void 0!==e||void 0!==n)throw TypeError("Bad Promise constructor");e=t,n=a}),this.resolve=f(e),this.reject=f(n)},M=function(t){try{t()}catch(e){return{error:e}}},R=function(t,e){if(!t.n){t.n=!0;var n=t.c;y(function(){for(var a=t.v,r=1==t.s,i=0,s=function(e){var n,i,o=r?e.ok:e.fail,s=e.resolve,u=e.reject;try{o?(r||(t.h=!0),n=o===!0?a:o(a),n===e.promise?u(TypeError("Promise-chain cycle")):(i=O(n))?i.call(n,s,u):s(n)):u(a)}catch(p){u(p)}};n.length>i;)s(n[i++]);n.length=0,t.n=!1,e&&setTimeout(function(){var e,n,r=t.p;j(r)&&(w?x.emit("unhandledRejection",a,r):(e=o.onunhandledrejection)?e({promise:r,reason:a}):(n=o.console)&&n.error&&n.error("Unhandled promise rejection",a)),t.a=void 0},1)})}},j=function(t){var e,n=t._d,a=n.a||n.c,r=0;if(n.h)return!1;for(;a.length>r;)if(e=a[r++],e.fail||!j(e.promise))return!1;return!0},L=function(t){var e=this;e.d||(e.d=!0,e=e.r||e,e.v=t,e.s=2,e.a=e.c.slice(),R(e,!0))},N=function(t){var e,n=this;if(!n.d){n.d=!0,n=n.r||n;try{if(n.p===t)throw TypeError("Promise can't be resolved itself");(e=O(t))?y(function(){var a={r:n,d:!1};try{e.call(t,s(N,a,1),s(L,a,1))}catch(r){L.call(a,r)}}):(n.v=t,n.s=1,R(n,!1))}catch(a){L.call({r:n,d:!1},a)}}};C||(k=function(t){f(t);var e=this._d={p:d(this,k,_),c:[],a:void 0,s:0,d:!1,v:void 0,h:!1,n:!1};try{t(s(N,e,1),s(L,e,1))}catch(n){L.call(e,n)}},t(60)(k.prototype,{then:function(t,e){var n=new T(b(this,k)),a=n.promise,r=this._d;return n.ok="function"==typeof t?t:!0,n.fail="function"==typeof e&&e,r.c.push(n),r.a&&r.a.push(n),r.s&&R(r,!1),a},"catch":function(t){return this.then(void 0,t)}})),p(p.G+p.W+p.F*!C,{Promise:k}),t(66)(k,_),t(65)(_),a=t(16)[_],p(p.S+p.F*!C,_,{reject:function(t){var e=new T(this),n=e.reject;return n(t),e.promise}}),p(p.S+p.F*(!C||E(!0)),_,{resolve:function(t){if(t instanceof k&&S(t.constructor,this))return t;var e=new T(this),n=e.resolve;return n(t),e.promise}}),p(p.S+p.F*!(C&&t(43)(function(t){k.all(t)["catch"](function(){})})),_,{all:function(t){var e=A(this),n=new T(e),a=n.resolve,i=n.reject,o=[],s=M(function(){h(t,!1,o.push,o);var n=o.length,s=Array(n);n?r.each.call(o,function(t,r){var o=!1;e.resolve(t).then(function(t){o||(o=!0,s[r]=t,--n||a(s))},i)}):a(s)});return s&&i(s.error),n.promise},race:function(t){var e=A(this),n=new T(e),a=n.reject,r=M(function(){h(t,!1,function(t){e.resolve(t).then(n.resolve,a)})});return r&&a(r.error),n.promise}})},{10:10,16:16,17:17,19:19,2:2,22:22,27:27,29:29,38:38,4:4,43:43,46:46,48:48,52:52,60:60,63:63,64:64,65:65,66:66,68:68,69:69,83:83}],139:[function(t,e,n){var a=t(22),r=Function.apply,i=t(4);a(a.S,"Reflect",{apply:function(t,e,n){return r.call(t,e,i(n))}})},{22:22,4:4}],140:[function(t,e,n){var a=t(46),r=t(22),i=t(2),o=t(4),s=t(38),u=Function.bind||t(16).Function.prototype.bind;r(r.S+r.F*t(24)(function(){function t(){}return!(Reflect.construct(function(){},[],t)instanceof t)}),"Reflect",{construct:function(t,e){i(t),o(e);var n=arguments.length<3?t:i(arguments[2]);if(t==n){switch(e.length){case 0:return new t;case 1:return new t(e[0]);case 2:return new t(e[0],e[1]);case 3:return new t(e[0],e[1],e[2]);case 4:return new t(e[0],e[1],e[2],e[3])}var r=[null];return r.push.apply(r,e),new(u.apply(t,r))}var p=n.prototype,c=a.create(s(p)?p:Object.prototype),l=Function.apply.call(t,c,e);return s(l)?l:c}})},{16:16,2:2,22:22,24:24,38:38,4:4,46:46}],141:[function(t,e,n){var a=t(46),r=t(22),i=t(4);r(r.S+r.F*t(24)(function(){Reflect.defineProperty(a.setDesc({},1,{value:1}),1,{value:2})}),"Reflect",{defineProperty:function(t,e,n){i(t);try{return a.setDesc(t,e,n),!0}catch(r){return!1}}})},{22:22,24:24,4:4,46:46}],142:[function(t,e,n){var a=t(22),r=t(46).getDesc,i=t(4);a(a.S,"Reflect",{deleteProperty:function(t,e){var n=r(i(t),e);return n&&!n.configurable?!1:delete t[e]}})},{22:22,4:4,46:46}],143:[function(t,e,n){"use strict";var a=t(22),r=t(4),i=function(t){this._t=r(t),this._i=0;var e,n=this._k=[];for(e in t)n.push(e)};t(41)(i,"Object",function(){var t,e=this,n=e._k;do if(e._i>=n.length)return{value:void 0,done:!0};while(!((t=n[e._i++])in e._t));return{value:t,done:!1}}),a(a.S,"Reflect",{enumerate:function(t){return new i(t)}})},{22:22,4:4,41:41}],144:[function(t,e,n){var a=t(46),r=t(22),i=t(4);r(r.S,"Reflect",{getOwnPropertyDescriptor:function(t,e){return a.getDesc(i(t),e)}})},{22:22,4:4,46:46}],145:[function(t,e,n){var a=t(22),r=t(46).getProto,i=t(4);a(a.S,"Reflect",{getPrototypeOf:function(t){return r(i(t))}})},{22:22,4:4,46:46}],146:[function(t,e,n){function a(t,e){var n,o,p=arguments.length<3?t:arguments[2];return u(t)===p?t[e]:(n=r.getDesc(t,e))?i(n,"value")?n.value:void 0!==n.get?n.get.call(p):void 0:s(o=r.getProto(t))?a(o,e,p):void 0}var r=t(46),i=t(30),o=t(22),s=t(38),u=t(4);o(o.S,"Reflect",{get:a})},{22:22,30:30,38:38,4:4,46:46}],147:[function(t,e,n){var a=t(22);a(a.S,"Reflect",{has:function(t,e){return e in t}})},{22:22}],148:[function(t,e,n){var a=t(22),r=t(4),i=Object.isExtensible;a(a.S,"Reflect",{isExtensible:function(t){return r(t),i?i(t):!0}})},{22:22,4:4}],149:[function(t,e,n){var a=t(22);a(a.S,"Reflect",{ownKeys:t(56)})},{22:22,56:56}],150:[function(t,e,n){var a=t(22),r=t(4),i=Object.preventExtensions;a(a.S,"Reflect",{preventExtensions:function(t){r(t);try{return i&&i(t),!0}catch(e){return!1}}})},{22:22,4:4}],151:[function(t,e,n){var a=t(22),r=t(64);r&&a(a.S,"Reflect",{setPrototypeOf:function(t,e){r.check(t,e);try{return r.set(t,e),!0}catch(n){return!1}}})},{22:22,64:64}],152:[function(t,e,n){function a(t,e,n){var o,c,l=arguments.length<4?t:arguments[3],f=r.getDesc(u(t),e);if(!f){if(p(c=r.getProto(t)))return a(c,e,n,l);f=s(0)}return i(f,"value")?f.writable!==!1&&p(l)?(o=r.getDesc(l,e)||s(0),o.value=n,r.setDesc(l,e,o),!0):!1:void 0===f.set?!1:(f.set.call(l,n),!0)}var r=t(46),i=t(30),o=t(22),s=t(59),u=t(4),p=t(38);o(o.S,"Reflect",{set:a})},{22:22,30:30,38:38,4:4,46:46,59:59}],153:[function(t,e,n){var a=t(46),r=t(29),i=t(39),o=t(26),s=r.RegExp,u=s,p=s.prototype,c=/a/g,l=/a/g,f=new s(c)!==c;!t(19)||f&&!t(24)(function(){return l[t(83)("match")]=!1,s(c)!=c||s(l)==l||"/a/i"!=s(c,"i")})||(s=function(t,e){var n=i(t),a=void 0===e;return this instanceof s||!n||t.constructor!==s||!a?f?new u(n&&!a?t.source:t,e):u((n=t instanceof s)?t.source:t,n&&a?o.call(t):e):t},a.each.call(a.getNames(u),function(t){t in s||a.setDesc(s,t,{configurable:!0,get:function(){return u[t]},set:function(e){u[t]=e}})}),p.constructor=s,s.prototype=p,t(61)(r,"RegExp",s)),t(65)("RegExp")},{19:19,24:24,26:26,29:29,39:39,46:46,61:61,65:65,83:83}],154:[function(t,e,n){var a=t(46);t(19)&&"g"!=/./g.flags&&a.setDesc(RegExp.prototype,"flags",{configurable:!0,get:t(26)})},{19:19,26:26,46:46}],155:[function(t,e,n){t(25)("match",1,function(t,e){return function(n){"use strict";var a=t(this),r=void 0==n?void 0:n[e];return void 0!==r?r.call(n,a):RegExp(n)[e](a+"")}})},{25:25}],156:[function(t,e,n){t(25)("replace",2,function(t,e,n){return function(a,r){"use strict";var i=t(this),o=void 0==a?void 0:a[e];return void 0!==o?o.call(a,i,r):n.call(i+"",a,r)}})},{25:25}],157:[function(t,e,n){t(25)("search",1,function(t,e){return function(n){"use strict";var a=t(this),r=void 0==n?void 0:n[e];return void 0!==r?r.call(n,a):RegExp(n)[e](a+"")}})},{25:25}],158:[function(t,e,n){t(25)("split",2,function(t,e,n){return function(a,r){"use strict";var i=t(this),o=void 0==a?void 0:a[e];return void 0!==o?o.call(a,i,r):n.call(i+"",a,r)}})},{25:25}],159:[function(t,e,n){"use strict";var a=t(12);t(15)("Set",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return a.def(this,t=0===t?0:t,t)}},a)},{12:12,15:15}],160:[function(t,e,n){"use strict";var a=t(22),r=t(70)(!1);a(a.P,"String",{codePointAt:function(t){return r(this,t)}})},{22:22,70:70}],161:[function(t,e,n){"use strict";var a=t(22),r=t(79),i=t(71),o="endsWith",s=""[o];a(a.P+a.F*t(23)(o),"String",{endsWith:function(t){var e=i(this,t,o),n=arguments,a=n.length>1?n[1]:void 0,u=r(e.length),p=void 0===a?u:Math.min(r(a),u),c=t+"";return s?s.call(e,c,p):e.slice(p-c.length,p)===c}})},{22:22,23:23,71:71,79:79}],162:[function(t,e,n){var a=t(22),r=t(76),i=String.fromCharCode,o=String.fromCodePoint;a(a.S+a.F*(!!o&&1!=o.length),"String",{fromCodePoint:function(t){for(var e,n=[],a=arguments,o=a.length,s=0;o>s;){if(e=+a[s++],r(e,1114111)!==e)throw RangeError(e+" is not a valid code point");n.push(65536>e?i(e):i(((e-=65536)>>10)+55296,e%1024+56320))}return n.join("")}})},{22:22,76:76}],163:[function(t,e,n){"use strict";var a=t(22),r=t(71),i="includes";a(a.P+a.F*t(23)(i),"String",{includes:function(t){return!!~r(this,t,i).indexOf(t,arguments.length>1?arguments[1]:void 0)}})},{22:22,23:23,71:71}],164:[function(t,e,n){"use strict";var a=t(70)(!0);t(42)(String,"String",function(t){this._t=t+"",this._i=0},function(){var t,e=this._t,n=this._i;return n>=e.length?{value:void 0,done:!0}:(t=a(e,n),this._i+=t.length,{value:t,done:!1})})},{42:42,70:70}],165:[function(t,e,n){var a=t(22),r=t(78),i=t(79);a(a.S,"String",{raw:function(t){for(var e=r(t.raw),n=i(e.length),a=arguments,o=a.length,s=[],u=0;n>u;)s.push(e[u++]+""),o>u&&s.push(a[u]+"");return s.join("")}})},{22:22,78:78,79:79}],166:[function(t,e,n){var a=t(22);a(a.P,"String",{repeat:t(73)})},{22:22,73:73}],167:[function(t,e,n){"use strict";var a=t(22),r=t(79),i=t(71),o="startsWith",s=""[o];a(a.P+a.F*t(23)(o),"String",{startsWith:function(t){var e=i(this,t,o),n=arguments,a=r(Math.min(n.length>1?n[1]:void 0,e.length)),u=t+"";return s?s.call(e,u,a):e.slice(a,a+u.length)===u}})},{22:22,23:23,71:71,79:79}],168:[function(t,e,n){"use strict";t(74)("trim",function(t){return function(){return t(this,3)}})},{74:74}],169:[function(t,e,n){"use strict";var a=t(46),r=t(29),i=t(30),o=t(19),s=t(22),u=t(61),p=t(24),c=t(67),l=t(66),f=t(82),d=t(83),h=t(47),m=t(28),v=t(21),g=t(36),b=t(4),y=t(78),_=t(59),x=a.getDesc,w=a.setDesc,k=a.create,P=m.get,E=r.Symbol,C=r.JSON,S=C&&C.stringify,A=!1,O=d("_hidden"),T=a.isEnum,M=c("symbol-registry"),R=c("symbols"),j="function"==typeof E,L=Object.prototype,N=o&&p(function(){return 7!=k(w({},"a",{get:function(){return w(this,"a",{value:7}).a}})).a})?function(t,e,n){var a=x(L,e);a&&delete L[e],w(t,e,n),a&&t!==L&&w(L,e,a)}:w,F=function(t){var e=R[t]=k(E.prototype);return e._k=t,o&&A&&N(L,t,{configurable:!0,set:function(e){i(this,O)&&i(this[O],t)&&(this[O][t]=!1),N(this,t,_(1,e))}}),e},D=function(t){return"symbol"==typeof t},I=function(t,e,n){return n&&i(R,e)?(n.enumerable?(i(t,O)&&t[O][e]&&(t[O][e]=!1),n=k(n,{enumerable:_(0,!1)})):(i(t,O)||w(t,O,_(1,{})),t[O][e]=!0),N(t,e,n)):w(t,e,n)},B=function(t,e){b(t);for(var n,a=v(e=y(e)),r=0,i=a.length;i>r;)I(t,n=a[r++],e[n]);return t},q=function(t,e){return void 0===e?k(t):B(k(t),e)},G=function(t){var e=T.call(this,t);return e||!i(this,t)||!i(R,t)||i(this,O)&&this[O][t]?e:!0},U=function(t,e){var n=x(t=y(t),e);return!n||!i(R,e)||i(t,O)&&t[O][e]||(n.enumerable=!0),n},V=function(t){for(var e,n=P(y(t)),a=[],r=0;n.length>r;)i(R,e=n[r++])||e==O||a.push(e);return a},z=function(t){for(var e,n=P(y(t)),a=[],r=0;n.length>r;)i(R,e=n[r++])&&a.push(R[e]);return a},W=function(t){if(void 0!==t&&!D(t)){for(var e,n,a=[t],r=1,i=arguments;i.length>r;)a.push(i[r++]);return e=a[1],"function"==typeof e&&(n=e),(n||!g(e))&&(e=function(t,e){return n&&(e=n.call(this,t,e)),D(e)?void 0:e}),a[1]=e,S.apply(C,a)}},H=p(function(){var t=E();return"[null]"!=S([t])||"{}"!=S({a:t})||"{}"!=S(Object(t))});j||(E=function(){if(D(this))throw TypeError("Symbol is not a constructor");return F(f(arguments.length>0?arguments[0]:void 0))},u(E.prototype,"toString",function(){return this._k}),D=function(t){return t instanceof E},a.create=q,a.isEnum=G,a.getDesc=U,a.setDesc=I,a.setDescs=B,a.getNames=m.get=V,a.getSymbols=z,o&&!t(48)&&u(L,"propertyIsEnumerable",G,!0));var Q={"for":function(t){return i(M,t+="")?M[t]:M[t]=E(t)},keyFor:function(t){return h(M,t)},useSetter:function(){A=!0},useSimple:function(){A=!1}};a.each.call("hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),function(t){var e=d(t);Q[t]=j?e:F(e)}),A=!0,s(s.G+s.W,{Symbol:E}),s(s.S,"Symbol",Q),s(s.S+s.F*!j,"Object",{create:q,defineProperty:I,defineProperties:B,getOwnPropertyDescriptor:U,getOwnPropertyNames:V,getOwnPropertySymbols:z}),C&&s(s.S+s.F*(!j||H),"JSON",{stringify:W}),l(E,"Symbol"),l(Math,"Math",!0),l(r.JSON,"JSON",!0)},{19:19,21:21,22:22,24:24,28:28,29:29,30:30,36:36,4:4,46:46,47:47,48:48,59:59,61:61,66:66,67:67,78:78,82:82,83:83}],170:[function(t,e,n){"use strict";var a=t(46),r=t(61),i=t(14),o=t(38),s=t(30),u=i.frozenStore,p=i.WEAK,c=Object.isExtensible||o,l={},f=t(15)("WeakMap",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{get:function(t){if(o(t)){if(!c(t))return u(this).get(t);if(s(t,p))return t[p][this._i]}},set:function(t,e){return i.def(this,t,e)}},i,!0,!0);7!=(new f).set((Object.freeze||Object)(l),7).get(l)&&a.each.call(["delete","has","get","set"],function(t){var e=f.prototype,n=e[t];r(e,t,function(e,a){if(o(e)&&!c(e)){var r=u(this)[t](e,a);return"set"==t?this:r}return n.call(this,e,a)})})},{14:14,15:15,30:30,38:38,46:46,61:61}],171:[function(t,e,n){"use strict";var a=t(14);t(15)("WeakSet",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return a.def(this,t,!0)}},a,!1,!0)},{14:14,15:15}],172:[function(t,e,n){"use strict";var a=t(22),r=t(7)(!0);a(a.P,"Array",{includes:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0)}}),t(3)("includes")},{22:22,3:3,7:7}],173:[function(t,e,n){var a=t(22);a(a.P,"Map",{toJSON:t(13)("Map")})},{13:13,22:22}],174:[function(t,e,n){var a=t(22),r=t(55)(!0);a(a.S,"Object",{entries:function(t){return r(t)}})},{22:22,55:55}],175:[function(t,e,n){var a=t(46),r=t(22),i=t(56),o=t(78),s=t(59);r(r.S,"Object",{getOwnPropertyDescriptors:function(t){for(var e,n,r=o(t),u=a.setDesc,p=a.getDesc,c=i(r),l={},f=0;c.length>f;)n=p(r,e=c[f++]),e in l?u(l,e,s(0,n)):l[e]=n;return l}})},{22:22,46:46,56:56,59:59,78:78}],176:[function(t,e,n){var a=t(22),r=t(55)(!1);a(a.S,"Object",{values:function(t){return r(t)}})},{22:22,55:55}],177:[function(t,e,n){var a=t(22),r=t(62)(/[\\^$*+?.()|[\]{}]/g,"\\$&");a(a.S,"RegExp",{escape:function(t){return r(t)}})},{22:22,62:62}],178:[function(t,e,n){var a=t(22);a(a.P,"Set",{toJSON:t(13)("Set")})},{13:13,22:22}],179:[function(t,e,n){"use strict";var a=t(22),r=t(70)(!0);a(a.P,"String",{at:function(t){return r(this,t)}})},{22:22,70:70}],180:[function(t,e,n){"use strict";var a=t(22),r=t(72);a(a.P,"String",{padLeft:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0,!0)}})},{22:22,72:72}],181:[function(t,e,n){"use strict";var a=t(22),r=t(72);a(a.P,"String",{padRight:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0,!1)}})},{22:22,72:72}],182:[function(t,e,n){"use strict";t(74)("trimLeft",function(t){return function(){return t(this,1)}})},{74:74}],183:[function(t,e,n){"use strict";t(74)("trimRight",function(t){return function(){return t(this,2)}})},{74:74}],184:[function(t,e,n){var a=t(46),r=t(22),i=t(17),o=t(16).Array||Array,s={},u=function(t,e){a.each.call(t.split(","),function(t){void 0==e&&t in o?s[t]=o[t]:t in[]&&(s[t]=i(Function.call,[][t],e))})};u("pop,reverse,shift,keys,values,entries",1),u("indexOf,every,some,forEach,map,filter,find,findIndex,includes",3),u("join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill"),r(r.S,"Array",s)},{16:16,17:17,22:22,46:46}],185:[function(t,e,n){t(91);var a=t(29),r=t(31),i=t(45),o=t(83)("iterator"),s=a.NodeList,u=a.HTMLCollection,p=s&&s.prototype,c=u&&u.prototype,l=i.NodeList=i.HTMLCollection=i.Array;p&&!p[o]&&r(p,o,l),c&&!c[o]&&r(c,o,l)},{29:29,31:31,45:45,83:83,91:91}],186:[function(t,e,n){var a=t(22),r=t(75);a(a.G+a.B,{setImmediate:r.set,clearImmediate:r.clear})},{22:22,75:75}],187:[function(t,e,n){var a=t(29),r=t(22),i=t(33),o=t(57),s=a.navigator,u=!!s&&/MSIE .\./.test(s.userAgent),p=function(t){return u?function(e,n){return t(i(o,[].slice.call(arguments,2),"function"==typeof e?e:Function(e)),n)}:t};r(r.G+r.B+r.F*u,{setTimeout:p(a.setTimeout),setInterval:p(a.setInterval)})},{22:22,29:29,33:33,57:57}],188:[function(t,e,n){t(85),t(169),t(124),t(132),t(136),t(137),t(125),t(135),t(134),t(130),t(131),t(129),t(126),t(128),t(133),t(127),t(95),t(94),t(114),t(115),t(116),t(117),t(118),t(119),t(120),t(121),t(122),t(123),t(97),t(98),t(99),t(100),t(101),t(102),t(103),t(104),t(105),t(106),t(107),t(108),t(109),t(110),t(111),t(112),t(113),t(162),t(165),t(168),t(164),t(160),t(161),t(163),t(166),t(167),t(90),t(92),t(91),t(93),t(86),t(87),t(89),t(88),t(153),t(154),t(155),t(156),t(157),t(158),t(138),t(96),t(159),t(170),t(171),t(139),t(140),t(141),t(142),t(143),t(146),t(144),t(145),t(147),t(148),t(149),t(150),t(152),t(151),t(172),t(179),t(180),t(181),t(182),t(183),t(177),t(175),t(176),t(174),t(173),t(178),t(184),t(187),t(186),t(185),e.exports=t(16)},{100:100,101:101,102:102,103:103,104:104,105:105,106:106,107:107,108:108,109:109,110:110,111:111,112:112,113:113,114:114,115:115,116:116,117:117,118:118,119:119,120:120,121:121,122:122,123:123,124:124,125:125,126:126,127:127,128:128,129:129,130:130,131:131,132:132,133:133,134:134,135:135,136:136,137:137,138:138,139:139,140:140,141:141,142:142,143:143,144:144,145:145,146:146,147:147,148:148,149:149,150:150,151:151,152:152,153:153,154:154,155:155,156:156,157:157,158:158,159:159,16:16,160:160,161:161,162:162,163:163,164:164,165:165,166:166,167:167,168:168,169:169,170:170,171:171,172:172,173:173,174:174,175:175,176:176,177:177,178:178,179:179,180:180,181:181,182:182,183:183,184:184,185:185,186:186,187:187,85:85,86:86,87:87,88:88,89:89,90:90,91:91,92:92,93:93,94:94,95:95,96:96,97:97,98:98,99:99}],189:[function(t,e,n){(function(n){(function(t,n){!function(n){"use strict";function a(t,e,n,a){var r=Object.create((e||i).prototype),o=new h(a||[]);return r._invoke=l(t,n,o),r}function r(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(a){return{type:"throw",arg:a}}}function i(){}function o(){}function s(){}function u(t){["next","throw","return"].forEach(function(e){t[e]=function(t){return this._invoke(e,t)}})}function p(t){this.arg=t}function c(e){function n(t,n){var a=e[t](n),r=a.value;return r instanceof p?Promise.resolve(r.arg).then(i,o):Promise.resolve(r).then(function(t){return a.value=t,a})}function a(t,e){function a(){return n(t,e)}return r=r?r.then(a,a):new Promise(function(t){t(a())})}"object"==typeof t&&t.domain&&(n=t.domain.bind(n));var r,i=n.bind(e,"next"),o=n.bind(e,"throw");n.bind(e,"return");this._invoke=a}function l(t,e,n){var a=w;return function(i,o){if(a===P)throw Error("Generator is already running");if(a===E){if("throw"===i)throw o;return v()}for(;;){var s=n.delegate;if(s){if("return"===i||"throw"===i&&s.iterator[i]===g){n.delegate=null;var u=s.iterator["return"];if(u){var p=r(u,s.iterator,o);if("throw"===p.type){i="throw",o=p.arg;continue}}if("return"===i)continue}var p=r(s.iterator[i],s.iterator,o);if("throw"===p.type){n.delegate=null,i="throw",o=p.arg;continue}i="next",o=g;var c=p.arg;if(!c.done)return a=k,c;n[s.resultName]=c.value,n.next=s.nextLoc,n.delegate=null}if("next"===i)n._sent=o,a===k?n.sent=o:n.sent=g;else if("throw"===i){if(a===w)throw a=E,o;n.dispatchException(o)&&(i="next",o=g)}else"return"===i&&n.abrupt("return",o);a=P;var p=r(t,e,n);if("normal"===p.type){a=n.done?E:k;var c={value:p.arg,done:n.done};if(p.arg!==C)return c;n.delegate&&"next"===i&&(o=g)}else"throw"===p.type&&(a=E,i="throw",o=p.arg)}}}function f(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function d(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function h(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(f,this),this.reset(!0)}function m(t){if(t){var e=t[y];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,a=function r(){for(;++n=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),C}},"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},C}}}("object"==typeof n?n:"object"==typeof window?window:"object"==typeof self?self:this)}).call(this,t(202),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:{})},{202:202}],190:[function(t,e,n){!function(t){"use strict";function e(){return c.createDocumentFragment()}function n(t){return c.createElement(t)}function a(t){if(1===t.length)return r(t[0]);for(var n=e(),a=B.call(t),i=0;i-1}}([].indexOf||function(t){for(q=this.length;q--&&this[q]!==t;);return q}),item:function(t){return this[t]||null},remove:function(){for(var t,e=0;e=u?e(i):document.fonts.load(p(i,i.family),s).then(function(e){1<=e.length?t(i):setTimeout(f,25)},function(){e(i)})};f()}else n(function(){function n(){var e;(e=-1!=v&&-1!=g||-1!=v&&-1!=b||-1!=g&&-1!=b)&&((e=v!=g&&v!=b&&g!=b)||(null===l&&(e=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent),l=!!e&&(536>parseInt(e[1],10)||536===parseInt(e[1],10)&&11>=parseInt(e[2],10))),e=l&&(v==y&&g==y&&b==y||v==_&&g==_&&b==_||v==x&&g==x&&b==x)),e=!e),e&&(null!==w.parentNode&&w.parentNode.removeChild(w),clearTimeout(k),t(i))}function f(){if((new Date).getTime()-c>=u)null!==w.parentNode&&w.parentNode.removeChild(w),e(i);else{var t=document.hidden;(!0===t||void 0===t)&&(v=d.a.offsetWidth,g=h.a.offsetWidth,b=m.a.offsetWidth,n()),k=setTimeout(f,50)}}var d=new a(s),h=new a(s),m=new a(s),v=-1,g=-1,b=-1,y=-1,_=-1,x=-1,w=document.createElement("div"),k=0;w.dir="ltr",r(d,p(i,"sans-serif")),r(h,p(i,"serif")),r(m,p(i,"monospace")),w.appendChild(d.a),w.appendChild(h.a),w.appendChild(m.a),document.body.appendChild(w),y=d.a.offsetWidth,_=h.a.offsetWidth,x=m.a.offsetWidth,f(),o(d,function(t){v=t,n()}),r(d,p(i,'"'+i.family+'",sans-serif')),o(h,function(t){g=t,n()}),r(h,p(i,'"'+i.family+'",serif')),o(m,function(t){b=t,n()}),r(m,p(i,'"'+i.family+'",monospace'))})})},window.FontFaceObserver=s,window.FontFaceObserver.prototype.check=s.prototype.a,void 0!==e&&(e.exports=window.FontFaceObserver)}()},{}],193:[function(t,e,n){!function(t,n){function a(t,e){var n=t.createElement("p"),a=t.getElementsByTagName("head")[0]||t.documentElement;return n.innerHTML="x",a.insertBefore(n.lastChild,a.firstChild)}function r(){var t=_.elements;return"string"==typeof t?t.split(" "):t}function i(t,e){var n=_.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof t&&(t=t.join(" ")),_.elements=n+" "+t,c(e)}function o(t){var e=y[t[g]];return e||(e={},b++,t[g]=b,y[b]=e),e}function s(t,e,a){if(e||(e=n),f)return e.createElement(t);a||(a=o(e));var r;return r=a.cache[t]?a.cache[t].cloneNode():v.test(t)?(a.cache[t]=a.createElem(t)).cloneNode():a.createElem(t),!r.canHaveChildren||m.test(t)||r.tagUrn?r:a.frag.appendChild(r)}function u(t,e){if(t||(t=n),f)return t.createDocumentFragment();e=e||o(t);for(var a=e.frag.cloneNode(),i=0,s=r(),u=s.length;u>i;i++)a.createElement(s[i]);return a}function p(t,e){e.cache||(e.cache={},e.createElem=t.createElement,e.createFrag=t.createDocumentFragment,e.frag=e.createFrag()),t.createElement=function(n){return _.shivMethods?s(n,t,e):e.createElem(n)},t.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-:]+/g,function(t){return e.createElem(t),e.frag.createElement(t),'c("'+t+'")'})+");return n}")(_,e.frag)}function c(t){t||(t=n);var e=o(t);return!_.shivCSS||l||e.hasCSS||(e.hasCSS=!!a(t,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),f||p(t,e),t}var l,f,d="3.7.3-pre",h=t.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,v=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,g="_html5shiv",b=0,y={};!function(){try{var t=n.createElement("a");t.innerHTML="",l="hidden"in t,f=1==t.childNodes.length||function(){n.createElement("a");var t=n.createDocumentFragment();return void 0===t.cloneNode||void 0===t.createDocumentFragment||void 0===t.createElement}()}catch(e){l=!0,f=!0}}();var _={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:d,shivCSS:h.shivCSS!==!1,supportsUnknownElements:f,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:c,createElement:s,createDocumentFragment:u,addElements:i};t.html5=_,c(n),"object"==typeof e&&e.exports&&(e.exports=_)}("undefined"!=typeof window?window:this,document)},{}],194:[function(t,e,n){(function(t){(function(t){!function(t){function e(t,e,n,a){for(var i,o=n.slice(),s=r(e,t),u=0,p=o.length;p>u&&(handler=o[u],"object"==typeof handler?"function"==typeof handler.handleEvent&&handler.handleEvent(s):handler.call(t,s),!s.stoppedImmediatePropagation);u++);return i=!s.stoppedPropagation,a&&i&&t.parentNode?t.parentNode.dispatchEvent(s):!s.defaultPrevented}function n(t,e){return{configurable:!0,get:t,set:e}}function a(t,e,a){var r=b(e||t,a);v(t,"textContent",n(function(){return r.get.call(this)},function(t){r.set.call(this,t)}))}function r(t,e){return t.currentTarget=e,t.eventPhase=t.target===t.currentTarget?2:3,t}function i(t,e){for(var n=t.length;n--&&t[n]!==e;);return n}function o(){if("BR"===this.tagName)return"\n";for(var t=this.firstChild,e=[];t;)8!==t.nodeType&&7!==t.nodeType&&e.push(t.textContent),t=t.nextSibling;return e.join("")}function s(t){var e=document.createEvent("Event");e.initEvent("input",!0,!0),(t.srcElement||t.fromElement||document).dispatchEvent(e)}function u(t){!f&&k.test(document.readyState)&&(f=!f,document.detachEvent(d,u),t=document.createEvent("Event"),t.initEvent(h,!0,!0),document.dispatchEvent(t))}function p(t){for(var e;e=this.lastChild;)this.removeChild(e);null!=t&&this.appendChild(document.createTextNode(t))}function c(e,n){return n||(n=t.event),n.target||(n.target=n.srcElement||n.fromElement||document),n.timeStamp||(n.timeStamp=(new Date).getTime()),n}if(!document.createEvent){var l=!0,f=!1,d="onreadystatechange",h="DOMContentLoaded",m="__IE8__"+Math.random(),v=Object.defineProperty||function(t,e,n){t[e]=n.value},g=Object.defineProperties||function(e,n){for(var a in n)if(y.call(n,a))try{v(e,a,n[a])}catch(r){t.console&&console.log(a+" failed on object:",e,r.message)}},b=Object.getOwnPropertyDescriptor,y=Object.prototype.hasOwnProperty,_=t.Element.prototype,x=t.Text.prototype,w=/^[a-z]+$/,k=/loaded|complete/,P={},E=document.createElement("div"),C=document.documentElement,S=C.removeAttribute,A=C.setAttribute;a(t.HTMLCommentElement.prototype,_,"nodeValue"),a(t.HTMLScriptElement.prototype,null,"text"),a(x,null,"nodeValue"),a(t.HTMLTitleElement.prototype,null,"text"),v(t.HTMLStyleElement.prototype,"textContent",function(t){return n(function(){return t.get.call(this.styleSheet)},function(e){t.set.call(this.styleSheet,e)})}(b(t.CSSStyleSheet.prototype,"cssText"))),g(_,{textContent:{get:o,set:p},firstElementChild:{get:function(){for(var t=this.childNodes||[],e=0,n=t.length;n>e;e++)if(1==t[e].nodeType)return t[e]}},lastElementChild:{get:function(){for(var t=this.childNodes||[],e=t.length;e--;)if(1==t[e].nodeType)return t[e]}},oninput:{get:function(){return this._oninput||null},set:function(t){this._oninput&&(this.removeEventListener("input",this._oninput),this._oninput=t,t&&this.addEventListener("input",t))}},previousElementSibling:{get:function(){for(var t=this.previousSibling;t&&1!=t.nodeType;)t=t.previousSibling;return t}},nextElementSibling:{get:function(){for(var t=this.nextSibling;t&&1!=t.nodeType;)t=t.nextSibling;return t}},childElementCount:{get:function(){for(var t=0,e=this.childNodes||[],n=e.length;n--;t+=1==e[n].nodeType);return t}},addEventListener:{value:function(t,n,a){if("function"==typeof n||"object"==typeof n){var r,o,u=this,p="on"+t,l=u[m]||v(u,m,{value:{}})[m],f=l[p]||(l[p]={}),d=f.h||(f.h=[]);if(!y.call(f,"w")){if(f.w=function(t){return t[m]||e(u,c(u,t),d,!1)},!y.call(P,p))if(w.test(t)){try{r=document.createEventObject(),r[m]=!0,9!=u.nodeType&&(null==u.parentNode&&E.appendChild(u),(o=u.getAttribute(p))&&S.call(u,p)),u.fireEvent(p,r),P[p]=!0}catch(r){for(P[p]=!1;E.hasChildNodes();)E.removeChild(E.firstChild)}null!=o&&A.call(u,p,o)}else P[p]=!1;(f.n=P[p])&&u.attachEvent(p,f.w)}i(d,n)<0&&d[a?"unshift":"push"](n),"input"===t&&u.attachEvent("onkeyup",s)}}},dispatchEvent:{value:function(t){var n,a=this,r="on"+t.type,i=a[m],o=i&&i[r],s=!!o;return t.target||(t.target=a),s?o.n?a.fireEvent(r,t):e(a,t,o.h,!0):(n=a.parentNode)?n.dispatchEvent(t):!0,!t.defaultPrevented}},removeEventListener:{value:function(t,e,n){if("function"==typeof e||"object"==typeof e){var a=this,r="on"+t,o=a[m],s=o&&o[r],u=s&&s.h,p=u?i(u,e):-1;p>-1&&u.splice(p,1)}}}}),g(x,{addEventListener:{value:_.addEventListener},dispatchEvent:{value:_.dispatchEvent},removeEventListener:{value:_.removeEventListener}}),g(t.XMLHttpRequest.prototype,{addEventListener:{value:function(t,e,n){var a=this,r="on"+t,o=a[m]||v(a,m,{value:{}})[m],s=o[r]||(o[r]={}),u=s.h||(s.h=[]);i(u,e)<0&&(a[r]||(a[r]=function(){var e=document.createEvent("Event");e.initEvent(t,!0,!0),a.dispatchEvent(e)}),u[n?"unshift":"push"](e))}},dispatchEvent:{value:function(t){var n=this,a="on"+t.type,r=n[m],i=r&&r[a],o=!!i;return o&&(i.n?n.fireEvent(a,t):e(n,t,i.h,!0))}},removeEventListener:{value:_.removeEventListener}}),g(t.Event.prototype,{bubbles:{value:!0,writable:!0},cancelable:{value:!0,writable:!0},preventDefault:{value:function(){this.cancelable&&(this.defaultPrevented=!0,this.returnValue=!1)}},stopPropagation:{value:function(){this.stoppedPropagation=!0,this.cancelBubble=!0}},stopImmediatePropagation:{value:function(){this.stoppedImmediatePropagation=!0,this.stopPropagation()}},initEvent:{value:function(t,e,n){this.type=t,this.bubbles=!!e,this.cancelable=!!n,this.bubbles||this.stopPropagation()}}}),g(t.HTMLDocument.prototype,{defaultView:{get:function(){return this.parentWindow}},textContent:{get:function(){return 11===this.nodeType?o.call(this):null},set:function(t){11===this.nodeType&&p.call(this,t)}},addEventListener:{value:function(e,n,a){var r=this;_.addEventListener.call(r,e,n,a),l&&e===h&&!k.test(r.readyState)&&(l=!1,r.attachEvent(d,u),t==top&&!function i(t){try{r.documentElement.doScroll("left"),u()}catch(e){setTimeout(i,50)}}())}},dispatchEvent:{value:_.dispatchEvent},removeEventListener:{value:_.removeEventListener},createEvent:{value:function(t){var e;if("Event"!==t)throw Error("unsupported "+t);return e=document.createEventObject(),e.timeStamp=(new Date).getTime(),e}}}),g(t.Window.prototype,{getComputedStyle:{value:function(){function t(t){this._=t}function e(){}var n=/^(?:[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/,a=/^(top|right|bottom|left)$/,r=/\-([a-z])/g,i=function(t,e){return e.toUpperCase()};return t.prototype.getPropertyValue=function(t){var e,o,s,u=this._,p=u.style,c=u.currentStyle,l=u.runtimeStyle;return t=("float"===t?"style-float":t).replace(r,i),e=c?c[t]:p[t],n.test(e)&&!a.test(t)&&(o=p.left,s=l&&l.left,s&&(l.left=c.left),p.left="fontSize"===t?"1em":e,e=p.pixelLeft+"px",p.left=o,s&&(l.left=s)),null==e?e:e+""||"auto"},e.prototype.getPropertyValue=function(){return null},function(n,a){return a?new e(n):new t(n)}}()},addEventListener:{value:function(n,a,r){var o,s=t,u="on"+n;s[u]||(s[u]=function(t){return e(s,c(s,t),o,!1)}),o=s[u][m]||(s[u][m]=[]),i(o,a)<0&&o[r?"unshift":"push"](a)}},dispatchEvent:{value:function(e){var n=t["on"+e.type];return n?n.call(t,e)!==!1&&!e.defaultPrevented:!0}},removeEventListener:{value:function(e,n,a){var r="on"+e,o=(t[r]||Object)[m],s=o?i(o,n):-1;s>-1&&o.splice(s,1)}}}),function(t,e,n){for(n=0;n=s)return(0,u["default"])({points:n});for(var l=1;s-1>=l;l++)i.push((0,p.times)(a,(0,p.minus)(n[l],n[l-1])));for(var f=[(0,p.plus)(n[0],c(i[0],i[1]))],l=1;s-2>=l;l++)f.push((0,p.minus)(n[l],(0,p.average)([i[l],i[l-1]])));f.push((0,p.minus)(n[s-1],c(i[s-2],i[s-3])));var d=f[0],h=f[1],m=n[0],v=n[1],g=(e=(0,o["default"])()).moveto.apply(e,r(m)).curveto(d[0],d[1],h[0],h[1],v[0],v[1]);return{path:(0,p.range)(2,s).reduce(function(t,e){var a=f[e],r=n[e];return t.smoothcurveto(a[0],a[1],r[0],r[1])},g),centroid:(0,p.average)(n)}},e.exports=n["default"]},{198:198,199:199,200:200}],196:[function(t,e,n){"use strict";function a(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),i=t(197),o=a(i),s=t(198),u=1e-5,p=function(t,e){var n=t.map(e),a=n.sort(function(t,e){var n=r(t,2),a=n[0],i=(n[1],r(e,2)),o=i[0];i[1];return a-o}),i=a.length,o=a[0][0],p=a[i-1][0],c=(0,s.minBy)(a,function(t){return t[1]}),l=(0,s.maxBy)(a,function(t){return t[1]});return o==p&&(p+=u),c==l&&(l+=u),{points:a,xmin:o,xmax:p,ymin:c,ymax:l}};n["default"]=function(t){var e=t.data,n=t.xaccessor,a=t.yaccessor,i=t.width,u=t.height,c=t.closed,l=t.min,f=t.max;n||(n=function(t){var e=r(t,2),n=e[0];e[1];return n}),a||(a=function(t){var e=r(t,2),n=(e[0],e[1]);return n});var d=function(t){return[n(t),a(t)]},h=e.map(function(t){return p(t,d)}),m=(0,s.minBy)(h,function(t){return t.xmin}),v=(0,s.maxBy)(h,function(t){return t.xmax}),g=null==l?(0,s.minBy)(h,function(t){return t.ymin}):l,b=null==f?(0,s.maxBy)(h,function(t){return t.ymax}):f;c&&(g=Math.min(g,0),b=Math.max(b,0));var y=c?0:g,_=(0,o["default"])([m,v],[0,i]),x=(0,o["default"])([g,b],[u,0]),w=function(t){var e=r(t,2),n=e[0],a=e[1];return[_(n),x(a)]};return{arranged:h,scale:w,xscale:_,yscale:x,base:y}},e.exports=n["default"]},{197:197,198:198}],197:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function i(t,e){var n=a(t,2),r=n[0],o=n[1],s=a(e,2),u=s[0],p=s[1],c=function(t){return u+(p-u)*(t-r)/(o-r)};return c.inverse=function(){return i([u,p],[r,o])},c};n["default"]=r,e.exports=n["default"]},{}],198:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function(t){return t.reduce(function(t,e){return t+e},0)},i=function(t){return t.reduce(function(t,e){return Math.min(t,e)})},o=function(t){return t.reduce(function(t,e){return Math.max(t,e)})},s=function(t,e){return t.reduce(function(t,n){return t+e(n)},0)},u=function(t,e){return t.reduce(function(t,n){return Math.min(t,e(n))},1/0)},p=function(t,e){return t.reduce(function(t,n){return Math.max(t,e(n))},-(1/0))},c=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],u=o[1];return[r+s,i+u]},l=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],u=o[1];return[r-s,i-u]},f=function(t,e){var n=a(e,2),r=n[0],i=n[1];return[t*r,t*i]},d=function(t){var e=a(t,2),n=e[0],r=e[1];return Math.sqrt(n*n+r*r)},h=function(t){return t.reduce(c,[0,0])},m=function(t){return f(1/t.length,t.reduce(c))},v=function(t,e){return f(t,[Math.sin(e),-Math.cos(e)])},g=function(t,e){var n=t||{};for(var a in n){var r=n[a];e[a]=r(e.index,e.item,e.group)}return e},b=function(t,e,n){for(var a=[],r=t;e>r;r++)a.push(r);return n&&a.push(e),a},y=function(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=Object.keys(t)[Symbol.iterator]();!(a=(o=s.next()).done);a=!0){var u=o.value,p=t[u];n.push(e(u,p))}}catch(c){r=!0,i=c}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n},_=function(t){return y(t,function(t,e){return[t,e]})},x=function(t){return t};n.sum=r,n.min=i,n.max=o,n.sumBy=s,n.minBy=u,n.maxBy=p,n.plus=c,n.minus=l,n.times=f,n.id=x,n.length=d,n.sumVectors=h,n.average=m,n.onCircle=v,n.enhance=g,n.range=b,n.mapObject=y,n.pairs=_,n["default"]={sum:r,min:i,max:o,sumBy:s,minBy:u,maxBy:p,plus:c,minus:l,times:f,id:x,length:d,sumVectors:h,average:m,onCircle:v,enhance:g,range:b,mapObject:y,pairs:_}},{}],199:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function i(t){var e=t||[],n=function(t,e){var n=t.slice(0,t.length);return n.push(e),n},r=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],u=o[1];return r===s&&i===u},o=function(t,e){for(var n=t.length;"0"===t.charAt(n-1);)n-=1;return"."===t.charAt(n-1)&&(n-=1),t.substr(0,n)},s=function(t,e){var n=t.toFixed(e);return o(n)},u=function(t){var e=t.command,n=t.params,a=n.map(function(t){return s(t,6)});return e+" "+a.join(" ")},p=function(t,e){var n=t.command,r=t.params,i=a(e,2),o=i[0],s=i[1];switch(n){case"M":return[r[0],r[1]];case"L":return[r[0],r[1]];case"H":return[r[0],s];case"V":return[o,r[0]];case"Z":return null;case"C":return[r[4],r[5]];case"S":return[r[2],r[3]];case"Q":return[r[2],r[3]];case"T":return[r[0],r[1]];case"A":return[r[5],r[6]]}},c=function(t,e){return function(n){var a="object"==typeof n?t.map(function(t){return n[t]}):arguments;return e.apply(null,a)}},l=function(t){return i(n(e,t))};return{moveto:c(["x","y"],function(t,e){return l({command:"M",params:[t,e]})}),lineto:c(["x","y"],function(t,e){return l({command:"L",params:[t,e]})}),hlineto:c(["x"],function(t){return l({command:"H",params:[t]})}),vlineto:c(["y"],function(t){return l({command:"V",params:[t]})}),closepath:function(){return l({command:"Z",params:[]})},curveto:c(["x1","y1","x2","y2","x","y"],function(t,e,n,a,r,i){return l({command:"C",params:[t,e,n,a,r,i]})}),smoothcurveto:c(["x2","y2","x","y"],function(t,e,n,a){return l({command:"S",params:[t,e,n,a]})}),qcurveto:c(["x1","y1","x","y"],function(t,e,n,a){return l({command:"Q",params:[t,e,n,a]})}),smoothqcurveto:c(["x","y"],function(t,e){return l({command:"T",params:[t,e]})}),arc:c(["rx","ry","xrot","largeArcFlag","sweepFlag","x","y"],function(t,e,n,a,r,i,o){return l({command:"A",params:[t,e,n,a,r,i,o]})}),print:function(){return e.map(u).join(" ")},points:function(){var t=[],n=[0,0],a=!0,r=!1,i=void 0;try{for(var o,s=e[Symbol.iterator]();!(a=(o=s.next()).done);a=!0){var u=o.value,c=p(u,n);n=c,c&&t.push(c)}}catch(l){r=!0,i=l}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return t},instructions:function(){return e.slice(0,e.length)},connect:function(t){var e=this.points(),n=e[e.length-1],a=t.points()[0],o=t.instructions().slice(1);return r(n,a)||o.unshift({command:"L",params:a}),i(this.instructions().concat(o))}}};n["default"]=function(){return r()},e.exports=n["default"]},{}],200:[function(t,e,n){"use strict";function a(t){return t&&t.__esModule?t:{"default":t}}function r(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e1)for(var n=1;n1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];for(var r,i;i=n.shift();)for(r in i)Ro.call(i,r)&&(t[r]=i[r]);return t}function r(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];return n.forEach(function(e){for(var n in e)!e.hasOwnProperty(n)||n in t||(t[n]=e[n])}),t}function i(t){return"[object Array]"===jo.call(t)}function o(t){return Lo.test(jo.call(t))}function s(t,e){return null===t&&null===e?!0:"object"==typeof t||"object"==typeof e?!1:t===e}function u(t){return!isNaN(parseFloat(t))&&isFinite(t)}function p(t){return t&&"[object Object]"===jo.call(t)}function c(t,e){return t.replace(/%s/g,function(){return e.shift()})}function l(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];throw t=c(t,n),Error(t)}function f(){Rv.DEBUG&&Oo.apply(null,arguments)}function d(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];t=c(t,n),To(t,n)}function h(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];t=c(t,n),No[t]||(No[t]=!0,To(t,n))}function m(){Rv.DEBUG&&d.apply(null,arguments)}function v(){Rv.DEBUG&&h.apply(null,arguments)}function g(t,e,n){var a=b(t,e,n);return a?a[t][n]:null}function b(t,e,n){for(;e;){if(n in e[t])return e;if(e.isolated)return null;e=e.parent}}function y(t){return function(){return t}}function _(t){var e,n,a,r,i,o;for(e=t.split("."),(n=zo[e.length])||(n=x(e.length)),i=[],a=function(t,n){return t?"*":e[n]},r=n.length;r--;)o=n[r].map(a).join("."),i.hasOwnProperty(o)||(i.push(o),i[o]=!0);return i}function x(t){var e,n,a,r,i,o,s,u,p="";if(!zo[t]){for(a=[];p.length=i;i+=1){for(n=i.toString(2);n.lengtho;o++)u.push(r(n[o]));a[i]=u}zo[t]=a}return zo[t]}function w(t,e,n,a){var r=t[e];if(!r||!r.equalsOrStartsWith(a)&&r.equalsOrStartsWith(n))return t[e]=r?r.replace(n,a):a,!0}function k(t){var e=t.slice(2);return"i"===t[1]&&u(e)?+e:e}function P(t){return null==t?t:(Qo.hasOwnProperty(t)||(Qo[t]=new Ko(t)),Qo[t])}function E(t,e){function n(e,n){var a,r,o;return n.isRoot?o=[].concat(Object.keys(t.viewmodel.data),Object.keys(t.viewmodel.mappings),Object.keys(t.viewmodel.computations)):(a=t.viewmodel.wrapped[n.str],r=a?a.get():t.viewmodel.get(n),o=r?Object.keys(r):null),o&&o.forEach(function(t){"_ractive"===t&&i(r)||e.push(n.join(t))}),e}var a,r,o;for(a=e.str.split("."),o=[Yo];r=a.shift();)"*"===r?o=o.reduce(n,[]):o[0]===Yo?o[0]=P(r):o=o.map(C(r));return o}function C(t){return function(e){return e.join(t)}}function S(t){return t?t.replace(Wo,".$1"):""}function A(t,e,n){if("string"!=typeof e||!u(n))throw Error("Bad arguments");var a=void 0,r=void 0;if(/\*/.test(e))return r={},E(t,P(S(e))).forEach(function(e){var a=t.viewmodel.get(e);if(!u(a))throw Error(Jo);r[e.str]=a+n}),t.set(r);if(a=t.get(e),!u(a))throw Error(Jo);return t.set(e,+a+n)}function O(t,e){return Xo(this,t,void 0===e?1:+e)}function T(t){this.event=t,this.method="on"+t,this.deprecate=as[t]}function M(t,e){var n=t.indexOf(e);-1===n&&t.push(e)}function R(t,e){for(var n=0,a=t.length;a>n;n++)if(t[n]==e)return!0;return!1}function j(t,e){var n;if(!i(t)||!i(e))return!1;if(t.length!==e.length)return!1;for(n=t.length;n--;)if(t[n]!==e[n])return!1;return!0}function L(t){return"string"==typeof t?[t]:void 0===t?[]:t;
-}function N(t){return t[t.length-1]}function F(t,e){var n=t.indexOf(e);-1!==n&&t.splice(n,1)}function D(t){for(var e=[],n=t.length;n--;)e[n]=t[n];return e}function I(t){setTimeout(t,0)}function B(t,e){return function(){for(var n;n=t.shift();)n(e)}}function q(t,e,n,a){var r;if(e===t)throw new TypeError("A promise's fulfillment handler cannot return the same promise");if(e instanceof rs)e.then(n,a);else if(!e||"object"!=typeof e&&"function"!=typeof e)n(e);else{try{r=e.then}catch(i){return void a(i)}if("function"==typeof r){var o,s,u;s=function(e){o||(o=!0,q(t,e,n,a))},u=function(t){o||(o=!0,a(t))};try{r.call(e,s,u)}catch(i){if(!o)return a(i),void(o=!0)}}else n(e)}}function G(t,e,n){var a;return e=S(e),"~/"===e.substr(0,2)?(a=P(e.substring(2)),z(t,a.firstKey,n)):"."===e[0]?(a=U(cs(n),e),a&&z(t,a.firstKey,n)):a=V(t,P(e),n),a}function U(t,e){var n;if(void 0!=t&&"string"!=typeof t&&(t=t.str),"."===e)return P(t);if(n=t?t.split("."):[],"../"===e.substr(0,3)){for(;"../"===e.substr(0,3);){if(!n.length)throw Error('Could not resolve reference - too many "../" prefixes');n.pop(),e=e.substring(3)}return n.push(e),P(n.join("."))}return P(t?t+e.replace(/^\.\//,"."):e.replace(/^\.\/?/,""))}function V(t,e,n,a){var r,i,o,s,u;if(e.isRoot)return e;for(i=e.firstKey;n;)if(r=n.context,n=n.parent,r&&(s=!0,o=t.viewmodel.get(r),o&&("object"==typeof o||"function"==typeof o)&&i in o))return r.join(e.str);return W(t.viewmodel,i)?e:t.parent&&!t.isolated&&(s=!0,n=t.component.parentFragment,i=P(i),u=V(t.parent,i,n,!0))?(t.viewmodel.map(i,{origin:t.parent.viewmodel,keypath:u}),e):a||s?void 0:(t.viewmodel.set(e,void 0),e)}function z(t,e){var n;!t.parent||t.isolated||W(t.viewmodel,e)||(e=P(e),(n=V(t.parent,e,t.component.parentFragment,!0))&&t.viewmodel.map(e,{origin:t.parent.viewmodel,keypath:n}))}function W(t,e){return""===e||e in t.data||e in t.computations||e in t.mappings}function H(t){t.teardown()}function Q(t){t.unbind()}function K(t){t.unrender()}function $(t){t.cancel()}function Y(t){t.detach()}function X(t){t.detachNodes()}function J(t){!t.ready||t.outros.length||t.outroChildren||(t.outrosComplete||(t.parent?t.parent.decrementOutros(t):t.detachNodes(),t.outrosComplete=!0),t.intros.length||t.totalChildren||("function"==typeof t.callback&&t.callback(),t.parent&&t.parent.decrementTotal()))}function Z(){for(var t,e,n;ds.ractives.length;)e=ds.ractives.pop(),n=e.viewmodel.applyChanges(),n&&gs.fire(e,n);for(tt(),t=0;t=0;i--)r=t._subs[e[i]],r&&(s=gt(t,r,n,a)&&s);if(Vs.dequeue(t),t.parent&&s){if(o&&t.component){var u=t.component.name+"."+e[e.length-1];e=P(u).wildcardMatches(),n&&(n.component=t)}vt(t.parent,e,n,a)}}function gt(t,e,n,a){var r=null,i=!1;n&&!n._noArg&&(a=[n].concat(a)),e=e.slice();for(var o=0,s=e.length;s>o;o+=1)e[o].apply(t,a)===!1&&(i=!0);return n&&!n._noArg&&i&&(r=n.original)&&(r.preventDefault&&r.preventDefault(),r.stopPropagation&&r.stopPropagation()),!i}function bt(t){var e={args:Array.prototype.slice.call(arguments,1)};zs(this,t,e)}function yt(t){var e;return t=P(S(t)),e=this.viewmodel.get(t,Qs),void 0===e&&this.parent&&!this.isolated&&ls(this,t.str,this.component.parentFragment)&&(e=this.viewmodel.get(t)),e}function _t(e,n){if(!this.fragment.rendered)throw Error("The API has changed - you must call `ractive.render(target[, anchor])` to render your Ractive instance. Once rendered you can use `ractive.insert()`.");if(e=t(e),n=t(n)||null,!e)throw Error("You must specify a valid target to insert into");e.insertBefore(this.detach(),n),this.el=e,(e.__ractive_instances__||(e.__ractive_instances__=[])).push(this),this.detached=null,xt(this)}function xt(t){$s.fire(t),t.findAllComponents("*").forEach(function(t){xt(t.instance)})}function wt(t,e,n){var a,r;return t=P(S(t)),a=this.viewmodel.get(t),i(a)&&i(e)?(r=bs.start(this,!0),this.viewmodel.merge(t,a,e,n),bs.end(),r):this.set(t,e,n&&n.complete)}function kt(t,e){var n,a;return n=E(t,e),a={},n.forEach(function(e){a[e.str]=t.get(e.str)}),a}function Pt(t,e,n,a){var r,i,o;e=P(S(e)),a=a||cu,e.isPattern?(r=new uu(t,e,n,a),t.viewmodel.patternObservers.push(r),i=!0):r=new Zs(t,e,n,a),r.init(a.init),t.viewmodel.register(e,r,i?"patternObservers":"observers"),r.ready=!0;var s={cancel:function(){var n;o||(i?(n=t.viewmodel.patternObservers.indexOf(r),t.viewmodel.patternObservers.splice(n,1),t.viewmodel.unregister(e,r,"patternObservers")):t.viewmodel.unregister(e,r,"observers"),o=!0)}};return t._observers.push(s),s}function Et(t,e,n){var a,r,i,o;if(p(t)){n=e,r=t,a=[];for(t in r)r.hasOwnProperty(t)&&(e=r[t],a.push(this.observe(t,e,n)));return{cancel:function(){for(;a.length;)a.pop().cancel()}}}if("function"==typeof t)return n=e,e=t,t="",pu(this,t,e,n);if(i=t.split(" "),1===i.length)return pu(this,t,e,n);for(a=[],o=i.length;o--;)t=i[o],t&&a.push(pu(this,t,e,n));return{cancel:function(){for(;a.length;)a.pop().cancel()}}}function Ct(t,e,n){var a=this.observe(t,function(){e.apply(this,arguments),a.cancel()},{init:!1,defer:n&&n.defer});return a}function St(t,e){var n,a=this;if(t)n=t.split(" ").map(du).filter(hu),n.forEach(function(t){var n,r;(n=a._subs[t])&&(e?(r=n.indexOf(e),-1!==r&&n.splice(r,1)):a._subs[t]=[])});else for(t in this._subs)delete this._subs[t];return this}function At(t,e){var n,a,r,i=this;if("object"==typeof t){n=[];for(a in t)t.hasOwnProperty(a)&&n.push(this.on(a,t[a]));return{cancel:function(){for(var t;t=n.pop();)t.cancel()}}}return r=t.split(" ").map(du).filter(hu),r.forEach(function(t){(i._subs[t]||(i._subs[t]=[])).push(e)}),{cancel:function(){return i.off(t,e)}}}function Ot(t,e){var n=this.on(t,function(){e.apply(this,arguments),n.cancel()});return n}function Tt(t,e,n){var a,r,i,o,s,u,p=[];if(a=Mt(t,e,n),!a)return null;for(r=t.length,s=a.length-2-a[1],i=Math.min(r,a[0]),o=i+a[1],u=0;i>u;u+=1)p.push(u);for(;o>u;u+=1)p.push(-1);for(;r>u;u+=1)p.push(u+s);return 0!==s?p.touchedFrom=a[0]:p.touchedFrom=t.length,p}function Mt(t,e,n){switch(e){case"splice":for(void 0!==n[0]&&n[0]<0&&(n[0]=t.length+Math.max(n[0],-t.length));n.length<2;)n.push(0);return n[1]=Math.min(n[1],t.length-n[0]),n;case"sort":case"reverse":return null;case"pop":return t.length?[t.length-1,1]:[0,0];case"push":return[t.length,0].concat(n);case"shift":return[0,t.length?1:0];case"unshift":return[0,0].concat(n)}}function Rt(e,n){var a,r,i,o=this;if(i=this.transitionsEnabled,this.noIntro&&(this.transitionsEnabled=!1),a=bs.start(this,!0),bs.scheduleTask(function(){return Mu.fire(o)},!0),this.fragment.rendered)throw Error("You cannot call ractive.render() on an already rendered instance! Call ractive.unrender() first");if(e=t(e)||this.el,n=t(n)||this.anchor,this.el=e,this.anchor=n,!this.append&&e){var s=e.__ractive_instances__;s&&s.length&&jt(s),e.innerHTML=""}return this.cssId&&Ou.apply(),e&&((r=e.__ractive_instances__)?r.push(this):e.__ractive_instances__=[this],n?e.insertBefore(this.fragment.render(),n):e.appendChild(this.fragment.render())),bs.end(),this.transitionsEnabled=i,a.then(function(){return Ru.fire(o)})}function jt(t){t.splice(0,t.length).forEach(H)}function Lt(t,e){for(var n=t.slice(),a=e.length;a--;)~n.indexOf(e[a])||n.push(e[a]);return n}function Nt(t,e){var n,a,r;return a='[data-ractive-css~="{'+e+'}"]',r=function(t){var e,n,r,i,o,s,u,p=[];for(e=[];n=Iu.exec(t);)e.push({str:n[0],base:n[1],modifiers:n[2]});for(i=e.map(Dt),u=e.length;u--;)s=i.slice(),r=e[u],s[u]=r.base+a+r.modifiers||"",o=i.slice(),o[u]=a+" "+o[u],p.push(s.join(" "),o.join(" "));return p.join(", ")},n=qu.test(t)?t.replace(qu,a):t.replace(Du,"").replace(Fu,function(t,e){var n,a;return Bu.test(e)?t:(n=e.split(",").map(Ft),a=n.map(r).join(", ")+" ",t.replace(e,a))})}function Ft(t){return t.trim?t.trim():t.replace(/^\s+/,"").replace(/\s+$/,"")}function Dt(t){return t.str}function It(t){t&&t.constructor!==Object&&("function"==typeof t||("object"!=typeof t?l("data option must be an object or a function, `"+t+"` is not valid"):m("If supplied, options.data should be a plain JavaScript object - using a non-POJO as the root object may work, but is discouraged")))}function Bt(t,e){It(e);var n="function"==typeof t,a="function"==typeof e;return e||n||(e={}),n||a?function(){var r=a?qt(e,this):e,i=n?qt(t,this):t;return Gt(r,i)}:Gt(e,t)}function qt(t,e){var n=t.call(e);if(n)return"object"!=typeof n&&l("Data function must return an object"),n.constructor!==Object&&v("Data function returned something other than a plain JavaScript object. This might work, but is strongly discouraged"),n}function Gt(t,e){if(t&&e){for(var n in e)n in t||(t[n]=e[n]);return t}return t||e}function Ut(t){var e=Po(Ku);return e.parse=function(e,n){return Vt(e,n||t)},e}function Vt(t,e){if(!Hu)throw Error("Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser");return Hu(t,e||this.options)}function zt(t,e){var n;if(!Ji){if(e&&e.noThrow)return;throw Error("Cannot retrieve template #"+t+" as Ractive is not running in a browser.")}if(Wt(t)&&(t=t.substring(1)),!(n=document.getElementById(t))){if(e&&e.noThrow)return;throw Error("Could not find template element with id #"+t)}if("SCRIPT"!==n.tagName.toUpperCase()){if(e&&e.noThrow)return;throw Error("Template element with id #"+t+", must be a i;)c(r,a=t[i++])&&(~E(o,a)||o.push(a));return o}},B=function(){};i(i.S,"Object",{getPrototypeOf:r.getProto=r.getProto||function(t){return t=g(t),c(t,k)?t[k]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?C:null},getOwnPropertyNames:r.getNames=r.getNames||I(N,N.length,!0),create:r.create=r.create||function(t,e){var n;return null!==t?(B.prototype=h(t),n=new B,B.prototype=null,n[k]=t):n=F(),void 0===e?n:R(n,e)},keys:r.getKeys=r.getKeys||I(L,D,!1)});var q=function(t,e,n){if(!(e in j)){for(var a=[],r=0;e>r;r++)a[r]="a["+r+"]";j[e]=Function("F,a","return new F("+a.join(",")+")")}return j[e](t,n)};i(i.P,"Function",{bind:function(t){var e=m(this),n=A.call(arguments,1),a=function(){var r=n.concat(A.call(arguments));return this instanceof a?q(e,r.length,r):f(e,r,t)};return v(e.prototype)&&(a.prototype=e.prototype),a}}),i(i.P+i.F*d(function(){u&&A.call(u)}),"Array",{slice:function(t,e){var n=x(this.length),a=l(this);if(e=void 0===e?n:e,"Array"==a)return A.call(this,t,e);for(var r=_(t,n),i=_(e,n),o=x(i-r),s=Array(o),u=0;o>u;u++)s[u]="String"==a?this.charAt(r+u):this[r+u];return s}}),i(i.P+i.F*(w!=Object),"Array",{join:function(t){return O.call(w(this),void 0===t?",":t)}}),i(i.S,"Array",{isArray:t(36)});var G=function(t){return function(e,n){m(e);var a=w(this),r=x(a.length),i=t?r-1:0,o=t?-1:1;if(arguments.length<2)for(;;){if(i in a){n=a[i],i+=o;break}if(i+=o,t?0>i:i>=r)throw TypeError("Reduce of empty array with no initial value")}for(;t?i>=0:r>i;i+=o)i in a&&(n=e(n,a[i],i,this));return n}},U=function(t){return function(e){return t(this,e,arguments[1])}};i(i.P,"Array",{forEach:r.each=r.each||U(P(0)),map:U(P(1)),filter:U(P(2)),some:U(P(3)),every:U(P(4)),reduce:G(!1),reduceRight:G(!0),indexOf:U(E),lastIndexOf:function(t,e){var n=b(this),a=x(n.length),r=a-1;for(arguments.length>1&&(r=Math.min(r,y(e))),0>r&&(r=x(a+r));r>=0;r--)if(r in n&&n[r]===t)return r;return-1}}),i(i.S,"Date",{now:function(){return+new Date}});var V=function(t){return t>9?t:"0"+t};i(i.P+i.F*(d(function(){return"0385-07-25T07:06:39.999Z"!=new Date(-5e13-1).toISOString()})||!d(function(){new Date(NaN).toISOString()})),"Date",{toISOString:function(){if(!isFinite(this))throw RangeError("Invalid time value");var t=this,e=t.getUTCFullYear(),n=t.getUTCMilliseconds(),a=0>e?"-":e>9999?"+":"";return a+("00000"+Math.abs(e)).slice(a?-6:-4)+"-"+V(t.getUTCMonth()+1)+"-"+V(t.getUTCDate())+"T"+V(t.getUTCHours())+":"+V(t.getUTCMinutes())+":"+V(t.getUTCSeconds())+"."+(n>99?n:"0"+V(n))+"Z"}})},{11:11,19:19,2:2,20:20,22:22,24:24,30:30,32:32,33:33,34:34,36:36,38:38,4:4,46:46,59:59,7:7,76:76,77:77,78:78,79:79,8:8,80:80,82:82}],86:[function(t,e,n){var a=t(22);a(a.P,"Array",{copyWithin:t(5)}),t(3)("copyWithin")},{22:22,3:3,5:5}],87:[function(t,e,n){var a=t(22);a(a.P,"Array",{fill:t(6)}),t(3)("fill")},{22:22,3:3,6:6}],88:[function(t,e,n){"use strict";var a=t(22),r=t(8)(6),i="findIndex",o=!0;i in[]&&Array(1)[i](function(){o=!1}),a(a.P+a.F*o,"Array",{findIndex:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0)}}),t(3)(i)},{22:22,3:3,8:8}],89:[function(t,e,n){"use strict";var a=t(22),r=t(8)(5),i="find",o=!0;i in[]&&Array(1)[i](function(){o=!1}),a(a.P+a.F*o,"Array",{find:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0)}}),t(3)(i)},{22:22,3:3,8:8}],90:[function(t,e,n){"use strict";var a=t(17),r=t(22),i=t(80),o=t(40),s=t(35),u=t(79),p=t(84);r(r.S+r.F*!t(43)(function(t){Array.from(t)}),"Array",{from:function(t){var e,n,r,c,l=i(t),f="function"==typeof this?this:Array,d=arguments,h=d.length,m=h>1?d[1]:void 0,v=void 0!==m,g=0,b=p(l);if(v&&(m=a(m,h>2?d[2]:void 0,2)),void 0==b||f==Array&&s(b))for(e=u(l.length),n=new f(e);e>g;g++)n[g]=v?m(l[g],g):l[g];else for(c=b.call(l),n=new f;!(r=c.next()).done;g++)n[g]=v?o(c,m,[r.value,g],!0):r.value;return n.length=g,n}})},{17:17,22:22,35:35,40:40,43:43,79:79,80:80,84:84}],91:[function(t,e,n){"use strict";var a=t(3),r=t(44),i=t(45),o=t(78);e.exports=t(42)(Array,"Array",function(t,e){this._t=o(t),this._i=0,this._k=e},function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,r(1)):"keys"==e?r(0,n):"values"==e?r(0,t[n]):r(0,[n,t[n]])},"values"),i.Arguments=i.Array,a("keys"),a("values"),a("entries")},{3:3,42:42,44:44,45:45,78:78}],92:[function(t,e,n){"use strict";var a=t(22);a(a.S+a.F*t(24)(function(){function t(){}return!(Array.of.call(t)instanceof t)}),"Array",{of:function(){for(var t=0,e=arguments,n=e.length,a=new("function"==typeof this?this:Array)(n);n>t;)a[t]=e[t++];return a.length=n,a}})},{22:22,24:24}],93:[function(t,e,n){t(65)("Array")},{65:65}],94:[function(t,e,n){"use strict";var a=t(46),r=t(38),i=t(83)("hasInstance"),o=Function.prototype;i in o||a.setDesc(o,i,{value:function(t){if("function"!=typeof this||!r(t))return!1;if(!r(this.prototype))return t instanceof this;for(;t=a.getProto(t);)if(this.prototype===t)return!0;return!1}})},{38:38,46:46,83:83}],95:[function(t,e,n){var a=t(46).setDesc,r=t(59),i=t(30),o=Function.prototype,s=/^\s*function ([^ (]*)/,u="name";u in o||t(19)&&a(o,u,{configurable:!0,get:function(){var t=(""+this).match(s),e=t?t[1]:"";return i(this,u)||a(this,u,r(5,e)),e}})},{19:19,30:30,46:46,59:59}],96:[function(t,e,n){"use strict";var a=t(12);t(15)("Map",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{get:function(t){var e=a.getEntry(this,t);return e&&e.v},set:function(t,e){return a.def(this,0===t?0:t,e)}},a,!0)},{12:12,15:15}],97:[function(t,e,n){var a=t(22),r=t(50),i=Math.sqrt,o=Math.acosh;a(a.S+a.F*!(o&&710==Math.floor(o(Number.MAX_VALUE))),"Math",{acosh:function(t){return(t=+t)<1?NaN:t>94906265.62425156?Math.log(t)+Math.LN2:r(t-1+i(t-1)*i(t+1))}})},{22:22,50:50}],98:[function(t,e,n){function a(t){return isFinite(t=+t)&&0!=t?0>t?-a(-t):Math.log(t+Math.sqrt(t*t+1)):t}var r=t(22);r(r.S,"Math",{asinh:a})},{22:22}],99:[function(t,e,n){var a=t(22);a(a.S,"Math",{atanh:function(t){return 0==(t=+t)?t:Math.log((1+t)/(1-t))/2}})},{22:22}],100:[function(t,e,n){var a=t(22),r=t(51);a(a.S,"Math",{cbrt:function(t){return r(t=+t)*Math.pow(Math.abs(t),1/3)}})},{22:22,51:51}],101:[function(t,e,n){var a=t(22);a(a.S,"Math",{clz32:function(t){return(t>>>=0)?31-Math.floor(Math.log(t+.5)*Math.LOG2E):32}})},{22:22}],102:[function(t,e,n){var a=t(22),r=Math.exp;a(a.S,"Math",{cosh:function(t){return(r(t=+t)+r(-t))/2}})},{22:22}],103:[function(t,e,n){var a=t(22);a(a.S,"Math",{expm1:t(49)})},{22:22,49:49}],104:[function(t,e,n){var a=t(22),r=t(51),i=Math.pow,o=i(2,-52),s=i(2,-23),u=i(2,127)*(2-s),p=i(2,-126),c=function(t){return t+1/o-1/o};a(a.S,"Math",{fround:function(t){var e,n,a=Math.abs(t),i=r(t);return p>a?i*c(a/p/s)*p*s:(e=(1+s/o)*a,n=e-(e-a),n>u||n!=n?i*(1/0):i*n)}})},{22:22,51:51}],105:[function(t,e,n){var a=t(22),r=Math.abs;a(a.S,"Math",{hypot:function(t,e){for(var n,a,i=0,o=0,s=arguments,u=s.length,p=0;u>o;)n=r(s[o++]),n>p?(a=p/n,i=i*a*a+1,p=n):n>0?(a=n/p,i+=a*a):i+=n;return p===1/0?1/0:p*Math.sqrt(i)}})},{22:22}],106:[function(t,e,n){var a=t(22),r=Math.imul;a(a.S+a.F*t(24)(function(){return-5!=r(4294967295,5)||2!=r.length}),"Math",{imul:function(t,e){var n=65535,a=+t,r=+e,i=n&a,o=n&r;return 0|i*o+((n&a>>>16)*o+i*(n&r>>>16)<<16>>>0)}})},{22:22,24:24}],107:[function(t,e,n){var a=t(22);a(a.S,"Math",{log10:function(t){return Math.log(t)/Math.LN10}})},{22:22}],108:[function(t,e,n){var a=t(22);a(a.S,"Math",{log1p:t(50)})},{22:22,50:50}],109:[function(t,e,n){var a=t(22);a(a.S,"Math",{log2:function(t){return Math.log(t)/Math.LN2}})},{22:22}],110:[function(t,e,n){var a=t(22);a(a.S,"Math",{sign:t(51)})},{22:22,51:51}],111:[function(t,e,n){var a=t(22),r=t(49),i=Math.exp;a(a.S+a.F*t(24)(function(){return-2e-17!=!Math.sinh(-2e-17)}),"Math",{sinh:function(t){return Math.abs(t=+t)<1?(r(t)-r(-t))/2:(i(t-1)-i(-t-1))*(Math.E/2)}})},{22:22,24:24,49:49}],112:[function(t,e,n){var a=t(22),r=t(49),i=Math.exp;a(a.S,"Math",{tanh:function(t){var e=r(t=+t),n=r(-t);return e==1/0?1:n==1/0?-1:(e-n)/(i(t)+i(-t))}})},{22:22,49:49}],113:[function(t,e,n){var a=t(22);a(a.S,"Math",{trunc:function(t){return(t>0?Math.floor:Math.ceil)(t)}})},{22:22}],114:[function(t,e,n){"use strict";var a=t(46),r=t(29),i=t(30),o=t(11),s=t(81),u=t(24),p=t(74).trim,c="Number",l=r[c],f=l,d=l.prototype,h=o(a.create(d))==c,m="trim"in String.prototype,v=function(t){
+var e=s(t,!1);if("string"==typeof e&&e.length>2){e=m?e.trim():p(e,3);var n,a,r,i=e.charCodeAt(0);if(43===i||45===i){if(n=e.charCodeAt(2),88===n||120===n)return NaN}else if(48===i){switch(e.charCodeAt(1)){case 66:case 98:a=2,r=49;break;case 79:case 111:a=8,r=55;break;default:return+e}for(var o,u=e.slice(2),c=0,l=u.length;l>c;c++)if(o=u.charCodeAt(c),48>o||o>r)return NaN;return parseInt(u,a)}}return+e};l(" 0o1")&&l("0b1")&&!l("+0x1")||(l=function(t){var e=arguments.length<1?0:t,n=this;return n instanceof l&&(h?u(function(){d.valueOf.call(n)}):o(n)!=c)?new f(v(e)):v(e)},a.each.call(t(19)?a.getNames(f):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),function(t){i(f,t)&&!i(l,t)&&a.setDesc(l,t,a.getDesc(f,t))}),l.prototype=d,d.constructor=l,t(61)(r,c,l))},{11:11,19:19,24:24,29:29,30:30,46:46,61:61,74:74,81:81}],115:[function(t,e,n){var a=t(22);a(a.S,"Number",{EPSILON:Math.pow(2,-52)})},{22:22}],116:[function(t,e,n){var a=t(22),r=t(29).isFinite;a(a.S,"Number",{isFinite:function(t){return"number"==typeof t&&r(t)}})},{22:22,29:29}],117:[function(t,e,n){var a=t(22);a(a.S,"Number",{isInteger:t(37)})},{22:22,37:37}],118:[function(t,e,n){var a=t(22);a(a.S,"Number",{isNaN:function(t){return t!=t}})},{22:22}],119:[function(t,e,n){var a=t(22),r=t(37),i=Math.abs;a(a.S,"Number",{isSafeInteger:function(t){return r(t)&&i(t)<=9007199254740991}})},{22:22,37:37}],120:[function(t,e,n){var a=t(22);a(a.S,"Number",{MAX_SAFE_INTEGER:9007199254740991})},{22:22}],121:[function(t,e,n){var a=t(22);a(a.S,"Number",{MIN_SAFE_INTEGER:-9007199254740991})},{22:22}],122:[function(t,e,n){var a=t(22);a(a.S,"Number",{parseFloat:parseFloat})},{22:22}],123:[function(t,e,n){var a=t(22);a(a.S,"Number",{parseInt:parseInt})},{22:22}],124:[function(t,e,n){var a=t(22);a(a.S+a.F,"Object",{assign:t(53)})},{22:22,53:53}],125:[function(t,e,n){var a=t(38);t(54)("freeze",function(t){return function(e){return t&&a(e)?t(e):e}})},{38:38,54:54}],126:[function(t,e,n){var a=t(78);t(54)("getOwnPropertyDescriptor",function(t){return function(e,n){return t(a(e),n)}})},{54:54,78:78}],127:[function(t,e,n){t(54)("getOwnPropertyNames",function(){return t(28).get})},{28:28,54:54}],128:[function(t,e,n){var a=t(80);t(54)("getPrototypeOf",function(t){return function(e){return t(a(e))}})},{54:54,80:80}],129:[function(t,e,n){var a=t(38);t(54)("isExtensible",function(t){return function(e){return a(e)?t?t(e):!0:!1}})},{38:38,54:54}],130:[function(t,e,n){var a=t(38);t(54)("isFrozen",function(t){return function(e){return a(e)?t?t(e):!1:!0}})},{38:38,54:54}],131:[function(t,e,n){var a=t(38);t(54)("isSealed",function(t){return function(e){return a(e)?t?t(e):!1:!0}})},{38:38,54:54}],132:[function(t,e,n){var a=t(22);a(a.S,"Object",{is:t(63)})},{22:22,63:63}],133:[function(t,e,n){var a=t(80);t(54)("keys",function(t){return function(e){return t(a(e))}})},{54:54,80:80}],134:[function(t,e,n){var a=t(38);t(54)("preventExtensions",function(t){return function(e){return t&&a(e)?t(e):e}})},{38:38,54:54}],135:[function(t,e,n){var a=t(38);t(54)("seal",function(t){return function(e){return t&&a(e)?t(e):e}})},{38:38,54:54}],136:[function(t,e,n){var a=t(22);a(a.S,"Object",{setPrototypeOf:t(64).set})},{22:22,64:64}],137:[function(t,e,n){"use strict";var a=t(10),r={};r[t(83)("toStringTag")]="z",r+""!="[object z]"&&t(61)(Object.prototype,"toString",function(){return"[object "+a(this)+"]"},!0)},{10:10,61:61,83:83}],138:[function(t,e,n){"use strict";var a,r=t(46),i=t(48),o=t(29),s=t(17),u=t(10),p=t(22),c=t(38),l=t(4),f=t(2),d=t(69),h=t(27),m=t(64).set,v=t(63),g=t(83)("species"),b=t(68),y=t(52),_="Promise",x=o.process,w="process"==u(x),k=o[_],P=function(t){var e=new k(function(){});return t&&(e.constructor=Object),k.resolve(e)===e},E=function(){function e(t){var n=new k(t);return m(n,e.prototype),n}var n=!1;try{if(n=k&&k.resolve&&P(),m(e,k),e.prototype=r.create(k.prototype,{constructor:{value:e}}),e.resolve(5).then(function(){})instanceof e||(n=!1),n&&t(19)){var a=!1;k.resolve(r.setDesc({},"then",{get:function(){a=!0}})),n=a}}catch(i){n=!1}return n}(),C=function(t,e){return i&&t===k&&e===a?!0:v(t,e)},S=function(t){var e=l(t)[g];return void 0!=e?e:t},A=function(t){var e;return c(t)&&"function"==typeof(e=t.then)?e:!1},O=function(t){var e,n;this.promise=new t(function(t,a){if(void 0!==e||void 0!==n)throw TypeError("Bad Promise constructor");e=t,n=a}),this.resolve=f(e),this.reject=f(n)},T=function(t){try{t()}catch(e){return{error:e}}},M=function(t,e){if(!t.n){t.n=!0;var n=t.c;y(function(){for(var a=t.v,r=1==t.s,i=0,s=function(e){var n,i,o=r?e.ok:e.fail,s=e.resolve,u=e.reject;try{o?(r||(t.h=!0),n=o===!0?a:o(a),n===e.promise?u(TypeError("Promise-chain cycle")):(i=A(n))?i.call(n,s,u):s(n)):u(a)}catch(p){u(p)}};n.length>i;)s(n[i++]);n.length=0,t.n=!1,e&&setTimeout(function(){var e,n,r=t.p;R(r)&&(w?x.emit("unhandledRejection",a,r):(e=o.onunhandledrejection)?e({promise:r,reason:a}):(n=o.console)&&n.error&&n.error("Unhandled promise rejection",a)),t.a=void 0},1)})}},R=function(t){var e,n=t._d,a=n.a||n.c,r=0;if(n.h)return!1;for(;a.length>r;)if(e=a[r++],e.fail||!R(e.promise))return!1;return!0},j=function(t){var e=this;e.d||(e.d=!0,e=e.r||e,e.v=t,e.s=2,e.a=e.c.slice(),M(e,!0))},L=function(t){var e,n=this;if(!n.d){n.d=!0,n=n.r||n;try{if(n.p===t)throw TypeError("Promise can't be resolved itself");(e=A(t))?y(function(){var a={r:n,d:!1};try{e.call(t,s(L,a,1),s(j,a,1))}catch(r){j.call(a,r)}}):(n.v=t,n.s=1,M(n,!1))}catch(a){j.call({r:n,d:!1},a)}}};E||(k=function(t){f(t);var e=this._d={p:d(this,k,_),c:[],a:void 0,s:0,d:!1,v:void 0,h:!1,n:!1};try{t(s(L,e,1),s(j,e,1))}catch(n){j.call(e,n)}},t(60)(k.prototype,{then:function(t,e){var n=new O(b(this,k)),a=n.promise,r=this._d;return n.ok="function"==typeof t?t:!0,n.fail="function"==typeof e&&e,r.c.push(n),r.a&&r.a.push(n),r.s&&M(r,!1),a},"catch":function(t){return this.then(void 0,t)}})),p(p.G+p.W+p.F*!E,{Promise:k}),t(66)(k,_),t(65)(_),a=t(16)[_],p(p.S+p.F*!E,_,{reject:function(t){var e=new O(this),n=e.reject;return n(t),e.promise}}),p(p.S+p.F*(!E||P(!0)),_,{resolve:function(t){if(t instanceof k&&C(t.constructor,this))return t;var e=new O(this),n=e.resolve;return n(t),e.promise}}),p(p.S+p.F*!(E&&t(43)(function(t){k.all(t)["catch"](function(){})})),_,{all:function(t){var e=S(this),n=new O(e),a=n.resolve,i=n.reject,o=[],s=T(function(){h(t,!1,o.push,o);var n=o.length,s=Array(n);n?r.each.call(o,function(t,r){var o=!1;e.resolve(t).then(function(t){o||(o=!0,s[r]=t,--n||a(s))},i)}):a(s)});return s&&i(s.error),n.promise},race:function(t){var e=S(this),n=new O(e),a=n.reject,r=T(function(){h(t,!1,function(t){e.resolve(t).then(n.resolve,a)})});return r&&a(r.error),n.promise}})},{10:10,16:16,17:17,19:19,2:2,22:22,27:27,29:29,38:38,4:4,43:43,46:46,48:48,52:52,60:60,63:63,64:64,65:65,66:66,68:68,69:69,83:83}],139:[function(t,e,n){var a=t(22),r=Function.apply;a(a.S,"Reflect",{apply:function(t,e,n){return r.call(t,e,n)}})},{22:22}],140:[function(t,e,n){var a=t(46),r=t(22),i=t(2),o=t(4),s=t(38),u=Function.bind||t(16).Function.prototype.bind;r(r.S+r.F*t(24)(function(){function t(){}return!(Reflect.construct(function(){},[],t)instanceof t)}),"Reflect",{construct:function(t,e){i(t);var n=arguments.length<3?t:i(arguments[2]);if(t==n){if(void 0!=e)switch(o(e).length){case 0:return new t;case 1:return new t(e[0]);case 2:return new t(e[0],e[1]);case 3:return new t(e[0],e[1],e[2]);case 4:return new t(e[0],e[1],e[2],e[3])}var r=[null];return r.push.apply(r,e),new(u.apply(t,r))}var p=n.prototype,c=a.create(s(p)?p:Object.prototype),l=Function.apply.call(t,c,e);return s(l)?l:c}})},{16:16,2:2,22:22,24:24,38:38,4:4,46:46}],141:[function(t,e,n){var a=t(46),r=t(22),i=t(4);r(r.S+r.F*t(24)(function(){Reflect.defineProperty(a.setDesc({},1,{value:1}),1,{value:2})}),"Reflect",{defineProperty:function(t,e,n){i(t);try{return a.setDesc(t,e,n),!0}catch(r){return!1}}})},{22:22,24:24,4:4,46:46}],142:[function(t,e,n){var a=t(22),r=t(46).getDesc,i=t(4);a(a.S,"Reflect",{deleteProperty:function(t,e){var n=r(i(t),e);return n&&!n.configurable?!1:delete t[e]}})},{22:22,4:4,46:46}],143:[function(t,e,n){"use strict";var a=t(22),r=t(4),i=function(t){this._t=r(t),this._i=0;var e,n=this._k=[];for(e in t)n.push(e)};t(41)(i,"Object",function(){var t,e=this,n=e._k;do if(e._i>=n.length)return{value:void 0,done:!0};while(!((t=n[e._i++])in e._t));return{value:t,done:!1}}),a(a.S,"Reflect",{enumerate:function(t){return new i(t)}})},{22:22,4:4,41:41}],144:[function(t,e,n){var a=t(46),r=t(22),i=t(4);r(r.S,"Reflect",{getOwnPropertyDescriptor:function(t,e){return a.getDesc(i(t),e)}})},{22:22,4:4,46:46}],145:[function(t,e,n){var a=t(22),r=t(46).getProto,i=t(4);a(a.S,"Reflect",{getPrototypeOf:function(t){return r(i(t))}})},{22:22,4:4,46:46}],146:[function(t,e,n){function a(t,e){var n,o,p=arguments.length<3?t:arguments[2];return u(t)===p?t[e]:(n=r.getDesc(t,e))?i(n,"value")?n.value:void 0!==n.get?n.get.call(p):void 0:s(o=r.getProto(t))?a(o,e,p):void 0}var r=t(46),i=t(30),o=t(22),s=t(38),u=t(4);o(o.S,"Reflect",{get:a})},{22:22,30:30,38:38,4:4,46:46}],147:[function(t,e,n){var a=t(22);a(a.S,"Reflect",{has:function(t,e){return e in t}})},{22:22}],148:[function(t,e,n){var a=t(22),r=t(4),i=Object.isExtensible;a(a.S,"Reflect",{isExtensible:function(t){return r(t),i?i(t):!0}})},{22:22,4:4}],149:[function(t,e,n){var a=t(22);a(a.S,"Reflect",{ownKeys:t(56)})},{22:22,56:56}],150:[function(t,e,n){var a=t(22),r=t(4),i=Object.preventExtensions;a(a.S,"Reflect",{preventExtensions:function(t){r(t);try{return i&&i(t),!0}catch(e){return!1}}})},{22:22,4:4}],151:[function(t,e,n){var a=t(22),r=t(64);r&&a(a.S,"Reflect",{setPrototypeOf:function(t,e){r.check(t,e);try{return r.set(t,e),!0}catch(n){return!1}}})},{22:22,64:64}],152:[function(t,e,n){function a(t,e,n){var o,c,l=arguments.length<4?t:arguments[3],f=r.getDesc(u(t),e);if(!f){if(p(c=r.getProto(t)))return a(c,e,n,l);f=s(0)}return i(f,"value")?f.writable!==!1&&p(l)?(o=r.getDesc(l,e)||s(0),o.value=n,r.setDesc(l,e,o),!0):!1:void 0===f.set?!1:(f.set.call(l,n),!0)}var r=t(46),i=t(30),o=t(22),s=t(59),u=t(4),p=t(38);o(o.S,"Reflect",{set:a})},{22:22,30:30,38:38,4:4,46:46,59:59}],153:[function(t,e,n){var a=t(46),r=t(29),i=t(39),o=t(26),s=r.RegExp,u=s,p=s.prototype,c=/a/g,l=/a/g,f=new s(c)!==c;!t(19)||f&&!t(24)(function(){return l[t(83)("match")]=!1,s(c)!=c||s(l)==l||"/a/i"!=s(c,"i")})||(s=function(t,e){var n=i(t),a=void 0===e;return this instanceof s||!n||t.constructor!==s||!a?f?new u(n&&!a?t.source:t,e):u((n=t instanceof s)?t.source:t,n&&a?o.call(t):e):t},a.each.call(a.getNames(u),function(t){t in s||a.setDesc(s,t,{configurable:!0,get:function(){return u[t]},set:function(e){u[t]=e}})}),p.constructor=s,s.prototype=p,t(61)(r,"RegExp",s)),t(65)("RegExp")},{19:19,24:24,26:26,29:29,39:39,46:46,61:61,65:65,83:83}],154:[function(t,e,n){var a=t(46);t(19)&&"g"!=/./g.flags&&a.setDesc(RegExp.prototype,"flags",{configurable:!0,get:t(26)})},{19:19,26:26,46:46}],155:[function(t,e,n){t(25)("match",1,function(t,e){return function(n){"use strict";var a=t(this),r=void 0==n?void 0:n[e];return void 0!==r?r.call(n,a):RegExp(n)[e](a+"")}})},{25:25}],156:[function(t,e,n){t(25)("replace",2,function(t,e,n){return function(a,r){"use strict";var i=t(this),o=void 0==a?void 0:a[e];return void 0!==o?o.call(a,i,r):n.call(i+"",a,r)}})},{25:25}],157:[function(t,e,n){t(25)("search",1,function(t,e){return function(n){"use strict";var a=t(this),r=void 0==n?void 0:n[e];return void 0!==r?r.call(n,a):RegExp(n)[e](a+"")}})},{25:25}],158:[function(t,e,n){t(25)("split",2,function(t,e,n){return function(a,r){"use strict";var i=t(this),o=void 0==a?void 0:a[e];return void 0!==o?o.call(a,i,r):n.call(i+"",a,r)}})},{25:25}],159:[function(t,e,n){"use strict";var a=t(12);t(15)("Set",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return a.def(this,t=0===t?0:t,t)}},a)},{12:12,15:15}],160:[function(t,e,n){"use strict";var a=t(22),r=t(70)(!1);a(a.P,"String",{codePointAt:function(t){return r(this,t)}})},{22:22,70:70}],161:[function(t,e,n){"use strict";var a=t(22),r=t(79),i=t(71),o="endsWith",s=""[o];a(a.P+a.F*t(23)(o),"String",{endsWith:function(t){var e=i(this,t,o),n=arguments,a=n.length>1?n[1]:void 0,u=r(e.length),p=void 0===a?u:Math.min(r(a),u),c=t+"";return s?s.call(e,c,p):e.slice(p-c.length,p)===c}})},{22:22,23:23,71:71,79:79}],162:[function(t,e,n){var a=t(22),r=t(76),i=String.fromCharCode,o=String.fromCodePoint;a(a.S+a.F*(!!o&&1!=o.length),"String",{fromCodePoint:function(t){for(var e,n=[],a=arguments,o=a.length,s=0;o>s;){if(e=+a[s++],r(e,1114111)!==e)throw RangeError(e+" is not a valid code point");n.push(65536>e?i(e):i(((e-=65536)>>10)+55296,e%1024+56320))}return n.join("")}})},{22:22,76:76}],163:[function(t,e,n){"use strict";var a=t(22),r=t(71),i="includes";a(a.P+a.F*t(23)(i),"String",{includes:function(t){return!!~r(this,t,i).indexOf(t,arguments.length>1?arguments[1]:void 0)}})},{22:22,23:23,71:71}],164:[function(t,e,n){"use strict";var a=t(70)(!0);t(42)(String,"String",function(t){this._t=t+"",this._i=0},function(){var t,e=this._t,n=this._i;return n>=e.length?{value:void 0,done:!0}:(t=a(e,n),this._i+=t.length,{value:t,done:!1})})},{42:42,70:70}],165:[function(t,e,n){var a=t(22),r=t(78),i=t(79);a(a.S,"String",{raw:function(t){for(var e=r(t.raw),n=i(e.length),a=arguments,o=a.length,s=[],u=0;n>u;)s.push(e[u++]+""),o>u&&s.push(a[u]+"");return s.join("")}})},{22:22,78:78,79:79}],166:[function(t,e,n){var a=t(22);a(a.P,"String",{repeat:t(73)})},{22:22,73:73}],167:[function(t,e,n){"use strict";var a=t(22),r=t(79),i=t(71),o="startsWith",s=""[o];a(a.P+a.F*t(23)(o),"String",{startsWith:function(t){var e=i(this,t,o),n=arguments,a=r(Math.min(n.length>1?n[1]:void 0,e.length)),u=t+"";return s?s.call(e,u,a):e.slice(a,a+u.length)===u}})},{22:22,23:23,71:71,79:79}],168:[function(t,e,n){"use strict";t(74)("trim",function(t){return function(){return t(this,3)}})},{74:74}],169:[function(t,e,n){"use strict";var a=t(46),r=t(29),i=t(30),o=t(19),s=t(22),u=t(61),p=t(24),c=t(67),l=t(66),f=t(82),d=t(83),h=t(47),m=t(28),v=t(21),g=t(36),b=t(4),y=t(78),_=t(59),x=a.getDesc,w=a.setDesc,k=a.create,P=m.get,E=r.Symbol,C=r.JSON,S=C&&C.stringify,A=!1,O=d("_hidden"),T=a.isEnum,M=c("symbol-registry"),R=c("symbols"),j="function"==typeof E,L=Object.prototype,N=o&&p(function(){return 7!=k(w({},"a",{get:function(){return w(this,"a",{value:7}).a}})).a})?function(t,e,n){var a=x(L,e);a&&delete L[e],w(t,e,n),a&&t!==L&&w(L,e,a)}:w,D=function(t){var e=R[t]=k(E.prototype);return e._k=t,o&&A&&N(L,t,{configurable:!0,set:function(e){i(this,O)&&i(this[O],t)&&(this[O][t]=!1),N(this,t,_(1,e))}}),e},F=function(t){return"symbol"==typeof t},I=function(t,e,n){return n&&i(R,e)?(n.enumerable?(i(t,O)&&t[O][e]&&(t[O][e]=!1),n=k(n,{enumerable:_(0,!1)})):(i(t,O)||w(t,O,_(1,{})),t[O][e]=!0),N(t,e,n)):w(t,e,n)},B=function(t,e){b(t);for(var n,a=v(e=y(e)),r=0,i=a.length;i>r;)I(t,n=a[r++],e[n]);return t},q=function(t,e){return void 0===e?k(t):B(k(t),e)},G=function(t){var e=T.call(this,t);return e||!i(this,t)||!i(R,t)||i(this,O)&&this[O][t]?e:!0},U=function(t,e){var n=x(t=y(t),e);return!n||!i(R,e)||i(t,O)&&t[O][e]||(n.enumerable=!0),n},V=function(t){for(var e,n=P(y(t)),a=[],r=0;n.length>r;)i(R,e=n[r++])||e==O||a.push(e);return a},z=function(t){for(var e,n=P(y(t)),a=[],r=0;n.length>r;)i(R,e=n[r++])&&a.push(R[e]);return a},W=function(t){if(void 0!==t&&!F(t)){for(var e,n,a=[t],r=1,i=arguments;i.length>r;)a.push(i[r++]);return e=a[1],"function"==typeof e&&(n=e),(n||!g(e))&&(e=function(t,e){return n&&(e=n.call(this,t,e)),F(e)?void 0:e}),a[1]=e,S.apply(C,a)}},H=p(function(){var t=E();return"[null]"!=S([t])||"{}"!=S({a:t})||"{}"!=S(Object(t))});j||(E=function(){if(F(this))throw TypeError("Symbol is not a constructor");return D(f(arguments.length>0?arguments[0]:void 0))},u(E.prototype,"toString",function(){return this._k}),F=function(t){return t instanceof E},a.create=q,a.isEnum=G,a.getDesc=U,a.setDesc=I,a.setDescs=B,a.getNames=m.get=V,a.getSymbols=z,o&&!t(48)&&u(L,"propertyIsEnumerable",G,!0));var Q={"for":function(t){return i(M,t+="")?M[t]:M[t]=E(t)},keyFor:function(t){return h(M,t)},useSetter:function(){A=!0},useSimple:function(){A=!1}};a.each.call("hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),function(t){var e=d(t);Q[t]=j?e:D(e)}),A=!0,s(s.G+s.W,{Symbol:E}),s(s.S,"Symbol",Q),s(s.S+s.F*!j,"Object",{create:q,defineProperty:I,defineProperties:B,getOwnPropertyDescriptor:U,getOwnPropertyNames:V,getOwnPropertySymbols:z}),C&&s(s.S+s.F*(!j||H),"JSON",{stringify:W}),l(E,"Symbol"),l(Math,"Math",!0),l(r.JSON,"JSON",!0)},{19:19,21:21,22:22,24:24,28:28,29:29,30:30,36:36,4:4,46:46,47:47,48:48,59:59,61:61,66:66,67:67,78:78,82:82,83:83}],170:[function(t,e,n){"use strict";var a=t(46),r=t(61),i=t(14),o=t(38),s=t(30),u=i.frozenStore,p=i.WEAK,c=Object.isExtensible||o,l={},f=t(15)("WeakMap",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{get:function(t){if(o(t)){if(!c(t))return u(this).get(t);if(s(t,p))return t[p][this._i]}},set:function(t,e){return i.def(this,t,e)}},i,!0,!0);7!=(new f).set((Object.freeze||Object)(l),7).get(l)&&a.each.call(["delete","has","get","set"],function(t){var e=f.prototype,n=e[t];r(e,t,function(e,a){if(o(e)&&!c(e)){var r=u(this)[t](e,a);return"set"==t?this:r}return n.call(this,e,a)})})},{14:14,15:15,30:30,38:38,46:46,61:61}],171:[function(t,e,n){"use strict";var a=t(14);t(15)("WeakSet",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return a.def(this,t,!0)}},a,!1,!0)},{14:14,15:15}],172:[function(t,e,n){"use strict";var a=t(22),r=t(7)(!0);a(a.P,"Array",{includes:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0)}}),t(3)("includes")},{22:22,3:3,7:7}],173:[function(t,e,n){var a=t(22);a(a.P,"Map",{toJSON:t(13)("Map")})},{13:13,22:22}],174:[function(t,e,n){var a=t(22),r=t(55)(!0);a(a.S,"Object",{entries:function(t){return r(t)}})},{22:22,55:55}],175:[function(t,e,n){var a=t(46),r=t(22),i=t(56),o=t(78),s=t(59);r(r.S,"Object",{getOwnPropertyDescriptors:function(t){for(var e,n,r=o(t),u=a.setDesc,p=a.getDesc,c=i(r),l={},f=0;c.length>f;)n=p(r,e=c[f++]),e in l?u(l,e,s(0,n)):l[e]=n;return l}})},{22:22,46:46,56:56,59:59,78:78}],176:[function(t,e,n){var a=t(22),r=t(55)(!1);a(a.S,"Object",{values:function(t){return r(t)}})},{22:22,55:55}],177:[function(t,e,n){var a=t(22),r=t(62)(/[\\^$*+?.()|[\]{}]/g,"\\$&");a(a.S,"RegExp",{escape:function(t){return r(t)}})},{22:22,62:62}],178:[function(t,e,n){var a=t(22);a(a.P,"Set",{toJSON:t(13)("Set")})},{13:13,22:22}],179:[function(t,e,n){"use strict";var a=t(22),r=t(70)(!0);a(a.P,"String",{at:function(t){return r(this,t)}})},{22:22,70:70}],180:[function(t,e,n){"use strict";var a=t(22),r=t(72);a(a.P,"String",{padLeft:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0,!0)}})},{22:22,72:72}],181:[function(t,e,n){"use strict";var a=t(22),r=t(72);a(a.P,"String",{padRight:function(t){return r(this,t,arguments.length>1?arguments[1]:void 0,!1)}})},{22:22,72:72}],182:[function(t,e,n){"use strict";t(74)("trimLeft",function(t){return function(){return t(this,1)}})},{74:74}],183:[function(t,e,n){"use strict";t(74)("trimRight",function(t){return function(){return t(this,2)}})},{74:74}],184:[function(t,e,n){var a=t(46),r=t(22),i=t(17),o=t(16).Array||Array,s={},u=function(t,e){a.each.call(t.split(","),function(t){void 0==e&&t in o?s[t]=o[t]:t in[]&&(s[t]=i(Function.call,[][t],e))})};u("pop,reverse,shift,keys,values,entries",1),u("indexOf,every,some,forEach,map,filter,find,findIndex,includes",3),u("join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill"),r(r.S,"Array",s)},{16:16,17:17,22:22,46:46}],185:[function(t,e,n){t(91);var a=t(29),r=t(31),i=t(45),o=t(83)("iterator"),s=a.NodeList,u=a.HTMLCollection,p=s&&s.prototype,c=u&&u.prototype,l=i.NodeList=i.HTMLCollection=i.Array;p&&!p[o]&&r(p,o,l),c&&!c[o]&&r(c,o,l)},{29:29,31:31,45:45,83:83,91:91}],186:[function(t,e,n){var a=t(22),r=t(75);a(a.G+a.B,{setImmediate:r.set,clearImmediate:r.clear})},{22:22,75:75}],187:[function(t,e,n){var a=t(29),r=t(22),i=t(33),o=t(57),s=a.navigator,u=!!s&&/MSIE .\./.test(s.userAgent),p=function(t){return u?function(e,n){return t(i(o,[].slice.call(arguments,2),"function"==typeof e?e:Function(e)),n)}:t};r(r.G+r.B+r.F*u,{setTimeout:p(a.setTimeout),setInterval:p(a.setInterval)})},{22:22,29:29,33:33,57:57}],188:[function(t,e,n){t(85),t(169),t(124),t(132),t(136),t(137),t(125),t(135),t(134),t(130),t(131),t(129),t(126),t(128),t(133),t(127),t(95),t(94),t(114),t(115),t(116),t(117),t(118),t(119),t(120),t(121),t(122),t(123),t(97),t(98),t(99),t(100),t(101),t(102),t(103),t(104),t(105),t(106),t(107),t(108),t(109),t(110),t(111),t(112),t(113),t(162),t(165),t(168),t(164),t(160),t(161),t(163),t(166),t(167),t(90),t(92),t(91),t(93),t(86),t(87),t(89),t(88),t(153),t(154),t(155),t(156),t(157),t(158),t(138),t(96),t(159),t(170),t(171),t(139),t(140),t(141),t(142),t(143),t(146),t(144),t(145),t(147),t(148),t(149),t(150),t(152),t(151),t(172),t(179),t(180),t(181),t(182),t(183),t(177),t(175),t(176),t(174),t(173),t(178),t(184),t(187),t(186),t(185),e.exports=t(16)},{100:100,101:101,102:102,103:103,104:104,105:105,106:106,107:107,108:108,109:109,110:110,111:111,112:112,113:113,114:114,115:115,116:116,117:117,118:118,119:119,120:120,121:121,122:122,123:123,124:124,125:125,126:126,127:127,128:128,129:129,130:130,131:131,132:132,133:133,134:134,135:135,136:136,137:137,138:138,139:139,140:140,141:141,142:142,143:143,144:144,145:145,146:146,147:147,148:148,149:149,150:150,151:151,152:152,153:153,154:154,155:155,156:156,157:157,158:158,159:159,16:16,160:160,161:161,162:162,163:163,164:164,165:165,166:166,167:167,168:168,169:169,170:170,171:171,172:172,173:173,174:174,175:175,176:176,177:177,178:178,179:179,180:180,181:181,182:182,183:183,184:184,185:185,186:186,187:187,85:85,86:86,87:87,88:88,89:89,90:90,91:91,92:92,93:93,94:94,95:95,96:96,97:97,98:98,99:99}],189:[function(t,e,n){(function(n){(function(t,n){!function(n){"use strict";function a(t,e,n,a){var r=Object.create((e||i).prototype),o=new h(a||[]);return r._invoke=l(t,n,o),r}function r(t,e,n){try{return{type:"normal",arg:t.call(e,n)}}catch(a){return{type:"throw",arg:a}}}function i(){}function o(){}function s(){}function u(t){["next","throw","return"].forEach(function(e){t[e]=function(t){return this._invoke(e,t)}})}function p(t){this.arg=t}function c(e){function n(t,n){var a=e[t](n),r=a.value;return r instanceof p?Promise.resolve(r.arg).then(i,o):Promise.resolve(r).then(function(t){return a.value=t,a})}function a(t,e){function a(){return n(t,e)}return r=r?r.then(a,a):new Promise(function(t){t(a())})}"object"==typeof t&&t.domain&&(n=t.domain.bind(n));var r,i=n.bind(e,"next"),o=n.bind(e,"throw");n.bind(e,"return");this._invoke=a}function l(t,e,n){var a=w;return function(i,o){if(a===P)throw Error("Generator is already running");if(a===E){if("throw"===i)throw o;return v()}for(;;){var s=n.delegate;if(s){if("return"===i||"throw"===i&&s.iterator[i]===g){n.delegate=null;var u=s.iterator["return"];if(u){var p=r(u,s.iterator,o);if("throw"===p.type){i="throw",o=p.arg;continue}}if("return"===i)continue}var p=r(s.iterator[i],s.iterator,o);if("throw"===p.type){n.delegate=null,i="throw",o=p.arg;continue}i="next",o=g;var c=p.arg;if(!c.done)return a=k,c;n[s.resultName]=c.value,n.next=s.nextLoc,n.delegate=null}if("next"===i)n._sent=o,a===k?n.sent=o:n.sent=g;else if("throw"===i){if(a===w)throw a=E,o;n.dispatchException(o)&&(i="next",o=g)}else"return"===i&&n.abrupt("return",o);a=P;var p=r(t,e,n);if("normal"===p.type){a=n.done?E:k;var c={value:p.arg,done:n.done};if(p.arg!==C)return c;n.delegate&&"next"===i&&(o=g)}else"throw"===p.type&&(a=E,i="throw",o=p.arg)}}}function f(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function d(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function h(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(f,this),this.reset(!0)}function m(t){if(t){var e=t[y];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var n=-1,a=function r(){for(;++n=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),C}},"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},C}}}("object"==typeof n?n:"object"==typeof window?window:"object"==typeof self?self:this)}).call(this,t(202),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:{})},{202:202}],190:[function(t,e,n){!function(t){"use strict";function e(){return c.createDocumentFragment()}function n(t){return c.createElement(t)}function a(t){if(1===t.length)return r(t[0]);for(var n=e(),a=B.call(t),i=0;i-1}}([].indexOf||function(t){for(q=this.length;q--&&this[q]!==t;);return q}),item:function(t){return this[t]||null},remove:function(){for(var t,e=0;e=u?e(i):document.fonts.load(p(i,i.family),s).then(function(e){1<=e.length?t(i):setTimeout(f,25)},function(){e(i)})};f()}else n(function(){function n(){var e;(e=-1!=v&&-1!=g||-1!=v&&-1!=b||-1!=g&&-1!=b)&&((e=v!=g&&v!=b&&g!=b)||(null===l&&(e=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent),l=!!e&&(536>parseInt(e[1],10)||536===parseInt(e[1],10)&&11>=parseInt(e[2],10))),e=l&&(v==y&&g==y&&b==y||v==_&&g==_&&b==_||v==x&&g==x&&b==x)),e=!e),e&&(null!==w.parentNode&&w.parentNode.removeChild(w),clearTimeout(k),t(i))}function f(){if((new Date).getTime()-c>=u)null!==w.parentNode&&w.parentNode.removeChild(w),e(i);else{var t=document.hidden;(!0===t||void 0===t)&&(v=d.a.offsetWidth,g=h.a.offsetWidth,b=m.a.offsetWidth,n()),k=setTimeout(f,50)}}var d=new a(s),h=new a(s),m=new a(s),v=-1,g=-1,b=-1,y=-1,_=-1,x=-1,w=document.createElement("div"),k=0;w.dir="ltr",r(d,p(i,"sans-serif")),r(h,p(i,"serif")),r(m,p(i,"monospace")),w.appendChild(d.a),w.appendChild(h.a),w.appendChild(m.a),document.body.appendChild(w),y=d.a.offsetWidth,_=h.a.offsetWidth,x=m.a.offsetWidth,f(),o(d,function(t){v=t,n()}),r(d,p(i,'"'+i.family+'",sans-serif')),o(h,function(t){g=t,n()}),r(h,p(i,'"'+i.family+'",serif')),o(m,function(t){b=t,n()}),r(m,p(i,'"'+i.family+'",monospace'))})})},window.FontFaceObserver=s,window.FontFaceObserver.prototype.check=s.prototype.a,void 0!==e&&(e.exports=window.FontFaceObserver)}()},{}],193:[function(t,e,n){!function(t,n){function a(t,e){var n=t.createElement("p"),a=t.getElementsByTagName("head")[0]||t.documentElement;return n.innerHTML="x",a.insertBefore(n.lastChild,a.firstChild)}function r(){var t=_.elements;return"string"==typeof t?t.split(" "):t}function i(t,e){var n=_.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof t&&(t=t.join(" ")),_.elements=n+" "+t,c(e)}function o(t){var e=y[t[g]];return e||(e={},b++,t[g]=b,y[b]=e),e}function s(t,e,a){if(e||(e=n),f)return e.createElement(t);a||(a=o(e));var r;return r=a.cache[t]?a.cache[t].cloneNode():v.test(t)?(a.cache[t]=a.createElem(t)).cloneNode():a.createElem(t),!r.canHaveChildren||m.test(t)||r.tagUrn?r:a.frag.appendChild(r)}function u(t,e){if(t||(t=n),f)return t.createDocumentFragment();e=e||o(t);for(var a=e.frag.cloneNode(),i=0,s=r(),u=s.length;u>i;i++)a.createElement(s[i]);return a}function p(t,e){e.cache||(e.cache={},e.createElem=t.createElement,e.createFrag=t.createDocumentFragment,e.frag=e.createFrag()),t.createElement=function(n){return _.shivMethods?s(n,t,e):e.createElem(n)},t.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-:]+/g,function(t){return e.createElem(t),e.frag.createElement(t),'c("'+t+'")'})+");return n}")(_,e.frag)}function c(t){t||(t=n);var e=o(t);return!_.shivCSS||l||e.hasCSS||(e.hasCSS=!!a(t,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),f||p(t,e),t}var l,f,d="3.7.3-pre",h=t.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,v=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,g="_html5shiv",b=0,y={};!function(){try{var t=n.createElement("a");t.innerHTML="",l="hidden"in t,f=1==t.childNodes.length||function(){n.createElement("a");var t=n.createDocumentFragment();return void 0===t.cloneNode||void 0===t.createDocumentFragment||void 0===t.createElement}()}catch(e){l=!0,f=!0}}();var _={elements:h.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:d,shivCSS:h.shivCSS!==!1,supportsUnknownElements:f,shivMethods:h.shivMethods!==!1,type:"default",shivDocument:c,createElement:s,createDocumentFragment:u,addElements:i};t.html5=_,c(n),"object"==typeof e&&e.exports&&(e.exports=_)}("undefined"!=typeof window?window:this,document)},{}],194:[function(t,e,n){(function(t){(function(t){!function(t){function e(t,e,n,a){for(var i,o=n.slice(),s=r(e,t),u=0,p=o.length;p>u&&(handler=o[u],"object"==typeof handler?"function"==typeof handler.handleEvent&&handler.handleEvent(s):handler.call(t,s),!s.stoppedImmediatePropagation);u++);return i=!s.stoppedPropagation,a&&i&&t.parentNode?t.parentNode.dispatchEvent(s):!s.defaultPrevented}function n(t,e){return{configurable:!0,get:t,set:e}}function a(t,e,a){var r=b(e||t,a);v(t,"textContent",n(function(){return r.get.call(this)},function(t){r.set.call(this,t)}))}function r(t,e){return t.currentTarget=e,t.eventPhase=t.target===t.currentTarget?2:3,t}function i(t,e){for(var n=t.length;n--&&t[n]!==e;);return n}function o(){if("BR"===this.tagName)return"\n";for(var t=this.firstChild,e=[];t;)8!==t.nodeType&&7!==t.nodeType&&e.push(t.textContent),t=t.nextSibling;return e.join("")}function s(t){var e=document.createEvent("Event");e.initEvent("input",!0,!0),(t.srcElement||t.fromElement||document).dispatchEvent(e)}function u(t){!f&&k.test(document.readyState)&&(f=!f,document.detachEvent(d,u),t=document.createEvent("Event"),t.initEvent(h,!0,!0),document.dispatchEvent(t))}function p(t){for(var e;e=this.lastChild;)this.removeChild(e);null!=t&&this.appendChild(document.createTextNode(t))}function c(e,n){return n||(n=t.event),n.target||(n.target=n.srcElement||n.fromElement||document),n.timeStamp||(n.timeStamp=(new Date).getTime()),n}if(!document.createEvent){var l=!0,f=!1,d="onreadystatechange",h="DOMContentLoaded",m="__IE8__"+Math.random(),v=Object.defineProperty||function(t,e,n){t[e]=n.value},g=Object.defineProperties||function(e,n){for(var a in n)if(y.call(n,a))try{v(e,a,n[a])}catch(r){t.console&&console.log(a+" failed on object:",e,r.message)}},b=Object.getOwnPropertyDescriptor,y=Object.prototype.hasOwnProperty,_=t.Element.prototype,x=t.Text.prototype,w=/^[a-z]+$/,k=/loaded|complete/,P={},E=document.createElement("div"),C=document.documentElement,S=C.removeAttribute,A=C.setAttribute;a(t.HTMLCommentElement.prototype,_,"nodeValue"),a(t.HTMLScriptElement.prototype,null,"text"),a(x,null,"nodeValue"),a(t.HTMLTitleElement.prototype,null,"text"),v(t.HTMLStyleElement.prototype,"textContent",function(t){return n(function(){return t.get.call(this.styleSheet)},function(e){t.set.call(this.styleSheet,e)})}(b(t.CSSStyleSheet.prototype,"cssText"))),g(_,{textContent:{get:o,set:p},firstElementChild:{get:function(){for(var t=this.childNodes||[],e=0,n=t.length;n>e;e++)if(1==t[e].nodeType)return t[e]}},lastElementChild:{get:function(){for(var t=this.childNodes||[],e=t.length;e--;)if(1==t[e].nodeType)return t[e]}},oninput:{get:function(){return this._oninput||null},set:function(t){this._oninput&&(this.removeEventListener("input",this._oninput),this._oninput=t,t&&this.addEventListener("input",t))}},previousElementSibling:{get:function(){for(var t=this.previousSibling;t&&1!=t.nodeType;)t=t.previousSibling;return t}},nextElementSibling:{get:function(){for(var t=this.nextSibling;t&&1!=t.nodeType;)t=t.nextSibling;return t}},childElementCount:{get:function(){for(var t=0,e=this.childNodes||[],n=e.length;n--;t+=1==e[n].nodeType);return t}},addEventListener:{value:function(t,n,a){if("function"==typeof n||"object"==typeof n){var r,o,u=this,p="on"+t,l=u[m]||v(u,m,{value:{}})[m],f=l[p]||(l[p]={}),d=f.h||(f.h=[]);if(!y.call(f,"w")){if(f.w=function(t){return t[m]||e(u,c(u,t),d,!1)},!y.call(P,p))if(w.test(t)){try{r=document.createEventObject(),r[m]=!0,9!=u.nodeType&&(null==u.parentNode&&E.appendChild(u),(o=u.getAttribute(p))&&S.call(u,p)),u.fireEvent(p,r),P[p]=!0}catch(r){for(P[p]=!1;E.hasChildNodes();)E.removeChild(E.firstChild)}null!=o&&A.call(u,p,o)}else P[p]=!1;(f.n=P[p])&&u.attachEvent(p,f.w)}i(d,n)<0&&d[a?"unshift":"push"](n),"input"===t&&u.attachEvent("onkeyup",s)}}},dispatchEvent:{value:function(t){var n,a=this,r="on"+t.type,i=a[m],o=i&&i[r],s=!!o;return t.target||(t.target=a),s?o.n?a.fireEvent(r,t):e(a,t,o.h,!0):(n=a.parentNode)?n.dispatchEvent(t):!0,!t.defaultPrevented}},removeEventListener:{value:function(t,e,n){if("function"==typeof e||"object"==typeof e){var a=this,r="on"+t,o=a[m],s=o&&o[r],u=s&&s.h,p=u?i(u,e):-1;p>-1&&u.splice(p,1)}}}}),g(x,{addEventListener:{value:_.addEventListener},dispatchEvent:{value:_.dispatchEvent},removeEventListener:{value:_.removeEventListener}}),g(t.XMLHttpRequest.prototype,{addEventListener:{value:function(t,e,n){var a=this,r="on"+t,o=a[m]||v(a,m,{value:{}})[m],s=o[r]||(o[r]={}),u=s.h||(s.h=[]);i(u,e)<0&&(a[r]||(a[r]=function(){var e=document.createEvent("Event");e.initEvent(t,!0,!0),a.dispatchEvent(e)}),u[n?"unshift":"push"](e))}},dispatchEvent:{value:function(t){var n=this,a="on"+t.type,r=n[m],i=r&&r[a],o=!!i;return o&&(i.n?n.fireEvent(a,t):e(n,t,i.h,!0))}},removeEventListener:{value:_.removeEventListener}}),g(t.Event.prototype,{bubbles:{value:!0,writable:!0},cancelable:{value:!0,writable:!0},preventDefault:{value:function(){this.cancelable&&(this.defaultPrevented=!0,this.returnValue=!1)}},stopPropagation:{value:function(){this.stoppedPropagation=!0,this.cancelBubble=!0}},stopImmediatePropagation:{value:function(){this.stoppedImmediatePropagation=!0,this.stopPropagation()}},initEvent:{value:function(t,e,n){this.type=t,this.bubbles=!!e,this.cancelable=!!n,this.bubbles||this.stopPropagation()}}}),g(t.HTMLDocument.prototype,{defaultView:{get:function(){return this.parentWindow}},textContent:{get:function(){return 11===this.nodeType?o.call(this):null},set:function(t){11===this.nodeType&&p.call(this,t)}},addEventListener:{value:function(e,n,a){var r=this;_.addEventListener.call(r,e,n,a),l&&e===h&&!k.test(r.readyState)&&(l=!1,r.attachEvent(d,u),t==top&&!function i(t){try{r.documentElement.doScroll("left"),u()}catch(e){setTimeout(i,50)}}())}},dispatchEvent:{value:_.dispatchEvent},removeEventListener:{value:_.removeEventListener},createEvent:{value:function(t){var e;if("Event"!==t)throw Error("unsupported "+t);return e=document.createEventObject(),e.timeStamp=(new Date).getTime(),e}}}),g(t.Window.prototype,{getComputedStyle:{value:function(){function t(t){this._=t}function e(){}var n=/^(?:[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|))(?!px)[a-z%]+$/,a=/^(top|right|bottom|left)$/,r=/\-([a-z])/g,i=function(t,e){return e.toUpperCase()};return t.prototype.getPropertyValue=function(t){var e,o,s,u=this._,p=u.style,c=u.currentStyle,l=u.runtimeStyle;return t=("float"===t?"style-float":t).replace(r,i),e=c?c[t]:p[t],n.test(e)&&!a.test(t)&&(o=p.left,s=l&&l.left,s&&(l.left=c.left),p.left="fontSize"===t?"1em":e,e=p.pixelLeft+"px",p.left=o,s&&(l.left=s)),null==e?e:e+""||"auto"},e.prototype.getPropertyValue=function(){return null},function(n,a){return a?new e(n):new t(n)}}()},addEventListener:{value:function(n,a,r){var o,s=t,u="on"+n;s[u]||(s[u]=function(t){return e(s,c(s,t),o,!1)}),o=s[u][m]||(s[u][m]=[]),i(o,a)<0&&o[r?"unshift":"push"](a)}},dispatchEvent:{value:function(e){var n=t["on"+e.type];return n?n.call(t,e)!==!1&&!e.defaultPrevented:!0}},removeEventListener:{value:function(e,n,a){var r="on"+e,o=(t[r]||Object)[m],s=o?i(o,n):-1;s>-1&&o.splice(s,1)}}}),function(t,e,n){for(n=0;n=s)return(0,u["default"])({points:n});for(var l=1;s-1>=l;l++)i.push((0,p.times)(a,(0,p.minus)(n[l],n[l-1])));for(var f=[(0,p.plus)(n[0],c(i[0],i[1]))],l=1;s-2>=l;l++)f.push((0,p.minus)(n[l],(0,p.average)([i[l],i[l-1]])));f.push((0,p.minus)(n[s-1],c(i[s-2],i[s-3])));var d=f[0],h=f[1],m=n[0],v=n[1],g=(e=(0,o["default"])()).moveto.apply(e,r(m)).curveto(d[0],d[1],h[0],h[1],v[0],v[1]);return{path:(0,p.range)(2,s).reduce(function(t,e){var a=f[e],r=n[e];return t.smoothcurveto(a[0],a[1],r[0],r[1])},g),centroid:(0,p.average)(n)}},e.exports=n["default"]},{198:198,199:199,200:200}],196:[function(t,e,n){"use strict";function a(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(n,"__esModule",{value:!0});var r=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),i=t(197),o=a(i),s=t(198),u=1e-5,p=function(t,e){var n=t.map(e),a=n.sort(function(t,e){var n=r(t,2),a=n[0],i=(n[1],r(e,2)),o=i[0];i[1];return a-o}),i=a.length,o=a[0][0],p=a[i-1][0],c=(0,s.minBy)(a,function(t){return t[1]}),l=(0,s.maxBy)(a,function(t){return t[1]});return o==p&&(p+=u),c==l&&(l+=u),{points:a,xmin:o,xmax:p,ymin:c,ymax:l}};n["default"]=function(t){var e=t.data,n=t.xaccessor,a=t.yaccessor,i=t.width,u=t.height,c=t.closed,l=t.min,f=t.max;n||(n=function(t){var e=r(t,2),n=e[0];e[1];return n}),a||(a=function(t){var e=r(t,2),n=(e[0],e[1]);return n});var d=function(t){return[n(t),a(t)]},h=e.map(function(t){return p(t,d)}),m=(0,s.minBy)(h,function(t){return t.xmin}),v=(0,s.maxBy)(h,function(t){return t.xmax}),g=null==l?(0,s.minBy)(h,function(t){return t.ymin}):l,b=null==f?(0,s.maxBy)(h,function(t){return t.ymax}):f;c&&(g=Math.min(g,0),b=Math.max(b,0));var y=c?0:g,_=(0,o["default"])([m,v],[0,i]),x=(0,o["default"])([g,b],[u,0]),w=function(t){var e=r(t,2),n=e[0],a=e[1];return[_(n),x(a)]};return{arranged:h,scale:w,xscale:_,yscale:x,base:y}},e.exports=n["default"]},{197:197,198:198}],197:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function i(t,e){var n=a(t,2),r=n[0],o=n[1],s=a(e,2),u=s[0],p=s[1],c=function(t){return u+(p-u)*(t-r)/(o-r)};return c.inverse=function(){return i([u,p],[r,o])},c};n["default"]=r,e.exports=n["default"]},{}],198:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function(t){return t.reduce(function(t,e){return t+e},0)},i=function(t){return t.reduce(function(t,e){return Math.min(t,e)})},o=function(t){return t.reduce(function(t,e){return Math.max(t,e)})},s=function(t,e){return t.reduce(function(t,n){return t+e(n)},0)},u=function(t,e){return t.reduce(function(t,n){return Math.min(t,e(n))},1/0)},p=function(t,e){return t.reduce(function(t,n){return Math.max(t,e(n))},-(1/0))},c=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],u=o[1];return[r+s,i+u]},l=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],u=o[1];return[r-s,i-u]},f=function(t,e){var n=a(e,2),r=n[0],i=n[1];return[t*r,t*i]},d=function(t){var e=a(t,2),n=e[0],r=e[1];return Math.sqrt(n*n+r*r)},h=function(t){return t.reduce(c,[0,0])},m=function(t){return f(1/t.length,t.reduce(c))},v=function(t,e){return f(t,[Math.sin(e),-Math.cos(e)])},g=function(t,e){var n=t||{};for(var a in n){var r=n[a];e[a]=r(e.index,e.item,e.group)}return e},b=function(t,e,n){for(var a=[],r=t;e>r;r++)a.push(r);return n&&a.push(e),a},y=function(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=Object.keys(t)[Symbol.iterator]();!(a=(o=s.next()).done);a=!0){var u=o.value,p=t[u];n.push(e(u,p))}}catch(c){r=!0,i=c}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n},_=function(t){return y(t,function(t,e){return[t,e]})},x=function(t){return t};n.sum=r,n.min=i,n.max=o,n.sumBy=s,n.minBy=u,n.maxBy=p,n.plus=c,n.minus=l,n.times=f,n.id=x,n.length=d,n.sumVectors=h,n.average=m,n.onCircle=v,n.enhance=g,n.range=b,n.mapObject=y,n.pairs=_,n["default"]={sum:r,min:i,max:o,sumBy:s,minBy:u,maxBy:p,plus:c,minus:l,times:f,id:x,length:d,sumVectors:h,average:m,onCircle:v,enhance:g,range:b,mapObject:y,pairs:_}},{}],199:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var a=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(u){r=!0,i=u}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),r=function i(t){var e=t||[],n=function(t,e){var n=t.slice(0,t.length);return n.push(e),n},r=function(t,e){var n=a(t,2),r=n[0],i=n[1],o=a(e,2),s=o[0],u=o[1];return r===s&&i===u},o=function(t,e){for(var n=t.length;"0"===t.charAt(n-1);)n-=1;return"."===t.charAt(n-1)&&(n-=1),t.substr(0,n)},s=function(t,e){var n=t.toFixed(e);return o(n)},u=function(t){var e=t.command,n=t.params,a=n.map(function(t){return s(t,6)});return e+" "+a.join(" ")},p=function(t,e){var n=t.command,r=t.params,i=a(e,2),o=i[0],s=i[1];switch(n){case"M":return[r[0],r[1]];case"L":return[r[0],r[1]];case"H":return[r[0],s];case"V":return[o,r[0]];case"Z":return null;case"C":return[r[4],r[5]];case"S":return[r[2],r[3]];case"Q":return[r[2],r[3]];case"T":return[r[0],r[1]];case"A":return[r[5],r[6]]}},c=function(t,e){return function(n){var a="object"==typeof n?t.map(function(t){return n[t]}):arguments;return e.apply(null,a)}},l=function(t){return i(n(e,t))};return{moveto:c(["x","y"],function(t,e){return l({command:"M",params:[t,e]})}),lineto:c(["x","y"],function(t,e){return l({command:"L",params:[t,e]})}),hlineto:c(["x"],function(t){return l({command:"H",params:[t]})}),vlineto:c(["y"],function(t){return l({command:"V",params:[t]})}),closepath:function(){return l({command:"Z",params:[]})},curveto:c(["x1","y1","x2","y2","x","y"],function(t,e,n,a,r,i){return l({command:"C",params:[t,e,n,a,r,i]})}),smoothcurveto:c(["x2","y2","x","y"],function(t,e,n,a){return l({command:"S",params:[t,e,n,a]})}),qcurveto:c(["x1","y1","x","y"],function(t,e,n,a){return l({command:"Q",params:[t,e,n,a]})}),smoothqcurveto:c(["x","y"],function(t,e){return l({command:"T",params:[t,e]})}),arc:c(["rx","ry","xrot","largeArcFlag","sweepFlag","x","y"],function(t,e,n,a,r,i,o){return l({command:"A",params:[t,e,n,a,r,i,o]})}),print:function(){return e.map(u).join(" ")},points:function(){var t=[],n=[0,0],a=!0,r=!1,i=void 0;try{for(var o,s=e[Symbol.iterator]();!(a=(o=s.next()).done);a=!0){var u=o.value,c=p(u,n);n=c,c&&t.push(c)}}catch(l){r=!0,i=l}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return t},instructions:function(){return e.slice(0,e.length)},connect:function(t){var e=this.points(),n=e[e.length-1],a=t.points()[0],o=t.instructions().slice(1);return r(n,a)||o.unshift({command:"L",params:a}),i(this.instructions().concat(o))}}};n["default"]=function(){return r()},e.exports=n["default"]},{}],200:[function(t,e,n){"use strict";function a(t){return t&&t.__esModule?t:{"default":t}}function r(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e1)for(var n=1;n1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];for(var r,i;i=n.shift();)for(r in i)Ro.call(i,r)&&(t[r]=i[r]);return t}function r(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];return n.forEach(function(e){for(var n in e)!e.hasOwnProperty(n)||n in t||(t[n]=e[n])}),t}function i(t){return"[object Array]"===jo.call(t)}function o(t){return Lo.test(jo.call(t))}function s(t,e){return null===t&&null===e?!0:"object"==typeof t||"object"==typeof e?!1:t===e}function u(t){return!isNaN(parseFloat(t))&&isFinite(t)}function p(t){return t&&"[object Object]"===jo.call(t)}function c(t,e){return t.replace(/%s/g,function(){return e.shift()})}function l(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];throw t=c(t,n),Error(t)}function f(){Rv.DEBUG&&Oo.apply(null,arguments)}function d(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];t=c(t,n),To(t,n)}function h(t){for(var e=arguments.length,n=Array(e>1?e-1:0),a=1;e>a;a++)n[a-1]=arguments[a];t=c(t,n),No[t]||(No[t]=!0,To(t,n))}function m(){Rv.DEBUG&&d.apply(null,arguments)}function v(){Rv.DEBUG&&h.apply(null,arguments)}function g(t,e,n){var a=b(t,e,n);return a?a[t][n]:null}function b(t,e,n){for(;e;){if(n in e[t])return e;if(e.isolated)return null;e=e.parent}}function y(t){return function(){return t}}function _(t){var e,n,a,r,i,o;for(e=t.split("."),(n=zo[e.length])||(n=x(e.length)),i=[],a=function(t,n){return t?"*":e[n]},r=n.length;r--;)o=n[r].map(a).join("."),i.hasOwnProperty(o)||(i.push(o),i[o]=!0);return i}function x(t){var e,n,a,r,i,o,s,u,p="";if(!zo[t]){for(a=[];p.length=i;i+=1){for(n=i.toString(2);n.lengtho;o++)u.push(r(n[o]));a[i]=u}zo[t]=a}return zo[t]}function w(t,e,n,a){var r=t[e];if(!r||!r.equalsOrStartsWith(a)&&r.equalsOrStartsWith(n))return t[e]=r?r.replace(n,a):a,!0}function k(t){var e=t.slice(2);return"i"===t[1]&&u(e)?+e:e}function P(t){return null==t?t:(Qo.hasOwnProperty(t)||(Qo[t]=new Ko(t)),Qo[t])}function E(t,e){function n(e,n){var a,r,o;return n.isRoot?o=[].concat(Object.keys(t.viewmodel.data),Object.keys(t.viewmodel.mappings),Object.keys(t.viewmodel.computations)):(a=t.viewmodel.wrapped[n.str],r=a?a.get():t.viewmodel.get(n),o=r?Object.keys(r):null),o&&o.forEach(function(t){"_ractive"===t&&i(r)||e.push(n.join(t))}),e}var a,r,o;for(a=e.str.split("."),o=[Yo];r=a.shift();)"*"===r?o=o.reduce(n,[]):o[0]===Yo?o[0]=P(r):o=o.map(C(r));return o}function C(t){return function(e){return e.join(t)}}function S(t){return t?t.replace(Wo,".$1"):""}function A(t,e,n){if("string"!=typeof e||!u(n))throw Error("Bad arguments");var a=void 0,r=void 0;if(/\*/.test(e))return r={},E(t,P(S(e))).forEach(function(e){var a=t.viewmodel.get(e);if(!u(a))throw Error(Jo);r[e.str]=a+n}),t.set(r);if(a=t.get(e),!u(a))throw Error(Jo);return t.set(e,+a+n)}function O(t,e){return Xo(this,t,void 0===e?1:+e)}function T(t){this.event=t,this.method="on"+t,this.deprecate=as[t]}function M(t,e){var n=t.indexOf(e);-1===n&&t.push(e)}function R(t,e){for(var n=0,a=t.length;a>n;n++)if(t[n]==e)return!0;return!1}function j(t,e){var n;if(!i(t)||!i(e))return!1;if(t.length!==e.length)return!1;for(n=t.length;n--;)if(t[n]!==e[n])return!1;return!0}function L(t){return"string"==typeof t?[t]:void 0===t?[]:t}function N(t){return t[t.length-1]}function D(t,e){var n=t.indexOf(e);-1!==n&&t.splice(n,1)}function F(t){for(var e=[],n=t.length;n--;)e[n]=t[n];return e}function I(t){setTimeout(t,0);
+}function B(t,e){return function(){for(var n;n=t.shift();)n(e)}}function q(t,e,n,a){var r;if(e===t)throw new TypeError("A promise's fulfillment handler cannot return the same promise");if(e instanceof rs)e.then(n,a);else if(!e||"object"!=typeof e&&"function"!=typeof e)n(e);else{try{r=e.then}catch(i){return void a(i)}if("function"==typeof r){var o,s,u;s=function(e){o||(o=!0,q(t,e,n,a))},u=function(t){o||(o=!0,a(t))};try{r.call(e,s,u)}catch(i){if(!o)return a(i),void(o=!0)}}else n(e)}}function G(t,e,n){var a;return e=S(e),"~/"===e.substr(0,2)?(a=P(e.substring(2)),z(t,a.firstKey,n)):"."===e[0]?(a=U(cs(n),e),a&&z(t,a.firstKey,n)):a=V(t,P(e),n),a}function U(t,e){var n;if(void 0!=t&&"string"!=typeof t&&(t=t.str),"."===e)return P(t);if(n=t?t.split("."):[],"../"===e.substr(0,3)){for(;"../"===e.substr(0,3);){if(!n.length)throw Error('Could not resolve reference - too many "../" prefixes');n.pop(),e=e.substring(3)}return n.push(e),P(n.join("."))}return P(t?t+e.replace(/^\.\//,"."):e.replace(/^\.\/?/,""))}function V(t,e,n,a){var r,i,o,s,u;if(e.isRoot)return e;for(i=e.firstKey;n;)if(r=n.context,n=n.parent,r&&(s=!0,o=t.viewmodel.get(r),o&&("object"==typeof o||"function"==typeof o)&&i in o))return r.join(e.str);return W(t.viewmodel,i)?e:t.parent&&!t.isolated&&(s=!0,n=t.component.parentFragment,i=P(i),u=V(t.parent,i,n,!0))?(t.viewmodel.map(i,{origin:t.parent.viewmodel,keypath:u}),e):a||s?void 0:(t.viewmodel.set(e,void 0),e)}function z(t,e){var n;!t.parent||t.isolated||W(t.viewmodel,e)||(e=P(e),(n=V(t.parent,e,t.component.parentFragment,!0))&&t.viewmodel.map(e,{origin:t.parent.viewmodel,keypath:n}))}function W(t,e){return""===e||e in t.data||e in t.computations||e in t.mappings}function H(t){t.teardown()}function Q(t){t.unbind()}function K(t){t.unrender()}function $(t){t.cancel()}function Y(t){t.detach()}function X(t){t.detachNodes()}function J(t){!t.ready||t.outros.length||t.outroChildren||(t.outrosComplete||(t.parent?t.parent.decrementOutros(t):t.detachNodes(),t.outrosComplete=!0),t.intros.length||t.totalChildren||("function"==typeof t.callback&&t.callback(),t.parent&&t.parent.decrementTotal()))}function Z(){for(var t,e,n;ds.ractives.length;)e=ds.ractives.pop(),n=e.viewmodel.applyChanges(),n&&gs.fire(e,n);for(tt(),t=0;t=0;i--)r=t._subs[e[i]],r&&(s=gt(t,r,n,a)&&s);if(Vs.dequeue(t),t.parent&&s){if(o&&t.component){var u=t.component.name+"."+e[e.length-1];e=P(u).wildcardMatches(),n&&(n.component=t)}vt(t.parent,e,n,a)}}function gt(t,e,n,a){var r=null,i=!1;n&&!n._noArg&&(a=[n].concat(a)),e=e.slice();for(var o=0,s=e.length;s>o;o+=1)e[o].apply(t,a)===!1&&(i=!0);return n&&!n._noArg&&i&&(r=n.original)&&(r.preventDefault&&r.preventDefault(),r.stopPropagation&&r.stopPropagation()),!i}function bt(t){var e={args:Array.prototype.slice.call(arguments,1)};zs(this,t,e)}function yt(t){var e;return t=P(S(t)),e=this.viewmodel.get(t,Qs),void 0===e&&this.parent&&!this.isolated&&ls(this,t.str,this.component.parentFragment)&&(e=this.viewmodel.get(t)),e}function _t(e,n){if(!this.fragment.rendered)throw Error("The API has changed - you must call `ractive.render(target[, anchor])` to render your Ractive instance. Once rendered you can use `ractive.insert()`.");if(e=t(e),n=t(n)||null,!e)throw Error("You must specify a valid target to insert into");e.insertBefore(this.detach(),n),this.el=e,(e.__ractive_instances__||(e.__ractive_instances__=[])).push(this),this.detached=null,xt(this)}function xt(t){$s.fire(t),t.findAllComponents("*").forEach(function(t){xt(t.instance)})}function wt(t,e,n){var a,r;return t=P(S(t)),a=this.viewmodel.get(t),i(a)&&i(e)?(r=bs.start(this,!0),this.viewmodel.merge(t,a,e,n),bs.end(),r):this.set(t,e,n&&n.complete)}function kt(t,e){var n,a;return n=E(t,e),a={},n.forEach(function(e){a[e.str]=t.get(e.str)}),a}function Pt(t,e,n,a){var r,i,o;e=P(S(e)),a=a||cu,e.isPattern?(r=new uu(t,e,n,a),t.viewmodel.patternObservers.push(r),i=!0):r=new Zs(t,e,n,a),r.init(a.init),t.viewmodel.register(e,r,i?"patternObservers":"observers"),r.ready=!0;var s={cancel:function(){var n;o||(i?(n=t.viewmodel.patternObservers.indexOf(r),t.viewmodel.patternObservers.splice(n,1),t.viewmodel.unregister(e,r,"patternObservers")):t.viewmodel.unregister(e,r,"observers"),o=!0)}};return t._observers.push(s),s}function Et(t,e,n){var a,r,i,o;if(p(t)){n=e,r=t,a=[];for(t in r)r.hasOwnProperty(t)&&(e=r[t],a.push(this.observe(t,e,n)));return{cancel:function(){for(;a.length;)a.pop().cancel()}}}if("function"==typeof t)return n=e,e=t,t="",pu(this,t,e,n);if(i=t.split(" "),1===i.length)return pu(this,t,e,n);for(a=[],o=i.length;o--;)t=i[o],t&&a.push(pu(this,t,e,n));return{cancel:function(){for(;a.length;)a.pop().cancel()}}}function Ct(t,e,n){var a=this.observe(t,function(){e.apply(this,arguments),a.cancel()},{init:!1,defer:n&&n.defer});return a}function St(t,e){var n,a=this;if(t)n=t.split(" ").map(du).filter(hu),n.forEach(function(t){var n,r;(n=a._subs[t])&&(e?(r=n.indexOf(e),-1!==r&&n.splice(r,1)):a._subs[t]=[])});else for(t in this._subs)delete this._subs[t];return this}function At(t,e){var n,a,r,i=this;if("object"==typeof t){n=[];for(a in t)t.hasOwnProperty(a)&&n.push(this.on(a,t[a]));return{cancel:function(){for(var t;t=n.pop();)t.cancel()}}}return r=t.split(" ").map(du).filter(hu),r.forEach(function(t){(i._subs[t]||(i._subs[t]=[])).push(e)}),{cancel:function(){return i.off(t,e)}}}function Ot(t,e){var n=this.on(t,function(){e.apply(this,arguments),n.cancel()});return n}function Tt(t,e,n){var a,r,i,o,s,u,p=[];if(a=Mt(t,e,n),!a)return null;for(r=t.length,s=a.length-2-a[1],i=Math.min(r,a[0]),o=i+a[1],u=0;i>u;u+=1)p.push(u);for(;o>u;u+=1)p.push(-1);for(;r>u;u+=1)p.push(u+s);return 0!==s?p.touchedFrom=a[0]:p.touchedFrom=t.length,p}function Mt(t,e,n){switch(e){case"splice":for(void 0!==n[0]&&n[0]<0&&(n[0]=t.length+Math.max(n[0],-t.length));n.length<2;)n.push(0);return n[1]=Math.min(n[1],t.length-n[0]),n;case"sort":case"reverse":return null;case"pop":return t.length?[t.length-1,1]:[0,0];case"push":return[t.length,0].concat(n);case"shift":return[0,t.length?1:0];case"unshift":return[0,0].concat(n)}}function Rt(e,n){var a,r,i,o=this;if(i=this.transitionsEnabled,this.noIntro&&(this.transitionsEnabled=!1),a=bs.start(this,!0),bs.scheduleTask(function(){return Mu.fire(o)},!0),this.fragment.rendered)throw Error("You cannot call ractive.render() on an already rendered instance! Call ractive.unrender() first");if(e=t(e)||this.el,n=t(n)||this.anchor,this.el=e,this.anchor=n,!this.append&&e){var s=e.__ractive_instances__;s&&s.length&&jt(s),e.innerHTML=""}return this.cssId&&Ou.apply(),e&&((r=e.__ractive_instances__)?r.push(this):e.__ractive_instances__=[this],n?e.insertBefore(this.fragment.render(),n):e.appendChild(this.fragment.render())),bs.end(),this.transitionsEnabled=i,a.then(function(){return Ru.fire(o)})}function jt(t){t.splice(0,t.length).forEach(H)}function Lt(t,e){for(var n=t.slice(),a=e.length;a--;)~n.indexOf(e[a])||n.push(e[a]);return n}function Nt(t,e){var n,a,r;return a='[data-ractive-css~="{'+e+'}"]',r=function(t){var e,n,r,i,o,s,u,p=[];for(e=[];n=Iu.exec(t);)e.push({str:n[0],base:n[1],modifiers:n[2]});for(i=e.map(Ft),u=e.length;u--;)s=i.slice(),r=e[u],s[u]=r.base+a+r.modifiers||"",o=i.slice(),o[u]=a+" "+o[u],p.push(s.join(" "),o.join(" "));return p.join(", ")},n=qu.test(t)?t.replace(qu,a):t.replace(Fu,"").replace(Du,function(t,e){var n,a;return Bu.test(e)?t:(n=e.split(",").map(Dt),a=n.map(r).join(", ")+" ",t.replace(e,a))})}function Dt(t){return t.trim?t.trim():t.replace(/^\s+/,"").replace(/\s+$/,"")}function Ft(t){return t.str}function It(t){t&&t.constructor!==Object&&("function"==typeof t||("object"!=typeof t?l("data option must be an object or a function, `"+t+"` is not valid"):m("If supplied, options.data should be a plain JavaScript object - using a non-POJO as the root object may work, but is discouraged")))}function Bt(t,e){It(e);var n="function"==typeof t,a="function"==typeof e;return e||n||(e={}),n||a?function(){var r=a?qt(e,this):e,i=n?qt(t,this):t;return Gt(r,i)}:Gt(e,t)}function qt(t,e){var n=t.call(e);if(n)return"object"!=typeof n&&l("Data function must return an object"),n.constructor!==Object&&v("Data function returned something other than a plain JavaScript object. This might work, but is strongly discouraged"),n}function Gt(t,e){if(t&&e){for(var n in e)n in t||(t[n]=e[n]);return t}return t||e}function Ut(t){var e=Po(Ku);return e.parse=function(e,n){return Vt(e,n||t)},e}function Vt(t,e){if(!Hu)throw Error("Missing Ractive.parse - cannot parse template. Either preparse or use the version that includes the parser");return Hu(t,e||this.options)}function zt(t,e){var n;if(!Ji){if(e&&e.noThrow)return;throw Error("Cannot retrieve template #"+t+" as Ractive is not running in a browser.")}if(Wt(t)&&(t=t.substring(1)),!(n=document.getElementById(t))){if(e&&e.noThrow)return;throw Error("Could not find template element with id #"+t)}if("SCRIPT"!==n.tagName.toUpperCase()){if(e&&e.noThrow)return;throw Error("Template element with id #"+t+", must be a