diff --git a/_maps/map_files/cyberiad/cyberiad.dmm b/_maps/map_files/cyberiad/cyberiad.dmm
index 76163e88f7a..790b1cbd7bf 100644
--- a/_maps/map_files/cyberiad/cyberiad.dmm
+++ b/_maps/map_files/cyberiad/cyberiad.dmm
@@ -2390,7 +2390,7 @@
"aTX" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/wall,/area/hallway/secondary/construction{name = "\improper Garden"})
"aTY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/structure/table/glass,/obj/item/weapon/hatchet,/obj/item/weapon/minihoe,/obj/item/weapon/crowbar,/obj/item/device/analyzer/plant_analyzer,/obj/item/weapon/reagent_containers/glass/bucket,/obj/machinery/firealarm{dir = 8; pixel_x = -24},/turf/simulated/floor{icon_state = "green"; dir = 8},/area/hallway/secondary/construction{name = "\improper Garden"})
"aTZ" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 1; scrub_Toxins = 1},/turf/simulated/floor,/area/hallway/secondary/construction{name = "\improper Garden"})
-"aUa" = (/obj/structure/table/glass,/obj/item/weapon/storage/bag/plants,/obj/item/device/analyzer/plant_analyzer,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = -6; pixel_y = -25},/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/floor{icon_state = "green"; dir = 4},/area/hallway/secondary/construction{name = "\improper Garden"})
+"aUa" = (/obj/machinery/atm{pixel_y = -32},/turf/simulated/floor{dir = 2; icon_state = "barber"},/area/civilian/barber)
"aUb" = (/obj/structure/table,/obj/item/weapon/wrench,/obj/item/device/analyzer,/turf/simulated/floor,/area/storage/primary)
"aUc" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/storage/primary)
"aUd" = (/obj/machinery/hologram/holopad,/turf/simulated/floor,/area/storage/primary)
@@ -2525,7 +2525,7 @@
"aWC" = (/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics)
"aWD" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/obj/machinery/portable_atmospherics/hydroponics/soil,/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor/grass,/area/hydroponics)
"aWE" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/machinery/portable_atmospherics/hydroponics/soil,/turf/simulated/floor/grass,/area/hydroponics)
-"aWF" = (/obj/structure/closet/crate/hydroponics,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/screwdriver,/obj/item/weapon/shovel/spade,/obj/item/weapon/wrench,/obj/item/weapon/wrench,/obj/item/weapon/reagent_containers/glass/bucket,/obj/item/weapon/storage/box/botanydisk,/obj/item/weapon/storage/box/beakers,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics)
+"aWF" = (/obj/structure/window/reinforced{dir = 8},/obj/structure/closet/crate/hydroponics/prespawned,/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics)
"aWG" = (/obj/structure/table,/obj/item/weapon/watertank,/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics)
"aWH" = (/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/hidden/supply{level = 1},/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics)
"aWI" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/obj/structure/closet/secure_closet/hydroponics,/turf/simulated/floor{icon_state = "hydrofloor"},/area/hydroponics)
@@ -6162,6 +6162,7 @@
"coz" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor/plating,/area/maintenance/asmaint)
"coA" = (/turf/simulated/wall/r_wall,/area/maintenance/asmaint)
"coB" = (/obj/machinery/alarm{dir = 1; pixel_y = -22},/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light,/obj/effect/decal/warning_stripes/southwestcorner,/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology)
+"coC" = (/obj/structure/table/glass,/obj/item/weapon/storage/bag/plants/portaseeder,/obj/item/device/analyzer/plant_analyzer,/obj/machinery/light_switch{dir = 2; name = "light switch "; pixel_x = -6; pixel_y = -25},/obj/item/device/radio/intercom{frequency = 1459; name = "station intercom (General)"; pixel_x = 28},/turf/simulated/floor{icon_state = "green"; dir = 4},/area/hallway/secondary/construction{name = "\improper Garden"})
"coD" = (/obj/effect/spawner/window/reinforced,/turf/simulated/floor/plating,/area/maintenance/asmaint)
"coE" = (/obj/structure/sign/biohazard,/turf/simulated/wall,/area/toxins/xenobiology)
"coF" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/door/firedoor,/obj/machinery/door/airlock/research{name = "Xenobiology Research"; req_access_txt = "47"},/obj/structure/disposalpipe/segment,/turf/simulated/floor{icon_state = "white"},/area/toxins/xenobiology)
@@ -7141,13 +7142,13 @@
"cHs" = (/obj/machinery/atmospherics/binary/volume_pump/on{dir = 8; name = "Air To Distro"},/obj/machinery/power/apc{dir = 1; name = "Atmospherics Distribution Loop APC"; pixel_y = 24},/obj/structure/cable{icon_state = "0-2"; pixel_y = 1; d2 = 2},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor,/area/atmos/distribution)
"cHt" = (/obj/effect/spawner/window/reinforced,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id_tag = "atmos"; name = "Atmos Blast Door"; opacity = 0},/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 4; level = 2},/turf/simulated/floor/plating,/area/atmos/distribution)
"cHu" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 6; level = 2},/turf/simulated/floor,/area/atmos/distribution)
-"cHv" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 10; level = 2},/turf/space,/area/space)
+"cHv" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow{dir = 10; level = 2},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk2"; icon_state = "catwalk2"},/area/space)
"cHw" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/machinery/camera{c_tag = "Virology Module North"; network = list("SS13")},/turf/simulated/floor{dir = 1; icon_state = "whitegreen"},/area/medical/virology)
"cHx" = (/obj/structure/rack,/obj/effect/spawner/lootdrop/maintenance{lootcount = 2; name = "2maintenance loot spawner"},/turf/simulated/floor/plating,/area/maintenance/asmaint2)
"cHy" = (/obj/structure/closet,/turf/simulated/floor/plating,/area/maintenance/asmaint2)
"cHz" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor,/area/atmos/distribution)
"cHA" = (/obj/machinery/atmospherics/pipe/simple/visible/cyan{dir = 4; level = 2},/obj/machinery/atmospherics/binary/pump{dir = 1; name = "Mix to Gas Turbine"},/turf/simulated/floor,/area/atmos/distribution)
-"cHB" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/space,/area/space)
+"cHB" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk3"; icon_state = "catwalk3"},/area/space)
"cHC" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4; level = 1},/turf/simulated/wall/r_wall,/area/medical/virology)
"cHD" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8; initialize_directions = 11; level = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/plating,/area/maintenance/asmaint)
"cHE" = (/obj/machinery/camera{c_tag = "Xenobiology Module South"; dir = 4; network = list("Research","SS13"); pixel_x = 0},/obj/structure/table/reinforced,/obj/machinery/door_control{id = "xenobio1"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/obj/structure/window/reinforced{dir = 1},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor{dir = 4; icon_state = "warning"},/area/toxins/xenobiology)
@@ -7744,8 +7745,8 @@
"cSX" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/space,/area/space)
"cSY" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/yellow{level = 2},/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/space,/area/space)
"cSZ" = (/obj/structure/lattice,/obj/machinery/atmospherics/pipe/simple/visible/cyan{level = 2},/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/space,/area/space)
-"cTa" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/turf/space,/area/space)
-"cTb" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 9},/turf/space,/area/space)
+"cTa" = (/obj/structure/lattice,/turf/simulated/wall/r_wall,/area/atmos)
+"cTb" = (/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk6"; icon_state = "catwalk6"},/area/space)
"cTc" = (/obj/machinery/power/emitter,/turf/simulated/floor/plating,/area/storage/secure)
"cTd" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering)
"cTe" = (/obj/item/device/multitool,/turf/simulated/floor/plating/airless,/area/engine/engineering)
@@ -7788,7 +7789,7 @@
"cTP" = (/obj/item/device/radio,/turf/simulated/floor/plating/airless,/area/engine/engineering)
"cTQ" = (/obj/structure/lattice,/obj/item/clothing/head/hardhat,/turf/space,/area/space)
"cTR" = (/obj/structure/sign/securearea,/turf/simulated/wall/r_wall,/area/engine/engineering)
-"cTS" = (/obj/machinery/camera{c_tag = "Mini Satellite Access"; dir = 4; network = list("SS13","MiniSat")},/obj/item/device/radio/intercom{broadcasting = 0; listening = 1; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/engine/engineering)
+"cTS" = (/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk12"; icon_state = "catwalk12"},/area/space)
"cTT" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/engine/engineering)
"cTU" = (/turf/simulated/floor{icon_state = "dark"},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/structure/transit_tube{icon_state = "Block"},/turf/simulated/floor{tag = "icon-siding8 (NORTH)"; icon_state = "siding8"; dir = 1},/area/engine/engineering)
"cTV" = (/obj/effect/spawner/window/reinforced,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/plating,/area/engine/engineering)
@@ -7799,26 +7800,26 @@
"cUa" = (/obj/machinery/power/emitter{anchored = 1; dir = 8; state = 2},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/machinery/camera/emp_proof{c_tag = "Engineering Singularity East"; dir = 8; network = list("Singularity","SS13")},/turf/simulated/floor/plating/airless,/area/engine/engineering)
"cUb" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering)
"cUc" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/command{name = "MiniSat Access"; req_access_txt = "75"},/turf/simulated/floor,/area/engine/engineering)
-"cUd" = (/turf/simulated/floor{icon_state = "blue"; dir = 8},/area/engine/engineering)
+"cUd" = (/obj/machinery/atmospherics/pipe/simple/visible/yellow,/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk9"; icon_state = "catwalk9"},/area/space)
"cUe" = (/turf/simulated/floor{icon_state = "dark"},/obj/structure/transit_tube/station{dir = 8; icon_state = "closed"},/obj/structure/transit_tube_pod,/turf/simulated/floor{tag = "icon-siding8 (NORTH)"; icon_state = "siding8"; dir = 1},/area/engine/engineering)
"cUf" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering)
"cUg" = (/obj/structure/grille,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering)
"cUh" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering)
"cUi" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering)
"cUj" = (/obj/structure/grille,/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"; tag = ""},/turf/simulated/floor/plating/airless,/area/engine/engineering)
-"cUk" = (/obj/structure/closet/emcloset,/obj/machinery/light_switch{pixel_x = -27},/turf/simulated/floor{dir = 10; icon_state = "blue"},/area/engine/engineering)
+"cUk" = (/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk3"; icon_state = "catwalk3"},/area/space)
"cUl" = (/obj/machinery/light,/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/engine/engineering)
-"cUm" = (/turf/simulated/floor{icon_state = "dark"},/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor{tag = "icon-siding8 (NORTH)"; icon_state = "siding8"; dir = 1},/area/engine/engineering)
+"cUm" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 4},/obj/structure/lattice,/turf/space,/area/space)
"cUn" = (/obj/effect/spawner/window/reinforced,/obj/structure/transit_tube{icon_state = "N-S"},/turf/simulated/floor/plating,/area/engine/engineering)
"cUo" = (/obj/structure/transit_tube{icon_state = "N-SE"},/turf/space,/area/space)
"cUp" = (/obj/structure/transit_tube{tag = "icon-D-SW"; icon_state = "D-SW"},/turf/space,/area/space)
-"cUq" = (/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth{id_tag = "escape_pod_5_berth"; pixel_x = 25; pixel_y = -5; tag_door = "escape_pod_5_berth_hatch"},/turf/simulated/floor/plating,/area/engine/engineering)
+"cUq" = (/obj/machinery/atmospherics/pipe/simple/heat_exchanging{dir = 9},/obj/structure/lattice,/turf/space,/area/space)
"cUr" = (/obj/structure/transit_tube{tag = "icon-D-NE"; icon_state = "D-NE"},/turf/space,/area/space)
-"cUs" = (/obj/structure/transit_tube{tag = "icon-E-NW"; icon_state = "E-NW"},/turf/space,/area/space)
+"cUs" = (/obj/machinery/light/small{dir = 8},/obj/structure/sign/securearea{desc = "A warning sign which reads 'EXTERNAL AIRLOCK'"; icon_state = "space"; layer = 4; name = "EXTERNAL AIRLOCK"; pixel_x = 32},/turf/simulated/floor/plating,/area/engine/engineering)
"cUt" = (/obj/structure/transit_tube,/obj/structure/lattice,/turf/space,/area/space)
"cUu" = (/obj/structure/transit_tube,/turf/space,/area/space)
-"cUv" = (/obj/structure/transit_tube{icon_state = "E-W-Pass"},/turf/space,/area/space)
-"cUw" = (/obj/structure/transit_tube{icon_state = "W-SE"},/turf/space,/area/space)
+"cUv" = (/obj/machinery/access_button/airlock_exterior{master_tag = "atmospherics_south"; pixel_x = -25; pixel_y = -8},/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk6"; icon_state = "catwalk6"},/area/space)
+"cUw" = (/turf/simulated/floor/plating/airless/catwalk{tag = "icon-catwalk9"; icon_state = "catwalk9"},/area/space)
"cUx" = (/obj/structure/transit_tube{tag = "icon-D-SW"; icon_state = "D-SW"},/obj/structure/lattice,/turf/space,/area/space)
"cUy" = (/obj/machinery/door/airlock/external{frequency = 1379; icon_state = "door_locked"; id_tag = "escape_pod_5_berth_hatch"; locked = 1; name = "Escape Pod"; req_access = null; req_access_txt = "13"},/turf/simulated/floor/plating,/area/engine/engineering)
"cUz" = (/obj/structure/transit_tube{icon_state = "NW-SE"},/obj/structure/lattice,/turf/space,/area/space)
@@ -8271,6 +8272,23 @@
"dde" = (/obj/machinery/camera{c_tag = "Starboard Primary Hallway 2"; dir = 2; network = list("SS13")},/obj/structure/flora/corn_stalk/alt_2,/turf/simulated/floor{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west)
"ddf" = (/obj/structure/flora/straw_bail/alt_2,/obj/effect/decal/straw/edge{dir = 10},/turf/simulated/floor{dir = 1; icon_state = "whitecorner"},/area/hallway/primary/starboard/west)
"ddg" = (/obj/item/device/radio/intercom{pixel_y = 25},/obj/effect/decal/straw/edge,/turf/simulated/floor,/area/hallway/primary/starboard/west)
+"ddh" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 6},/turf/simulated/floor/plating,/area/engine/engineering)
+"ddi" = (/obj/machinery/light/small{dir = 1},/obj/machinery/atmospherics/unary/vent_pump/high_volume{dir = 8; frequency = 1379; id_tag = "atmospherics_south_pump"},/obj/machinery/airlock_sensor{frequency = 1379; id_tag = "atmospherics_south_sensor"; pixel_x = -8; pixel_y = -30},/obj/machinery/embedded_controller/radio/airlock/airlock_controller{frequency = 1379; id_tag = "atmospherics_south"; pixel_x = 0; pixel_y = -25; req_access_txt = null; tag_airpump = "atmospherics_south_pump"; tag_chamber_sensor = "atmospherics_south_sensor"; tag_exterior_door = "atmospherics_south_outer"; tag_interior_door = "atmospherics_south_inner"},/turf/simulated/floor/plating,/area/engine/engineering)
+"ddj" = (/obj/machinery/atmospherics/pipe/simple/hidden{dir = 4},/obj/machinery/door/airlock/external{aiControlDisabled = 1; frequency = 1379; hackProof = 1; icon_state = "door_locked"; id_tag = "atmospherics_south_inner"; locked = 1; name = "Atmospherics External Access"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/engine/engineering)
+"ddk" = (/obj/machinery/door/airlock/external{aiControlDisabled = 1; frequency = 1379; hackProof = 1; icon_state = "door_locked"; id_tag = "atmospherics_south_outer"; locked = 1; name = "Atmospherics External Access"; req_access_txt = "13"},/turf/simulated/floor/plating,/area/engine/engineering)
+"ddl" = (/obj/machinery/atmospherics/pipe/simple/hidden,/obj/machinery/access_button/airlock_interior{master_tag = "atmospherics_south"; pixel_x = 22; pixel_y = 10},/turf/simulated/floor/plating,/area/engine/engineering)
+"ddm" = (/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/engine/engineering)
+"ddn" = (/obj/machinery/camera{c_tag = "Mini Satellite Access"; dir = 4; network = list("SS13","MiniSat")},/obj/structure/closet/emcloset,/turf/simulated/floor{dir = 9; icon_state = "blue"},/area/engine/engineering)
+"ddo" = (/obj/item/device/radio/intercom{dir = 1; name = "station intercom (General)"; pixel_y = 25},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/engine/engineering)
+"ddp" = (/obj/machinery/light_switch{name = "light switch "; dir = 2; pixel_x = 0; pixel_y = -22},/turf/simulated/floor{dir = 10; icon_state = "blue"},/area/engine/engineering)
+"ddq" = (/turf/simulated/floor{dir = 0; icon_state = "blue"},/area/engine/engineering)
+"ddr" = (/obj/machinery/light/small{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden,/turf/simulated/floor/plating,/area/engine/engineering)
+"dds" = (/obj/machinery/embedded_controller/radio/simple_docking_controller/escape_pod_berth{id_tag = "escape_pod_5_berth"; pixel_x = 25; pixel_y = -5; tag_door = "escape_pod_5_berth_hatch"},/obj/machinery/atmospherics/pipe/simple/hidden{dir = 9; icon_state = "intact"},/turf/simulated/floor/plating,/area/engine/engineering)
+"ddt" = (/obj/machinery/atmospherics/unary/portables_connector{dir = 4},/obj/machinery/portable_atmospherics/canister/air,/turf/simulated/floor/plating,/area/engine/engineering)
+"ddu" = (/obj/structure/transit_tube{tag = "icon-E-NW"; icon_state = "E-NW"},/obj/structure/lattice,/turf/space,/area/space)
+"ddv" = (/obj/structure/transit_tube{icon_state = "W-SE"},/obj/structure/lattice,/turf/space,/area/space)
+"ddw" = (/obj/machinery/firealarm{dir = 2; pixel_y = 24},/turf/simulated/floor{dir = 1; icon_state = "blue"},/area/space)
+"ddx" = (/obj/structure/transit_tube{icon_state = "E-W-Pass"},/turf/space,/area/space)
(1,1,1) = {"
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -8368,7 +8386,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapsapsapsaaaaaaaaaaaaaaaaaaaabaabaaaaabaaaaaaaabaxRaxSaxTaxUaxRaxVaxVaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawmaxWaxXaxYaxZayaaybaycaydayeayfaxqaxqaygaxqaxqaxqaxqaxqayhaxqaxqaxqaxqaxqaxqayiaxqaxqaxqaxqayjaxqaykaxqaylaxqaymaynapWayoaypayqayraysaytaxEayuavUayvaywayxayyayzayAayBawMavWaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaabayCayDayEayFayCaabaaaaabaaaaaaaabaaaaaaaabaabaaaaaaayGasMavlasMavlayHayIayHayJayHayHayHayKayGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaxVaxVaxVaxVaxVaabaabaxRayLayMayNaxRayOaxVaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawmayPayQayRaySayTawmayUayVayWayXayYayZazaazbazcayXayXayXazdayXayXayXayXayXayXazeazfazgazgazgazhaziazjaziazkazlazmaznapWazoazoazoazoazoazoaxEaxFavUazpaxHazqavVcscazraxJcvYavWaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaabayCazsaztazuayCaabaaaaabaaaaaaaabaaaaaaayGazvayGazvayGayKayHayHayHayHayHayHayHayHayHazwazxayGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaazyazzazyaaaaaaaaaaxVaxVaxVaxVazAazBazCaxVaaaaaaaxRazDazEazFazGazHaxVaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaawmawmawmawmawmawmawmazIazIazJazKazKazLazMazNazOazPazPazOazQazOazRazRazRazRazRazRazSazRazRazTazUazVazWazIazXazIazYazIazIaqVazZaovaovaovaovaAaaxFavUaAbaxHaAcavVaAdayAayBawMavWaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaazyaAeazyaaaaabayCaAfaAgaAhayCaAiaAiaAiaAiaAiazvazvazvayGaAjayHazwazxayJayHayJayJayJayGaAkayGayGayGayGayGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaAlaAmaAlaaaaaaaabaxVaAnaAoaApazHaAqazHaxVaAlaAlaxRaxRaAraAsazGazHaxVaxVaAlaAlaAlaxVaxVaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazJaAtaAuaAvazMaAwazOaAxaAyaAzaAAaABaACaADaAEaAFaAGaAHaAIaAJaAKaALaxqaxraAMaANaAOaAPaAQaAPaAPaAPaARaAPaAPaAPaAPaASaATaAUaAVaAWaAXaAYcNsaBaaxJdcuavWaabaBbaBcaBcaBcaBcaBcaBdaabaabaaaaaaaaaaaaazvaBeazvaaaaAiayCayCaBfaBgayCaBhayHayHayHayJaBiayHaBjayGayHayHayHaBkayJayHayGaBlaBmayGayHaBnayGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaAlaAmaAlaaaaaaaabaxVaAnaAoaApazHaAqazHaxVaAlaAlaxRaxRaAraAsazGazHaxVaxVaAlaAlaAlaxVaxVaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazJaAtaAuaAvazMaAwazOaAxaAyaAzaAAaABaACaADaAEaAFaAGaAHaAIaAJaAKaALaxqaxraAMaANaAOaAPaAQaAPaAPaAPaARaAPaAPaAPaAPaASaATaAUaAVaAWaAXaAYcNsaBaaUadcuavWaabaBbaBcaBcaBcaBcaBcaBdaabaabaaaaaaaaaaaaazvaBeazvaaaaAiayCayCaBfaBgayCaBhayHayHayHayJaBiayHaBjayGayHayHayHaBkayJayHayGaBlaBmayGayHaBnayGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBoaBpaBqaaaaBraBsaBtaabaabaAlazHaAlaaaaaaaabaxVaBuaBvaBwaBxaByaBzaxVaBAazHaBBaBCaBDaBEaBEaBEaBEaBEaBEaBEaBEaBFaxVaaaaBGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBHaBIaBJaBKazMaAwazOaBLafvaBNaAAaABaBOaBPaBPaBPaBPaBPaAIaBPaAKaxlaxqaxrazIaBQaBRaBSaBTaBSaBSaBUaBVaBWaBWaBWaBWaBWaBWaBXaBYaBZaCaaCbaCcaCdaCeavWavWaCfaCgaChaChaChaChaChaCgaCfaabaaaaaaaaaaaaazvaCiaCjaaaaAiaCkaClaCmaCnayHayHayHayJayHayJaCoayHayHayGayHaCpaCqaCoaAkayHayGaCraCsayGayHaCtayGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaCuaCvaCwaCvaCuaCxaCyaCxaCuaabaAlaCzaCAaaaaaaaxVaxVaxVaxVaxVaCBaCCaCDaCEaCFaCGaCGaCHaCIaCIaCJaCKaxVazHaxVaxVaxVaCLaxVaaaaabaaaaaaaaaaaaaaaaaaaabaabaabaabaabaabaabaabaCMaCNaCOaBKazMaAwazOaCPaCQaCRaAAaCSaCTaBPaCUaBPaCVaCVaAIaBPaAKaxlaxqaCWazIaCXaBRaCYaCZaDaaDbaDcaDdaDeaDfaDgaDhaDiaDjaDkaDlaDmaDnaDoaDpaDqaDraDsaDtaCfaCgaChaChaChaChaChaCgaCfaabaabaabaabazvazvaDuaDvazvaAiaDwayHaDxayHayKayHayGayGaDyayGayGaDzayJayJaCoaDAaDBayHayGayHaDCaDCaDCaDCaDCaDCaDCaDCaDCaDDaDDaDDaDDaacaDDaDDaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDEaCvaDFaCvaDEaCxaDGaCxaDEaxVaAlaDHaDIaAlaAlaxVazHazHazHazHazHazHazHaCBaCLaxVaxVaxVaxVaxVaDJaxVaxVazHaDKaxVaDLaCLaxVaxVaxVaaaaaaaaaaaaaaaaDMaDMaDMaDMaDMaDMaDMaDMaabaCMaDNaDOaDPaDQaDRaDSaDTaDUaDVaDWaABaDXaBPaDYaDZaEaaEbaEcaEdaAKaxlaxqaxrazIatsaEeaEfaCZaDaaDbaEgaEhaEhaEhaEhaEhaEhaEhaEhaEhaEhaEiaEjaEkaElaEmaEnaEoaEpaCgaChaChaChaChaChaCgaCfaCfaCfaaaaaaazvayHaEqaEraBhaEsaDAaCoaDxayHaEtayIaEuaAkayHayHayHayHaEvayHayHaDAaEwayHaDzayHaDCaExaEyaEzaDCaEAaEBaECaDCaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -8384,7 +8402,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaNhaNmaNiaODaOEaOFaOGaOHaOIaOJaOKaOLaOMaONaOOaKzaKBaOPaMoaOQaORaOSaOTaOSaOUaKHaOVaMqaOWaOXaOYaOXaOZaPaaPbaPcaPdaPdaPdaPdaPdaPdaPeaPfaMvaaaaLRaPgaNHaPhaNJaPiaLRaaaaJGaJLaJMaPjaPkaPlaPmaPnaJMaGvaIKaPoaPoaKPaPpaMHaKSaPqaKSaMHaPraKWaPsaPsaIKaPtazUaPuazIaKbaEeaPvaPvaPvaPvaPwaPxaPyaPzaPAaPBaPBaPBaPCaPBaPDaPEaPFaPGaPHaPEaPIaPJazxayGayGayGayGayGayGayGayGayGayGayGayGaBMayGayGayGayGayHaDxaOiazvaabazvayHaPLaPMaPNaPOaPPaPQaPRaPRaPRaPRaPSaPTaPUaPVaPWaPXaPWaPYaPWaPWaPZaQaaQbaQbaQcaQdaQeaQeaQeaQeaQeaQeaQeaQeaQeabLadbaaaaaaaaaaaaaaaaaaaaaaQfaQfaQfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaQgaQhaQiaOMaQjaOFaQjaOFaQjaOFaQjaOMaQkaQlaKzaKBaQmaMoaQnaQoaQpaQqaQraQsaKHaQtaMqaQuaQvaQwaQxaQyaKHaQzaPdaPdaPdaPdaPdaPdaPdaPeaQAaMvaabaLRaQBaQCaQDaQEaQFaLRaabaJGaJLaJMaQGaQHaQIaQJaQKaJMaGvaIKaIKaIKaIKaQLaLXaJOaLYaJOaLXaQMaIKaIKaIKaIKaQNaQOaQPazIaMKaQQaQRaQRaQRaQSaQTaQUaQVaQWaQXaQVaQYaQZaRaaQVaRbaRcaRdaReaRfaMeaRgaRhaRiaRjaRjaRhaRkaRlaRlaRlaRlaRlaRmaRnaRlaRoaRpaRqaRraRsaRtaRuaRvaRwaRxaRwaRyaRzayHayGaRAaRBaRCaRDaREaRFaRGaRHaRIaRJaRIaRKaRLaRMaRNaROaRPaRQaRRaRSaRTaRUaQdaRVaRWaRXaRYaRZaSaaSbaScaSdapraaaaaaaaaaaaaaaaaaaaaaQfaQfaQfaQfaQfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaSfaOFaOFaNjaOMaQjaOFaQjaSgaQjaOFaQjaOMaQkaQlaKzaKBaShaMoaMoaSiaSjaSkaSjaMoaKHaKHaKHaKHaSlaSmaSnaSoaKHaSpaSqaSraPdaPdaSsaPdaStaSuaSvaMvaaaaLRaLRaSwaSxaSwaLRaLRaaaaJGaJLaJMaSyaSzaSAaQJaSBaJMaGvaIKaJNaJOaSCaNRaLXaJOaLYaJOaLXaNTaSDaIKaIKaIKaSEaSFaSGaSHaSIaSJamKamKaSKaSLaSMaSNaMcaSOaMQaMcaSPaMcaSQaMcaSRaSSaSTaSUaSVaSWaSXaSYaSZaTaaTbaTcaTdaTbaTbaTeaTbaSYaTfaSYaOvaTgaSYaThaTiaTjaTkaTlaTmaTnaToaTpaTqaTraOuaTsaTtaTuaTvaTwaTxaTyaTzaRHaTAaTBaRIaTCaTDaTEaTFaROaTGaRQaRRaRSaTHaTIaQdaTJaTKaTKaTLaScaScaScaScaSdapraaaaaaaaaaaaaaaaaaaQfaQfaQfaQfaQfaQfaQfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaTMaTNaQiaOMaQjaOFaQjaOFaQjaOFaQjaOMaQkaQlaKzaKBaTOaTPaTQaTRaTSaTSaJraTTaTUaTVaTWaTXaTYaTZaMqaUaaKHaUbaUcaUdaUeaUfaUgaUhaUiaUjaUkaMvaaaaabaaaaUlaUmaUlaaaaabaaaaCuaJLaJMaUnaUoaUpaUqaUraJMaGvaIKaUsaUtaKPaUuaUvaKSaUwaKSaUxaUyaUzaIKaUAaUBaUCaUDaUEaUFaUGaUHaaaaaaaSKaUIaUJaUKaMcaULaUMaMQaMQaUNaMQaMQaMQaUOaMeaUPaMeaUQaURaMeaUSaMeaUTaUUaUVaUWaUXaUYaUTaUZaVaaVbaVcaVbaVbaVbaVbaVdaVbaVbaVeaVbaVfaVgaVbaVhayHaRDaViaTvaVjaVkaVlaVmaVnaVoaVpaVqaRIaVraVsaVtaVuaVvaTGaRQaRRaRSaRTaVwaQdaVxaTKaTKaTLaScaScaScaScaSdapraaaaaaaaaaaaaaaaaaaQfaQfaQfaQfaQfaQfaQfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaONaTMaTNaQiaOMaQjaOFaQjaOFaQjaOFaQjaOMaQkaQlaKzaKBaTOaTPaTQaTRaTSaTSaJraTTaTUaTVaTWaTXaTYaTZaMqcoCaKHaUbaUcaUdaUeaUfaUgaUhaUiaUjaUkaMvaaaaabaaaaUlaUmaUlaaaaabaaaaCuaJLaJMaUnaUoaUpaUqaUraJMaGvaIKaUsaUtaKPaUuaUvaKSaUwaKSaUxaUyaUzaIKaUAaUBaUCaUDaUEaUFaUGaUHaaaaaaaSKaUIaUJaUKaMcaULaUMaMQaMQaUNaMQaMQaMQaUOaMeaUPaMeaUQaURaMeaUSaMeaUTaUUaUVaUWaUXaUYaUTaUZaVaaVbaVcaVbaVbaVbaVbaVdaVbaVbaVeaVbaVfaVgaVbaVhayHaRDaViaTvaVjaVkaVlaVmaVnaVoaVpaVqaRIaVraVsaVtaVuaVvaTGaRQaRRaRSaRTaVwaQdaVxaTKaTKaTLaScaScaScaScaSdapraaaaaaaaaaaaaaaaaaaQfaQfaQfaQfaQfaQfaQfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVyaVzaNiaODaOMaOFaVAaVBaOFaOFaVCaVAaOMaONaVDaKzaKBaVEaVFaVGaVHaVGaVGaVGaVGaVGaVIaJraKHaVJaVKaVJaKHaKHaVLaVMaVLaMuaMuaMuaMuaVLaVNaVOaMvaVPaVQaVQaVRaVSaVRaVQaVQaVTaVUaVVaJMaVWaJMaVXaVYaVZaJMaWaaIKaIKaIKaIKaWbaWcaWdaWeaWdaWcaWbaIKaIKaWfaUDaUDaUDaUDaWgaWhaWiaWjaWkaSKaWlaUJaWmaMcaMcaMcaMcaMcaMcaMcaMeaMeaUOaWnaWoaWpaWqaWraWsaWuaWtaUTaWvaWwaWxaWyaWzaUTaWAaWBaWCaWDaWCaWEaWFaWGaWHaWIaWJaWKaWLaWMaWNaVbaWOaRtaWPaWQaWRaVjaWSaVlaVmaWTaRIaWUaWVaWWaWXaWYaTFaTFaRIaRIaRQaRRaRSaTHaWZaQdaXaaXbaXcaXdaXeaXfaScaScaXgapraaaaaaaaaaaaaaaaQfaQfaQfaQfaQfaQfaQfaQfaQfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaVyaNiaNjaNiaNiaNkaNlaNiaNiaNjaVzaXhaCuaXiaVEaInaXjaXjaXkaXjaXlaDEaXmaXnaJraXoaXpaXqaXqaXraXsaXqaXtaXqaXqaXqaXuaXqaXqaXvaXwaXxaXyaXzaXAaXyaXBaXyaXyaXyaXyaXCaXDaXEaXqaXqaXFaXGaXHaXIaXJaXKaXLaXMaXRaXPaXPaXPaXPaXPaXPaXPaXQaXWaXXaXSaXTaXUaXVaXYaZHaXZaUDaUDaYaaYbaYcaYbaYcaYdaYeaYfaYgaYhaYiaMeaYkaYjaYmaYlaYnaYnaYoaYpaYqaYraUTaYsaYtaYuaYuaYvaUTaYwaYxaYyaYzaYAaZTaYBaYCaYDaWNaYEaYFaYGaYHaWNaVbaVhaKsaRDaYIaYJaYJaYKaYLaYJaYMaRIaYNaYOaRIaYPaYQaTFaYRaRIaYSaYTaYUaRSaQbaQbaQdaYVaQeaYWaYXaQeaQeaQeaQeaQeabLadbaaaaaaaaaaaaaQfaQfaQfaQfaQfaQfaQfaQfaQfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaInaYYaKzaKzaKzaKzaKzaKzaYYaInaMlaCuaYZaZaaInaZbaZcaZdaZdaZeaDEaZfaXnaZgaZhaXpaZiaZjaZkaZlaZlaZmaZnaZnaZnaZoaZpaZpaZqaZraZsaZlaZlaZtaZpaZvaZwaZxaZxaZyaZzaZAaZuaZuaZuaZBaXGaXHaXIaXJaXJaXJaXJaZCaXJaXJaXJaXJaXJaXJaZDaZEaZNaZFaZGaZJaZIaZLaZKaZMaZNaZNaZNaZOaZPaZPaZPaZQaYiaYiaYiaZRaZSaYiaMebbsaZUaYnaYnaZVaYnaZWaZXaYqaZYaUTaZZbaababbacbadaUTbaebafbagbahbaibajaVbbakbalbakaVbaVbaVbaVeaVbaVbaVhayHaRDbamaTvaTvaTvbanaTvbaoaRIaRIaRIaRIaRIaRIaRIbapaRIaRSaRSaRRaRSbaqbaraQbbasbatbaubavbawbaxbaybazbaAaaaaaaaaaaaaaQfaQfaQfaQfaQfaQfaQfaQfaQfaQfaQfaQfaQfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -8458,28 +8476,28 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyacyacyacyacyacyacyacyacyaaaaaaaaaaaaaaaaaaaacGacGafxacGacGagiafxafxafxafxacGafxafxacGcOcaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJbcOdcLucOecOfcOgcOhcMucOicOjcOkcOlcOmcOncOocOpcOqcOrcGOcOsdcKcOucOvcOwcOxcOycOzcOAdcLcNwcJecOCcODcLKcOEcECcOFcLQcOGcOHcDFcMNcMOcKNcDFcOIcMRcJBcOJcOKcKQcOLcDQcOMcMXcMXcCKcHBcoDcEhcMgchCbJGbYDclUclUclUcMhclUdblcFacFcbVicMjcMibGycuscGvbVibGycMkcITcoAaaaaaackPckPckPckPckPckPckPckPckPckPckPckPckPaaaaaaaaaaaaaabaabaaaaaabwobwobwocvzcyJcMmcMlbxXcxHaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacyacyacyacyacyacyacyacyacyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcJbcJbcJbcOWcOXcOXcOXcMucOYcOZcPacPacPbcPccMzcPdcPecPfcPgcPhdcMcPicPjcPkcPlcPmcPncPidcNcPpcPqcPrcPscPtcPucPvcNHcLQcPwcPxcDFcMNcDFcPycDFcMQcMRcJBcJCcPzcJEcNMcCKcCKcCKcCKcCKcHBcoDcMncKXchCcITcMYcMocMocMocMZbVicFgcFecFhbVicNacKVcKVcNbcHrczhbGybGycoAcoAaaaaaacONaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaabaaabwocyKcNccNdcyJcNfcNebxXcxHaaaaaaaaaaaaaaaaaaaahaaacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabcPEcPFcPGcOXaabaabcMucPHcPIcPacPacPJcMucPKcPLdcOcPNcPOcPPdcPcECcPRcPScPTcGOcPUcECdcQcPWcPXcPNcPNdcRcPZcECcQacLQcQbcQccDFcMNcDFcLScLTcQdcQecMScQfdcScIDcQhcDQcQicQjcQjcCKcHBcoDcNhcNgbVibVicEhbVibVibGycNibVibVicGwbVibVicNkcNjcNmcNlcNQcoAcoAcoAcoAaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaabaabbwocNRcunbOMcyJcyJcyJbxXbwoaabaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabcPEcQqcQrcOXaabaaacMucQscPIcPacPacQtcMucQucQvcECcQwcQxcQxdcTcECcQycQzcQAcQBdcUcECcQxcQxcQxcQwcECcQCcQucECcNHcLQcQDcQEcQFcQGcQHcQIcQJcQKcIAcQLcJCdcVcJEcNMcEVcQNcQOcQPcCKcHBcoAcoAcEhcdbcNScEhcNTbVibGycNVcNUcNXcNWcMocMocNYcGvbVicNZcoAcoAaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaabwobwobwobwobwocOObOMcyJcOQcOPbxXbwoaabaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabcPEcQqcQrcOXaabaaacMucQscPIcPacPacQtcMucQucQvcECcQwcQxcQxdcTcECcQycQzcQAcQBdcUcECcQxcQxcQxcQwcECcQCcQucECcNHcTacQDcQEcQFcQGcQHcQIcQJcQKcIAcQLcJCdcVcJEcNMcEVcQNcQOcQPcCKcHBcoAcoAcEhcdbcNScEhcNTbVibGycNVcNUcNXcNWcMocMocNYcGvbVicNZcoAcoAaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaabwobwobwobwobwocOObOMcyJcOQcOPbxXbwoaabaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQSaaaaaaaaacQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcPEcOXcQTcPEcQUaaacMucQVcQWcPacPacQXcMucQYcQZdcWcRacRbcRccRdcRecRfcRgcRhcRicPucRecRbcRbcRbcRjdcWcRkcRlcECcNHcRmcMNcRncRocQJcRpcRqcRrcRscRtcRucRvdcXcKQcOLcDQcRxcQjcQjcCKcHBcoAbGycORcOTcOScNYcgmbVibGybGybGycGvcOUbGycGqcFicHrbVicEhbwoaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaabwobxXbxXbxXcyKcOOcOVcyJcPAbxXbxXbwoaabaabaabaaaaaaaaaaaacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacRycRycRycRycRycRycRycMucRzcOZcPacPacRAcMucMHcRBcECcECcRecRecRecRecRCcPNcRDcPNcREcRecRecRecRecECcECcRFcRGcECcNHcLQcRHcRIcRocRJcRKcDFcDFcRLcJxcRJcJCcRMcJEcNMcCKcCKcCKcCKcCKcHBcoAcITbGycPCcPBbGycQkbVibVicQlbVicQmcdccyHcQnbVibVibVicEhbwoaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaaaaaaaabwobwobwocQpcQocyKcOObOMbxXbxXbxXcYgbwoaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQSaaaaaacQSaaaaaacQScQScQScQScQScQScQSaaaaaacQSaaaaaacQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacRycRycRycRycRycRycRycMucRNcROcPacPacRPcMucECcRQcECcRRcRScRScLOcLOcLOcLOcLOcLOcLOcLOcLOcRScRScRTcECcRUcECcECcNHcLQcRVcQFcRWcRXcRYcRZcSacRXcSacRXcSbcQJcSccNMaabaabaabaabaabcHBcYhcYicYicYkcYjcYicYicYicYlcYncYmcQmcYobVicQmbVicYpbVicEhbwocxHcxHcxHbwocxHcxHcxHcxHbwocxHcxHcxHcxHbwobwobwobwobwobwobwobwobwobwoczMbwocyKbwocYqbxXcHycOObOMcyJcyJcLecyJbwoaabczraaaaaaaaaaaaaaaaaacJacJacJacJaaaaaaacJacJacJacJacJacJacJaaaaaaacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQSaaacQScQScQScQScQScQScQScQScQSaaacQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacRycRycRycRycRycRycRycMucSdcSecPacPacSfcMucSgcShcSicSjaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabaaaaaacSkcSlcSmcSncECcSocMJcFUcSqcSrcSscStcSucSvcSwcDFcSxcSycSzcSAcNMaabaaaaaaaabaaacYscYrdbwcYtcYwcYvcYycYxcYicqTbGybGycYzcdccYAcGvbGybGycYBcMncYCcYCcYCcYCcYCcYCcYCcYCcYCcYCcYCcYCcYCcYCcYDcYCcYCcYCcYCcmvcyJbFecnGbxXcYEczMbwobwobwocLebwocOObOMcyJcYFbxXbxXbwoaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQSaaacQScQScQScQScQScQScQScQScQSaaacQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacRycRycRycRycRycRycRycMucRzcOZcPacPacSCcMucSDcSEcSEaaaaaaaabaabaabaabaabaabaabaabaabaabaabaaaaaacSEcSEcSDcECcMHcLQcSAcSFcSGcSHcSIcSJcSAcSHcSAcJEcSAcJEcSAcNMaabaaaaaaaabaaacYhcYGcYIcYHcYKcYJcYMcYLcYibGybGybVicQmcYNbVicGvcGqcFicYPcYOcYQcYQcYQcYQcYQcYQcYScYRcYQcYQcYQcYQcYQcYQcYUcYTcYWcYVcYYcYXcYZcYZcYZcYZcZbcZacZccYZcYZcYZcYZcZdbXScyJcOPbxXcZebwoaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQSaaacQScQScQScQScQScQScQScQScQSaaacQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacRycRycRycRycRycRycRycMucSLcSMcPacPacSNcMucSOcSPcSEaabaabaabcSQaaaaaaaaaaaacSQaaaaaacSQaabaabaabcSEcSRcSScECcMHcECaabcSTaabcSUcSVcSWcSXcSYcSXcSZcSXcSZcTacTbaabaabaabaabaaacYhcZfcYIcZgcZicZhcZkcZjcYicZlbGybGycGvcZmbVicGvcGvcZncoAcoAcxHcxHcxHcxHbwocxHcxHcxHcxHbwocxHcxHcxHcxHbwocZobxXcyJcJMbxXcyJcyJcxHcxHckVcyJcZpbxXcZpcyJcZrcZqcoVbwobwobwobwobwoaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacMucTccSMcPacPacSCcMucTdcSEcTeaaaaaaaabaaaaaaaaaaaaaaacTfaaaaaaaaaaabaaaaaacSEcSEcTdcECcMHcECcCKcTgcEVcTgcCKcTgcEVcTgcCKcThcEVcTicCKaaaaaaaaaaaaaabaabcYhcZscZucZtcZvcZhcZxcZwcZycYPcZAcZzcGvcdcbGycZBcQmbVicoAaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaabwocZCczfcyJcZDbxXcyJaaaaaaaaaaaacyJbxXbxXcNRcqecqecqfcqgcqeaaaaabaabaabaabcZEaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacMucTjcOZcPacPacTkcMucTlcTmcSEaaaaaaaabaaaaaaaabaabaabaabaabaaaaaaaabaaaaaacSEcTncTocECcTpcECcCKcTqcTrcTscCKcTtcTucTvcCKcTwcTxcTycCKaaaaaaaaaaaaaaaaabcZGcZFcZucZHcZJcZIcZLcZKcYicZMcQmbVicQmcZNbVicZOcQmcozcoAcoDcoDcoDazyaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaabwocZPcyJcyJcHxbxXcyJcyJcxHcxHcyJcyJbxXcZQczfcqecrecrfcrgcqeaaaaaaaabaabaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaccMucMucMucMucMucMucMucECcSDcSEaaaaaaaabcSQaabaabaacaacaacaabcTzaaaaabaaaaaacSEcSDcECcECcMHcECcCKcTAcTBcTAcCKcTCcTDcTCcCKcTEcTFcTEcCKaaaaaaaaaaaaaaaaaacYhcZRcZTcZScZucZUcZWcZVcYicZXcZZcZYdaacAhbGycGvcGvdabdaddacbGydaeazyaaaaabaaacxHcxHcxHbwobwobwobwobwobwodafcyKcyJdagbxXbxXcyJbxXbxXbxXbxXcYqbxXcPAcqecrZcsacsbcqeaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacaabaacaacaabaabaabacGacGcECcECcTGcSEaaaaaaaabaaaaaaaabcTHcTIaacaabaaaaaaaabaaaaaacSEcTJcECcECcMHcECcCKcTAcTKcTAcCKcTCcTLcTCcCKcTEcTMcTEcCKaaaaaaaaaaaaaaaaaacYhcYhcYhdahcYhdaidajdaicYicZXdakbGycGzdalcFicHrcGvdamcoAcoDcoDcoDdanaabaabaaacxHdaodapcyJbxXdaqdarcNRcyJdasbxXcyJdatbxXbxXdaubxXbwobwobwocxHcxHbwocqectrctscttcqeaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaabaaaaaaaabaabacGcECcECcSDcSEaaaaaaaabaaacTNaabaacaacaacaabaabcSQaabaaaaaacSEcSDcECcECcMHcECcCKcCKcCKcCKcCKcCKcCKcCKcCKcCKcCKcCKcCKaaaaaaaaaaaaaaaaaaaaaaaaaaadavcYhdawdaydaxcYibGydazbGybGydaAdaBcGqdaDdaCcoAaaaaaaaaaaaaaaaaabaaacxHdaEdaFdaubxXcQobxXbxXdaucZobxXcyJcyJcyJcyJcyJbxXbwoaabaaaaaaaaaaabcuzcuzcuAcuzcuzaabaabczraabaabcZEaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabcECcTncTocSEaaaaaaaabaaaaaaaabaabaabaabaabaaaaaaaabaaaaaacSEcTlcTmcECcTpcECcECcECcECcECaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaGcYhdaidaHdaicYhcoAdaIcFicFidaJdaLdaKcoAcoAcoAaaaaaaaaaaaaaaaaabaaacxHdaodaMcyJcNRbxXbxXdaNcyJdaObxXbxXbxXbxXbxXbxXbxXbwoaabaaaaaaaaaaabaaacuzcvEcuzaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaacQScQScQScQSaaaaaacQScQScQScQScQScQScQSaaaaaacQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaabcECcTdcSEcTPaaaaaacTQaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaacSEcSEcTdcECcMHcTRcTScTTcTUcTVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaGcYhdaPdaRdaQdaSaabcoAcoAcoDdaTcoDcoAcoAaaaaabaaaaaaaaaaaaaaaaabaabcxHcxHcxHbwobwobwobxXcyJbwodaUbwobwocNRbFeczfbzNczMbwoaabaaaaaaaaaaabaaacuzcwMcuzaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcECcTXcTYcSEaabaabaabcSQaaaaaacSQaaaaaaaaaaaacSQaabcTZaabcSEcUacUbcECcMHcUccUdcGOcUecTVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaadaGcYhcYhdaVcYhcYhaaaaabaaaaaadaWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaabwodaFdaXbwocGxaabbwobwocxHcxHczMbwoaaaaabaaaaaaaaaaabaaaaaacxZaaaaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacECcUfcUgcUhaaaaaaaabaabaabaabaabaabaabaabaabaabaabaaaaaacUicUgcUjcECcMHcECcUkcUlcUmcReaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcdazycYhdaYcYhdaZaabaabaaaaaadctaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaahaaaaaabwodbbdbabwodbcaabaaaaabaaaaaaaabaaaaaaaabaaaaaaaaaaabaaaaaacznaaaaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacNycECcKDcSkcUhaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabaaaaaacUicSjcKDcECcECcMHcECcECcECcUncECaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabazydbddbedbdazyaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaaaaaaaaacxHdbfcxHcxHaabczraaaaabaaaaaaaabaaaagQagQacGaqZaabaabaabaabcGEaabaabaabaabczragiagQagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaacECcECcSkcRScRScRScRScRScRScRScRScRScRScRScRScRScSjcECcECcECcECcTpcECaaaaabcUocUpaabaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaabazyaaaaaaaaaazyaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaacxHdbgcxHaaaaaaaaaaaaaabaaaaaaaabaaaagQaaaaaaaabaaaaabaaaaaacHNaaaaaaaabaaaaabaaaaaaagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaacECcECcECcECcECcECcECcECcECcECcECcECcECcECcECcECcECaaacECcECcUqcECaabaabcUrcUscUtcUucUvcUucUtcUucUvcUucUtcUucUvcUucUtcUucUvcUwcUxaaaaabazyazyazyazyazyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaacxHdbhcxHaaaaaaaaaaaaaabaaaaaaaabaaaagQaaacIYcIYcIYcIYcIYaabcIZaabcIYcIYcIYcIYcIYaaaagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacECcECcUycECcECcECcECaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaaacUrcUzcUpaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaacxHdbicxHaaaaaaaaaaaaaaaaaaaaaaabaaaagQaabcKccKdcKdcKdcKdcKecKfcKgcKhcKhcKhcKhcKiaabagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacECcMHcMHcUAcUBcUBcUCaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabcUDcUzcUxaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabdbHdbjdbjaaaaaaaaaaaaaaaaaaaaaaabaaaagQaabcLrcLrcLrcLrcLraaacIZaaacLrcLrcLrcLrcLraabagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacECcTpcMHcUEcUFcUGcUHaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaacUrcUzcUpaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaabaaaagQaaaaabaaaaabaabaabaaacIZaaaaabaaaaabaaaaabaaaagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQSaaaaaacQSaaaaaacQScQScQScQScQScQScQSaaaaaacQSaaaaaacQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacRycRycRycRycRycRycRycMucRNcROcPacPacRPcMucECcRQcECcRRcRScRScLOcLOcLOcLOcLOcLOcLOcLOcLOcRScRScRTcECcRUcECcECcNHcLQcRVcQFcRWcRXcRYcRZcSacRXcSacRXcSbcQJcSccNMcTbcTScTScTScTScUdcYhcYicYicYkcYjcYicYicYicYlcYncYmcQmcYobVicQmbVicYpbVicEhbwocxHcxHcxHbwocxHcxHcxHcxHbwocxHcxHcxHcxHbwobwobwobwobwobwobwobwobwobwoczMbwocyKbwocYqbxXcHycOObOMcyJcyJcLecyJbwoaabczraaaaaaaaaaaaaaaaaacJacJacJacJaaaaaaacJacJacJacJacJacJacJaaaaaaacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQSaaacQScQScQScQScQScQScQScQScQSaaacQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacRycRycRycRycRycRycRycMucSdcSecPacPacSfcMucSgcShcSicSjaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabaaaaaacSkcSlcSmcSncECcSocMJcFUcSqcSrcSscStcSucSvcSwcDFcSxcSycSzcSAcNMcUkaaaaabaabaaacYscYrdbwcYtcYwcYvcYycYxcYicqTbGybGycYzcdccYAcGvbGybGycYBcMncYCcYCcYCcYCcYCcYCcYCcYCcYCcYCcYCcYCcYCcYCcYDcYCcYCcYCcYCcmvcyJbFecnGbxXcYEczMbwobwobwocLebwocOObOMcyJcYFbxXbxXbwoaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQSaaacQScQScQScQScQScQScQScQScQSaaacQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacRycRycRycRycRycRycRycMucRzcOZcPacPacSCcMucSDcSEcSEaaaaaaaabaabaabaabaabaabaabaabaabaabaabaaaaaacSEcSEcSDcECcMHcLQcSAcSFcSGcSHcSIcSJcSAcSHcSAcJEcSAcJEcSAcNMcUkaaaacGacGacGcYhcYGcYIcYHcYKcYJcYMcYLcYibGybGybVicQmcYNbVicGvcGqcFicYPcYOcYQcYQcYQcYQcYQcYQcYScYRcYQcYQcYQcYQcYQcYQcYUcYTcYWcYVcYYcYXcYZcYZcYZcYZcZbcZacZccYZcYZcYZcYZcZdbXScyJcOPbxXcZebwoaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQSaaacQScQScQScQScQScQScQScQScQSaaacQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacRycRycRycRycRycRycRycMucSLcSMcPacPacSNcMucSOcSPcSEaabaabaabcSQaaaaaaaaaaaacSQaaaaaacSQaabaabaabcSEcSRcSScECcMHcECaabcSTaabcSUcSVcSWcSXcSYcSXcSZcSXcSZcUmcUqcUkaaaacGaabaaacYhcZfcYIcZgcZicZhcZkcZjcYicZlbGybGycGvcZmbVicGvcGvcZncoAcoAcxHcxHcxHcxHbwocxHcxHcxHcxHbwocxHcxHcxHcxHbwocZobxXcyJcJMbxXcyJcyJcxHcxHckVcyJcZpbxXcZpcyJcZrcZqcoVbwobwobwobwobwoaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacMucTccSMcPacPacSCcMucTdcSEcTeaaaaaaaabaaaaaaaaaaaaaaacTfaaaaaaaaaaabaaaaaacSEcSEcTdcECcMHcECcCKcTgcEVcTgcCKcTgcEVcTgcCKcThcEVcTicCKaabcUkaaaacGaabaabcYhcZscZucZtcZvcZhcZxcZwcZycYPcZAcZzcGvcdcbGycZBcQmbVicoAaaaaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaabwocZCczfcyJcZDbxXcyJaaaaaaaaaaaacyJbxXbxXcNRcqecqecqfcqgcqeaaaaabaabaabaabcZEaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacMucTjcOZcPacPacTkcMucTlcTmcSEaaaaaaaabaaaaaaaabaabaabaabaabaaaaaaaabaaaaaacSEcTncTocECcTpcECcCKcTqcTrcTscCKcTtcTucTvcCKcTwcTxcTycCKaabcUkaaaacGaaaaabcZGcZFcZucZHcZJcZIcZLcZKcYicZMcQmbVicQmcZNbVicZOcQmcozcoAcoDcoDcoDazyaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaabwocZPcyJcyJcHxbxXcyJcyJcxHcxHcyJcyJbxXcZQczfcqecrecrfcrgcqeaaaaaaaabaabaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaccMucMucMucMucMucMucMucECcSDcSEaaaaaaaabcSQaabaabaacaacaacaabcTzaaaaabaaaaaacSEcSDcECcECcMHcECcCKcTAcTBcTAcCKcTCcTDcTCcCKcTEcTFcTEcCKaabcUkaaaacGaaaaaacYhcZRcZTcZScZucZUcZWcZVcYicZXcZZcZYdaacAhbGycGvcGvdabdaddacbGydaeazyaaaaabaaacxHcxHcxHbwobwobwobwobwobwodafcyKcyJdagbxXbxXcyJbxXbxXbxXbxXcYqbxXcPAcqecrZcsacsbcqeaabaaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacJacJacJacJacJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaacaabaacaacaabaabaabacGacGcECcECcTGcSEaaaaaaaabaaaaaaaabcTHcTIaacaabaaaaaaaabaaaaaacSEcTJcECcECcMHcECcCKcTAcTKcTAcCKcTCcTLcTCcCKcTEcTMcTEcCKaabcUkaaaacGaaaaaacYhcYhcYhdahcYhdaidajdaicYicZXdakbGycGzdalcFicHrcGvdamcoAcoDcoDcoDdanaabaabaaacxHdaodapcyJbxXdaqdarcNRcyJdasbxXcyJdatbxXbxXdaubxXbwobwobwocxHcxHbwocqectrctscttcqeaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaabaabaaaaaaaabaabacGcECcECcSDcSEaaaaaaaabaaacTNaabaacaacaacaabaabcSQaabaaaaaacSEcSDcECcECcMHcECcCKcCKcCKcCKcCKcCKcCKcCKcCKcCKcCKcCKcCKaabcUkaaaaqZaaaaaaaaaaaaaaadavcYhdawdaydaxcYibGydazbGybGydaAdaBcGqdaDdaCcoAaaaaaaaaaaaaaaaaabaaacxHdaEdaFdaubxXcQobxXbxXdaucZobxXcyJcyJcyJcyJcyJbxXbwoaabaaaaaaaaaaabcuzcuzcuAcuzcuzaabaabczraabaabcZEaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabcECcTncTocSEaaaaaaaabaaaaaaaabaabaabaabaabaaaaaaaabaaaaaacSEcTlcTmcECcUscECcECcECcECcUvcTScTScTScTScTScTScTScTScTScTScUwaaaacGaabaabaabaabaabdaGcYhdaidaHdaicYhcoAdaIcFicFidaJdaLdaKcoAcoAcoAaaaaaaaaaaaaaaaaabaaacxHdaodaMcyJcNRbxXbxXdaNcyJdaObxXbxXbxXbxXbxXbxXbxXbwoaabaaaaaaaaaaabaaacuzcvEcuzaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaacQScQScQScQSaaaaaacQScQScQScQScQScQScQSaaaaaacQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaabcECcTdcSEcTPaaaaaacTQaaaaaaaaaaabaaaaaaaaaaaaaaaaabaaaaaacSEcSEcTdcECddhddjddicMHddkcUwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGaabaabaabaabaabdaGcYhdaPdaRdaQdaSaabcoAcoAcoDdaTcoDcoAcoAaaaaabaaaaaaaaaaaaaaaaabaabcxHcxHcxHbwobwobwobxXcyJbwodaUbwobwocNRbFeczfbzNczMbwoaabaaaaaaaaaaabaaacuzcwMcuzaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabcECcTXcTYcSEaabaabaabcSQaaaaaacSQaaaaaaaaaaaacSQaabcTZaabcSEcUacUbcECddlcECcECcECcECcECcECacGacGacGaqZacGacGacGacGacGacGacGacGaahaaaaaaaaaaaadaGcYhcYhdaVcYhcYhaaaaabaaaaaadaWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaabwodaFdaXbwocGxaabbwobwocxHcxHczMbwoaaaaabaaaaaaaaaaabaaaaaacxZaaaaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacECcUfcUgcUhaaaaaaaabaabaabaabaabaabaabaabaabaabaabaaaaaacUicUgcUjcECddmcTRddnddocTTcTUcTVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcdazycYhdaYcYhdaZaabaabaaaaaadctaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaahaaaaaabwodbbdbabwodbcaabaaaaabaaaaaaaabaaaaaaaabaaaaaaaaaaabaaaaaacznaaaaaaaabaaaaabaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacNycECcKDcSkcUhaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaabaaaaaacUicSjcKDcECcECddmcUcddpcUlddqcUecTVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazydbddbedbdazyaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaaaaaaaaacxHdbfcxHcxHaabczraaaaabaaaaaaaabaaaagQagQacGaqZaabaabaabaabcGEaabaabaabaabczragiagQagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaacECcECcSkcRScRScRScRScRScRScRScRScRScRScRScRScRScSjcECcECcECcECddrcECcECcECcECcUncECaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabazyaaaaaaaaaazyaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaacxHdbgcxHaaaaaaaaaaaaaabaaaaaaaabaaaagQaaaaaaaabaaaaabaaaaaacHNaaaaaaaabaaaaabaaaaaaagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaacECcECcECcECcECcECcECcECcECcECcECcECcECcECcECcECcECaaacECddtddscECaaaaaaaaacUocUxaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaabazyazyazyazyazyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaacxHdbhcxHaaaaaaaaaaaaaabaaaaaaaabaaaagQaaacIYcIYcIYcIYcIYaabcIZaabcIYcIYcIYcIYcIYaaaagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacQScQScQScQScQSaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacECcECcUycECcECcECcECcUrdducUuddxcUucUtcUuddxcUucUucUuddxcUucUtcUuddxcUuddvcUpaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaacxHdbicxHaaaaaaaaaaaaaaaaaaaaaaabaaaagQaabcKccKdcKdcKdcKdcKecKfcKgcKhcKhcKhcKhcKiaabagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacECcMHcMHcUAcUBcUBcUCaabaabaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaaaabaaaaaaaaacUDcULcUxaabaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabdbHdbjdbjaaaaaaaaaaaaaaaaaaaaaaabaaaagQaabcLrcLrcLrcLrcLraaacIZaaacLrcLrcLrcLrcLraabagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacECcTpcMHcUEcUFcUGcUHaabaabaabaabaabaabaabaabaabaabaabaabaabaabaabczraabaabcUDcUzcUpaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaabaaaagQaaaaabaaaaabaabaabaaacIZaaaaabaaaaabaaaaabaaaagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacECcUIcMHcUJcUBcUBcUKaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaacUDcULcUpaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaagQaaacIYcIYcIYcIYcIYaabcIZaabcIYcIYcIYcIYcIYaabagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacNycECcECcECcECcECcECaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaabcUDcUMaabaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQaabcKccKdcKdcKdcKdcKecKfcKgcKhcKhcKhcKhcObaabagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaabcUNcUOcUNcUPcUPcUQcUQcUQcUQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQaabcLrcLrcLrcLrcLraaacIZaabcLrcLrcLrcLrcLraaaagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -8488,7 +8506,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaaaaaaaaaaabcUNcVecVfcVacVacVgcVhcVicUQaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQaabcKccKdcKdcKdcKdcQQcQRcQQcKhcKhcKhcKhcObaabagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaabaabaabcUNcUNcVjcVacVacUQcVkcUQcUQaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQaabcLrcLrcLrcLrcLraaacGEaaacLrcLrcLrcLrcLraaaagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaacaacaaaaabaaacUPcVlcVacVacVmcVncUPaabaabaabaacaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQaaaaaaaabaabaabaaaaaacGEaabaaaaaaaabaabaaaaaaagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGacGcVocVoacGacGaaacUPcVpcVqcVrcVscVtcUPaaaacGacGcVocVoacGacGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQagQagQagQagQaaaaaaaaacGEaaaaaaaaaagQagQagQaqZagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaddwaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGacGcVocVoacGacGaaacUPcVpcVqcVrcVscVtcUPaaaacGacGcVocVoacGacGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQagQagQagQagQaaaaaaaaacGEaaaaaaaaaagQagQagQaqZagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGcVucVvcVwcVxacGacGcUPcVycVzcVAcVacVBcUPacGacGcVCcVDcVEcVFacGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQaabcSBaabagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOaaacTOcTOcTOcTOcTOaaacTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacVGcVGcVGcVGcVGcVGcVGcVGcVGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGcVucVvcVEcVHcVIcVJcVJcVKcVLcVJcVMcVNcVJcVJcVIcVOcVvcVEcVFacGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQaaaaabaaaagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacTOcTOcTOcTOcTOaaacTOcTOcTOcTOcTOaaacTOcTOcTOcTOcTOaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacVGcVGcVGcVGcVGcVGcVGcVGcVGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacGcVucVPcVQcVRcVRcVScVTcVUcVVcVWcVWcVXcVYcVZcWacWacWbcWccVFacGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagQagQagQagQagQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index dc6c8d0d7bc..500553e1f28 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -20,7 +20,7 @@
init_datum_subtypes(/datum/job, joblist, list(/datum/job/ai, /datum/job/cyborg), "title")
init_datum_subtypes(/datum/superheroes, all_superheroes, null, "name")
- init_datum_subtypes(/datum/nations, all_nations, null, "name")
+ init_datum_subtypes(/datum/nations, all_nations, null, "default_name")
init_datum_subtypes(/datum/language, all_languages, null, "name")
for (var/language_name in all_languages)
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index fe27e399c84..cc6d6f9c621 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -1,20 +1,38 @@
-/proc/random_underwear(var/gender)
+proc/random_underwear(gender, species = "Human")
+ var/list/pick_list = list()
switch(gender)
- if(MALE) return pick(underwear_m)
- if(FEMALE) return pick(underwear_f)
- else return pick(underwear_list)
+ if(MALE) pick_list = underwear_m
+ if(FEMALE) pick_list = underwear_f
+ else pick_list = underwear_list
+ return pick_species_allowed_underwear(pick_list, species)
-/proc/random_undershirt(var/gender)
+proc/random_undershirt(gender, species = "Human")
+ var/list/pick_list = list()
switch(gender)
- if(MALE) return pick(undershirt_m)
- if(FEMALE) return pick(undershirt_f)
- else return pick(undershirt_list)
+ if(MALE) pick_list = undershirt_m
+ if(FEMALE) pick_list = undershirt_f
+ else pick_list = undershirt_list
+ return pick_species_allowed_underwear(pick_list, species)
-/proc/random_socks(gender)
+proc/random_socks(gender, species = "Human")
+ var/list/pick_list = list()
switch(gender)
- if(MALE) return pick(socks_m)
- if(FEMALE) return pick(socks_f)
- else return pick(socks_list)
+ if(MALE) pick_list = socks_m
+ if(FEMALE) pick_list = socks_f
+ else pick_list = socks_list
+ return pick_species_allowed_underwear(pick_list, species)
+
+proc/pick_species_allowed_underwear(list/all_picks, species)
+ var/list/valid_picks = list()
+ for(var/test in all_picks)
+ var/datum/sprite_accessory/S = all_picks[test]
+ if(!(species in S.species_allowed))
+ continue
+ valid_picks += test
+
+ if(!valid_picks.len) valid_picks += "Nude"
+
+ return pick(valid_picks)
proc/random_hair_style(var/gender, species = "Human")
var/h_style = "Bald"
@@ -35,7 +53,7 @@ proc/random_hair_style(var/gender, species = "Human")
return h_style
-/proc/GetOppositeDir(var/dir)
+proc/GetOppositeDir(var/dir)
switch(dir)
if(NORTH) return SOUTH
if(SOUTH) return NORTH
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 80b54678f14..e6917bc8830 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1594,6 +1594,15 @@ atom/proc/GetTypeInAllContents(typepath)
colour += temp_col
return colour
+/proc/get_random_chemical(var/is_plant = 0)
+ var/list/blocked = blocked_chems.Copy() //blocked_chems list is found in code/_globalvars/lists/reagents.dm
+ if(is_plant)
+ blocked.Add(plant_blocked_chems.Copy()) //plant_blocked_chems list is found in code/_globalvars/lists/reagents.dm
+ var/picked_chem = pick(chemical_reagents_list)
+ if(blocked.Find(picked_chem))
+ return get_random_chemical(is_plant)
+ return picked_chem
+
/proc/get_distant_turf(var/turf/T,var/direction,var/distance)
if(!T || !direction || !distance) return
@@ -1679,7 +1688,7 @@ var/mob/dview/dview_mob = new
if(orbiting)
loc = get_turf(orbiting)
orbiting = null
-
+
//Centers an image.
//Requires:
//The Image
@@ -1720,7 +1729,7 @@ var/mob/dview/dview_mob = new
if(A.simulated)
return 0
return 1
-
+
/proc/screen_loc2turf(scr_loc, turf/origin)
var/tX = text2list(scr_loc, ",")
var/tY = text2list(tX[2], ":")
@@ -1732,4 +1741,3 @@ var/mob/dview/dview_mob = new
tY = max(1, min(world.maxy, origin.y + (text2num(tY) - (world.view + 1))))
return locate(tX, tY, tZ)
-
\ No newline at end of file
diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm
index 2b7068e1231..8a3d8f090a9 100644
--- a/code/_globalvars/lists/mobs.dm
+++ b/code/_globalvars/lists/mobs.dm
@@ -52,7 +52,8 @@ var/global/list/blocked_mobs = list(/mob/living/simple_animal,
/mob/living/simple_animal/ascendant_shadowling,
/mob/living/simple_animal/slaughter,
/mob/living/simple_animal/hostile/retaliate/araneus,
- /mob/living/simple_animal/hostile/syndicate/ranged/orion
+ /mob/living/simple_animal/hostile/syndicate/ranged/orion,
+ /mob/living/simple_animal/hostile/statue
)
var/global/list/med_hud_users = list()
diff --git a/code/_globalvars/lists/reagents.dm b/code/_globalvars/lists/reagents.dm
index 8088219e149..f6639796b97 100644
--- a/code/_globalvars/lists/reagents.dm
+++ b/code/_globalvars/lists/reagents.dm
@@ -1,12 +1,61 @@
// Base chemicals
-var/list/base_chemicals = list("water","oxygen","nitrogen","hydrogen","potassium","mercury","carbon","chlorine","fluorine","phosphorus","lithium","sulfur","sacid","radium","iron","aluminum","silicon","sugar","ethanol")
+var/list/base_chemicals = list("water","oxygen","nitrogen","hydrogen","potassium","mercury","carbon",
+ "chlorine","fluorine","phosphorus","lithium","sulfur","sacid","radium",
+ "iron","aluminum","silicon","sugar","ethanol")
// Standard chemicals
-var/list/standard_chemicals = list("slimejelly","blood","water","lube","charcoal","toxin","cyanide","morphine","epinephrine","space_drugs","serotrotium","oxygen","copper","nitrogen","hydrogen","potassium","mercury","sulfur","carbon","chlorine","fluorine","sodium","phosphorus","lithium","sugar","sacid","facid","glycerol","radium","mutadone","thermite","mutagen","virusfood","iron","gold","silver","uranium","aluminum","silicon","fuel","cleaner","atrazine","plasma","teporone","lexorin","silver_sulfadiazine","salbutamol","perfluorodecalin","omnizine","synaptizine","haloperidol","potass_iodide","pen_acid","mannitol","oculine","styptic_powder","methamphetamine","cryoxadone","spaceacillin","carpotoxin","lsd","fluorosurfactant","fluorosurfactant","ethanol","ammonia","diethylamine","antihol","pancuronium","lipolicide","condensedcapsaicin","frostoil","amanitin","psilocybin","enzyme","nothing","salglu_solution","antifreeze","neurotoxin")
+var/list/standard_chemicals = list("slimejelly","blood","water","lube","charcoal","toxin","cyanide",
+ "morphine","epinephrine","space_drugs","serotrotium","oxygen","copper",
+ "nitrogen","hydrogen","potassium","mercury","sulfur","carbon","chlorine",
+ "fluorine","sodium","phosphorus","lithium","sugar","sacid","facid",
+ "glycerol","radium","mutadone","thermite","mutagen","virusfood","iron",
+ "gold","silver","uranium","aluminum","silicon","fuel","cleaner","atrazine",
+ "plasma","teporone","lexorin","silver_sulfadiazine","salbutamol",
+ "perfluorodecalin","omnizine","synaptizine","haloperidol","potass_iodide",
+ "pen_acid","mannitol","oculine","styptic_powder","methamphetamine",
+ "cryoxadone","spaceacillin","carpotoxin","lsd","fluorosurfactant",
+ "fluorosurfactant","ethanol","ammonia","diethylamine","antihol","pancuronium",
+ "lipolicide","condensedcapsaicin","frostoil","amanitin","psilocybin",
+ "enzyme","nothing","salglu_solution","antifreeze","neurotoxin")
// Rare chemicals
var/list/rare_chemicals = list("minttoxin","nanites","xenomicrobes","adminordrazine")
// Standard medicines
-var/list/standard_medicines = list("charcoal","toxin","cyanide","morphine","epinephrine","space_drugs","serotrotium","mutadone","mutagen","teporone","lexorin","silver_sulfadiazine","salbutamol","perfluorodecalin","omnizine","synaptizine","haloperidol","potass_iodide","pen_acid","mannitol","oculine","styptic_powder","methamphetamine","spaceacillin","carpotoxin","lsd","ethanol","ammonia","diethylamine","antihol","pancuronium","lipolicide","condensedcapsaicin","frostoil","amanitin","psilocybin","nothing","salglu_solution","neurotoxin")
+var/list/standard_medicines = list("charcoal","toxin","cyanide","morphine","epinephrine","space_drugs",
+ "serotrotium","mutadone","mutagen","teporone","lexorin","silver_sulfadiazine",
+ "salbutamol","perfluorodecalin","omnizine","synaptizine","haloperidol",
+ "potass_iodide","pen_acid","mannitol","oculine","styptic_powder",
+ "methamphetamine","spaceacillin","carpotoxin","lsd","ethanol","ammonia",
+ "diethylamine","antihol","pancuronium","lipolicide","condensedcapsaicin",
+ "frostoil","amanitin","psilocybin","nothing","salglu_solution","neurotoxin")
// Rare medicines
var/list/rare_medicines = list("nanites","xenomicrobes","minttoxin","adminordrazine","blood")
// Drinks
-var/list/drinks = list("beer2","hot_coco","orangejuice","tomatojuice","limejuice","carrotjuice","berryjuice","poisonberryjuice","watermelonjuice","lemonjuice","banana","nothing","potato","milk","soymilk","cream","coffee","tea","icecoffee","icetea","cola","nuka_cola","spacemountainwind","thirteenloko","dr_gibb","space_up","lemon_lime","beer","whiskey","gin","rum","vodka","holywater","tequilla","vermouth","wine","tonic","kahlua","cognac","ale","sodawater","ice","bilk","atomicbomb","threemileisland","goldschlager","patron","gintonic","cubalibre","whiskeycola","martini","vodkamartini","whiterussian","screwdrivercocktail","booger","bloodymary","gargleblaster","bravebull","tequillasunrise","toxinsspecial","beepskysmash","salglu_solution","irishcream","manlydorf","longislandicedtea","moonshine","b52","irishcoffee","margarita","blackrussian","manhattan","manhattan_proj","whiskeysoda","antifreeze","barefoot","snowwhite","demonsblood","vodkatonic","ginfizz","bahama_mama","singulo","sbiten","devilskiss","red_mead","mead","iced_beer","grog","aloe","andalusia","alliescocktail","soy_latte","cafe_latte","acidspit","amasec","neurotoxin","hippiesdelight","bananahonk","silencer","changelingsting","irishcarbomb","syndicatebomb","erikasurprise","driestmartini")
\ No newline at end of file
+var/list/drinks = list("beer2","hot_coco","orangejuice","tomatojuice","limejuice","carrotjuice",
+ "berryjuice","poisonberryjuice","watermelonjuice","lemonjuice","banana",
+ "nothing","potato","milk","soymilk","cream","coffee","tea","icecoffee",
+ "icetea","cola","nuka_cola","spacemountainwind","thirteenloko","dr_gibb",
+ "space_up","lemon_lime","beer","whiskey","gin","rum","vodka","holywater",
+ "tequilla","vermouth","wine","tonic","kahlua","cognac","ale","sodawater",
+ "ice","bilk","atomicbomb","threemileisland","goldschlager","patron","gintonic",
+ "cubalibre","whiskeycola","martini","vodkamartini","whiterussian","screwdrivercocktail",
+ "booger","bloodymary","gargleblaster","bravebull","tequillasunrise","toxinsspecial",
+ "beepskysmash","salglu_solution","irishcream","manlydorf","longislandicedtea",
+ "moonshine","b52","irishcoffee","margarita","blackrussian","manhattan",
+ "manhattan_proj","whiskeysoda","antifreeze","barefoot","snowwhite","demonsblood",
+ "vodkatonic","ginfizz","bahama_mama","singulo","sbiten","devilskiss","red_mead",
+ "mead","iced_beer","grog","aloe","andalusia","alliescocktail","soy_latte",
+ "cafe_latte","acidspit","amasec","neurotoxin","hippiesdelight","bananahonk",
+ "silencer","changelingsting","irishcarbomb","syndicatebomb","erikasurprise","driestmartini")
+
+//Random chem blacklist
+var/global/list/blocked_chems = list("polonium", "initropidril", "concentrated_initro",
+ "sodium_thiopental", "ketamine", "coniine",
+ "adminordrazine", "nanites", "hellwater",
+ "mutationtoxin", "amutationtoxin", "venom",
+ "spore", "stimulants", "stimulative_agent",
+ "syndicate_nanites", "ripping_tendrils", "boiling_oil",
+ "envenomed_filaments", "lexorin_jelly", "kinetic",
+ "cryogenic_liquid", "dark_matter", "b_sorium",
+ "reagent", "life")
+
+//List of chems/mixtures that can't grow in plants (in addition to the global random chem blacklist)
+var/global/list/plant_blocked_chems = list() //filled in /datum/reagents/New() with chems that have can_grow_in_plants = 0
\ No newline at end of file
diff --git a/code/defines/procs/announce.dm b/code/defines/procs/announce.dm
index 34822d2d509..0267bd88d98 100644
--- a/code/defines/procs/announce.dm
+++ b/code/defines/procs/announce.dm
@@ -1,6 +1,8 @@
/var/datum/announcement/minor/minor_announcement = new()
/var/datum/announcement/priority/priority_announcement = new(do_log = 0)
/var/datum/announcement/priority/command/command_announcement = new(do_log = 0, do_newscast = 1)
+/var/datum/announcement/priority/enemy/communications_announcement = new(do_log = 0, do_newscast = 1)
+
/datum/announcement
var/title = "Attention"
@@ -16,7 +18,7 @@
sound = new_sound
log = do_log
newscast = do_newscast
-
+
/datum/announcement/minor/New(var/do_log = 0, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
title = "Attention"
@@ -32,12 +34,17 @@
title = "[command_name()] Update"
announcement_type = "[command_name()] Update"
+/datum/announcement/priority/enemy/New(var/do_log = 1, var/new_sound = sound('sound/AI/intercept2.ogg'), var/do_newscast = 0)
+ ..(do_log, new_sound, do_newscast)
+ title = "[command_name()] Update"
+ announcement_type = "Enemy Communications"
+
/datum/announcement/priority/security/New(var/do_log = 1, var/new_sound = sound('sound/misc/notice2.ogg'), var/do_newscast = 0)
..(do_log, new_sound, do_newscast)
title = "Security Announcement"
announcement_type = "Security Announcement"
-/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast, var/msg_sanitized = 0)
+/datum/announcement/proc/Announce(var/message as text, var/new_title = "", var/new_sound = null, var/do_newscast = newscast, var/msg_sanitized = 0, var/from)
if(!message)
return
var/tmp/message_title = new_title ? new_title : title
@@ -47,7 +54,7 @@
message = trim_strip_html_properly(message)
message_title = html_encode(message_title)
- Message(message, message_title)
+ Message(message, message_title, from)
if(do_newscast)
NewsCast(message, message_title)
Sound(message_sound)
@@ -84,6 +91,18 @@ datum/announcement/priority/command/Message(message as text, message_title as te
if(!istype(M,/mob/new_player) && !isdeaf(M))
M << command
+datum/announcement/priority/enemy/Message(message as text, message_title as text, from as text)
+ var/command
+ command += "
[from]
"
+ if (message_title)
+ command += "
[message_title]
"
+
+ command += "
[message]
"
+ command += "
"
+ for(var/mob/M in player_list)
+ if(!istype(M,/mob/new_player) && !isdeaf(M))
+ M << command
+
datum/announcement/priority/security/Message(message as text, message_title as text)
world << "[message_title]"
world << "[message]"
diff --git a/code/game/dna/genes/goon_disabilities.dm b/code/game/dna/genes/goon_disabilities.dm
index 14e25c4ef69..2db8f3e08f0 100644
--- a/code/game/dna/genes/goon_disabilities.dm
+++ b/code/game/dna/genes/goon_disabilities.dm
@@ -37,9 +37,10 @@
block=RADBLOCK
OnMobLife(var/mob/living/owner)
- owner.apply_effect(max(owner.radiation, 20), IRRADIATE)
+ var/radiation_amount = abs(min(owner.radiation - 20,0))
+ owner.apply_effect(radiation_amount, IRRADIATE)
for(var/mob/living/L in range(1, owner))
- if(L == owner)
+ if(L == owner)
continue
L << "You are enveloped by a soft green glow emanating from [owner]."
L.apply_effect(5, IRRADIATE)
diff --git a/code/game/dna/genes/goon_powers.dm b/code/game/dna/genes/goon_powers.dm
index 8e3542ef6c8..e9e07437350 100644
--- a/code/game/dna/genes/goon_powers.dm
+++ b/code/game/dna/genes/goon_powers.dm
@@ -288,9 +288,9 @@
if(is_type_in_list(O,types_allowed))
possible_targets += O
- targets += input("Choose the target of your hunger.", "Targeting") as anything in possible_targets
+ targets += input("Choose the target of your hunger.", "Targeting") as null|anything in possible_targets
- if(!targets.len) //doesn't waste the spell
+ if(!targets.len || !targets[1]) //doesn't waste the spell
revert_cast(user)
return
@@ -529,7 +529,11 @@
/obj/effect/proc_holder/spell/targeted/empath/choose_targets(mob/user = usr)
var/list/targets = new /list()
- targets += input("Choose the target to spy on.", "Targeting") as mob in range(7,usr)
+ targets += input("Choose the target to spy on.", "Targeting") as null|mob in range(7,usr)
+
+ if(!targets.len || !targets[1]) //doesn't waste the spell
+ revert_cast(user)
+ return
perform(targets)
diff --git a/code/game/dna/genes/powers.dm b/code/game/dna/genes/powers.dm
index 19cab0c0bfc..3ce2abb549e 100644
--- a/code/game/dna/genes/powers.dm
+++ b/code/game/dna/genes/powers.dm
@@ -113,10 +113,12 @@
activate(var/mob/M, var/connected, var/flags)
..(M,connected,flags)
M.pass_flags |= PASSTABLE
+ M.resize = 0.8
deactivate(var/mob/M, var/connected, var/flags)
..()
M.pass_flags &= ~PASSTABLE
+ M.resize = 1.25
// OLD HULK BEHAVIOR
/datum/dna/gene/basic/hulk
diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm
index 3c8168d4157..b34f2108560 100644
--- a/code/game/dna/genes/vg_powers.dm
+++ b/code/game/dna/genes/vg_powers.dm
@@ -128,25 +128,25 @@ Obviously, requires DNA2.
return
var/mob/living/carbon/human/M=usr
- var/new_facial = input("Please select facial hair color.", "Character Generation",rgb(M.r_facial,M.g_facial,M.b_facial)) as color
+ var/new_facial = input("Please select facial hair color.", "Character Generation",rgb(M.r_facial,M.g_facial,M.b_facial)) as null|color
if(new_facial)
M.r_facial = hex2num(copytext(new_facial, 2, 4))
M.g_facial = hex2num(copytext(new_facial, 4, 6))
M.b_facial = hex2num(copytext(new_facial, 6, 8))
- var/new_hair = input("Please select hair color.", "Character Generation",rgb(M.r_hair,M.g_hair,M.b_hair)) as color
+ var/new_hair = input("Please select hair color.", "Character Generation",rgb(M.r_hair,M.g_hair,M.b_hair)) as null|color
if(new_facial)
M.r_hair = hex2num(copytext(new_hair, 2, 4))
M.g_hair = hex2num(copytext(new_hair, 4, 6))
M.b_hair = hex2num(copytext(new_hair, 6, 8))
- var/new_eyes = input("Please select eye color.", "Character Generation",rgb(M.r_eyes,M.g_eyes,M.b_eyes)) as color
+ var/new_eyes = input("Please select eye color.", "Character Generation",rgb(M.r_eyes,M.g_eyes,M.b_eyes)) as null|color
if(new_eyes)
M.r_eyes = hex2num(copytext(new_eyes, 2, 4))
M.g_eyes = hex2num(copytext(new_eyes, 4, 6))
M.b_eyes = hex2num(copytext(new_eyes, 6, 8))
- var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", "[35-M.s_tone]") as text
+ var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", "[35-M.s_tone]") as null|text
if (!new_tone)
new_tone = 35
@@ -234,13 +234,20 @@ Obviously, requires DNA2.
start_recharge()
return
- targets += input("Choose the target to talk to.", "Targeting") as mob in validtargets
+ targets += input("Choose the target to talk to.", "Targeting") as null|mob in validtargets
+
+ if(!targets.len || !targets[1]) //doesn't waste the spell
+ revert_cast(user)
+ return
perform(targets)
/obj/effect/proc_holder/spell/targeted/remotetalk/cast(list/targets)
if(!ishuman(usr)) return
- var/say = strip_html(input("What do you wish to say"))
+ var/say = input("What do you wish to say") as text|null
+ if(!say)
+ return
+ say = strip_html(say)
for(var/mob/living/target in targets)
log_say("Project Mind: [key_name(usr)]->[key_name(target)]: [say]")
@@ -292,7 +299,11 @@ Obviously, requires DNA2.
start_recharge()
return
- targets += input("Choose the target to spy on.", "Targeting") as mob in validtargets
+ targets += input("Choose the target to spy on.", "Targeting") as null|mob in validtargets
+
+ if(!targets.len || !targets[targets.len]) //doesn't waste the spell
+ revert_cast(user)
+ return
perform(targets)
diff --git a/code/game/gamemodes/meteor/meteor.dm b/code/game/gamemodes/meteor/meteor.dm
index f24b3bb37f6..23ab40f98b6 100644
--- a/code/game/gamemodes/meteor/meteor.dm
+++ b/code/game/gamemodes/meteor/meteor.dm
@@ -24,7 +24,7 @@
/datum/game_mode/meteor/proc/sendmeteors()
- var/waveduration = world.time + rand(0,1000) + text2num("[wave]000" / 2)
+ var/waveduration = world.time + rand(0,1000) + text2num("[wave]000") / 2
var/waitduration = rand(3000,6000)
while(waveduration - world.time > 0)
sleep(max(65 - text2num("[wave]0") / 2, 40))
diff --git a/code/game/gamemodes/nations/nations.dm b/code/game/gamemodes/nations/nations.dm
index 24c7bc1e82b..39c81b4b8d0 100644
--- a/code/game/gamemodes/nations/nations.dm
+++ b/code/game/gamemodes/nations/nations.dm
@@ -14,10 +14,12 @@ datum/game_mode/nations
send_intercept()
split_teams()
set_ai()
+ assign_leaders()
// remove_access()
for(var/mob/M in player_list)
if(!istype(M,/mob/new_player))
M << sound('sound/effects/purge_siren.ogg')
+
return ..()
/datum/game_mode/nations/proc/send_intercept()
@@ -39,7 +41,12 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudatmosia")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ if(H.mind.assigned_role == H.mind.nation.default_leader)
+ H.mind.nation.current_leader = H.mind.current
+ H << "You have been chosen to lead the nation of [H.mind.nation.default_name]!"
+ continue
+ H << "You are now part of the great sovereign nation of [H.mind.nation.default_name]!"
continue
if(H.mind.assigned_role in medical_positions)
@@ -47,7 +54,12 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudmedistan")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ if(H.mind.assigned_role == H.mind.nation.default_leader)
+ H.mind.nation.current_leader = H.mind.current
+ H << "You have been chosen to lead the nation of [H.mind.nation.default_name]!"
+ continue
+ H << "You are now part of the great sovereign nation of [H.mind.nation.default_name]!"
continue
if(H.mind.assigned_role in science_positions)
@@ -55,7 +67,12 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudscientopia")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ if(H.mind.assigned_role == H.mind.nation.default_leader)
+ H.mind.nation.current_leader = H.mind.current
+ H << "You have been chosen to lead the nation of [H.mind.nation.default_name]!"
+ continue
+ H << "You are now part of the great sovereign nation of [H.mind.nation.default_name]!"
continue
if(H.mind.assigned_role in security_positions)
@@ -63,7 +80,12 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudbrigston")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ if(H.mind.assigned_role == H.mind.nation.default_leader)
+ H.mind.nation.current_leader = H.mind.current
+ H << "You have been chosen to lead the nation of [H.mind.nation.default_name]!"
+ continue
+ H << "You are now part of the great sovereign nation of [H.mind.nation.default_name]!"
continue
if(H.mind.assigned_role in cargonians)
@@ -71,7 +93,12 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudcargonia")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ if(H.mind.assigned_role == H.mind.nation.default_leader)
+ H.mind.nation.current_leader = H.mind.current
+ H << "You have been chosen to lead the nation of [H.mind.nation.default_name]!"
+ continue
+ H << "You are now part of the great sovereign nation of [H.mind.nation.default_name]!"
continue
if(H.mind.assigned_role in servicion)
@@ -79,7 +106,12 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudservice")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ if(H.mind.assigned_role == H.mind.nation.default_leader)
+ H.mind.nation.current_leader = H.mind.current
+ H << "You have been chosen to lead the nation of [H.mind.nation.default_name]!"
+ continue
+ H << "You are now part of the great sovereign nation of [H.mind.nation.default_name]!"
continue
if(H.mind.assigned_role in support_positions)
@@ -87,7 +119,12 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudcommand")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ if(H.mind.assigned_role == H.mind.nation.default_leader)
+ H.mind.nation.current_leader = H.mind.current
+ H << "You have been chosen to lead the nation of [H.mind.nation.default_name]!"
+ continue
+ H << "You are now part of the great sovereign nation of [H.mind.nation.default_name]!"
continue
if(H.mind.assigned_role in command_positions)
@@ -95,7 +132,12 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudcommand")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ if(H.mind.assigned_role == H.mind.nation.default_leader)
+ H.mind.nation.current_leader = H.mind.current
+ H << "You have been chosen to lead the nation of [H.mind.nation.default_name]!"
+ continue
+ H << "You are now part of the great sovereign nation of [H.mind.nation.default_name]!"
continue
if(H.mind.assigned_role in civilian_positions)
@@ -129,6 +171,22 @@ datum/game_mode/nations
if(W.z in config.station_levels)
W.req_access = list()
+
+/datum/game_mode/nations/proc/assign_leaders()
+ for(var/name in all_nations)
+ var/datum/nations/N = all_nations[name]
+ if(!N.current_name)
+ N.current_name = N.default_name
+ if(!N.current_leader && N.membership.len)
+ N.current_leader = pick(N.membership)
+ N.current_leader << "You have been chosen to lead the nation of [N.current_name]!"
+ if(N.current_leader)
+ var/mob/living/carbon/human/H = N.current_leader
+ H.verbs += /mob/living/carbon/human/proc/set_nation_name
+ H.verbs += /mob/living/carbon/human/proc/set_ranks
+ H.verbs += /mob/living/carbon/human/proc/choose_heir
+ N.update_nation_id()
+
/**
* LateSpawn hook.
* Called in newplayer.dm when a humanoid character joins the round after it started.
@@ -148,7 +206,8 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudatmosia")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ H << "You are now part of the great sovereign nation of [H.mind.nation.current_name]!"
return 1
if(H.mind.assigned_role in medical_positions)
@@ -156,7 +215,8 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudmedistan")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ H << "You are now part of the great sovereign nation of [H.mind.nation.current_name]!"
return 1
if(H.mind.assigned_role in science_positions)
@@ -164,7 +224,8 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudscientopia")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ H << "You are now part of the great sovereign nation of [H.mind.nation.current_name]!"
return 1
if(H.mind.assigned_role in security_positions)
@@ -172,7 +233,8 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudbrigston")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ H << "You are now part of the great sovereign nation of [H.mind.nation.current_name]!"
return 1
if(H.mind.assigned_role in cargonians)
@@ -180,7 +242,8 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudcargonia")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ H << "You are now part of the great sovereign nation of [H.mind.nation.current_name]!"
return 1
if(H.mind.assigned_role in servicion)
@@ -188,7 +251,8 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudservice")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ H << "You are now part of the great sovereign nation of [H.mind.nation.current_name]!"
return 1
if(H.mind.assigned_role in support_positions)
@@ -196,7 +260,8 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudcommand")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ H << "You are now part of the great sovereign nation of [H.mind.nation.current_name]!"
return 1
if(H.mind.assigned_role in command_positions)
@@ -204,7 +269,8 @@ datum/game_mode/nations
H.hud_updateflag |= 1 << NATIONS_HUD
var/I = image('icons/mob/hud.dmi', loc = H.mind.current, icon_state = "hudcommand")
H.client.images += I
- H << "You are now part of the great sovereign nation of [H.mind.nation.name]!"
+ H.mind.nation.membership += H.mind.current
+ H << "You are now part of the great sovereign nation of [H.mind.nation.current_name]!"
return 1
if(H.mind.assigned_role in civilian_positions)
diff --git a/code/game/gamemodes/nations/nationsdatums.dm b/code/game/gamemodes/nations/nationsdatums.dm
index 64067acb041..0e94ac28e8a 100644
--- a/code/game/gamemodes/nations/nationsdatums.dm
+++ b/code/game/gamemodes/nations/nationsdatums.dm
@@ -1,23 +1,37 @@
/datum/nations
- var/name
+ var/default_name
+ var/current_name
+ var/default_leader
+ var/current_leader
+ var/list/membership = list()
+ var/leader_rank = "Leader"
+ var/member_rank = "Member"
+ var/heir
/datum/nations/atmosia
- name = "Atmosia"
+ default_name = "Atmosia"
+ default_leader = "Chief Engineer"
/datum/nations/brigston
- name = "Brigston"
+ default_name = "Brigston"
+ default_leader = "Head of Security"
/datum/nations/cargonia
- name = "Cargonia"
+ default_name = "Cargonia"
+ default_leader = "Quartermaster"
/datum/nations/command
- name = "People's Republic of Commandzakstan"
+ default_name = "People's Republic of Commandzakstan"
+ default_leader = "Captain"
/datum/nations/medistan
- name = "Medistan"
+ default_name = "Medistan"
+ default_leader = "Chief Medical Officer"
/datum/nations/scientopia
- name = "Scientopia"
+ default_name = "Scientopia"
+ default_leader = "Research Director"
/datum/nations/service
- name = "Servicion"
\ No newline at end of file
+ default_name = "Servicion"
+ default_leader = "Bartender"
\ No newline at end of file
diff --git a/code/game/gamemodes/nations/nationsprocs.dm b/code/game/gamemodes/nations/nationsprocs.dm
new file mode 100644
index 00000000000..a0784a3ca08
--- /dev/null
+++ b/code/game/gamemodes/nations/nationsprocs.dm
@@ -0,0 +1,112 @@
+/mob/living/carbon/human/proc/set_nation_name()
+ set name = "Rename Nation"
+ set category = "Nations"
+ set desc = "Click to rename your nation. You are only able to do this once."
+
+ var/datum/game_mode/nations/mode = get_nations_mode()
+ if (!mode) return 1
+
+ if(!mode.kickoff) return 1
+
+ var/mob/living/carbon/human/H = src
+ if(H.mind && H.mind.nation && H.mind.nation.current_leader == H)
+ var/input = stripped_input(H,"What do you want to name your nation?", ,"", MAX_NAME_LEN)
+
+ if(input)
+ H.mind.nation.current_name = input
+ H.mind.nation.update_nation_id()
+ H << "You rename your nation to [input]."
+ H.verbs -= /mob/living/carbon/human/proc/set_nation_name
+ return 1
+
+
+/mob/living/carbon/human/proc/set_ranks()
+ set name = "Set Ranks"
+ set category = "Nations"
+ set desc = "Click to set a rank for Leaders and Members."
+
+ var/datum/game_mode/nations/mode = get_nations_mode()
+ if (!mode) return 1
+
+ if(!mode.kickoff) return 1
+
+ var/mob/living/carbon/human/H = src
+ if(H.mind && H.mind.nation && H.mind.nation.current_leader == H)
+ var/type = input(H, "What rank do you want to change?", "Rename Rank", "") in list("Leader","Member")
+ var/input = stripped_input(H,"What rank do you want?", ,"", MAX_NAME_LEN)
+ if(input)
+ if(type == "Leader")
+ H.mind.nation.leader_rank = input
+ H.mind.nation.update_nation_id()
+
+ if(type == "Member")
+ H.mind.nation.member_rank = input
+ H.mind.nation.update_nation_id()
+ H << "You changed the [type] rank of your nation to [input]."
+ return 1
+
+/mob/living/carbon/human/proc/choose_heir()
+ set name = "Choose Heir"
+ set category = "Nations"
+ set desc = "Click to pick a Heir. Note that the Heir has the ability to take over your role at ANY TIME. Choose carefully."
+
+ var/datum/game_mode/nations/mode = get_nations_mode()
+ if (!mode) return 1
+
+ if(!mode.kickoff) return 1
+
+ var/mob/living/carbon/human/H = src
+ if(H.mind && H.mind.nation && H.mind.nation.current_leader == H)
+ var/heir = input(H, "Who do you wish to make your heir?", "Choose Heir", "") as null|anything in H.mind.nation.membership
+ if(heir)
+ if(H.mind.nation.heir)
+ var/mob/living/carbon/human/oldheir = H.mind.nation.heir
+ oldheir << "You are no longer the heir to your nation!"
+ oldheir.verbs -= /mob/living/carbon/human/proc/takeover
+ var/mob/living/carbon/human/newheir = heir
+ H.mind.nation.heir = newheir
+ newheir.verbs += /mob/living/carbon/human/proc/takeover
+ newheir << "You have been selected to be the heir to your nation's leadership!"
+ H << "You have selected [heir] to be your heir!"
+
+
+/mob/living/carbon/human/proc/takeover()
+ set name = "Become Leader"
+ set category = "Nations"
+ set desc = "Click to replace your current nation's leader with yourself."
+
+ var/datum/game_mode/nations/mode = get_nations_mode()
+ if (!mode) return 1
+
+ if(!mode.kickoff) return 1
+
+ var/mob/living/carbon/human/H = src
+ if(H.mind && H.mind.nation && H.mind.nation.heir == H)
+ var/confirmation = input(H, "Are you sure you want to take over leadership?", "Become Leader", "") as null|anything in list("Yes", "No")
+ if(confirmation == "Yes")
+ var/mob/living/carbon/human/oldleader = H.mind.nation.current_leader
+ oldleader << "You have been replaced by [H.name] as the leader of [H.mind.nation.current_name]!"
+ oldleader.verbs -= /mob/living/carbon/human/proc/set_nation_name
+ oldleader.verbs -= /mob/living/carbon/human/proc/set_ranks
+ oldleader.verbs -= /mob/living/carbon/human/proc/choose_heir
+ H.mind.nation.current_leader = H
+ H.mind.nation.heir = null
+ H.verbs -= /mob/living/carbon/human/proc/takeover
+ H.verbs += /mob/living/carbon/human/proc/set_nation_name
+ H.verbs += /mob/living/carbon/human/proc/set_ranks
+ H.verbs += /mob/living/carbon/human/proc/choose_heir
+ H << "You have replaced [oldleader.name] as the leader of [H.mind.nation.current_name]!"
+ H.mind.nation.update_nation_id()
+
+
+/datum/nations/proc/update_nation_id()
+ for(var/mob/living/carbon/human/M in membership)
+ for(var/obj/item/weapon/card/id/I in M.contents)
+ if(I.registered_name == M.real_name)
+ if(M == current_leader)
+ I.name = "[I.registered_name]'s ID Card ([current_name] [leader_rank])"
+ I.assignment = "[current_name] [leader_rank]"
+ else
+ I.name = "[I.registered_name]'s ID Card ([current_name] [member_rank])"
+ I.assignment = "[current_name] [member_rank]"
+
diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm
index c2c10c80758..d6f5f2e47fc 100644
--- a/code/game/gamemodes/shadowling/shadowling_abilities.dm
+++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm
@@ -99,6 +99,14 @@
if(F.on)
G.toggle_gunlight()
G.visible_message("[G]'s light fades and turns off.")
+ else if(istype(I, /obj/item/clothing/head/hardhat)) //There really needs to be a better way to handle this.
+ var/obj/item/clothing/head/hardhat/hhat = I
+ if(hhat.on)
+ hhat.on = 0
+ hhat.set_light(0)
+ hhat.icon_state = "hardhat0_[hhat.item_color]"
+ hhat.item_state = "hardhat0_[hhat.item_color]"
+ hhat.visible_message("[hhat]'s light fades and turns off.")
return I.light_range
/obj/effect/proc_holder/spell/aoe_turf/veil/proc/extinguishMob(var/mob/living/H)
diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm
index 1672fde7d02..7317450e02d 100644
--- a/code/game/machinery/camera/tracking.dm
+++ b/code/game/machinery/camera/tracking.dm
@@ -157,7 +157,7 @@
src.track = TB
return targets
-/mob/living/silicon/ai/proc/ai_camera_track(var/target_name in trackable_mobs())
+/mob/living/silicon/ai/proc/ai_camera_track(target_name in trackable_mobs())
set category = "AI Commands"
set name = "Track With Camera"
set desc = "Select who you would like to track."
@@ -187,7 +187,7 @@
U.cameraFollow = target
U << "Now tracking [target.name] on camera."
target.tracking_initiated()
-
+
spawn (0)
while (U.cameraFollow == target)
if (U.cameraFollow == null)
@@ -229,7 +229,7 @@
return 0
if(istype(M.loc,/obj/effect/dummy))
return 0
-
+
if((T && (T.z in config.contact_levels)) && ((hassensorlevel(M, SUIT_SENSOR_TRACKING) || M in aibots)))
return 1
@@ -259,4 +259,3 @@
tracking_entities--
if(!tracking_entities && has_zeroth_law())
src << "Internal camera is no longer being accessed."
-
\ No newline at end of file
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 325e01d2c52..fa58b9526fc 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -18,20 +18,10 @@
/obj/item/weapon/storage/fancy/crayons = 2,
/obj/item/toy/spinningtoy = 2,
/obj/item/toy/crossbow/tommygun = 2,
- /obj/item/toy/prize/ripley = 1,
- /obj/item/toy/prize/fireripley = 1,
- /obj/item/toy/prize/deathripley = 1,
- /obj/item/toy/prize/gygax = 1,
- /obj/item/toy/prize/durand = 1,
- /obj/item/toy/prize/honk = 1,
- /obj/item/toy/prize/marauder = 1,
- /obj/item/toy/prize/seraph = 1,
- /obj/item/toy/prize/mauler = 1,
- /obj/item/toy/prize/odysseus = 1,
- /obj/item/toy/prize/phazon = 1,
+ /obj/random/prize = 5,
/obj/item/toy/nuke = 2,
/obj/item/toy/cards/deck = 2,
- /obj/item/toy/carpplushie = 2,
+ /obj/random/carp_plushie = 2,
/obj/item/toy/minimeteor = 2,
/obj/item/toy/redbutton = 2,
/obj/item/toy/owl = 2,
@@ -47,7 +37,8 @@
/obj/item/toy/flash = 2,
/obj/item/toy/minigibber = 2,
/obj/item/toy/toy_xeno = 2,
- /obj/random/figure = 16
+ /obj/random/figure = 16,
+ /obj/random/plushie = 7,
)
/obj/machinery/computer/arcade/power_change()
diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm
index 54939994cef..ecbdf219cd3 100644
--- a/code/game/machinery/machinery.dm
+++ b/code/game/machinery/machinery.dm
@@ -149,15 +149,7 @@ Class Procs:
if(use_power && stat == 0)
use_power(7500/severity)
- var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( src.loc )
- pulse2.icon = 'icons/effects/effects.dmi'
- pulse2.icon_state = "empdisable"
- pulse2.name = "emp sparks"
- pulse2.anchored = 1
- pulse2.dir = pick(cardinal)
-
- spawn(10)
- pulse2.delete()
+ new/obj/effect/overlay/temp/emp(src.loc)
..()
/obj/machinery/ex_act(severity)
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index 008bc325714..eddbff40b5f 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -967,16 +967,16 @@
product_slogans = "THIS'S WHERE TH' SEEDS LIVE! GIT YOU SOME!;Hands down the best seed selection on the station!;Also certain mushroom varieties available, more for experts! Get certified today!"
product_ads = "We like plants!;Grow some crops!;Grow, baby, growww!;Aw h'yeah son!"
icon_state = "seeds"
- products = list(/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/appleseed = 3,/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,
+ products = list(/obj/item/seeds/aloeseed = 3,/obj/item/seeds/ambrosiavulgarisseed = 3,/obj/item/seeds/appleseed = 3,/obj/item/seeds/bananaseed = 3,/obj/item/seeds/berryseed = 3,
/obj/item/seeds/cabbageseed = 3,/obj/item/seeds/carrotseed = 3,/obj/item/seeds/cherryseed = 3,/obj/item/seeds/chantermycelium = 3,
- /obj/item/seeds/chiliseed = 3,/obj/item/seeds/cocoapodseed = 3,/obj/item/seeds/coffeeaseed = 3,/obj/item/seeds/cornseed = 3,
+ /obj/item/seeds/chiliseed = 3,/obj/item/seeds/cocoapodseed = 3,/obj/item/seeds/coffeeaseed = 3,/obj/item/seeds/comfreyseed =3,/obj/item/seeds/cornseed = 3,
/obj/item/seeds/eggplantseed = 3,/obj/item/seeds/grapeseed = 3,/obj/item/seeds/grassseed = 3,/obj/item/seeds/lemonseed = 3,
/obj/item/seeds/limeseed = 3,/obj/item/seeds/orangeseed = 3,/obj/item/seeds/peanutseed = 3,/obj/item/seeds/potatoseed = 3,/obj/item/seeds/poppyseed = 3,
/obj/item/seeds/pumpkinseed = 3,/obj/item/seeds/replicapod = 3,/obj/item/seeds/riceseed = 3,/obj/item/seeds/soyaseed = 3,/obj/item/seeds/sunflowerseed = 3,
/obj/item/seeds/teaasperaseed = 3,/obj/item/seeds/tobaccoseed = 3,/obj/item/seeds/tomatoseed = 3,
/obj/item/seeds/towermycelium = 3,/obj/item/seeds/watermelonseed = 3,/obj/item/seeds/wheatseed = 3,/obj/item/seeds/whitebeetseed = 3)
contraband = list(/obj/item/seeds/amanitamycelium = 2,/obj/item/seeds/glowshroom = 2,/obj/item/seeds/libertymycelium = 2,/obj/item/seeds/nettleseed = 2,
- /obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/reishimycelium = 2)
+ /obj/item/seeds/plumpmycelium = 2,/obj/item/seeds/random = 2, /obj/item/seeds/reishimycelium = 2)
premium = list(/obj/item/weapon/reagent_containers/spray/waterflower = 1)
/**
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
index e20010d0c2a..5fcdefe6215 100644
--- a/code/game/objects/effects/overlays.dm
+++ b/code/game/objects/effects/overlays.dm
@@ -19,6 +19,41 @@
..()
spawn(10) qdel(src)
+
+/obj/effect/overlay/temp
+ anchored = 1
+ layer = 4.1
+ mouse_opacity = 0
+ var/duration = 10
+ var/randomdir = 1
+
+/obj/effect/overlay/temp/New()
+ if(randomdir)
+ dir = pick(cardinal)
+ spawn(duration)
+ qdel(src)
+
+/obj/effect/overlay/temp/revenant
+ name = "spooky lights"
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "purplesparkles"
+
+/obj/effect/overlay/temp/revenant/cracks
+ name = "glowing cracks"
+ icon_state = "purplecrack"
+ duration = 6
+
+/obj/effect/overlay/temp/emp
+ name = "emp sparks"
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "empdisable"
+
+/obj/effect/overlay/temp/emp/pulse
+ name = "emp pulse"
+ icon_state = "emp pulse"
+ duration = 20
+ randomdir = 0
+
/obj/effect/overlay/palmtree_r
name = "Palm tree"
icon = 'icons/misc/beach2.dmi'
diff --git a/code/game/objects/empulse.dm b/code/game/objects/empulse.dm
index 8bff463e445..ed5bbadeadd 100644
--- a/code/game/objects/empulse.dm
+++ b/code/game/objects/empulse.dm
@@ -9,13 +9,7 @@ proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ")
if(heavy_range > 1)
- var/obj/effect/overlay/pulse = new/obj/effect/overlay ( epicenter )
- pulse.icon = 'icons/effects/effects.dmi'
- pulse.icon_state = "emppulse"
- pulse.name = "emp pulse"
- pulse.anchored = 1
- spawn(20)
- pulse.delete()
+ new/obj/effect/overlay/temp/emp/pulse(epicenter)
if(heavy_range > light_range)
light_range = heavy_range
diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm
index d40a9adb9d9..71c6be4d154 100644
--- a/code/game/objects/items/blueprints.dm
+++ b/code/game/objects/items/blueprints.dm
@@ -48,7 +48,7 @@
/obj/item/areaeditor/permit
name = "construction permit"
icon_state = "permit"
- desc = "This is a one-use permit that allows the user to offically declare a built room as new addition to the station."
+ desc = "This is a one-use permit that allows the user to officially declare a built room as new addition to the station."
fluffnotice = "Nanotrasen Engineering requires all on-station construction projects to be approved by a head of staff, as detailed in Nanotrasen Company Regulation 512-C (Mid-Shift Modifications to Company Property). \
By submitting this form, you accept any fines, fees, or personal injury/death that may occur during construction."
w_class = 1
@@ -57,7 +57,7 @@
. = ..()
var/area/A = get_area()
if(get_area_type() == AREA_STATION)
- . += "According to the [src], you are now in \"[A.name]\".
"
+ . += "According to the [src], you are now in \"[sanitize(A.name)]\".
"
var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500)
popup.set_content(.)
popup.open()
@@ -83,7 +83,7 @@
. = ..()
var/area/A = get_area()
if(get_area_type() == AREA_STATION)
- . += "According to the [src], you are now in \"[A.name]\".
"
+ . += "According to the [src], you are now in \"[sanitize(A.name)]\".
"
. += "You may move an amendment to the drawing.
"
var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500)
popup.set_content(.)
@@ -168,7 +168,7 @@
/obj/item/areaeditor/proc/edit_area()
var/area/A = get_area()
- var/prevname = "[A.name]"
+ var/prevname = "[sanitize(A.name)]"
var/str = trim(stripped_input(usr,"New area name:", "Blueprint Editing", prevname, MAX_NAME_LEN))
if(!str || !length(str) || str==prevname) //cancel
return
@@ -258,4 +258,4 @@
if(BORDER_SPACE)
return ROOM_ERR_SPACE
found+=T
- return found
\ No newline at end of file
+ return found
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index cfb3cd14c7c..85a664ad9fd 100755
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -849,7 +849,9 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/proc/create_message(var/mob/living/U = usr, var/obj/item/device/pda/P)
- var/t = input(U, "Please enter message", name, null) as text
+ var/t = input(U, "Please enter message", name, null) as text|null
+ if(!t)
+ return
t = sanitize(copytext(t, 1, MAX_MESSAGE_LEN))
t = readd_quotes(t)
if (!t || !istype(P))
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index 275c533958f..39196db70fa 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -111,15 +111,15 @@
else if(issilicon(M))
if(isrobot(M))
var/mob/living/silicon/robot/R = M
- if(R.activated(/obj/item/borg/combat/shield))
- add_logs(M, user, "flashed", object="[src.name]")
- user.visible_message("[user] tries to overloads [M]'s sensors with the [src.name], but if blocked by [M]'s shield!", "You try to overload [M]'s sensors with the [src.name], but are blocked by his shield!")
- return 1
- else
- M.Weaken(rand(5,10))
- add_logs(M, user, "flashed", object="[src.name]")
- user.visible_message("[user] overloads [M]'s sensors with the [src.name]!", "You overload [M]'s sensors with the [src.name]!")
- return 1
+ for(var/obj/item/borg/combat/shield/S in R.module.modules)
+ if(R.activated(S))
+ add_logs(M, user, "flashed", object="[src.name]")
+ user.visible_message("[user] tries to overloads [M]'s sensors with the [src.name], but if blocked by [M]'s shield!", "You try to overload [M]'s sensors with the [src.name], but are blocked by his shield!")
+ return 1
+ M.Weaken(rand(5,10))
+ add_logs(M, user, "flashed", object="[src.name]")
+ user.visible_message("[user] overloads [M]'s sensors with the [src.name]!", "You overload [M]'s sensors with the [src.name]!")
+ return 1
user.visible_message("[user] fails to blind [M] with the [src.name]!", "You fail to blind [M] with the [src.name]!")
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index f6f1fa5faa3..83043ed7770 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -118,20 +118,22 @@
else
user << "The [affecting.name] is cut open, you'll need more than some ointment!"
-/obj/item/stack/medical/bruise_pack/tajaran
- name = "\improper S'rendarr's Hand leaf"
- singular_name = "S'rendarr's Hand leaf"
+/obj/item/stack/medical/bruise_pack/comfrey
+ name = "\improper Comfrey leaf"
+ singular_name = "Comfrey leaf"
desc = "A soft leaf that is rubbed on bruises."
- icon = 'icons/obj/harvest.dmi'
- icon_state = "shand"
+ icon = 'icons/obj/hydroponics_products.dmi'
+ icon_state = "alien3-product"
+ color = "#378C61"
heal_brute = 7
-/obj/item/stack/medical/ointment/tajaran
- name = "\improper Messa's Tear leaf"
- singular_name = "Messa's Tear leaf"
+/obj/item/stack/medical/ointment/aloe
+ name = "\improper Aloe Vera leaf"
+ singular_name = "Aloe Vera leaf"
desc = "A cold leaf that is rubbed on burns."
- icon = 'icons/obj/harvest.dmi'
- icon_state = "mtear"
+ icon = 'icons/obj/hydroponics_products.dmi'
+ icon_state = "ambrosia-product"
+ color = "#4CC5C7"
heal_burn = 7
/obj/item/stack/medical/advanced/bruise_pack
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 7ebe3e2cfbb..41db700ac12 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -523,6 +523,15 @@
return
..()
+/obj/random/prize
+ name = "Random Mech Prize"
+ desc = "This is a random prize"
+ icon = 'icons/obj/toy.dmi'
+ icon_state = "ripleytoy"
+
+/obj/random/prize/item_to_spawn()
+ return pick(subtypesof(/obj/item/toy/prize)) //exclude the base type.
+
/obj/item/toy/prize/ripley
name = "toy ripley"
desc = "Mini-Mecha action figure! Collect them all! 1/11."
@@ -1096,6 +1105,167 @@ obj/item/toy/cards/deck/syndicate/black
playsound(src.loc, bitesound, 20, 1)
return ..()
+
+/obj/random/carp_plushie
+ name = "Random Carp Plushie"
+ desc = "This is a random plushie"
+ icon = 'icons/obj/toy.dmi'
+ icon_state = "carpplushie"
+
+/obj/random/carp_plushie/item_to_spawn()
+ return pick(typesof(/obj/item/toy/carpplushie)) //can pick any carp plushie, even the original.
+
+/obj/item/toy/carpplushie/ice
+ icon_state = "icecarp"
+
+/obj/item/toy/carpplushie/silent
+ icon_state = "silentcarp"
+
+/obj/item/toy/carpplushie/electric
+ icon_state = "electriccarp"
+
+/obj/item/toy/carpplushie/gold
+ icon_state = "goldcarp"
+
+/obj/item/toy/carpplushie/toxin
+ icon_state = "toxincarp"
+
+/obj/item/toy/carpplushie/dragon
+ icon_state = "dragoncarp"
+
+/obj/item/toy/carpplushie/pink
+ icon_state = "pinkcarp"
+
+/obj/item/toy/carpplushie/candy
+ icon_state = "candycarp"
+
+/obj/item/toy/carpplushie/nebula
+ icon_state = "nebulacarp"
+
+/obj/item/toy/carpplushie/void
+ icon_state = "voidcarp"
+
+/*
+ * Plushie
+ */
+
+
+/obj/item/toy/plushie
+ name = "plushie"
+ desc = "An adorable, soft, and cuddly plushie."
+ icon = 'icons/obj/toy.dmi'
+ var/poof_sound = 'sound/weapons/thudswoosh.ogg'
+ attack_verb = list("poofed", "bopped", "whapped","cuddled","fluffed")
+
+/obj/item/toy/plushie/attack(mob/M as mob, mob/user as mob)
+ playsound(loc, poof_sound, 20, 1) // Play the whoosh sound in local area
+ return ..()
+
+/obj/item/toy/plushie/attack_self(mob/user as mob)
+ var/cuddle_verb = pick("hugs","cuddles","snugs")
+ user.visible_message("[user] [cuddle_verb] the [src].")
+ playsound(get_turf(src), poof_sound, 50, 1, -1)
+ return ..()
+
+/obj/random/plushie
+ name = "Random Plushie"
+ desc = "This is a random plushie"
+ icon = 'icons/obj/toy.dmi'
+ icon_state = "redfox"
+
+/obj/random/plushie/item_to_spawn()
+ return pick(subtypesof(/obj/item/toy/plushie)) //exclude the base type.
+
+/obj/item/toy/plushie/corgi
+ name = "corgi plushie"
+ icon_state = "corgi"
+
+/obj/item/toy/plushie/girly_corgi
+ name = "corgi plushie"
+ icon_state = "girlycorgi"
+
+/obj/item/toy/plushie/robo_corgi
+ name = "borgi plushie"
+ icon_state = "robotcorgi"
+
+/obj/item/toy/plushie/octopus
+ name = "octopus plushie"
+ icon_state = "loveable"
+
+/obj/item/toy/plushie/face_hugger
+ name = "facehugger plushie"
+ icon_state = "huggable"
+
+//foxes are basically the best
+
+/obj/item/toy/plushie/red_fox
+ name = "red fox plushie"
+ icon_state = "redfox"
+
+/obj/item/toy/plushie/black_fox
+ name = "black fox plushie"
+ icon_state = "blackfox"
+
+/obj/item/toy/plushie/marble_fox
+ name = "marble fox plushie"
+ icon_state = "marblefox"
+
+/obj/item/toy/plushie/blue_fox
+ name = "blue fox plushie"
+ icon_state = "bluefox"
+
+/obj/item/toy/plushie/orange_fox
+ name = "orange fox plushie"
+ icon_state = "orangefox"
+
+/obj/item/toy/plushie/coffee_fox
+ name = "coffee fox plushie"
+ icon_state = "coffeefox"
+
+/obj/item/toy/plushie/pink_fox
+ name = "pink fox plushie"
+ icon_state = "pinkfox"
+
+/obj/item/toy/plushie/purple_fox
+ name = "purple fox plushie"
+ icon_state = "purplefox"
+
+/obj/item/toy/plushie/crimson_fox
+ name = "crimson fox plushie"
+ icon_state = "crimsonfox"
+
+/obj/item/toy/plushie/deer
+ name = "deer plushie"
+ icon_state = "deer"
+
+/obj/item/toy/plushie/black_cat
+ name = "black cat plushie"
+ icon_state = "blackcat"
+
+/obj/item/toy/plushie/grey_cat
+ name = "grey cat plushie"
+ icon_state = "greycat"
+
+/obj/item/toy/plushie/white_cat
+ name = "white cat plushie"
+ icon_state = "whitecat"
+
+/obj/item/toy/plushie/orange_cat
+ name = "orange cat plushie"
+ icon_state = "orangecat"
+
+/obj/item/toy/plushie/siamese_cat
+ name = "siamese cat plushie"
+ icon_state = "siamesecat"
+
+/obj/item/toy/plushie/tabby_cat
+ name = "tabby cat plushie"
+ icon_state = "tabbycat"
+
+/obj/item/toy/plushie/tuxedo_cat
+ name = "tuxedo cat plushie"
+ icon_state = "tuxedocat"
+
/*
* Foam Armblade
*/
diff --git a/code/game/objects/items/weapons/cash.dm b/code/game/objects/items/weapons/cash.dm
index be8cc69f39f..8cdc276ef6a 100644
--- a/code/game/objects/items/weapons/cash.dm
+++ b/code/game/objects/items/weapons/cash.dm
@@ -1,7 +1,10 @@
var/global/list/moneytypes=list(
/obj/item/weapon/spacecash/c1000 = 1000,
- /obj/item/weapon/spacecash/c500 = 500, // Might get rid of this.
+ /obj/item/weapon/spacecash/c500 = 500,
+ /obj/item/weapon/spacecash/c200 = 200,
/obj/item/weapon/spacecash/c100 = 100,
+ /obj/item/weapon/spacecash/c50 = 50,
+ /obj/item/weapon/spacecash/c20 = 20,
/obj/item/weapon/spacecash/c10 = 10,
/obj/item/weapon/spacecash = 1,
)
@@ -42,19 +45,36 @@ var/global/list/moneytypes=list(
/obj/item/weapon/spacecash/update_icon()
icon_state = "cash[worth]"
// Up to 100 items per stack.
- overlays = 0
- var/stacksize=round(amount/25)
pixel_x=rand(-7,7)
pixel_y=rand(-14,14)
- if(stacksize)
- // 0 = single
- // 1 = 1/4 stack
- // 2 = 1/2 stack
- // 3 = 3/4 stack
- // 4 = full stack
- var/image/stack = image(icon,icon_state="cashstack[stacksize]")
- stack.color=stack_color
- overlays += stack
+
+/obj/item/weapon/spacecash/proc/collect_from(var/obj/item/weapon/spacecash/cash)
+ if(cash.worth == src.worth)
+ var/taking = min(100-src.amount,cash.amount)
+ cash.amount -= taking
+ src.amount += taking
+ if(cash.amount <= 0)
+ qdel(cash)
+ return taking
+ return 0
+
+/obj/item/weapon/spacecash/afterattack(atom/A as mob|obj, mob/user as mob)
+ if(istype(A, /turf) || istype(A, /obj/structure/table) || istype(A, /obj/structure/rack))
+ var/turf/T = get_turf(A)
+ var/collected = 0
+ for(var/obj/item/weapon/spacecash/cash in T)
+ if(cash.worth == src.worth)
+ collected += collect_from(cash)
+ if(collected)
+ update_icon()
+ user << "You add [collected] credit [amount > 1 ? "chips":"chip"] to your stack of cash."
+ else if(istype(A,/obj/item/weapon/spacecash))
+ var/obj/item/weapon/spacecash/cash = A
+ var/collected = src.collect_from(cash)
+ if(collected)
+ update_icon()
+ user << "You add [collected] credit [amount > 1 ? "chips":"chip"] to your stack of cash."
+
/obj/item/weapon/spacecash/proc/get_total()
return worth * amount
@@ -62,37 +82,30 @@ var/global/list/moneytypes=list(
/obj/item/weapon/spacecash/c10
icon_state = "cash10"
worth = 10
- stack_color = "#663200"
/obj/item/weapon/spacecash/c20
icon_state = "cash10"
worth = 20
- stack_color = "#663200"
/obj/item/weapon/spacecash/c50
icon_state = "cash10"
worth = 50
- stack_color = "#663200"
/obj/item/weapon/spacecash/c100
icon_state = "cash100"
worth = 100
- stack_color = "#663200"
/obj/item/weapon/spacecash/c200
icon_state = "cash200"
worth = 200
- stack_color = "#663200"
/obj/item/weapon/spacecash/c500
icon_state = "cash500"
worth = 500
- stack_color = "#663200"
/obj/item/weapon/spacecash/c1000
icon_state = "cash1000"
worth = 1000
- stack_color = "#333333"
/proc/dispense_cash(var/amount, var/loc)
for(var/cashtype in moneytypes)
diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm
index 6d36129773a..eae015b09e7 100644
--- a/code/game/objects/items/weapons/dna_injector.dm
+++ b/code/game/objects/items/weapons/dna_injector.dm
@@ -94,6 +94,9 @@
return uses
/obj/item/weapon/dnainjector/attack(mob/M as mob, mob/user as mob)
+ if(!M.dna) //You know what would be nice? If the mob you're injecting has DNA, and so doesn't cause runtimes.
+ return 0
+
if(ishuman(M)) // Would've done this via species instead of type, but the basic mob doesn't have a species, go figure.
var/mob/living/carbon/human/H = M
if(H.species.flags & NO_DNA_RAD)
diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm
index 2d70a119b0d..dd182d394aa 100644
--- a/code/game/objects/items/weapons/explosives.dm
+++ b/code/game/objects/items/weapons/explosives.dm
@@ -62,7 +62,9 @@
..()
/obj/item/weapon/c4/attack_self(mob/user as mob)
- var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num
+ var/newtime = input(usr, "Please set the timer.", "Timer", 10) as num|null
+ if(newtime == null)
+ return
if(newtime < 10)
newtime = 10
if(newtime > 60000)
diff --git a/code/game/objects/items/weapons/hydroponics.dm b/code/game/objects/items/weapons/hydroponics.dm
deleted file mode 100644
index f1b04b9ed98..00000000000
--- a/code/game/objects/items/weapons/hydroponics.dm
+++ /dev/null
@@ -1,240 +0,0 @@
-/* Hydroponic stuff
- * Contains:
- * Sunflowers
- * Nettle
- * Deathnettle
- * Corbcob
- */
-
-
-
-/*
- * SeedBag
- */
-//uncomment when this is updated to match storage update
-/*
-/obj/item/weapon/seedbag
- icon = 'icons/obj/hydroponics.dmi'
- icon_state = "seedbag"
- name = "Seed Bag"
- desc = "A small satchel made for organizing seeds."
- var/mode = 1; //0 = pick one at a time, 1 = pick all on tile
- var/capacity = 500; //the number of seeds it can carry.
- slot_flags = SLOT_BELT
- w_class = 1
- var/list/item_quants = list()
-
-/obj/item/weapon/seedbag/attack_self(mob/user as mob)
- user.machine = src
- interact(user)
-
-/obj/item/weapon/seedbag/verb/toggle_mode()
- set name = "Switch Bagging Method"
- set category = "Object"
-
- mode = !mode
- switch (mode)
- if(1)
- usr << "The bag now picks up all seeds in a tile at once."
- if(0)
- usr << "The bag now picks up one seed pouch at a time."
-
-/obj/item/seeds/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
- ..()
- if (istype(O, /obj/item/weapon/seedbag))
- var/obj/item/weapon/seedbag/S = O
- if (S.mode == 1)
- for (var/obj/item/seeds/G in locate(src.x,src.y,src.z))
- if (S.contents.len < S.capacity)
- S.contents += G;
- if(S.item_quants[G.name])
- S.item_quants[G.name]++
- else
- S.item_quants[G.name] = 1
- else
- user << "\blue The seed bag is full."
- S.updateUsrDialog()
- return
- user << "\blue You pick up all the seeds."
- else
- if (S.contents.len < S.capacity)
- S.contents += src;
- if(S.item_quants[name])
- S.item_quants[name]++
- else
- S.item_quants[name] = 1
- else
- user << "\blue The seed bag is full."
- S.updateUsrDialog()
- return
-
-/obj/item/weapon/seedbag/interact(mob/user as mob)
-
- var/dat = "Select an item:
"
-
- if (contents.len == 0)
- dat += "No seeds loaded!"
- else
- for (var/O in item_quants)
- if(item_quants[O] > 0)
- var/N = item_quants[O]
- dat += "[capitalize(O)]:"
- dat += " [N] "
- dat += "Vend"
- dat += "
"
-
- dat += "
Unload All"
- dat += ""
- user << browse("Seedbag Supplies[dat]", "window=seedbag")
- onclose(user, "seedbag")
- return
-
-/obj/item/weapon/seedbag/Topic(href, href_list)
- if(..())
- return
-
- usr.machine = src
- if ( href_list["vend"] )
- var/N = href_list["vend"]
-
- if(item_quants[N] <= 0) // Sanity check, there are probably ways to press the button when it shouldn't be possible.
- return
-
- item_quants[N] -= 1
- for(var/obj/O in contents)
- if(O.name == N)
- O.loc = get_turf(src)
- usr.put_in_hands(O)
- break
-
- else if ( href_list["unload"] )
- item_quants.Cut()
- for(var/obj/O in contents )
- O.loc = get_turf(src)
-
- src.updateUsrDialog()
- return
-
-/obj/item/weapon/seedbag/updateUsrDialog()
- var/list/nearby = range(1, src)
- for(var/mob/M in nearby)
- if ((M.client && M.machine == src))
- src.attack_self(M)
-*/
-/*
- * Sunflower
- */
-
-/obj/item/weapon/grown/sunflower/attack(mob/M as mob, mob/user as mob)
- M << " [user] smacks you with a sunflower!FLOWER POWER"
- user << " Your sunflower's FLOWER POWER strikes [M]"
-
-/*
- * Sun/Novaflower
- */
-/obj/item/weapon/grown/novaflower/attack(mob/M as mob, mob/user as mob)
- M << " [user] smacks you with a novaflower!FLOWER POWER"
- user << " Your novaflower's FLOWER POWER strikes [M]"
-
-/obj/item/weapon/grown/novaflower/attack(mob/living/carbon/M as mob, mob/user as mob)
- if(!..()) return
- if(istype(M, /mob/living))
- M << "\red You are heated by the warmth of the of the [name]!"
- M.bodytemperature += potency/2 * TEMPERATURE_DAMAGE_COEFFICIENT
-
-/obj/item/weapon/grown/novaflower/pickup(mob/living/carbon/human/user as mob)
- if(!user.gloves)
- user << "\red The [name] burns your bare hand!"
- user.adjustFireLoss(rand(1,5))
-/*
-/*
- * Nettle
- */
-/obj/item/weapon/grown/nettle/pickup(mob/living/carbon/human/user as mob)
- if(!user.gloves)
- user << "\red The nettle burns your bare hand!"
- if(istype(user, /mob/living/carbon/human))
- var/organ = ((user.hand ? "l_":"r_") + "arm")
- var/obj/item/organ/external/affecting = user.get_organ(organ)
- if(affecting.take_damage(0,force))
- user.UpdateDamageIcon()
- else
- user.take_organ_damage(0,force)
-
-/obj/item/weapon/grown/nettle/afterattack(atom/A as mob|obj, mob/user as mob, proximity)
- if(!proximity) return
- if(force > 0)
- force -= rand(1,(force/3)+1) // When you whack someone with it, leaves fall off
- playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
- else
- usr << "All the leaves have fallen off the nettle from violent whacking."
- qdel(src)
-
-/obj/item/weapon/grown/nettle/changePotency(newValue) //-QualityVan
- potency = newValue
- force = round((5+potency/5), 1)
-
-/*
- * Deathnettle
- */
-
-/obj/item/weapon/grown/deathnettle/pickup(mob/living/carbon/human/user as mob)
- if(!user.gloves)
- if(istype(user, /mob/living/carbon/human))
- var/organ = ((user.hand ? "l_":"r_") + "arm")
- var/obj/item/organ/external/affecting = user.get_organ(organ)
- if(affecting.take_damage(0,force))
- user.UpdateDamageIcon()
- else
- user.take_organ_damage(0,force)
- if(prob(50))
- user.Paralyse(5)
- user << "\red You are stunned by the Deathnettle when you try picking it up!"
-
-/obj/item/weapon/grown/deathnettle/attack(mob/living/carbon/M as mob, mob/user as mob)
- if(!..()) return
- if(istype(M, /mob/living))
- M << "\red You are stunned by the powerful acid of the Deathnettle!"
-
- M.attack_log += text("\[[time_stamp()]\] Had the [src.name] used on them by [key_name(user)]")
- user.attack_log += text("\[[time_stamp()]\] Used the [src.name] on [key_name(M)]")
- msg_admin_attack("[key_name_admin(user)] used the [src.name] on [key_name_admin(M)]")
-
- if(!iscarbon(user))
- M.LAssailant = null
- else
- M.LAssailant = user
-
- playsound(loc, 'sound/weapons/bladeslice.ogg', 50, 1, -1)
-
- M.eye_blurry += force/7
- if(prob(20))
- M.Paralyse(force/6)
- M.Weaken(force/15)
- M.drop_item()
-
-/obj/item/weapon/grown/deathnettle/afterattack(atom/A as mob|obj, mob/user as mob, proximity)
- if(!proximity) return
- if (force > 0)
- force -= rand(1,(force/3)+1) // When you whack someone with it, leaves fall off
-
- else
- usr << "All the leaves have fallen off the deathnettle from violent whacking."
- qdel(src)
-
-/obj/item/weapon/grown/deathnettle/changePotency(newValue) //-QualityVan
- potency = newValue
- force = round((5+potency/2.5), 1)
-
-
-/*
- * Corncob
- */
-/obj/item/weapon/corncob/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
- ..()
- if(istype(W, /obj/item/weapon/circular_saw) || istype(W, /obj/item/weapon/hatchet) || istype(W, /obj/item/weapon/kitchen/utensil/knife) || istype(W, /obj/item/weapon/kitchenknife) || istype(W, /obj/item/weapon/kitchenknife/ritual))
- user << "You use [W] to fashion a pipe out of the corn cob!"
- new /obj/item/clothing/mask/cigarette/pipe/cobpipe (user.loc)
- qdel(src)
- return
-*/
\ No newline at end of file
diff --git a/code/game/objects/items/weapons/shards.dm b/code/game/objects/items/weapons/shards.dm
index df8c9fc329c..70513198e39 100644
--- a/code/game/objects/items/weapons/shards.dm
+++ b/code/game/objects/items/weapons/shards.dm
@@ -53,6 +53,8 @@
/obj/item/weapon/shard/Crossed(AM as mob|obj)
if(isliving(AM))
var/mob/living/M = AM
+ if (M.incorporeal_move || M.flying)//you are incorporal or flying..no shard stepping!
+ return
M << "\red You step on \the [src]!"
playsound(src.loc, 'sound/effects/glass_step.ogg', 50, 1) // not sure how to handle metal shards with sounds
if(ishuman(M))
diff --git a/code/game/objects/items/weapons/teleportation.dm b/code/game/objects/items/weapons/teleportation.dm
index 637e882bdbb..d079ecd47dd 100644
--- a/code/game/objects/items/weapons/teleportation.dm
+++ b/code/game/objects/items/weapons/teleportation.dm
@@ -127,8 +127,8 @@ Frequency:
turfs += T
if(turfs.len)
L["None (Dangerous)"] = pick(turfs)
- var/t1 = input(user, "Please select a teleporter to lock in on.", "Hand Teleporter") in L
- if ((user.get_active_hand() != src || user.stat || user.restrained()))
+ var/t1 = input(user, "Please select a teleporter to lock in on.", "Hand Teleporter") as null|anything in L
+ if (!t1 || (user.get_active_hand() != src || user.stat || user.restrained()))
return
if(active_portals >= 3)
user.show_message("\The [src] is recharging!")
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index aa7f18ef335..fad18f5e176 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -561,11 +561,19 @@
New()
..()
- new /obj/item/weapon/reagent_containers/spray/plantbgone(src)
- new /obj/item/weapon/reagent_containers/spray/plantbgone(src)
- new /obj/item/weapon/minihoe(src)
-// new /obj/item/weapon/weedspray(src)
-// new /obj/item/weapon/weedspray(src)
-// new /obj/item/weapon/pestspray(src)
-// new /obj/item/weapon/pestspray(src)
-// new /obj/item/weapon/pestspray(src)
+ new /obj/item/weapon/reagent_containers/glass/bucket(src)
+ new /obj/item/weapon/reagent_containers/glass/bucket(src)
+ new /obj/item/weapon/screwdriver(src)
+ new /obj/item/weapon/screwdriver(src)
+ new /obj/item/weapon/wrench(src)
+ new /obj/item/weapon/wrench(src)
+ new /obj/item/weapon/wirecutters(src)
+ new /obj/item/weapon/wirecutters(src)
+ new /obj/item/weapon/shovel/spade(src)
+ new /obj/item/weapon/shovel/spade(src)
+ new /obj/item/weapon/storage/box/botanydisk(src)
+ new /obj/item/weapon/storage/box/botanydisk(src)
+ new /obj/item/weapon/storage/box/beakers(src)
+ new /obj/item/weapon/storage/box/beakers(src)
+ new /obj/item/weapon/hand_labeler(src)
+ new /obj/item/weapon/hand_labeler(src)
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index b7f2f2d91bb..902257ae2db 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -18,10 +18,11 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
var/list/type = list("Question","Player Complaint")
var/selected_type = input("Pick a category.", "Admin Help", null, null) as null|anything in type
if(selected_type)
- msg = input("Please enter your message.", "Admin Help", null, null) as text
+ msg = input("Please enter your message.", "Admin Help", null, null) as text|null
- //clean the input msg
- if(!msg) return
+ //clean the input msg
+ if(!msg)
+ return
if(src.handle_spam_prevention(msg,MUTE_ADMINHELP))
return
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index e047a9c6497..b9a8991e5af 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -1,7 +1,7 @@
/client/proc/cmd_admin_drop_everything(mob/M as mob in mob_list)
set category = null
set name = "Drop Everything"
-
+
if(!check_rights(R_DEBUG|R_ADMIN))
return
@@ -19,10 +19,10 @@
/client/proc/cmd_admin_prison(mob/M as mob in mob_list)
set category = "Admin"
set name = "Prison"
-
+
if(!check_rights(R_ADMIN))
return
-
+
if (ismob(M))
if(istype(M, /mob/living/silicon/ai))
alert("The AI can't be sent to prison you jerk!", null, null, null, null, null)
@@ -48,10 +48,10 @@
set category = "Event"
set name = "Subtle Message"
- if(!ismob(M))
+ if(!ismob(M))
return
- if(!check_rights(R_SERVER|R_EVENT))
+ if(!check_rights(R_SERVER|R_EVENT))
return
var/msg = input("Message:", text("Subtle PM to [M.key]")) as text
@@ -70,7 +70,7 @@
/client/proc/cmd_mentor_check_new_players() //Allows mentors / admins to determine who the newer players are.
set category = "Admin"
set name = "Check new Players"
-
+
if(!check_rights(R_MENTOR|R_MOD|R_ADMIN))
return
@@ -103,7 +103,7 @@
set category = "Event"
set name = "Global Narrate"
- if(!check_rights(R_SERVER|R_EVENT))
+ if(!check_rights(R_SERVER|R_EVENT))
return
var/msg = input("Message:", text("Enter the text you wish to appear to everyone:")) as text
@@ -119,7 +119,7 @@
set category = "Event"
set name = "Direct Narrate"
- if(!check_rights(R_SERVER|R_EVENT))
+ if(!check_rights(R_SERVER|R_EVENT))
return
if(!M)
@@ -141,10 +141,10 @@
/client/proc/cmd_admin_godmode(mob/M as mob in mob_list)
set category = "Special Verbs"
set name = "Godmode"
-
+
if(!check_rights(R_ADMIN))
return
-
+
M.status_flags ^= GODMODE
usr << "\blue Toggled [(M.status_flags & GODMODE) ? "ON" : "OFF"]"
@@ -155,7 +155,7 @@
proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
if(automute)
- if(!config.automute_on)
+ if(!config.automute_on)
return
else
if(!usr || !usr.client)
@@ -165,7 +165,7 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
return
if(!M.client)
usr << "Error: cmd_admin_mute: This mob doesn't have a client tied to it."
- if(!M.client)
+ if(!M.client)
return
var/muteunmute
@@ -204,10 +204,10 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
/client/proc/cmd_admin_add_random_ai_law()
set category = "Event"
set name = "Add Random AI Law"
-
+
if(!check_rights(R_EVENT))
return
-
+
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
if(confirm != "Yes") return
log_admin("[key_name(src)] has added a random AI law.")
@@ -226,7 +226,7 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
if(!check_rights(R_SERVER))
return
-
+
var/action=""
if(config.antag_hud_allowed)
for(var/mob/dead/observer/g in get_ghosts())
@@ -256,10 +256,10 @@ proc/cmd_admin_mute(mob/M as mob, mute_type, automute = 0)
set category = "Server"
set name = "Toggle antagHUD Restrictions"
set desc = "Restricts players that have used antagHUD from being able to join this round."
-
+
if(!check_rights(R_SERVER))
return
-
+
var/action=""
if(config.antag_hud_restricted)
for(var/mob/dead/observer/g in get_ghosts())
@@ -289,10 +289,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Special Verbs"
set name = "Respawn Character"
set desc = "Respawn a person that has been gibbed/dusted/killed. They must be a ghost for this to work and preferably should not have a body to go back into."
-
+
if(!check_rights(R_SPAWN))
return
-
+
var/input = ckey(input(src, "Please specify which key will be respawned.", "Key", ""))
if(!input)
return
@@ -469,7 +469,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
new_xeno.ckey = ckey
message_admins("\blue [key_name_admin(usr)] has spawned [ckey] as a filthy xeno [alien_caste].", 1)
return 1
-
+
/client/proc/get_ghosts(var/notify = 0,var/what = 2)
// what = 1, return ghosts ass list.
@@ -493,15 +493,15 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(what==1)
return ghosts
else
- return mobs
-
+ return mobs
+
/client/proc/cmd_admin_add_freeform_ai_law()
set category = "Event"
set name = "Add Custom AI law"
-
+
if(!check_rights(R_EVENT))
return
-
+
var/input = input(usr, "Please enter anything you want the AI to do. Anything. Serious.", "What?", "") as text|null
if(!input)
return
@@ -519,10 +519,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/cmd_admin_rejuvenate(mob/living/M as mob in mob_list)
set category = "Special Verbs"
set name = "Rejuvenate"
-
+
if(!check_rights(R_REJUVINATE))
return
-
+
if(!mob)
return
if(!istype(M))
@@ -536,37 +536,65 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/cmd_admin_create_centcom_report()
set category = "Event"
- set name = "Create Command Report"
-
- if(!check_rights(R_SERVER|R_EVENT))
+ set name = "Create Communications Report"
+ var/list/MsgType = list("Centcom Report","Enemy Communications")
+ if(!check_rights(R_SERVER|R_EVENT))
return
+ var/type = input(usr, "Pick a type of report to send", "Report Type", "") as anything in MsgType
var/input = input(usr, "Please enter anything you want. Anything. Serious.", "What?", "") as message|null
var/customname = input(usr, "Pick a title for the report.", "Title") as text|null
if(!input)
return
- if(!customname)
- customname = "Nanotrasen Update"
- for (var/obj/machinery/computer/communications/C in machines)
- if(! (C.stat & (BROKEN|NOPOWER) ) )
- var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc )
- P.name = "'[command_name()] Update.'"
- P.info = input
- P.update_icon()
- C.messagetitle.Add("[command_name()] Update")
- C.messagetext.Add(P.info)
- switch(alert("Should this be announced to the general population?",,"Yes","No"))
- if("Yes")
- command_announcement.Announce(input, customname);
- if("No")
- world << "\red New Nanotrasen Update available at all communication consoles."
+ if(type == "Enemy Communications")
+ if(!customname)
+ customname = type
- world << sound('sound/AI/commandreport.ogg')
- log_admin("[key_name(src)] has created a command report: [input]")
- message_admins("[key_name_admin(src)] has created a command report", 1)
+ var/from = input(usr, "What kind of report? Example: Syndicate Communique", "From") as text|null
+ if(!from)
+ from = "Syndicate Communique"
+ switch(alert("Should this be announced to the general population?",,"Yes","No"))
+ if("Yes")
+ communications_announcement.Announce(input, customname, , , , from);
+ if("No")
+ world << "\red [from] available at all communications consoles."
+
+ for (var/obj/machinery/computer/communications/C in machines)
+ if(! (C.stat & (BROKEN|NOPOWER) ) )
+ var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc )
+ P.name = "[from]"
+ P.info = input
+ P.update_icon()
+ C.messagetitle.Add("[from]")
+ C.messagetext.Add(P.info)
+
+
+ if(type == "Centcom Report")
+ if(!customname)
+ customname = "Nanotrasen Update"
+
+ switch(alert("Should this be announced to the general population?",,"Yes","No"))
+ if("Yes")
+ command_announcement.Announce(input, customname);
+ if("No")
+ world << "\red New Nanotrasen Update available at all communication consoles."
+
+ for (var/obj/machinery/computer/communications/C in machines)
+ if(! (C.stat & (BROKEN|NOPOWER) ) )
+ var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc )
+ P.name = "'[command_name()] Update.'"
+ P.info = input
+ P.update_icon()
+ C.messagetitle.Add("[command_name()] Update")
+ C.messagetext.Add(P.info)
+
+ //world << sound('sound/AI/commandreport.ogg')
+ log_admin("[key_name(src)] has created a communications report: [input]")
+ message_admins("[key_name_admin(src)] has created a communications report", 1)
feedback_add_details("admin_verb","CCR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
/client/proc/cmd_admin_delete(atom/O as obj|mob|turf in view())
set category = "Admin"
set name = "Delete"
@@ -590,7 +618,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!check_rights(R_ADMIN))
return
-
+
if(job_master)
for(var/datum/job/job in job_master.occupations)
src << "[job.title]: [job.total_positions]"
@@ -600,7 +628,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Event"
set name = "Explosion"
- if(!check_rights(R_DEBUG|R_EVENT))
+ if(!check_rights(R_DEBUG|R_EVENT))
return
var/devastation = input("Range of total devastation. -1 to none", text("Input")) as num|null
@@ -631,7 +659,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Special Verbs"
set name = "EM Pulse"
- if(!check_rights(R_DEBUG|R_EVENT))
+ if(!check_rights(R_DEBUG|R_EVENT))
return
var/heavy = input("Range of heavy pulse.", text("Input")) as num|null
@@ -654,7 +682,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Special Verbs"
set name = "Gib"
- if(!check_rights(R_ADMIN|R_EVENT))
+ if(!check_rights(R_ADMIN|R_EVENT))
return
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
@@ -677,8 +705,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Event"
if(!check_rights(R_ADMIN|R_EVENT))
- return
-
+ return
+
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
if(confirm == "Yes")
if (istype(mob, /mob/dead/observer)) // so they don't spam gibs everywhere
@@ -693,7 +721,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/cmd_admin_check_contents(mob/living/M as mob in mob_list)
set category = "Special Verbs"
set name = "Check Contents"
-
+
if(!check_rights(R_ADMIN))
return
@@ -706,7 +734,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Special Verbs"
set name = "Change View Range"
set desc = "switches between 1x and custom views"
-
+
if(!check_rights(R_ADMIN))
return
@@ -727,7 +755,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if ((!( ticker ) || !emergency_shuttle.location()))
return
- if(!check_rights(R_ADMIN))
+ if(!check_rights(R_ADMIN))
return
var/confirm = alert(src, "You sure?", "Confirm", "Yes", "No")
@@ -743,8 +771,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
choice = input("The shuttle will not be able to leave if you call it. Call anyway?") in list("Confirm", "Cancel")
if(choice != "Confirm")
return
-
-
+
+
choice = input("Is this an emergency evacuation or a crew transfer?") in list("Emergency", "Crew Transfer")
if (choice == "Emergency")
@@ -763,7 +791,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set category = "Admin"
set name = "Cancel Shuttle"
- if(!check_rights(R_ADMIN))
+ if(!check_rights(R_ADMIN))
return
if(alert(src, "You sure?", "Confirm", "Yes", "No") != "Yes") return
@@ -785,7 +813,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if (!ticker)
return
- if(!check_rights(R_ADMIN))
+ if(!check_rights(R_ADMIN))
return
emergency_shuttle.deny_shuttle = !emergency_shuttle.deny_shuttle
@@ -798,8 +826,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
set name = "Attack Log"
if(!check_rights(R_ADMIN))
- return
-
+ return
+
usr << text("\red Attack Log for []", mob)
for(var/t in M.attack_log)
usr << t
@@ -811,7 +839,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set name = "Make Everyone Random"
set desc = "Make everyone have a random appearance. You can only use this before rounds!"
- if(!check_rights(R_SERVER|R_EVENT))
+ if(!check_rights(R_SERVER|R_EVENT))
return
if (ticker && ticker.mode)
@@ -845,7 +873,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set name = "Toggle random events on/off"
set desc = "Toggles random events such as meteors, black holes, blob (but not space dust) on/off"
- if(!check_rights(R_SERVER|R_EVENT))
+ if(!check_rights(R_SERVER|R_EVENT))
return
if(!config.allow_random_events)
@@ -863,7 +891,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
set name = "Toggle ERT"
set desc = "Toggle the station's ability to call a response team."
- if(!check_rights(R_EVENT))
+ if(!check_rights(R_EVENT))
return
if(ticker.mode.ert_disabled)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index b1c8e53ff1f..324b5e7b427 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -1040,7 +1040,7 @@ datum/preferences
if("input")
switch(href_list["preference"])
if("name")
- var/raw_name = input(user, "Choose your character's name:", "Character Preference") as text|null
+ var/raw_name = input(user, "Choose your character's name:", "Character Preference") as text|null
if (!isnull(raw_name)) // Check to ensure that the user entered text (rather than cancel.)
var/new_name = reject_bad_name(raw_name)
if(new_name)
@@ -1108,6 +1108,19 @@ datum/preferences
//this shouldn't happen
f_style = facial_hair_styles_list["Shaved"]
+ // Don't wear another species' underwear!
+ var/datum/sprite_accessory/S = underwear_list[underwear]
+ if(!(species in S.species_allowed))
+ underwear = random_underwear(gender, species)
+
+ S = undershirt_list[undershirt]
+ if(!(species in S.species_allowed))
+ undershirt = random_undershirt(gender, species)
+
+ S = socks_list[socks]
+ if(!(species in S.species_allowed))
+ socks = random_socks(gender, species)
+
//reset hair colour and skin colour
r_hair = 0//hex2num(copytext(new_hair, 2, 4))
g_hair = 0//hex2num(copytext(new_hair, 4, 6))
@@ -1156,7 +1169,7 @@ datum/preferences
var/input = "Choose your character's hair colour:"
if(species == "Machine")
input = "Choose your character's frame colour:"
- var/new_hair = input(user, input, "Character Preference") as color|null
+ var/new_hair = input(user, input, "Character Preference", rgb(r_hair, g_hair, b_hair)) as color|null
if(new_hair)
r_hair = hex2num(copytext(new_hair, 2, 4))
g_hair = hex2num(copytext(new_hair, 4, 6))
@@ -1190,10 +1203,10 @@ datum/preferences
var/new_body_accessory = input(user, "Choose your body accessory:", "Character Preference") as null|anything in possible_body_accessories
if(new_body_accessory)
- body_accessory = new_body_accessory
+ body_accessory = (new_body_accessory == "None") ? null : new_body_accessory
if("facial")
- var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference") as color|null
+ var/new_facial = input(user, "Choose your character's facial-hair colour:", "Character Preference", rgb(r_facial, g_facial, b_facial)) as color|null
if(new_facial)
r_facial = hex2num(copytext(new_facial, 2, 4))
g_facial = hex2num(copytext(new_facial, 4, 6))
@@ -1255,7 +1268,7 @@ datum/preferences
socks = new_socks
if("eyes")
- var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference") as color|null
+ var/new_eyes = input(user, "Choose your character's eye colour:", "Character Preference", rgb(r_eyes, g_eyes, b_eyes)) as color|null
if(new_eyes)
r_eyes = hex2num(copytext(new_eyes, 2, 4))
g_eyes = hex2num(copytext(new_eyes, 4, 6))
@@ -1270,7 +1283,7 @@ datum/preferences
if("skin")
if((species in list("Unathi", "Tajaran", "Skrell", "Slime People", "Vulpkanin", "Machine")) || body_accessory_by_species[species] || check_rights(R_ADMIN, 0, user))
- var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference") as color|null
+ var/new_skin = input(user, "Choose your character's skin colour: ", "Character Preference", rgb(r_skin, g_skin, b_skin)) as color|null
if(new_skin)
r_skin = hex2num(copytext(new_skin, 2, 4))
g_skin = hex2num(copytext(new_skin, 4, 6))
@@ -1278,7 +1291,7 @@ datum/preferences
if("ooccolor")
- var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference") as color|null
+ var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference", ooccolor) as color|null
if(new_ooccolor)
ooccolor = new_ooccolor
@@ -1423,7 +1436,7 @@ datum/preferences
UI_style = "Midnight"
if("UIcolor")
- var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!") as color|null
+ var/UI_style_color_new = input(user, "Choose your UI color, dark colors are not recommended!", UI_style_color) as color|null
if(!UI_style_color_new) return
UI_style_color = UI_style_color_new
diff --git a/code/modules/economy/EFTPOS.dm b/code/modules/economy/EFTPOS.dm
index efef8616f7f..30a1cb82af0 100644
--- a/code/modules/economy/EFTPOS.dm
+++ b/code/modules/economy/EFTPOS.dm
@@ -133,8 +133,10 @@
if("change_id")
var/attempt_code = text2num(input("Re-enter the current EFTPOS access code", "Confirm EFTPOS code"))
if(attempt_code == access_code)
- eftpos_name = input("Enter a new terminal ID for this device", "Enter new EFTPOS ID") + " EFTPOS scanner"
- print_reference()
+ var name = input("Enter a new terminal ID for this device", "Enter new EFTPOS ID") as text|null
+ if(name)
+ eftpos_name = name + " EFTPOS scanner"
+ print_reference()
else
usr << "\icon[src]Incorrect code entered."
if("link_account")
@@ -147,7 +149,9 @@
else
usr << "\icon[src]Unable to connect to accounts database."
if("trans_purpose")
- transaction_purpose = input("Enter reason for EFTPOS transaction", "Transaction purpose")
+ var/purpose = input("Enter reason for EFTPOS transaction", "Transaction purpose") as text|null
+ if(purpose)
+ transaction_purpose = purpose
if("trans_value")
var/try_num = input("Enter amount for EFTPOS transaction", "Transaction amount") as num
if(try_num < 0)
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 033221ce5f2..613ec7dcc35 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -113,7 +113,7 @@
descriptors |= "hallucinogenic"
if(reagents.has_reagent("styptic_powder"))
descriptors |= "medicinal"
- if(reagents.has_reagent("gold"))
+ if(reagents.has_reagent("gold") || reagents.has_reagent("silver"))
descriptors |= "shiny"
if(reagents.has_reagent("lube"))
descriptors |= "slippery"
@@ -300,6 +300,9 @@
// TODO: refactor all food paths to be less horrible and difficult to work with in this respect. ~Z
if(!istype(M) || (can_operate(M) && do_surgery(M,user,src))) return 0
+ if(!def_zone)
+ def_zone = check_zone(user.zone_sel.selecting)
+
user.lastattacked = M
M.lastattacker = user
user.attack_log += "\[[time_stamp()]\] Attacked [key_name(M)] with [name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(damtype)])"
@@ -311,7 +314,7 @@
var/hit = H.attacked_by(src, user, def_zone)
if(hit && hitsound)
playsound(loc, hitsound, 50, 1, -1)
- return hit
+ //return hit
else
if(attack_verb.len)
user.visible_message("[M] has been [pick(attack_verb)] with [src] by [user]!")
@@ -331,15 +334,23 @@
M.take_organ_damage(0, force)
M.updatehealth()
- if(seed && seed.get_trait(TRAIT_STINGS))
+ if(seed && seed.get_trait(TRAIT_CARNIVOROUS))
+ seed.do_thorns(M, src, def_zone)
+
+ if(ishuman(M) && seed && seed.get_trait(TRAIT_STINGS))
if(!reagents || reagents.total_volume <= 0)
return
- reagents.remove_any(rand(1,3))
- seed.thrown_at(src,M)
+ seed.do_sting(M, src, def_zone)
+ reagents.remove_any(rand(1,3)) //use up some of the reagents at random
sleep(-1)
if(!src)
return
- if(prob(35))
+ if(reagents && reagents.total_volume <= 0) //used-up fruit will be destroyed
+ if(user)
+ user << "\The [src] has dried out and crumbles to dust."
+ //user.drop_from_inventory(src)
+ qdel(src)
+ else if(prob(35)) //fruit that still has reagents has a chance of breaking each time it stings on hit
if(user)
user << "\The [src] has fallen to bits."
//user.drop_from_inventory(src)
@@ -366,44 +377,95 @@
if(src) qdel(src)
return
- if(seed.kitchen_tag == "grass")
- user.show_message("You make a grass tile out of \the [src]!", 1)
- for(var/i=0,i<2,i++)
- var/obj/item/stack/tile/grass/G = new (user.loc)
- G.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
- for (var/obj/item/stack/tile/grass/NG in user.loc)
- if(G==NG)
- continue
- if(NG.amount>=NG.max_amount)
- continue
- NG.attackby(G, user)
- user << "You add the newly-formed grass to the stack. It now contains [G.amount] tiles."
- qdel(src)
- return
-
- if(seed.get_trait(TRAIT_SPREAD) > 0)
+ if(user.a_intent == I_DISARM && seed.get_trait(TRAIT_SPREAD) > 0) //Using disarm so we can tell if you want to plant or convert non-final plants
user << "You plant the [src.name]."
new /obj/machinery/portable_atmospherics/hydroponics/soil/invisible(get_turf(user),src.seed)
new /obj/effect/plant(get_turf(user), src.seed)
qdel(src)
return
- /*
- if(seed.kitchen_tag)
+
+ if(!seed.final_form) //This isn't even my final form! (sorry, it had to be done)
switch(seed.kitchen_tag)
- if("shand")
- var/obj/item/stack/medical/bruise_pack/tajaran/poultice = new /obj/item/stack/medical/bruise_pack/tajaran(user.loc)
+ if("comfrey")
+ var/obj/item/stack/medical/bruise_pack/comfrey/poultice = new /obj/item/stack/medical/bruise_pack/comfrey(user.loc)
poultice.heal_brute = potency
user << "You mash the leaves into a poultice."
qdel(src)
return
- if("mtear")
- var/obj/item/stack/medical/ointment/tajaran/poultice = new /obj/item/stack/medical/ointment/tajaran(user.loc)
+ if("aloe")
+ var/obj/item/stack/medical/ointment/aloe/poultice = new /obj/item/stack/medical/ointment/aloe(user.loc)
poultice.heal_burn = potency
user << "You mash the petals into a poultice."
qdel(src)
return
- */
+ if("grass")
+ user.show_message("You make a grass tile out of \the [src]!", 1)
+ for(var/i=0,i<2,i++)
+ var/obj/item/stack/tile/grass/G = new (user.loc)
+ G.color = seed.get_trait(TRAIT_PRODUCT_COLOUR)
+ for (var/obj/item/stack/tile/grass/NG in user.loc)
+ if(G==NG)
+ continue
+ if(NG.amount>=NG.max_amount)
+ continue
+ NG.attackby(G, user)
+ user << "You add the newly-formed grass to the stack. It now contains [G.amount] tiles."
+ qdel(src)
+ return
+ if("sunflower")
+ var/obj/item/weapon/grown/sunflower/SF = new /obj/item/weapon/grown/sunflower(user.loc)
+ user.unEquip(src)
+ user.put_in_hands(SF)
+ qdel(src)
+ return
+ if("novaflower")
+ var/obj/item/weapon/grown/novaflower/NF = new /obj/item/weapon/grown/novaflower(user.loc)
+ if(prob(10))
+ user.say("PRAISE THE SUN!")
+ else
+ user << "PRAISE THE SUN!"
+ user.unEquip(src)
+ user.put_in_hands(NF)
+ qdel(src)
+ return
+ if("cashpod")
+ user << "You crack open the cash pod..."
+ var/value = round(seed.get_trait(TRAIT_POTENCY))
+ var/dosh
+ user.unEquip(src)
+ switch(value)
+ if(0)
+ user << "It's empty! What a waste..."
+ if(1 to 10)
+ user << "It has a space dollar inside. Woo."
+ dosh = new /obj/item/weapon/spacecash(user.loc)
+ if(11 to 20)
+ user << "It has 10 space dollars inside!"
+ dosh = new /obj/item/weapon/spacecash/c10(user.loc)
+ if(21 to 30)
+ user << "It has 20 space dollars inside! Cool!"
+ dosh = new /obj/item/weapon/spacecash/c20(user.loc)
+ if(31 to 40)
+ user << "It has 50 space dollars inside! Nice!"
+ dosh = new /obj/item/weapon/spacecash/c50(user.loc)
+ if(41 to 50)
+ user << "It has 100 space dollars inside! Sweet!"
+ dosh = new /obj/item/weapon/spacecash/c100(user.loc)
+ if(51 to 60)
+ user << "It has 200 space dollars inside! Awesome!"
+ dosh = new /obj/item/weapon/spacecash/c200(user.loc)
+ if(61 to 80)
+ user << "It has 500 space dollars inside! CHA-CHING!"
+ dosh = new /obj/item/weapon/spacecash/c500(user.loc)
+ else
+ user << "It has 1000 space dollars inside! JACKPOT!"
+ dosh = new /obj/item/weapon/spacecash/c1000(user.loc)
+
+ if(dosh)
+ user.put_in_hands(dosh)
+ qdel(src)
+ return
/obj/item/weapon/reagent_containers/food/snacks/grown/pickup(mob/user)
..()
diff --git a/code/modules/hydroponics/grown_inedible.dm b/code/modules/hydroponics/grown_inedible.dm
index a5497298947..b6a3b05d966 100644
--- a/code/modules/hydroponics/grown_inedible.dm
+++ b/code/modules/hydroponics/grown_inedible.dm
@@ -84,3 +84,47 @@
throwforce = 0
throw_speed = 4
throw_range = 20
+
+
+// Sunflower
+
+/obj/item/weapon/grown/sunflower
+ name = "sunflower"
+ desc = "A large, fresh-grown sunflower. How cheery!"
+ icon = 'icons/obj/harvest.dmi'
+ icon_state = "sunflower"
+ item_state = "sunflower"
+ w_class = 2.0
+ throwforce = 0
+ throw_speed = 4
+ throw_range = 20
+
+/obj/item/weapon/grown/sunflower/attack(mob/M as mob, mob/user as mob)
+ M << " [user] smacks you with a [name]!FLOWER POWER"
+ user << " Your [name]'s FLOWER POWER strikes [M]"
+
+
+// Novaflower
+
+/obj/item/weapon/grown/novaflower
+ name = "novaflower"
+ desc = "A large, fresh-grown novaflower. It seems to radiate heat."
+ icon = 'icons/obj/harvest.dmi'
+ icon_state = "novaflower"
+ item_state = "sunflower"
+ w_class = 2.0
+ throwforce = 0
+ throw_speed = 4
+ throw_range = 20
+
+/obj/item/weapon/grown/novaflower/attack(mob/living/carbon/M as mob, mob/user as mob)
+ M << "[user] smacks you with a [name]!FLOWER POWER"
+ user << " Your [name]'s FLOWER POWER strikes [M]"
+ if(istype(M, /mob/living))
+ M << "You are heated by the warmth of the of the [name]!"
+ M.bodytemperature += potency/2 * TEMPERATURE_DAMAGE_COEFFICIENT
+
+/obj/item/weapon/grown/novaflower/pickup(mob/living/carbon/human/user as mob)
+ if(!user.gloves)
+ user << "The [name] burns your bare hand!"
+ user.adjustFireLoss(rand(1,5))
diff --git a/code/modules/hydroponics/grown_predefined.dm b/code/modules/hydroponics/grown_predefined.dm
index 682ce791e91..523974abac3 100644
--- a/code/modules/hydroponics/grown_predefined.dm
+++ b/code/modules/hydroponics/grown_predefined.dm
@@ -37,4 +37,10 @@
plantname = "amanita"
/obj/item/weapon/reagent_containers/food/snacks/grown/ambrosiadeus
- plantname = "ambrosiadeus"
\ No newline at end of file
+ plantname = "ambrosiadeus"
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/aloe
+ plantname = "aloe"
+
+/obj/item/weapon/reagent_containers/food/snacks/grown/comfrey
+ plantname = "comfrey"
\ No newline at end of file
diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm
index 982da8315d2..d206c8f8e3a 100644
--- a/code/modules/hydroponics/seed.dm
+++ b/code/modules/hydroponics/seed.dm
@@ -21,7 +21,8 @@
var/kitchen_tag // Used by the reagent grinder.
var/trash_type // Garbage item produced when eaten.
var/splat_type = /obj/effect/decal/cleanable/fruit_smudge // Graffiti decal.
- var/has_mob_product
+ var/preset_product
+ var/final_form = 1
var/modular_icon = 0 // Dictates if the product uses a modular sprite. 0 = preset, 1 = modular
var/preset_icon = "undef" // Name of the iconstate in icon/obj/harvest.dmi to use for preset sprite
// Make sure to set this to the correct icon if not using a modular sprite
@@ -140,19 +141,47 @@
target.updatehealth()
// Adds reagents to a target.
-/datum/seed/proc/do_sting(var/mob/living/carbon/human/target, var/obj/item/fruit)
+/datum/seed/proc/do_sting(var/mob/living/carbon/human/target, var/obj/item/fruit, var/target_limb)
if(!get_trait(TRAIT_STINGS))
return
+ if(!target_limb) //if we weren't given a target_limb, pick a random one to try stinging
+ target_limb = pick("l_foot","r_foot","l_leg","r_leg","l_hand","r_hand","l_arm", "r_arm","head","chest","groin")
if(chems && chems.len)
- var/body_coverage = HEAD|HEADCOVERSMOUTH|HEADCOVERSEYES|UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS
+ if(!target.can_inject(target, 0, target_limb)) //if a syringe can't get through, neither can the sting
+ return
+
+ var/protection_needed
+ switch(target_limb)
+ if("head")
+ protection_needed = HEAD | HEADCOVERSMOUTH | HEADCOVERSEYES
+ if("chest")
+ protection_needed = UPPER_TORSO
+ if("groin")
+ protection_needed = LOWER_TORSO
+ if("l_arm","r_arm")
+ protection_needed = ARMS
+ if("l_hand","r_hand")
+ protection_needed = HANDS
+ if("l_leg","r_leg")
+ protection_needed = LEGS
+ if("l_foot","r_foot")
+ protection_needed = FEET
for(var/obj/item/clothing/clothes in target)
+
if(target.l_hand == clothes|| target.r_hand == clothes)
continue
- body_coverage &= ~(clothes.body_parts_covered)
+ protection_needed &= ~(clothes.body_parts_covered)
+ if((clothes.slot_flags & SLOT_HEAD) || (clothes.slot_flags & SLOT_MASK))
+ if(clothes.flags & HEADCOVERSEYES)
+ protection_needed &= ~(HEADCOVERSEYES)
+ if(clothes.flags & HEADCOVERSMOUTH)
+ protection_needed &= ~(HEADCOVERSMOUTH)
+ if(!protection_needed) //already got the needed protection, save some time and skip the rest of the loop
+ break
- if(!body_coverage)
+ if(!protection_needed) //properly protected, good job!
return
target << "You are stung by \the [fruit]!"
@@ -417,54 +446,37 @@
chems = list()
if(prob(80))
- chems["nutriment"] = list(rand(1,10),rand(10,20))
+ var/nutrient_type = rand(1,7)
+ switch(nutrient_type)
+ if(1)
+ chems["plantmatter"] = list(rand(1,10),rand(10,20))
+ if(2)
+ chems["nutriment"] = list(rand(1,10),rand(10,20))
+ if(3)
+ chems["protein"] = list(rand(1,10),rand(10,20))
+ if(4)
+ chems["plantmatter"] = list(rand(1,5),rand(10,20))
+ chems["nutriment"] = list(rand(1,5),rand(10,20))
+ if(5)
+ chems["plantmatter"] = list(rand(1,5),rand(10,20))
+ chems["protein"] = list(rand(1,5),rand(10,20))
+ if(6)
+ chems["protein"] = list(rand(1,5),rand(10,20))
+ chems["nutriment"] = list(rand(1,5),rand(10,20))
+ if(7)
+ chems["plantmatter"] = list(rand(1,3),rand(10,20))
+ chems["nutriment"] = list(rand(1,4),rand(10,20))
+ chems["protein"] = list(rand(1,3),rand(10,20))
var/additional_chems = rand(0,5)
if(additional_chems)
- var/list/possible_chems = list(
- "woodpulp",
- "styptic_powder",
- "methamphetamine",
- "cryoxadone",
- "blood",
- "water",
- "potassium",
- "plasticide",
- "epinephrine",
- "space_drugs",
- "salglu_solution",
- "mercury",
- "sugar",
- "radium",
- "mutadone",
- "mannitol",
- "thermite",
- "sal_acid",
- "atropine",
- "omnizine",
- "salbutamol",
- "plasma",
- "synaptizine",
- "haloperidol",
- "potass_iodide",
- "mitocholide",
- "toxin",
- "rezadone",
- "antihol",
- "slimejelly",
- "cyanide",
- "lsd",
- "morphine",
- "ether"
- )
-
for(var/x=1;x<=additional_chems;x++)
- if(!possible_chems.len)
- break
- var/new_chem = pick(possible_chems)
- possible_chems -= new_chem
- chems[new_chem] = list(rand(1,10),rand(10,20))
+ var/new_chem = get_random_chemical(1)
+ if(chems.Find(new_chem))
+ chems[new_chem] = list(rand(2,20),rand(5,15)) //DOUBLE UP
+ else
+ chems[new_chem] = list(rand(1,10),rand(10,20))
if(prob(90))
set_trait(TRAIT_REQUIRES_NUTRIENTS,1)
@@ -639,8 +651,8 @@
consume_gasses |= new_gasses
gene.values["[TRAIT_CONSUME_GASSES]"] = null
if(GENE_METABOLISM)
- has_mob_product = gene.values["mob_product"]
- gene.values["mob_product"] = null
+ preset_product = gene.values["alt_product"]
+ gene.values["alt_product"] = null
for(var/trait in gene.values)
set_trait(trait,gene.values["[trait]"])
@@ -669,7 +681,7 @@
if(GENE_HARDINESS)
traits_to_copy = list(TRAIT_TOXINS_TOLERANCE,TRAIT_PEST_TOLERANCE,TRAIT_WEED_TOLERANCE,TRAIT_ENDURANCE)
if(GENE_METABOLISM)
- P.values["mob_product"] = has_mob_product
+ P.values["alt_product"] = preset_product
traits_to_copy = list(TRAIT_REQUIRES_NUTRIENTS,TRAIT_REQUIRES_WATER,TRAIT_ALTER_TEMP)
if(GENE_VIGOUR)
traits_to_copy = list(TRAIT_PRODUCTION,TRAIT_MATURATION,TRAIT_YIELD,TRAIT_SPREAD)
@@ -729,14 +741,13 @@
currently_querying = list()
for(var/i = 0;i0) ? round(spread_chance*0.6) : round(spread_chance*0.3))
+ spread_chance = seed.get_trait(TRAIT_POTENCY)
+ if(growth_type == 0) //These don't spread far at all (glowshroom, glowberries, brown mold)
+ spread_distance = round(spread_chance*0.1)
+ else if(growth_type == 2 || growth_type == 3) //Vines and biomass can go further than worms and mold
+ spread_distance = round(spread_chance*0.6)
+ else //Worms and mold go a moderate distance
+ spread_distance = round(spread_chance*0.3)
update_icon()
spawn(1) // Plants will sometimes be spawned in the turf adjacent to the one they need to end up in, for the sake of correct dir/etc being set.
diff --git a/code/modules/hydroponics/spreading/spreading_response.dm b/code/modules/hydroponics/spreading/spreading_response.dm
index 53abedd3c78..0f991a56bfc 100644
--- a/code/modules/hydroponics/spreading/spreading_response.dm
+++ b/code/modules/hydroponics/spreading/spreading_response.dm
@@ -17,14 +17,16 @@
// Todo, cause damage.
user_unbuckle_mob(user, user)
-/obj/effect/plant/proc/trodden_on(var/mob/living/victim)
+/obj/effect/plant/Crossed(var/mob/living/victim)
if(!is_mature())
return
- var/mob/living/carbon/human/H = victim
- if(istype(H) && H.shoes)
- return
- seed.do_thorns(victim,src)
- seed.do_sting(victim,src,pick("r_foot","l_foot","r_leg","l_leg"))
+ var/target_limb = pick("r_foot","l_foot","r_leg","l_leg")
+ if(ishuman(victim))
+ var/mob/living/carbon/human/H = victim
+ if(H.shoes && prob(50)) //shoes will reduce chances of being stuck/stung by plants, but not always avoid it
+ return
+ seed.do_thorns(victim,src,target_limb)
+ seed.do_sting(victim,src,target_limb)
/obj/effect/plant/proc/entangle(var/mob/living/victim)
diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm
index 5bc193892a0..f255c558c20 100644
--- a/code/modules/hydroponics/trays/tray.dm
+++ b/code/modules/hydroponics/trays/tray.dm
@@ -68,6 +68,8 @@
"ammonia" = 1,
"diethylamine" = 2,
"nutriment" = 1,
+ "protein" = 1.75,
+ "plantmatter" = 1.25,
"adminordrazine" = 1,
"eznutrient" = 1,
"robustharvest" = 1,
@@ -117,6 +119,8 @@
"ammonia" = list( 0.5, 0, 0 ),
"diethylamine" = list( 1, 0, 0 ),
"nutriment" = list( 0.25, 0.15, 0 ),
+ "protein" = list( 0.25, 0.15, 0 ),
+ "plantmatter" = list( 0.25, 0.15, 0 ),
"radium" = list( -1.5, 0, 0.2),
"adminordrazine" = list( 1, 1, 1 ),
"robustharvest" = list( 0, 0.2, 0 ),
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index c7cc2dbdf7c..2a694bb1d6f 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -111,7 +111,7 @@ Works together with spawning an observer, noted above.
if(!loc) return
if(!client) return 0
-
+ regular_hud_updates()
if(client.images.len)
for(var/image/hud in client.images)
if(copytext(hud.icon_state,1,4) == "hud")
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index f3a376ee180..fa1d21e3bd5 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -245,6 +245,9 @@
stat(null, "Intent: [a_intent]")
stat(null, "Move Mode: [m_intent]")
+
+ stat(null, "Station Time: [worldtime2text()]")
+
if(ticker && ticker.mode && ticker.mode.name == "AI malfunction")
if(ticker.mode:malf_mode_declared)
stat(null, "Time left: [max(ticker.mode:AI_win_timeleft/(ticker.mode:apcs/3), 0)]")
@@ -275,7 +278,12 @@
if(mind.changeling)
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
stat("Absorbed DNA", mind.changeling.absorbedcount)
- stat(null, "Station Time: [worldtime2text()]")
+
+ if(mind.nation)
+ stat("Nation Name", "[mind.nation.current_name ? "[mind.nation.current_name]" : "[mind.nation.default_name]"]")
+ stat("Nation Leader", "[mind.nation.current_leader ? "[mind.nation.current_leader]" : "None"]")
+ stat("Nation Heir", "[mind.nation.heir ? "[mind.nation.heir]" : "None"]")
+
if(istype(loc, /obj/spacepod)) // Spacdpods!
var/obj/spacepod/S = loc
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 02916034467..fe373bf3280 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -90,7 +90,6 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(life_tick == 1)
regenerate_icons() // Make sure the inventory updates
-
/mob/living/carbon/human/calculate_affecting_pressure(var/pressure)
..()
var/pressure_difference = abs( pressure - ONE_ATMOSPHERE )
@@ -822,112 +821,67 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
return //TODO: DEFERRED
/mob/living/carbon/human/handle_regular_status_updates()
-
if(status_flags & GODMODE)
return 0
+ . = ..()
+
//SSD check, if a logged player is awake put them back to sleep!
if(player_logged && sleeping < 2)
sleeping = 2
- if(stat == DEAD) //DEAD. BROWN BREAD. SWIMMING WITH THE SPESS CARP
- blinded = 1
- silent = 0
- else //ALIVE. LIGHTS ARE ON
-
+ if(.) //alive
if(REGEN in mutations)
if(nutrition)
if(prob(10))
- var/randumb = rand(1,5)
+ var/randumb = rand(1, 5)
nutrition -= randumb
- heal_overall_damage(randumb,randumb)
+ heal_overall_damage(randumb, randumb)
if(nutrition < 0)
nutrition = 0
- // Sobering multiplier.
- // Sober block grants quadruple the alcohol metabolism.
-// var/sober_str=!(SOBER in mutations)?1:4
-
- updatehealth() //TODO
if(!in_stasis)
- handle_organs() //Optimized.
+ handle_organs()
handle_blood()
- if(health <= config.health_threshold_dead || brain_op_stage == 4.0)
- death()
- blinded = 1
- silent = 0
- return 1
-
- // the analgesic effect wears off slowly
+ //the analgesic effect wears off slowly
analgesic = max(0, analgesic - 1)
- //UNCONSCIOUS. NO-ONE IS HOME
- if( (getOxyLoss() > 50) || (config.health_threshold_crit >= health) )
- Paralyse(3)
-
- /* Done by handle_breath()
- if( health <= 20 && prob(1) )
- spawn(0)
- emote("gasp")
- if(!reagents.has_reagent("epinephrine"))
- adjustOxyLoss(1)*/
-
if(hallucination && !(species.flags & NO_DNA_RAD))
- spawn handle_hallucinations()
+ spawn()
+ handle_hallucinations()
- if(hallucination<=2)
+ if(hallucination <= 2)
hallucination = 0
halloss = 0
else
hallucination -= 2
-
- if(halloss > 100)
- src << "You're in too much pain to keep going..."
- for(var/mob/O in oviewers(src, null))
- O.show_message("[src] slumps to the ground, too weak to continue fighting.", 1)
- Paralyse(10)
- setHalLoss(99)
-
if(paralysis)
blinded = 1
stat = UNCONSCIOUS
- if(halloss > 0)
- adjustHalLoss(-3)
+
else if(sleeping)
speech_problem_flag = 1
- handle_dreams()
- adjustStaminaLoss(-10)
- adjustHalLoss(-3)
- if (mind)
+
+ if(mind)
//Are they SSD? If so we'll keep them asleep but work off some of that sleep var in case of ether or similar.
if(player_logged)
- sleeping = max(sleeping-1, 2)
- else
- sleeping = max(sleeping-1, 0)
+ sleeping = max(sleeping - 1, 2)
+
blinded = 1
stat = UNCONSCIOUS
- if( prob(2) && health && !hal_crit )
- spawn(0)
- emote("snore")
+
if(mind)
if(mind.vampire)
if(istype(loc, /obj/structure/closet/coffin))
adjustBruteLoss(-1)
adjustFireLoss(-1)
adjustToxLoss(-1)
+
else if(status_flags & FAKEDEATH)
blinded = 1
stat = UNCONSCIOUS
- else if(resting)
- if(halloss > 0)
- adjustHalLoss(-3)
- //CONSCIOUS
- else
- stat = CONSCIOUS
- if(halloss > 0)
- adjustHalLoss(-1)
if(embedded_flag && !(mob_master.current_cycle % 10))
var/list/E
@@ -935,7 +889,8 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(!E.len)
embedded_flag = 0
- //Vision
+
+ //Vision //god knows why this is here
var/obj/item/organ/vision
if(species.vision_organ)
vision = internal_organs_by_name[species.vision_organ]
@@ -944,17 +899,21 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
eye_blind = 0
blinded = 0
eye_blurry = 0
+
else if(!vision || vision.is_broken()) // Vision organs cut out or broken? Permablind.
eye_blind = 1
blinded = 1
eye_blurry = 1
+
else
//blindness
if(sdisabilities & BLIND) // Disabled-blind, doesn't get better on its own
blinded = 1
+
else if(eye_blind) // Blindness, heals slowly over time
eye_blind = max(eye_blind-1,0)
blinded = 1
+
else if(istype(glasses, /obj/item/clothing/glasses/sunglasses/blindfold)) //resting your eyes with a blindfold heals blurry eyes faster
eye_blurry = max(eye_blurry-3, 0)
blinded = 1
@@ -962,59 +921,26 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
//blurry sight
if(vision.is_bruised()) // Vision organs impaired? Permablurry.
eye_blurry = 1
+
if(eye_blurry) // Blurry eyes heal slowly
eye_blurry = max(eye_blurry-1, 0)
+
//Ears
if(sdisabilities & DEAF) //disabled-deaf, doesn't get better on its own
ear_deaf = max(ear_deaf, 1)
+
else if(ear_deaf) //deafness, heals slowly over time
- ear_deaf = max(ear_deaf-1, 0)
+ ear_deaf = max(ear_deaf - 1, 0)
+
else if(istype(l_ear, /obj/item/clothing/ears/earmuffs) || istype(r_ear, /obj/item/clothing/ears/earmuffs)) //resting your ears with earmuffs heals ear damage faster
- ear_damage = max(ear_damage-0.15, 0)
+ ear_damage = max(ear_damage - 0.15, 0)
ear_deaf = max(ear_deaf, 1)
+
else if(ear_damage < 25) //ear damage heals slowly under this threshold. otherwise you'll need earmuffs
- ear_damage = max(ear_damage-0.05, 0)
+ ear_damage = max(ear_damage - 0.05, 0)
- //Dizziness
- if(dizziness)
- var/client/C = client
- var/pixel_x_diff = 0
- var/pixel_y_diff = 0
- var/temp
- var/saved_dizz = dizziness
- dizziness = max(dizziness-1, 0)
- if(C)
- var/oldsrc = src
- var/amplitude = dizziness*(sin(dizziness * 0.044 * world.time) + 1) / 70 // This shit is annoying at high strength
- src = null
- spawn(0)
- if(C)
- temp = amplitude * sin(0.008 * saved_dizz * world.time)
- pixel_x_diff += temp
- C.pixel_x += temp
- temp = amplitude * cos(0.008 * saved_dizz * world.time)
- pixel_y_diff += temp
- C.pixel_y += temp
- sleep(3)
- if(C)
- temp = amplitude * sin(0.008 * saved_dizz * world.time)
- pixel_x_diff += temp
- C.pixel_x += temp
- temp = amplitude * cos(0.008 * saved_dizz * world.time)
- pixel_y_diff += temp
- C.pixel_y += temp
- sleep(3)
- if(C)
- C.pixel_x -= pixel_x_diff
- C.pixel_y -= pixel_y_diff
- src = oldsrc
- //Jitteryness
- if(jitteriness)
- do_jitter_animation(jitteriness)
-
- //Flying
if(flying)
spawn()
animate(src, pixel_y = pixel_y + 5 , time = 10, loop = 1, easing = SINE_EASING)
@@ -1026,9 +952,11 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(gloves && germ_level > gloves.germ_level && prob(10))
gloves.germ_level += 1
- CheckStamina()
- return 1
+ else //dead
+ blinded = 1
+ silent = 0
+
/mob/living/carbon/human/handle_vision()
client.screen.Remove(global_hud.blurry, global_hud.druggy, global_hud.vimpaired, global_hud.darkMask)
@@ -1070,10 +998,6 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
if(hud_updateflag)
handle_hud_list()
- if(ticker && ticker.mode.name == "nations")
- process_nations()
-
-
/mob/living/carbon/human/handle_random_events()
// Puke if toxloss is too high
@@ -1493,7 +1417,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc
holder.icon_state = "hudblank"
if(mind && mind.nation)
- switch(mind.nation.name)
+ switch(mind.nation.default_name)
if("Atmosia")
holder.icon_state = "hudatmosia"
if("Brigston")
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index ee7dcedec56..33af21120de 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -296,8 +296,8 @@
if(sleeping)
handle_dreams()
adjustStaminaLoss(-10)
- sleeping = max(sleeping-1, 0)
- if( prob(10) && health && !hal_crit )
+ sleeping = max(sleeping - 1, 0)
+ if(prob(10) && health && !hal_crit)
spawn(0)
emote("snore")
diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm
index 1b82d097cd8..1aa9e0f6191 100644
--- a/code/modules/mob/living/carbon/metroid/metroid.dm
+++ b/code/modules/mob/living/carbon/metroid/metroid.dm
@@ -722,43 +722,11 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle19"
+ w_class = 1
+ origin_tech = "biotech=4"
attack(mob/living/carbon/slime/M as mob, mob/user as mob)
if(!istype(M, /mob/living/carbon/slime))//If target is not a slime.
- user << " The potion only works on baby slimes!"
- return ..()
- if(M.is_adult) //Can't tame adults
- user << " Only baby slimes can be tamed!"
- return..()
- if(M.stat)
- user << " The slime is dead!"
- return..()
- if(M.mind)
- user << " The slime resists!"
- return ..()
- var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc)
- pet.icon_state = "[M.colour] baby slime"
- pet.icon_living = "[M.colour] baby slime"
- pet.icon_dead = "[M.colour] baby slime dead"
- pet.colour = "[M.colour]"
- user <<"You feed the slime the potion, removing it's powers and calming it."
- qdel(M)
- var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN))
-
- if (!newname)
- newname = "pet slime"
- pet.name = newname
- pet.real_name = newname
- qdel(src)
-
-/obj/item/weapon/slimepotion2
- name = "advanced docility potion"
- desc = "A potent chemical mix that will nullify a slime's powers, causing it to become docile and tame. This one is meant for adult slimes"
- icon = 'icons/obj/chemical.dmi'
- icon_state = "bottle19"
-
- attack(mob/living/carbon/slime/M as mob, mob/user as mob)
- if(!istype(M, /mob/living/carbon/slime/))//If target is not a slime.
user << " The potion only works on slimes!"
return ..()
if(M.stat)
@@ -767,20 +735,104 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
if(M.mind)
user << " The slime resists!"
return ..()
- var/mob/living/simple_animal/adultslime/pet = new /mob/living/simple_animal/adultslime(M.loc)
- pet.icon_state = "[M.colour] adult slime"
- pet.icon_living = "[M.colour] adult slime"
- pet.icon_dead = "[M.colour] baby slime dead"
- pet.colour = "[M.colour]"
- user <<"You feed the slime the potion, removing it's powers and calming it."
- qdel(M)
- var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN))
+ if(M.is_adult)
+ var/mob/living/simple_animal/adultslime/pet = new /mob/living/simple_animal/adultslime(M.loc)
+ pet.icon_state = "[M.colour] adult slime"
+ pet.icon_living = "[M.colour] adult slime"
+ pet.icon_dead = "[M.colour] baby slime dead"
+ pet.colour = "[M.colour]"
+ qdel(M)
+ var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN))
- if (!newname)
- newname = "pet slime"
- pet.name = newname
- pet.real_name = newname
+ if (!newname)
+ newname = "pet slime"
+ pet.name = newname
+ pet.real_name = newname
+ qdel(src)
+ else
+ var/mob/living/simple_animal/slime/pet = new /mob/living/simple_animal/slime(M.loc)
+ pet.icon_state = "[M.colour] baby slime"
+ pet.icon_living = "[M.colour] baby slime"
+ pet.icon_dead = "[M.colour] baby slime dead"
+ pet.colour = "[M.colour]"
+ qdel(M)
+ var/newname = sanitize(copytext(input(user, "Would you like to give the slime a name?", "Name your new pet", "pet slime") as null|text,1,MAX_NAME_LEN))
+
+ if (!newname)
+ newname = "pet slime"
+ pet.name = newname
+ pet.real_name = newname
+ qdel(src)
+ user <<"You feed the slime the potion, removing it's powers and calming it."
+
+/obj/item/weapon/sentience_potion
+ name = "sentience potion"
+ desc = "A miraculous chemical mix that can raise the intelligence of creatures to human levels. Unlike normal slime potions, it can be absorbed by any nonsentient being."
+ icon = 'icons/obj/chemical.dmi'
+ icon_state = "bottle19"
+ origin_tech = "biotech=5"
+ var/list/not_interested = list()
+ var/being_used = 0
+ w_class = 1
+
+
+/obj/item/weapon/sentience_potion/afterattack(mob/living/M, mob/user)
+ if(being_used || !ismob(M))
+ return
+ if(!isslime(M) && !isanimal(M) || M.ckey) //only works on animals that aren't player controlled
+ user << "[M] is already too intelligent for this to work!"
+ return ..()
+ if(M.stat)
+ user << "[M] is dead!"
+ return..()
+
+ user << "You offer the sentience potion to [M]..."
+ being_used = 1
+
+ var/list/candidates = get_candidates(BE_ALIEN, ALIEN_AFK_BRACKET)
+
+ shuffle(candidates)
+
+ var/time_passed = world.time
+ var/list/consenting_candidates = list()
+
+ for(var/candidate in candidates)
+
+ if(candidate in not_interested)
+ continue
+
+ spawn(0)
+ switch(alert(candidate, "Would you like to play as [M.name]? Please choose quickly!","Confirmation","Yes","No"))
+ if("Yes")
+ if((world.time-time_passed)>=50 || !src)
+ return
+ consenting_candidates += candidate
+ if("No")
+ if(!src)
+ return
+ not_interested += candidate
+
+ sleep(50)
+
+ if(!src)
+ return
+
+ listclearnulls(consenting_candidates) //some candidates might have left during sleep(50)
+
+ if(consenting_candidates.len)
+ var/client/C = null
+ C = pick(consenting_candidates)
+ M.key = C.key
+ M.universal_speak = 1
+ M.faction |= "sentient"
+ M << "All at once it makes sense: you know what you are and who you are! Self awareness is yours!"
+ M << "You are grateful to be self aware and owe [user] a great debt. Serve [user], and assist them in completing their goals at any cost."
+ user << "[M] accepts the potion and suddenly becomes attentive and aware. It worked!"
qdel(src)
+ else
+ user << "[M] looks interested for a moment, but then looks back down. Maybe you should try again later."
+ being_used = 0
+ ..()
/obj/item/weapon/slimesteroid
@@ -788,6 +840,9 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
desc = "A potent chemical mix that will cause a slime to generate more extract."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle16"
+ w_class = 1
+ origin_tech = "biotech=4"
+
attack(mob/living/carbon/slime/M as mob, mob/user as mob)
if(!istype(M, /mob/living/carbon/slime))//If target is not a slime.
@@ -812,6 +867,8 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
desc = "A potent chemical mix that will give a slime extract three uses."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle17"
+ w_class = 1
+ origin_tech = "biotech=4"
/obj/item/weapon/slimespeed
@@ -819,6 +876,8 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
desc = "A potent chemical mix that will remove the slowdown from any item."
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle3"
+ w_class = 1
+ origin_tech = "biotech=4"
/obj/item/weapon/slimespeed/afterattack(obj/item/C, mob/user)
..()
@@ -839,6 +898,9 @@ mob/living/carbon/slime/var/temperature_resistance = T0C+75
icon = 'icons/obj/chemical.dmi'
icon_state = "bottle17"
var/uses = 3
+ w_class = 1
+ origin_tech = "biotech=4"
+
/obj/item/weapon/slimefireproof/afterattack(obj/item/clothing/C, mob/user)
..()
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 1c222c9a298..0b1ee60a3ea 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -56,7 +56,8 @@
if(client)
regular_hud_updates() //THIS DOESN'T FUCKING UPDATE SHIT
handle_regular_hud_updates() //IT JUST REMOVES FUCKING HUD IMAGES
-
+ if(get_nations_mode())
+ process_nations()
/mob/living/proc/handle_breathing()
return
@@ -307,5 +308,5 @@
/mob/living/proc/process_nations()
if(client)
var/client/C = client
- for(var/mob/living/carbon/human/H in view(world.view, src))
+ for(var/mob/living/carbon/human/H in view(src, world.view))
C.images += H.hud_list[NATIONS_HUD]
\ 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 ef16209664b..8d1125982aa 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -55,7 +55,6 @@
aiRestorePowerRoutine = 0
blind.layer = 0
- return
else
@@ -154,8 +153,8 @@
if (MED_HUD)
process_med_hud(src, 1, eyeobj)
- if(ticker && ticker.mode.name == "nations")
- process_nations()
+ if(get_nations_mode())
+ process_nations_ai()
/mob/living/silicon/ai/updatehealth()
if(status_flags & GODMODE)
@@ -175,3 +174,9 @@
/mob/living/silicon/ai/rejuvenate()
..()
add_ai_verbs(src)
+
+/mob/living/silicon/ai/proc/process_nations_ai()
+ if(client)
+ var/client/C = client
+ for(var/mob/living/carbon/human/H in view(eyeobj, 14))
+ C.images += H.hud_list[NATIONS_HUD]
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm
index 38c7df68aa3..6a981464bd5 100644
--- a/code/modules/mob/living/silicon/pai/life.dm
+++ b/code/modules/mob/living/silicon/pai/life.dm
@@ -16,6 +16,7 @@
for (var/mob/M in viewers(T))
M.show_message("\red The data cable rapidly retracts back into its spool.", 3, "\red You hear a click and the sound of wire spooling rapidly.", 2)
qdel(src.cable)
+ cable = null
/mob/living/silicon/pai/updatehealth()
if(status_flags & GODMODE)
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index d00e209d2fb..2fd2ddcab61 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -6,7 +6,7 @@
robot_talk_understand = 0
emote_type = 2 // pAIs emotes are heard, not seen, so they can be seen through a container (eg. person)
small = 1
- pass_flags = 1
+ pass_flags = PASSTABLE
density = 0
holder_type = /obj/item/weapon/holder/pai
var/network = "SS13"
@@ -512,6 +512,10 @@
src << "You are far too small to pull anything!"
return
+/mob/living/silicon/pai/update_canmove()
+ . = ..()
+ density = 0 //this is reset every canmove update otherwise
+
/mob/living/silicon/pai/examine(mob/user)
..(user)
diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm
index 083b3cd8d3b..b5587a50e5d 100644
--- a/code/modules/mob/living/silicon/robot/inventory.dm
+++ b/code/modules/mob/living/silicon/robot/inventory.dm
@@ -45,6 +45,13 @@
if(activated(O))
src << "Already activated"
return
+ if (is_component_functioning("power cell") && cell)
+ if(istype(O, /obj/item/borg))
+ var/obj/item/borg/B = O
+ if(B.powerneeded)
+ if((cell.charge * 100 / cell.maxcharge) < B.powerneeded)
+ src << "Not enough power to activate [B.name]!"
+ return
if(!module_state_1)
O.mouse_opacity = initial(O.mouse_opacity)
module_state_1 = O
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index f57da9153bf..533bc1f7a2b 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -13,40 +13,42 @@
process_locks()
process_queued_alarms()
-
/mob/living/silicon/robot/proc/clamp_values()
SetStunned(min(stunned, 30))
SetParalysis(min(paralysis, 30))
SetWeakened(min(weakened, 20))
sleeping = 0
ear_deaf = 0
- adjustBruteLoss(0)
- adjustToxLoss(0)
- adjustOxyLoss(0)
- adjustFireLoss(0)
-/mob/living/silicon/robot/proc/use_power()
+
+/mob/living/silicon/robot/proc/use_power()
if (is_component_functioning("power cell") && cell)
- if(src.cell.charge <= 0)
+ if(module)
+ for(var/obj/item/borg/B in module.modules)
+ if(B.powerneeded)
+ if((cell.charge * 100 / cell.maxcharge) < B.powerneeded)
+ src << "Deactivating [B.name] due to lack of power!"
+ unEquip(B)
+ if(cell.charge <= 0)
uneq_all()
update_headlamp(1)
- src.stat = UNCONSCIOUS
+ stat = UNCONSCIOUS
has_power = 0
for(var/V in components)
var/datum/robot_component/C = components[V]
if(C.name == "actuator") // Let drained robots move, disable the rest
continue
C.consume_power()
- else if (src.cell.charge <= 100)
+ else if(cell.charge <= 100)
uneq_all()
- src.cell.use(1)
+ cell.use(1)
else
- if(src.module_state_1)
- src.cell.use(4)
- if(src.module_state_2)
- src.cell.use(4)
- if(src.module_state_3)
- src.cell.use(4)
+ if(module_state_1)
+ cell.use(4)
+ if(module_state_2)
+ cell.use(4)
+ if(module_state_3)
+ cell.use(4)
for(var/V in components)
var/datum/robot_component/C = components[V]
@@ -57,133 +59,116 @@
if(!is_component_functioning("actuator"))
Paralyse(3)
- src.eye_blind = 0
- src.stat = 0
+ eye_blind = 0
+ stat = 0
has_power = 1
else
uneq_all()
- src.stat = UNCONSCIOUS
+ stat = UNCONSCIOUS
update_headlamp(1)
Paralyse(3)
-/mob/living/silicon/robot/handle_regular_status_updates()
-
- if(src.camera && !scrambledcodes)
- if(src.stat == 2 || wires.IsCameraCut())
- src.camera.status = 0
- else
- src.camera.status = 1
-
+/mob/living/silicon/robot/updatehealth()
+ if(status_flags & GODMODE)
+ health = maxHealth
+ stat = CONSCIOUS
+ return
health = maxHealth - (getOxyLoss() + getFireLoss() + getBruteLoss())
- if(getOxyLoss() > 50) Paralyse(3)
+/mob/living/silicon/robot/handle_regular_status_updates()
- if(src.sleeping)
+ . = ..()
+
+ if(camera && !scrambledcodes)
+ if(stat == DEAD || wires.IsCameraCut())
+ camera.status = 0
+ else
+ camera.status = 1
+
+ if(getOxyLoss() > 50)
Paralyse(3)
- src.sleeping--
- if(src.resting)
+ if(sleeping)
+ Paralyse(3)
+ sleeping--
+
+ if(resting)
Weaken(5)
- if(health <= config.health_threshold_dead && src.stat != 2) //die only once
- death()
+ if(.) //alive
+ if(health <= config.health_threshold_dead)
+ death()
+ return
- if (src.stat != 2) //Alive.
- if(!istype(src,/mob/living/silicon/robot/drone))
+ if(!istype(src, /mob/living/silicon/robot/drone))
if(health < 50) //Gradual break down of modules as more damage is sustained
if(uneq_module(module_state_3))
src << "SYSTEM ERROR: Module 3 OFFLINE."
+
if(health < 0)
if(uneq_module(module_state_2))
src << "SYSTEM ERROR: Module 2 OFFLINE."
+
if(health < -50)
if(uneq_module(module_state_1))
src << "CRITICAL ERROR: All modules OFFLINE."
- if (src.paralysis || src.stunned || src.weakened) //Stunned etc.
- src.stat = 1
- if (src.stunned > 0)
- AdjustStunned(-1)
- if (src.weakened > 0)
- AdjustWeakened(-1)
- if (src.paralysis > 0)
- AdjustParalysis(-1)
- src.eye_blind = max(eye_blind, 1)
- else
- src.eye_blind = 0
+ if(paralysis || stunned || weakened)
+ stat = UNCONSCIOUS
- else //Not stunned.
- src.stat = 0
+ if(!paralysis > 0)
+ eye_blind = 0
- else //Dead.
- src.eye_blind = 1
+ else
+ stat = CONSCIOUS
- if (src.stuttering) src.stuttering--
-
- if (src.eye_blind)
- src.eye_blind--
-
- src.density = !( src.lying )
-
- if (src.disabilities & BLIND)
- src.eye_blind = max(1, eye_blind)
-
- if (src.eye_blurry > 0)
- src.eye_blurry--
- src.eye_blurry = max(0, src.eye_blurry)
-
- if (src.druggy > 0)
- src.druggy--
- src.druggy = max(0, src.druggy)
+ else //dead
+ eye_blind = 1
//update the state of modules and components here
- if (src.stat != 0)
+ if(stat != CONSCIOUS)
uneq_all()
- if(!is_component_functioning("radio") || src.stat == 1)
+ if(!is_component_functioning("radio") || stat == UNCONSCIOUS)
radio.on = 0
else
radio.on = 1
- if(is_component_functioning("camera") && src.stat == 0)
- src.blinded = 0
+ if(is_component_functioning("camera") && stat == CONSCIOUS)
+ blinded = 0
else
- src.blinded = 1
+ blinded = 1
if(!is_component_functioning("actuator"))
- src.Paralyse(3)
-
- if(ticker && ticker.mode.name == "nations")
- process_nations()
+ Paralyse(3)
return 1
/mob/living/silicon/robot/update_sight()
-
- if (src.stat == 2 || src.sight_mode & BORGXRAY)
- src.sight |= SEE_TURFS
- src.sight |= SEE_MOBS
- src.sight |= SEE_OBJS
- src.see_in_dark = 8
- src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ if(stat == DEAD || sight_mode & BORGXRAY)
+ sight |= SEE_TURFS
+ sight |= SEE_MOBS
+ sight |= SEE_OBJS
+ see_in_dark = 8
+ see_invisible = SEE_INVISIBLE_LEVEL_TWO
else
- src.see_in_dark = 8
- if (src.sight_mode & BORGMESON && src.sight_mode & BORGTHERM)
- src.sight |= SEE_TURFS
- src.sight |= SEE_MOBS
- src.see_invisible = SEE_INVISIBLE_MINIMUM
- else if (src.sight_mode & BORGMESON)
- src.sight |= SEE_TURFS
- src.see_invisible = SEE_INVISIBLE_MINIMUM
- src.see_in_dark = 1
- else if (src.sight_mode & BORGTHERM)
- src.sight |= SEE_MOBS
- src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
- else if (src.stat != 2)
- src.sight &= ~SEE_MOBS
- src.sight &= ~SEE_TURFS
- src.sight &= ~SEE_OBJS
- src.see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ see_in_dark = 8
+ if(sight_mode & BORGMESON && sight_mode & BORGTHERM)
+ sight |= SEE_TURFS
+ sight |= SEE_MOBS
+ see_invisible = SEE_INVISIBLE_MINIMUM
+ else if(sight_mode & BORGMESON)
+ sight |= SEE_TURFS
+ see_invisible = SEE_INVISIBLE_MINIMUM
+ see_in_dark = 1
+ else if(sight_mode & BORGTHERM)
+ sight |= SEE_MOBS
+ see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ else if(stat != DEAD)
+ sight &= ~SEE_MOBS
+ sight &= ~SEE_TURFS
+ sight &= ~SEE_OBJS
+ see_invisible = SEE_INVISIBLE_LEVEL_TWO
if(see_override)
see_invisible = see_override
@@ -197,11 +182,11 @@
if(stat != DEAD)
if(health >= maxHealth)
healths.icon_state = "health0"
- else if(health > maxHealth*0.5)
+ else if(health > maxHealth * 0.5)
healths.icon_state = "health2"
else if(health > 0)
healths.icon_state = "health3"
- else if(health > -maxHealth*0.5)
+ else if(health > -maxHealth * 0.5)
healths.icon_state = "health4"
else if(health > -maxHealth)
healths.icon_state = "health5"
@@ -266,6 +251,7 @@
mind.special_role = "traitor"
ticker.mode.traitors += src.mind
+
..()
return 1
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 0c46fe17f96..06bd83ed96f 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -224,7 +224,9 @@ var/list/robot_verbs_default = list(
modules = list("Peacekeeper")
if(mmi != null && mmi.alien)
modules = "Hunter"
- modtype = input("Please, select a module!", "Robot", null, null) in modules
+ modtype = input("Please, select a module!", "Robot", null, null) as null|anything in modules
+ if(!modtype)
+ return
designation = modtype
var/module_sprites[0] //Used to store the associations between sprite names and sprite index.
@@ -1016,8 +1018,9 @@ var/list/robot_verbs_default = list(
icon_state = "[base_icon]-roll"
else
icon_state = base_icon
- if(activated(/obj/item/borg/combat/shield))
- overlays += "[base_icon]-shield"
+ for(var/obj/item/borg/combat/shield/S in module.modules)
+ if(activated(S))
+ overlays += "[base_icon]-shield"
if(jetpackoverlay)
overlays += "minerjetpack-[icon_state]"
@@ -1430,7 +1433,6 @@ var/list/robot_verbs_default = list(
//subsystems
module.add_subsystems(src)
- hands.icon_state = lowertext("Combat")
updatename()
status_flags &= ~CANPUSH
@@ -1438,7 +1440,6 @@ var/list/robot_verbs_default = list(
radio.config(module.channels)
notify_ai(2)
-
/mob/living/silicon/robot/peacekeeper/New()
..()
module = new /obj/item/weapon/robot_module/peacekeeper(src)
@@ -1450,7 +1451,6 @@ var/list/robot_verbs_default = list(
//subsystems
module.add_subsystems(src)
- hands.icon_state = lowertext("Combat")
updatename()
status_flags &= ~CANPUSH
diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm
index dbfcf15caa8..fb46c2547de 100644
--- a/code/modules/mob/living/silicon/robot/robot_items.dm
+++ b/code/modules/mob/living/silicon/robot/robot_items.dm
@@ -72,11 +72,15 @@
//Personal shielding for the combat module.
+/obj/item/borg
+ var/powerneeded // Percentage of power remaining required to run item
+
/obj/item/borg/combat/shield
name = "personal shielding"
desc = "A powerful experimental module that turns aside or absorbs incoming attacks at the cost of charge."
icon = 'icons/obj/decals.dmi'
icon_state = "shock"
+ powerneeded = 25
var/shield_level = 0.5 //Percentage of damage absorbed by the shield.
/obj/item/borg/combat/shield/verb/set_shield_level()
@@ -92,4 +96,5 @@
name = "mobility module"
desc = "By retracting limbs and tucking in its head, a combat android can roll at high speeds."
icon = 'icons/obj/decals.dmi'
- icon_state = "shock"
\ No newline at end of file
+ icon_state = "shock"
+ powerneeded = 25
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/bot_swarm/swarmer.dm b/code/modules/mob/living/simple_animal/bot_swarm/swarmer.dm
index eba943b5b66..83b74b11e9e 100644
--- a/code/modules/mob/living/simple_animal/bot_swarm/swarmer.dm
+++ b/code/modules/mob/living/simple_animal/bot_swarm/swarmer.dm
@@ -70,6 +70,8 @@
ventcrawler = 2
ranged = 1
ranged_cooldown_cap = 2
+ universal_speak = 0
+ universal_understand = 0
projectilesound = 'sound/weapons/taser2.ogg'
AIStatus = AI_OFF
var/resources = 0 //Resource points, generated by consuming metal/glass
diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
index 5e57e2c8f7e..68aeeb72616 100644
--- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm
@@ -94,11 +94,14 @@
bot_amt--
switch(bot_type)
if("norm")
- new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
+ var/mob/living/simple_animal/hostile/hivebot/H = new /mob/living/simple_animal/hostile/hivebot(get_turf(src))
+ H.faction = faction
if("range")
- new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
+ var/mob/living/simple_animal/hostile/hivebot/range/R = new /mob/living/simple_animal/hostile/hivebot/range(get_turf(src))
+ R.faction = faction
if("rapid")
- new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src))
+ var/mob/living/simple_animal/hostile/hivebot/rapid/F = new /mob/living/simple_animal/hostile/hivebot/rapid(get_turf(src))
+ F.faction = faction
spawn(100)
qdel(src)
return
diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm
index 62934f3e53e..a466d62306b 100644
--- a/code/modules/mob/living/simple_animal/hostile/statue.dm
+++ b/code/modules/mob/living/simple_animal/hostile/statue.dm
@@ -174,16 +174,11 @@
/mob/living/simple_animal/hostile/statue/say()
return 0
-//Turn to dust when gibbed
-/mob/living/simple_animal/hostile/statue/gib(var/animation = 0)
- dust(animation)
-
-/mob/living/simple_animal/hostile/statue/death()
- living_mob_list -= src
- dead_mob_list += src
- if(key)
- respawnable_list += src
- gib()
+/mob/living/simple_animal/hostile/statue/death(gibbed)
+ if(!gibbed) //The looping ends here.
+ dust()
+ return
+ return ..()
//Stop attacking clientless mobs
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index fdaebc34f8a..44d29f118b7 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -343,7 +343,7 @@
//Search for item to steal
parrot_interest = search_for_item()
if(parrot_interest)
- custom_emote(1,"looks in [parrot_interest]'s direction and takes flight")
+ custom_emote(1,"looks in [parrot_interest]'s direction and takes flight.")
parrot_state = PARROT_SWOOP | PARROT_STEAL
icon_state = "parrot_fly"
return
@@ -731,4 +731,4 @@
/mob/living/simple_animal/parrot/proc/parrot_hear(var/message="")
if(!message || stat)
return
- speech_buffer.Add(message)
\ No newline at end of file
+ speech_buffer.Add(message)
diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm
index a62839665d7..70edbc27dd3 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm
@@ -2,17 +2,22 @@
//"Ghosts" that are invisible and move like ghosts, cannot take damage while invsible
//Don't hear deadchat and are NOT normal ghosts
//Admin-spawn or random event
+#define INVISIBILITY_REVENANT 50
/mob/living/simple_animal/revenant
name = "revenant"
desc = "A malevolent spirit."
icon = 'icons/mob/mob.dmi'
icon_state = "revenant_idle"
+ var/icon_idle = "revenant_idle"
+ var/icon_reveal = "revenant_revealed"
+ var/icon_stun = "revenant_stun"
+ var/icon_drain = "revenant_draining"
incorporeal_move = 3
- invisibility = INVISIBILITY_OBSERVER
- health = 25
- maxHealth = 25
- see_invisible = SEE_INVISIBLE_OBSERVER
+ invisibility = INVISIBILITY_REVENANT
+ health = INFINITY //Revenants don't use health, they use essence instead
+ maxHealth = INFINITY
+ see_invisible = INVISIBILITY_REVENANT
universal_understand = 1
response_help = "passes through"
response_disarm = "swings at"
@@ -23,34 +28,43 @@
harm_intent_damage = 0
friendly = "touches"
status_flags = 0
+ see_in_dark = 8
wander = 0
density = 0
flying = 1
anchored = 1
- var/essence = 25 //The resource of revenants. Max health is equal to three times this amount
- var/essence_regen_cap = 25 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount.
+ var/essence = 75 //The resource of revenants. Max health is equal to three times this amount
+ var/essence_regen_cap = 75 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount.
var/essence_regenerating = 1 //If the revenant regenerates essence or not; 1 for yes, 0 for no
- var/essence_regen_amount = 2 //How much essence regenerates
- var/essence_min = 1 //The minimum amount of essence a revenant can have; by default, it never drops below one
+ var/essence_regen_amount = 5 //How much essence regenerates
var/essence_accumulated = 0 //How much essence the revenant has stolen
var/revealed = 0 //If the revenant can take damage from normal sources.
+ var/unreveal_time = 0 //How long the revenant is revealed for, is about 2 seconds times this var.
+ var/unstun_time = 0 //How long the revenant is stunned for, is about 2 seconds times this var.
var/inhibited = 0 //If the revenant's abilities are blocked by a chaplain's power.
var/essence_drained = 0 //How much essence the revenant has drained.
var/draining = 0 //If the revenant is draining someone.
var/list/drained_mobs = list() //Cannot harvest the same mob twice
+ var/perfectsouls = 0 //How many perfect, regen-cap increasing souls the revenant has.
+ var/image/ghostimage = null //Visible to ghost with darkness off
/mob/living/simple_animal/revenant/Life()
..()
- if(essence < essence_min)
- essence = essence_min
+ if(revealed && essence <= 0)
+ death()
if(essence_regenerating && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate
- essence += essence_regen_amount
- if(essence > essence_regen_cap)
- essence = essence_regen_cap
- maxHealth = essence * 3
- if(!revealed)
- health = maxHealth //Heals to full when not revealed
+ essence = min(essence_regen_cap, essence+essence_regen_amount)
+ if(unreveal_time && world.time >= unreveal_time)
+ unreveal_time = 0
+ revealed = 0
+ invisibility = INVISIBILITY_REVENANT
+ src << "You are once more concealed."
+ if(unstun_time && world.time >= unstun_time)
+ unstun_time = 0
+ notransform = 0
+ src << "You can move again!"
+ update_spooky_icon()
/mob/living/simple_animal/revenant/ex_act(severity)
return 1 //Immune to the effects of explosions.
@@ -58,6 +72,19 @@
/mob/living/simple_animal/revenant/blob_act()
return 1 //blah blah blobs aren't in tune with the spirit world, or something.
+/mob/living/simple_animal/revenant/singularity_act()
+ return //don't walk into the singularity expecting to find corpses, okay?
+
+/mob/living/simple_animal/revenant/narsie_act()
+ return //most humans will now be either bones or harvesters, but we're still un-alive.
+
+/mob/living/simple_animal/revenant/adjustBruteLoss(amount)
+ if(!revealed)
+ return
+ essence = max(0, essence-amount)
+ if(essence == 0)
+ src << "You feel your essence fraying!"
+
/mob/living/simple_animal/revenant/ClickOn(var/atom/A, var/params) //Copypaste from ghost code - revenants can't interact with the world directly.
if(client.buildmode)
build_click(src, client.buildmode, params, A)
@@ -87,62 +114,78 @@
if(!castcheck(0))
return
if(draining)
- src << "You are already siphoning the essence of a soul!"
+ src << "You are already siphoning the essence of a soul!"
return
if(target in drained_mobs)
- src << "[target]'s soul is dead and empty."
+ src << "[target]'s soul is dead and empty."
return
if(!target.stat)
- src << "This being's soul is too strong to harvest."
+ src << "This being's soul is too strong to harvest."
if(prob(10))
target << "You feel as if you are being watched."
return
draining = 1
- essence_drained = 2
- src << "You search for the soul of [target]."
+ essence_drained = rand(15, 20)
+ src << "You search for the soul of [target]."
if(do_after(src, 10, 3, 0, target = target)) //did they get deleted in that second?
if(target.ckey)
- src << "Their soul burns with intelligence."
- essence_drained += 2
+ src << "Their soul burns with intelligence."
+ essence_drained += rand(20, 30)
if(target.stat != DEAD)
- src << "Their soul blazes with life!"
- essence_drained += 2
+ src << "Their soul blazes with life!"
+ essence_drained += rand(40, 50)
else
- src << "Their soul is weak and faltering."
+ src << "Their soul is weak and faltering."
if(do_after(src, 20, 6, 0, target = target)) //did they get deleted NOW?
switch(essence_drained)
- if(1 to 2)
- src << "[target] will not yield much essence. Still, every bit counts."
- if(3 to 4)
- src << "[target] will yield an average amount of essence."
- if(5 to INFINITY)
- src << "Such a feast! [target] will yield much essence to you."
- if(do_after(src, 30, 9, 0, target = target)) //how about now
+ if(1 to 30)
+ src << "[target] will not yield much essence. Still, every bit counts."
+ if(30 to 70)
+ src << "[target] will yield an average amount of essence."
+ if(70 to 90)
+ src << "Such a feast! [target] will yield much essence to you."
+ if(90 to INFINITY)
+ src << "Ah, the perfect soul. [target] will yield massive amounts of essence to you."
+ if(do_after(src, 20, 6, 0, target = target)) //how about now
if(!target.stat)
- src << "They are now powerful enough to fight off your draining."
+ src << "They are now powerful enough to fight off your draining."
target << "You feel something tugging across your body before subsiding."
draining = 0
return //hey, wait a minute...
- src << "You begin siphoning essence from [target]'s soul."
+ src << "You begin siphoning essence from [target]'s soul."
if(target.stat != DEAD)
target << "You feel a horribly unpleasant draining sensation as your grip on life weakens..."
icon_state = "revenant_draining"
- reveal(65)
- stun(65)
+ reveal(27)
+ stun(27)
target.visible_message("[target] suddenly rises slightly into the air, their skin turning an ashy gray.")
- target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=60)
- if(target) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
- change_essence_amount(essence_drained * 5, 0, target)
- src << "[target]'s soul has been considerably weakened and will yield no more essence for the time being."
- target.visible_message("[target] gently slumps back onto the ground.")
+ target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=26)
+ if(do_after(src, 30, 9, 0, target)) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
+ change_essence_amount(essence_drained, 0, target)
+ if(essence_drained > 90)
+ essence_regen_cap += 25
+ perfectsouls += 1
+ src << "The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap]."
+ src << "[target]'s soul has been considerably weakened and will yield no more essence for the time being."
+ target.visible_message("[target] slumps onto the ground.", \
+ "Violets lights, dancing in your vision, getting clo--")
drained_mobs.Add(target)
target.death(0)
- icon_state = "revenant_idle"
+ else
+ src << "[target ? "[target] has":"They have"] been drawn out of your grasp. The link has been broken."
+ draining = 0
+ essence_drained = 0
+ if(target) //Wait, target is WHERE NOW?
+ target.visible_message("[target] slumps onto the ground.", \
+ "Violets lights, dancing in your vision, receding--")
+ return
else
- src << "You are not close enough to siphon [target]'s soul. The link has been broken."
+ src << "You are not close enough to siphon [target ? "[target]'s":"their"] soul. The link has been broken."
draining = 0
+ essence_drained = 0
return
draining = 0
+ essence_drained = 0
return
/mob/living/simple_animal/revenant/say(message)
@@ -151,11 +194,17 @@
/mob/living/simple_animal/revenant/Stat()
..()
if(statpanel("Status"))
- stat(null, "Current essence: [essence]E")
+ stat(null, "Current essence: [essence]/[essence_regen_cap]E")
stat(null, "Stolen essence: [essence_accumulated]E")
+ stat(null, "Stolen perfect souls: [perfectsouls]")
/mob/living/simple_animal/revenant/New()
..()
+
+ ghostimage = image(src.icon,src,src.icon_state)
+ ghost_darkness_images |= ghostimage
+ updateallghostimages()
+
spawn(5)
if(src.mind)
src.mind.wipe_memory()
@@ -164,8 +213,8 @@
src << "You are a revenant."
src << "Your formerly mundane spirit has been infused with alien energies and empowered into a revenant."
src << "You are not dead, not alive, but somewhere in between. You are capable of limited interaction with both worlds."
- src << "You are invincible and invisible to everyone but other ghosts. Some abilities may change this."
- src << "To function, you are to drain the life essence from humans. This essence is a resource and will power all of your abilities."
+ src << "You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable."
+ src << "To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities."
src << "You do not remember anything of your past lives, nor will you remember anything about this one after your death."
src << "Be sure to read the wiki page at http://nanotrasen.se/wiki/index.php/Revenant to learn more."
var/datum/objective/revenant/objective = new
@@ -186,17 +235,21 @@
/mob/living/simple_animal/revenant/proc/giveSpells()
if(src.mind)
- src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_harvest
- src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_transmit
- src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_light
- src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile
- src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf
+ src.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null))
+ src.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/overload(null))
+ src.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/defile(null))
+ src.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction(null))
return 1
return 0
/mob/living/simple_animal/revenant/death()
..()
- src << "NO! No... it's too late, you can feel yourself fading..."
+ if(!revealed) //Revenants cannot die if they aren't revealed
+ return
+ ghost_darkness_images -= ghostimage
+ updateallghostimages()
+
+ src << "NO! No... it's too late, you can feel your essence breaking apart..."
notransform = 1
revealed = 1
invisibility = 0
@@ -206,8 +259,9 @@
for(var/i = alpha, i > 0, i -= 10)
sleep(0.1)
alpha = i
- visible_message("[src]'s body breaks apart into blue dust.")
- new /obj/item/weapon/ectoplasm/revenant(get_turf(src))
+ visible_message("[src]'s body breaks apart into a fine pile of blue dust.")
+ var/obj/item/weapon/ectoplasm/revenant/R = new (get_turf(src))
+ R.client_to_revive = src.client //If the essence reforms, the old revenant is put back in the body
ghostize()
qdel(src)
return
@@ -216,8 +270,8 @@
/mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params)
if(istype(W, /obj/item/weapon/nullrod))
visible_message("[src] violently flinches!", \
- "As the null rod passes through you, you feel your essence draining away!")
- essence -= 25 //hella effective
+ "As the null rod passes through you, you feel your essence draining away!")
+ adjustBruteLoss(25) //hella effective
inhibited = 1
spawn(30)
inhibited = 0
@@ -229,13 +283,13 @@
return
var/turf/T = get_turf(src)
if(istype(T, /turf/simulated/wall))
- src << "You cannot use abilities from inside of a wall."
+ src << "You cannot use abilities from inside of a wall."
return 0
if(src.inhibited)
- src << "Your powers have been suppressed by nulling energy!"
+ src << "Your powers have been suppressed by nulling energy!"
return 0
if(!src.change_essence_amount(essence_cost, 1))
- src << "You lack the essence to use that ability."
+ src << "You lack the essence to use that ability."
return 0
return 1
@@ -244,16 +298,14 @@
return
if(essence + essence_amt <= 0)
return
- essence += essence_amt
- essence = max(0, essence)
+ essence = max(0, essence+essence_amt)
if(essence_amt > 0)
- essence_accumulated += essence_amt
- essence_accumulated = max(0, essence_accumulated)
+ essence_accumulated = max(0, essence_accumulated+essence_amt)
if(!silent)
if(essence_amt > 0)
- src << "Gained [essence_amt]E from [source]."
+ src << "Gained [essence_amt]E from [source]."
else
- src << "Lost [essence_amt]E from [source]."
+ src << "Lost [essence_amt]E from [source]."
return 1
/mob/living/simple_animal/revenant/proc/reveal(time)
@@ -263,11 +315,13 @@
return
revealed = 1
invisibility = 0
- src << "You have been revealed."
- spawn(time)
- revealed = 0
- invisibility = INVISIBILITY_OBSERVER
- src << "You are once more concealed."
+ if(!unreveal_time)
+ src << "You have been revealed!"
+ unreveal_time = world.time + time
+ else
+ src << "You have been revealed!"
+ unreveal_time = unreveal_time + time
+ update_spooky_icon()
/mob/living/simple_animal/revenant/proc/stun(time)
if(!src)
@@ -275,16 +329,31 @@
if(time <= 0)
return
notransform = 1
- src << "You cannot move!"
- spawn(time)
- notransform = 0
- src << "You can move again!"
+ if(!unstun_time)
+ src << "You cannot move!"
+ unstun_time = world.time + time
+ else
+ src << "You cannot move!"
+ unstun_time = unstun_time + time
+ update_spooky_icon()
+
+/mob/living/simple_animal/revenant/proc/update_spooky_icon()
+ if(revealed)
+ if(notransform)
+ if(draining)
+ icon_state = icon_drain
+ else
+ icon_state = icon_stun
+ else
+ icon_state = icon_reveal
+ else
+ icon_state = icon_idle
/datum/objective/revenant
var/targetAmount = 100
/datum/objective/revenant/New()
- targetAmount = rand(100,200)
+ targetAmount = rand(200,500)
explanation_text = "Absorb [targetAmount] points of essence from humans."
..()
@@ -321,27 +390,23 @@
icon = 'icons/effects/effects.dmi'
icon_state = "revenantEctoplasm"
w_class = 2
- var/reforming = 0
- var/reformed = 0
+ var/reforming = 1
+ var/inert = 0
+ var/client/client_to_revive
/obj/item/weapon/ectoplasm/revenant/New()
..()
- reforming = 1
+ reforming = 0
spawn(600) //1 minutes
if(src && reforming)
return reform()
- if(src && !reforming)
+ else
+ inert = 1
visible_message("[src] settles down and seems lifeless.")
return
-/obj/item/weapon/ectoplasm/revenant/attack_hand(mob/user)
- if(reformed)
- user << "[src] keeps slipping out of your hands, you can't get a hold on it!"
- return
- ..()
-
/obj/item/weapon/ectoplasm/revenant/attack_self(mob/user)
- if(!reforming)
+ if(!reforming || inert)
return ..()
user.visible_message("[user] scatters [src] in all directions.", \
"You scatter [src] across the area. The particles slowly fade away.")
@@ -350,39 +415,58 @@
/obj/item/weapon/ectoplasm/revenant/throw_impact(atom/hit_atom)
..()
+ if(inert)
+ return
visible_message("[src] breaks into particles upon impact, which fade away to nothingness.")
qdel(src)
/obj/item/weapon/ectoplasm/revenant/examine(mob/user)
..(user)
- if(reforming)
- user << "It is shifting and distorted. It would be wise to destroy this."
- else if(!reforming)
- user << "It seems inert."
+ if(inert)
+ user << "It seems inert."
+ else if(reforming)
+ user << "It is shifting and distorted. It would be wise to destroy this."
/obj/item/weapon/ectoplasm/revenant/proc/reform()
- if(!reforming || !src)
+ if(inert || !src)
return
- message_admins("Revenant ectoplasm was left undestroyed for 1 minute and has reformed into a new revenant.")
+ var/key_of_revenant
+ message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.")
loc = get_turf(src) //In case it's in a backpack or someone's hand
- visible_message("[src] suddenly rises into the air before fading away.")
var/mob/living/simple_animal/revenant/R = new(get_turf(src))
- qdel(src)
- var/list/candidates = get_candidates(BE_REVENANT)
- if(!candidates.len)
- message_admins("No candidates were found for the new revenant. Oh well!")
- return 0
- var/client/C = pick(candidates)
- var/key_of_revenant = C.key
+ if(client_to_revive)
+ for(var/mob/M in dead_mob_list)
+ if(M.client == client_to_revive) //Only recreates the mob if the mob the client is in is dead
+ R.client = client_to_revive
+ key_of_revenant = client_to_revive.key
+
if(!key_of_revenant)
- message_admins("No ckey was found for the new revenant. Oh well!")
- return 0
+ message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...")
+ var/list/candidates = get_candidates(BE_REVENANT)
+ if(!candidates.len)
+ qdel(R)
+ message_admins("No candidates were found for the new revenant. Oh well!")
+ inert = 1
+ visible_message("[src] settles down and seems lifeless.")
+ return 0
+ var/client/C = pick(candidates)
+ key_of_revenant = C.key
+ if(!key_of_revenant)
+ qdel(R)
+ message_admins("No ckey was found for the new revenant. Oh well!")
+ inert = 1
+ visible_message("[src] settles down and seems lifeless.")
+ return 0
var/datum/mind/player_mind = new /datum/mind(key_of_revenant)
player_mind.active = 1
player_mind.transfer_to(R)
player_mind.assigned_role = "revenant"
player_mind.special_role = "Revenant"
ticker.mode.traitors |= player_mind
- message_admins("[key_of_revenant] has been made into a revenant by reforming ectoplasm.")
- log_game("[key_of_revenant] was spawned as a revenant by reforming ectoplasm.")
+ message_admins("[key_of_revenant] has been [client_to_revive ? "re":""]made into a revenant by reforming ectoplasm.")
+ log_game("[key_of_revenant] was [client_to_revive ? "re":""]made as a revenant by reforming ectoplasm.")
+ visible_message("[src] suddenly rises into the air before fading away.")
+ qdel(src)
+ if(src) //Should never happen, but just in case
+ inert = 1
return 1
diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
index 5838f8de600..02f231d7f73 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
@@ -1,18 +1,4 @@
-//Harvest Essence: The bread and butter of the revenant. The basic way of harvesting additional essence.
-/obj/effect/proc_holder/spell/targeted/revenant_harvest
- name = "Harvest"
- desc = "Siphons the lingering spectral essence from a human, empowering yourself."
- panel = "Revenant Abilities"
- charge_max = 0 //Short cooldown
- clothes_req = 0
- range = 1
-
-/obj/effect/proc_holder/spell/targeted/revenant_harvest/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- for(var/mob/living/carbon/human/target in targets)
- spawn(0)
- user.Harvest(target)
-
-//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob for 5E.
+//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob
/obj/effect/proc_holder/spell/targeted/revenant_transmit
name = "Transmit"
desc = "Telepathically transmits a message to the target."
@@ -21,155 +7,185 @@
clothes_req = 0
range = 7
include_user = 0
+ action_icon_state = "r_transmit"
+ action_background_icon_state = "bg_revenant"
-/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
+/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
for(var/mob/living/M in targets)
spawn(0)
var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
if(!msg)
charge_counter = charge_max
return
- log_say("Revenant Transmit: [key_name(usr)]->[key_name(M)]: [msg]")
- usr << "You transmit to [M]: [msg]"
- M << "A strange voice resonates in your head... [msg]"
- for(var/mob/dead/observer/G in player_list)
- G.show_message("Revenant message from [usr] ([ghost_follow_link(usr, ghost=G)]) to [M] ([ghost_follow_link(M, ghost=G)]): [msg]")
+ log_say("RevenantTransmit: [key_name(user)]->[key_name(M)] : [msg]")
+ usr << "You transmit to [M]: [msg]"
+ M << "An alien voice resonates from all around... [msg]"
+/obj/effect/proc_holder/spell/aoe_turf/revenant
+ clothes_req = 0
+ action_background_icon_state = "bg_revenant"
+ panel = "Revenant Abilities (Locked)"
+ name = "Report this to a coder"
+ var/reveal = 80 //How long it reveals the revenant in deciseconds
+ var/stun = 20 //How long it stuns the revenant in deciseconds
+ var/locked = 1 //If it's locked and needs to be unlocked before use
+ var/unlock_amount = 100 //How much essence it costs to unlock
+ var/cast_amount = 50 //How much essence it costs to use
+
+/obj/effect/proc_holder/spell/aoe_turf/revenant/New()
+ ..()
+ if(locked)
+ name = "[initial(name)] ([unlock_amount]E)"
+ else
+ name = "[initial(name)] ([cast_amount]E)"
+
+/obj/effect/proc_holder/spell/aoe_turf/revenant/can_cast(mob/living/simple_animal/revenant/user = usr)
+ if(user.inhibited)
+ return 0
+ if(charge_counter < charge_max)
+ return 0
+ if(locked)
+ if(user.essence <= unlock_amount)
+ return 0
+ if(user.essence <= cast_amount)
+ return 0
+ return 1
+
+/obj/effect/proc_holder/spell/aoe_turf/revenant/proc/attempt_cast(mob/living/simple_animal/revenant/user = usr)
+ if(locked)
+ if(!user.castcheck(-unlock_amount))
+ charge_counter = charge_max
+ return 0
+ name = "[initial(name)] ([cast_amount]E)"
+ user << "You have unlocked [initial(name)]!"
+ panel = "Revenant Abilities"
+ locked = 0
+ charge_counter = charge_max
+ return 0
+ if(!user.castcheck(-cast_amount))
+ charge_counter = charge_max
+ return 0
+ name = "[initial(name)] ([cast_amount]E)"
+ user.reveal(reveal)
+ user.stun(stun)
+ user.update_action_buttons()
+ return 1
+
//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people.
-/obj/effect/proc_holder/spell/aoe_turf/revenant_light
- name = "Overload Light (30E)"
+/obj/effect/proc_holder/spell/aoe_turf/revenant/overload
+ name = "Overload Lights"
desc = "Directs a large amount of essence into nearby electrical lights, causing lights to shock those nearby."
- panel = "Revenant Abilities (Locked)"
charge_max = 200
- clothes_req = 0
- range = 1
- var/reveal = 80
- var/stun = 20
- var/locked = 1
+ range = 5
+ stun = 30
+ cast_amount = 45
+ var/shock_range = 2
+ var/shock_damage = 18
+ action_icon_state = "overload_lights"
-/obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(locked)
- if(!user.castcheck(-30))
- charge_counter = charge_max
- return
- user << "You have unlocked Overload Lights!"
- name = "Overload Lights (20E)"
- panel = "Revenant Abilities"
- locked = 0
- range = 6
- charge_counter = charge_max
- return
- if(!user.castcheck(-20))
- charge_counter = charge_max
- return
- for(var/turf/T in targets)
- spawn(0)
- for(var/obj/machinery/light/L in T.contents)
- spawn(0)
- if(!L.on)
- return
- L.visible_message("\The [L] suddenly flares brightly and begins to spark!")
- sleep(10)
- var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread
- s.set_up(4, 1, L)
- s.start()
- sleep(10)
- for(var/mob/living/M in orange(4, L))
- if(M == user)
+/obj/effect/proc_holder/spell/aoe_turf/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
+ if(attempt_cast(user))
+ for(var/turf/T in targets)
+ spawn(0)
+ for(var/obj/machinery/light/L in T.contents)
+ spawn(0)
+ if(!L.on)
return
- M.Beam(L,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
- M.electrocute_act(25, "[L.name]")
- var/datum/effect/system/spark_spread/z = new /datum/effect/system/spark_spread
- z.set_up(4, 1, M)
- z.start()
- playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
- user.reveal(reveal)
- user.stun(stun)
+ L.visible_message("\The [L] suddenly flares brightly and begins to spark!")
+ var/datum/effect/system/spark_spread/s = new /datum/effect/system/spark_spread/
+ s.set_up(4, 0, L)
+ s.start()
+ new/obj/effect/overlay/temp/revenant(L.loc)
+ sleep(20)
+ if(!L.on) //wait, wait, don't shock me
+ return
+ flick("[L.base_state]2", L)
+ for(var/mob/living/carbon/human/M in view(shock_range, L))
+ if(M == user)
+ return
+ M.Beam(L,icon_state="purple_lightning",icon='icons/effects/effects.dmi',time=5)
+ M.electrocute_act(shock_damage, "[L.name]")
+ var/datum/effect/system/spark_spread/z = new /datum/effect/system/spark_spread/
+ z.set_up(4, 0, M)
+ z.start()
+ playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
//Defile: Corrupts nearby stuff, unblesses floor tiles.
-/obj/effect/proc_holder/spell/aoe_turf/revenant_defile
- name = "Defile (35E)"
- desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors, but not salt lines."
- panel = "Revenant Abilities (Locked)"
- charge_max = 200
- clothes_req = 0
- range = 1
- var/reveal = 100
- var/stun = 20
- var/locked = 1
+/obj/effect/proc_holder/spell/aoe_turf/revenant/defile
+ name = "Defile"
+ desc = "Twists and corrupts the nearby area as well as dispelling holy auras on floors."
+ charge_max = 150
+ range = 3
+ unlock_amount = 75
+ cast_amount = 40
+ action_icon_state = "defile"
+ var/stamdamage= 25
+ var/toxdamage = 5
+ var/confusion = 50
-/obj/effect/proc_holder/spell/aoe_turf/revenant_defile/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(locked)
- if(!user.castcheck(-35))
- charge_counter = charge_max
- return
- user << "You have unlocked Defile!"
- name = "Defile (20E)"
- panel = "Revenant Abilities"
- locked = 0
- range = 3
- charge_counter = charge_max
- return
- if(!user.castcheck(-20))
- charge_counter = charge_max
- return
- for(var/turf/T in targets)
- spawn(0)
- if(T.flags & NOJAUNT)
- T.flags -= NOJAUNT
- if(!istype(T, /turf/simulated/wall/cult) && istype(T, /turf/simulated/wall) && prob(40))
- T.ChangeTurf(/turf/simulated/wall/cult)
- if(!istype(T, /turf/simulated/floor/engine/cult) && istype(T, /turf/simulated/floor) && prob(40))
- T.ChangeTurf(/turf/simulated/floor/engine/cult)
- for(var/mob/living/carbon/human/human in T.contents)
- human << "You suddenly feel tired."
- human.adjustStaminaLoss(35)
- for(var/obj/structure/window/window in T.contents)
- window.hit(rand(50,125))
- for(var/obj/machinery/light/light in T.contents)
- light.flicker() //spooky
- user.reveal(reveal)
- user.stun(stun)
+/obj/effect/proc_holder/spell/aoe_turf/revenant/defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
+ if(attempt_cast(user))
+ for(var/turf/T in targets)
+ spawn(0)
+ if(T.flags & NOJAUNT)
+ T.flags -= NOJAUNT
+ new/obj/effect/overlay/temp/revenant(T)
+ for(var/mob/living/carbon/human/human in T.contents)
+ human << "You suddenly feel [pick("sick and tired", "tired and confused", "nauseated", "dizzy")]."
+ human.adjustStaminaLoss(stamdamage)
+ human.adjustToxLoss(toxdamage)
+ human.confused += confusion
+ new/obj/effect/overlay/temp/revenant(human.loc)
+ if(!istype(T, /turf/simulated/shuttle) && !istype(T, /turf/simulated/wall/rust) && !istype(T, /turf/simulated/wall/r_wall) && istype(T, /turf/simulated/wall) && prob(15))
+ new/obj/effect/overlay/temp/revenant(T)
+ T.ChangeTurf(/turf/simulated/wall/rust)
+ if(!istype(T, /turf/simulated/wall/r_wall/rust) && istype(T, /turf/simulated/wall/r_wall) && prob(15))
+ new/obj/effect/overlay/temp/revenant(T)
+ T.ChangeTurf(/turf/simulated/wall/r_wall/rust)
+ for(var/obj/structure/window/window in T.contents)
+ window.hit(rand(50,90))
+ if(window && window.is_fulltile())
+ new/obj/effect/overlay/temp/revenant/cracks(window.loc)
+ for(var/obj/machinery/light/light in T.contents)
+ light.flicker(30) //spooky
//Malfunction: Makes bad stuff happen to robots and machines.
-/obj/effect/proc_holder/spell/aoe_turf/revenant_malf
- name = "Malfunction (50E)"
+/obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction
+ name = "Malfunction"
desc = "Corrupts and damages nearby machines and mechanical objects."
- panel = "Revenant Abilities (Locked)"
- charge_max = 150
- clothes_req = 0
- range = 1
- var/reveal = 60
- var/stun = 30
- var/locked = 1
+ charge_max = 200
+ range = 4
+ unlock_amount = 150
+ action_icon_state = "malfunction"
-/obj/effect/proc_holder/spell/aoe_turf/revenant_malf/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
- if(locked)
- if(!user.castcheck(-50))
- charge_counter = charge_max
- return
- user << "You have unlocked Malfunction!"
- name = "Malfunction (15E)"
- panel = "Revenant Abilities"
- locked = 0
- range = 4
- charge_counter = charge_max
- return
- if(!user.castcheck(-15))
- charge_counter = charge_max
- return
- for(var/turf/T in targets)
- spawn(0)
- for(var/obj/machinery/bot/bot in T.contents)
- if(!bot.emagged)
- bot.locked = 0
- bot.open = 1
- bot.Emag(null)
- for(var/obj/machinery/mach in T.contents)
- if(prob(10))
- mach.emag_act(null)
-
- empulse(user.loc, 3, 5)
- user.reveal(reveal)
- user.stun(stun)
+//A note to future coders: do not replace this with an EMP because it will wreck malf AIs and gang dominators and everyone will hate you.
+/obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
+ if(attempt_cast(user))
+ for(var/turf/T in targets)
+ spawn(0)
+ for(var/obj/machinery/bot/bot in T.contents)
+ if(!bot.emagged)
+ new/obj/effect/overlay/temp/revenant(bot.loc)
+ bot.locked = 0
+ bot.open = 1
+ bot.Emag(null)
+ for(var/mob/living/carbon/human/human in T.contents)
+ human << "You feel [pick("your sense of direction flicker out", "a stabbing pain in your head", "your mind fill with static")]."
+ new/obj/effect/overlay/temp/revenant(human.loc)
+ human.emp_act(1)
+ for(var/obj/thing in T.contents)
+ if(istype(thing, /obj/machinery/power/apc) || istype(thing, /obj/machinery/power/smes) || istype(thing, /obj/machinery/bot)) //Doesn't work on dominators, SMES and APCs, to prevent kekkery
+ continue
+ if(prob(20))
+ if(prob(50))
+ new/obj/effect/overlay/temp/revenant(thing.loc)
+ thing.emag_act(null)
+ else
+ if(!istype(thing, /obj/machinery/clonepod)) //I hate everything but mostly the fact there's no better way to do this without just not affecting it at all
+ thing.emp_act(1)
+ for(var/mob/living/silicon/robot/S in T.contents) //Only works on cyborgs, not AI
+ playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1)
+ new/obj/effect/overlay/temp/revenant(S.loc)
+ S.spark_system.start()
+ S.emp_act(1)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/vox.dm b/code/modules/mob/living/simple_animal/vox.dm
index 3929e9f8f75..e48c7f81d3d 100644
--- a/code/modules/mob/living/simple_animal/vox.dm
+++ b/code/modules/mob/living/simple_animal/vox.dm
@@ -22,15 +22,14 @@
var/amp = null
var/quills = 3
-/mob/living/simple_animal/vox/armalis/death()
-
- living_mob_list -= src
- dead_mob_list += src
- stat = DEAD
- visible_message("\red [src] shudders violently and explodes!","\red You feel your body rupture!")
- explosion(get_turf(loc), -1, -1, 3, 5)
- src.gib()
- return
+/mob/living/simple_animal/vox/armalis/death(gibbed)
+ if(!gibbed)
+ stat = DEAD
+ visible_message("[src] shudders violently and explodes!","\red You feel your body rupture!")
+ explosion(get_turf(loc), -1, -1, 3, 5)
+ gib()
+ return
+ return ..()
/mob/living/simple_animal/vox/armalis/attackby(var/obj/item/O as obj, var/mob/user as mob, params)
if(O.force)
diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm
index 6f9e9ad1440..c6f9c2814c7 100644
--- a/code/modules/mob/new_player/preferences_setup.dm
+++ b/code/modules/mob/new_player/preferences_setup.dm
@@ -5,9 +5,9 @@ datum/preferences
gender = gender_override
else
gender = pick(MALE, FEMALE)
- underwear = random_underwear(gender)
- undershirt = random_undershirt(gender)
- socks = random_socks(gender)
+ underwear = random_underwear(gender, species)
+ undershirt = random_undershirt(gender, species)
+ socks = random_socks(gender, species)
if(species == "Human")
s_tone = random_skin_tone()
h_style = random_hair_style(gender, species)
@@ -223,7 +223,18 @@ datum/preferences
//Tail
if(current_species && (current_species.bodyflags & HAS_TAIL))
- var/icon/temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[current_species.tail]_s")
+ var/tail_icon
+ var/tail_icon_state
+
+ if(body_accessory)
+ var/datum/body_accessory/accessory = body_accessory_by_name[body_accessory]
+ tail_icon = accessory.icon
+ tail_icon_state = accessory.icon_state
+ else
+ tail_icon = "icons/effects/species.dmi"
+ tail_icon_state = "[current_species.tail]_s"
+
+ var/icon/temp = new /icon("icon" = tail_icon, "icon_state" = tail_icon_state)
preview_icon.Blend(temp, ICON_OVERLAY)
// Skin color
@@ -257,19 +268,19 @@ datum/preferences
if(underwear && current_species.clothing_flags & HAS_UNDERWEAR)
var/datum/sprite_accessory/underwear/U = underwear_list[underwear]
if(U)
- underwear_s = new/icon(U.icon, "[U.icon_state]_s", ICON_OVERLAY)
+ underwear_s = new/icon(U.icon, "uw_[U.icon_state]_s", ICON_OVERLAY)
var/icon/undershirt_s = null
if(undershirt && current_species.clothing_flags & HAS_UNDERSHIRT)
var/datum/sprite_accessory/undershirt/U2 = undershirt_list[undershirt]
if(U2)
- undershirt_s = new/icon(U2.icon, "[U2.icon_state]_s", ICON_OVERLAY)
+ undershirt_s = new/icon(U2.icon, "us_[U2.icon_state]_s", ICON_OVERLAY)
var/icon/socks_s = null
if(socks && current_species.clothing_flags & HAS_SOCKS)
var/datum/sprite_accessory/socks/U3 = socks_list[socks]
if(U3)
- socks_s = new/icon(U3.icon, "[U3.icon_state]_s", ICON_OVERLAY)
+ socks_s = new/icon(U3.icon, "sk_[U3.icon_state]_s", ICON_OVERLAY)
var/icon/clothes_s = null
var/uniform_dmi='icons/mob/uniform.dmi'
diff --git a/code/modules/mob/new_player/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories.dm
index 0fd9804bd46..50183e4e506 100644
--- a/code/modules/mob/new_player/sprite_accessories.dm
+++ b/code/modules/mob/new_player/sprite_accessories.dm
@@ -28,11 +28,11 @@
L[D.name] = D
switch(D.gender)
- if(MALE) male += D.name
- if(FEMALE) female += D.name
+ if(MALE) male[D.name] = D
+ if(FEMALE) female[D.name] = D
else
- male += D.name
- female += D.name
+ male[D.name] = D
+ female[D.name] = D
return L
/datum/sprite_accessory
@@ -115,16 +115,17 @@
icon_state = "hair_halfbang_alt"
ponytail1
- name = "Ponytail 1"
- icon_state = "hair_ponytail"
+ name = "Ponytail male"
+ icon_state = "hair_ponytailm"
+ gender = MALE
ponytail2
- name = "Ponytail 2"
- icon_state = "hair_pa"
+ name = "Ponytail female"
+ icon_state = "hair_ponytailf"
gender = FEMALE
ponytail3
- name = "Ponytail 3"
+ name = "Ponytail alt"
icon_state = "hair_ponytail3"
sideponytail
@@ -132,6 +133,17 @@
icon_state = "hair_stail"
gender = FEMALE
+ highponytail
+ name = "High Ponytail"
+ icon_state = "hair_highponytail"
+ gender = FEMALE
+
+
+ wisp
+ name = "Wisp"
+ icon_state = "hair_wisp"
+ gender = FEMALE
+
parted
name = "Parted"
icon_state = "hair_parted"
@@ -316,6 +328,7 @@
name = "Balding Hair"
icon_state = "hair_e"
gender = MALE // turnoff!
+
//////////////////////////////
//////START VG HAIRSTYLES/////
//////////////////////////////
@@ -1006,7 +1019,7 @@
/datum/sprite_accessory/underwear
icon = 'icons/mob/underwear.dmi'
- species_allowed = list("Human","Unathi","Vox","Diona","Kidan","Grey","Plasmaman","Skellington")
+ species_allowed = list("Human","Unathi","Vox","Diona","Vulpkanin","Kidan","Grey","Plasmaman","Skellington")
nude
name = "Nude"
@@ -1079,7 +1092,7 @@
/datum/sprite_accessory/undershirt
icon = 'icons/mob/underwear.dmi'
- species_allowed = list("Human","Unathi","Vox","Diona","Kidan","Grey","Plasmaman","Skellington")
+ species_allowed = list("Human","Unathi","Vox","Diona","Vulpkanin","Kidan","Grey","Plasmaman","Skellington")
/datum/sprite_accessory/undershirt/nude
name = "Nude"
@@ -1318,6 +1331,7 @@
///////////////////////
/datum/sprite_accessory/socks
icon = 'icons/mob/underwear.dmi'
+ species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/nude
name = "Nude"
@@ -1330,111 +1344,95 @@
name = "Normal White"
icon_state = "white_norm"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/black_norm
name = "Normal Black"
icon_state = "black_norm"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/white_short
name = "Short White"
icon_state = "white_short"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/black_short
name = "Short Black"
icon_state = "black_short"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/white_knee
name = "Knee-high White"
icon_state = "white_knee"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/black_knee
name = "Knee-high Black"
icon_state = "black_knee"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/thin_knee
name = "Knee-high Thin"
icon_state = "thin_knee"
gender = FEMALE
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/striped_knee
name = "Knee-high Striped"
icon_state = "striped_knee"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/rainbow_knee
name = "Knee-high Rainbow"
icon_state = "rainbow_knee"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/white_thigh
name = "Thigh-high White"
icon_state = "white_thigh"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/black_thigh
name = "Thigh-high Black"
icon_state = "black_thigh"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/thin_thigh
name = "Thigh-high Thin"
icon_state = "thin_thigh"
gender = FEMALE
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/striped_thigh
name = "Thigh-high Striped"
icon_state = "striped_thigh"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/rainbow_thigh
name = "Thigh-high Rainbow"
icon_state = "rainbow_thigh"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/pantyhose
name = "Pantyhose"
icon_state = "pantyhose"
gender = FEMALE
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/black_fishnet
name = "Black Fishnet"
icon_state = "black_fishnet"
gender = NEUTER
- species_allowed = list("Human","Unathi","Diona","Grey","Machine","Tajaran","Vulpkanin","Slime People","Skellington")
/datum/sprite_accessory/socks/vox_white
name = "Vox White"
diff --git a/code/modules/nano/modules/atmos_control.dm b/code/modules/nano/modules/atmos_control.dm
index 52da17c2c82..e43585243ae 100644
--- a/code/modules/nano/modules/atmos_control.dm
+++ b/code/modules/nano/modules/atmos_control.dm
@@ -3,7 +3,7 @@
var/obj/access = new()
var/emagged = 0
var/ui_ref
- var/list/monitored_alarms = list()
+ var/list/monitored_alarms = null
/datum/nano_module/atmos_control/New(atmos_computer, req_access, req_one_access, monitored_alarm_ids)
..()
@@ -23,7 +23,7 @@
if(href_list["alarm"])
if(ui_ref)
- var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms.len ? monitored_alarms : machines)
+ var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms ? monitored_alarms : machines)
if(alarm)
var/datum/topic_state/TS = generate_state(alarm)
alarm.ui_interact(usr, master_ui = ui_ref, state = TS)
diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm
index 8d8242cba70..173723bf4cb 100644
--- a/code/modules/paperwork/folders.dm
+++ b/code/modules/paperwork/folders.dm
@@ -35,8 +35,12 @@
user << "You put the [W] into \the [src]."
update_icon()
else if(istype(W, /obj/item/weapon/pen))
- var/n_name = sanitize(copytext(input(usr, "What would you like to label the folder?", "Folder Labelling", null) as text, 1, MAX_NAME_LEN))
- if((loc == usr && usr.stat == 0))
+ var/n_name = input(usr, "What would you like to label the folder?", "Folder Labelling", null) as text|null
+ if(!n_name)
+ return
+ n_name = sanitize(copytext(n_name, 1, MAX_NAME_LEN))
+
+ if((loc == usr || Adjacent(usr)) && usr.stat == 0)
name = "folder[(n_name ? text("- '[n_name]'") : null)]"
return
diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm
index f98c01072f6..47e1546de1a 100644
--- a/code/modules/reagents/Chemistry-Holder.dm
+++ b/code/modules/reagents/Chemistry-Holder.dm
@@ -22,6 +22,8 @@ var/const/INGEST = 2
for(var/path in paths)
var/datum/reagent/D = new path()
chemical_reagents_list[D.id] = D
+ if(!D.can_grow_in_plants)
+ plant_blocked_chems.Add(D.id)
if(!chemical_reactions_list)
//Chemical Reactions - Initialises all /datum/chemical_reaction into a list
// It is filtered into multiple lists within a list.
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index 55ba20e3880..7f090a72be6 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -569,12 +569,19 @@
else if (href_list["createpill"] || href_list["createpill_multiple"])
if(!condi)
var/count = 1
- if (href_list["createpill_multiple"]) count = isgoodnumber(input("Select the number of pills to make.", 10, pillamount) as num)
+ if (href_list["createpill_multiple"])
+ count = input("Select the number of pills to make.", 10, pillamount) as num|null
+ if(count == null)
+ return
+ count = isgoodnumber(count)
if (count > 20) count = 20 //Pevent people from creating huge stacks of pills easily. Maybe move the number to defines?
if (count <= 0) return
var/amount_per_pill = reagents.total_volume/count
if (amount_per_pill > 50) amount_per_pill = 50
- var/name = reject_bad_text(input(usr,"Name:","Name your pill!","[reagents.get_master_reagent_name()] ([amount_per_pill] units)"))
+ var/name = input(usr,"Name:","Name your pill!","[reagents.get_master_reagent_name()] ([amount_per_pill] units)") as text|null
+ if(!name)
+ return
+ name = reject_bad_text(name)
while (count--)
var/obj/item/weapon/reagent_containers/pill/P = new/obj/item/weapon/reagent_containers/pill(src.loc)
if(!name) name = reagents.get_master_reagent_name()
@@ -588,7 +595,10 @@
P.forceMove(loaded_pill_bottle)
src.updateUsrDialog()
else
- var/name = reject_bad_text(input(usr,"Name:","Name your bag!",reagents.get_master_reagent_name()))
+ var/name = input(usr,"Name:","Name your bag!",reagents.get_master_reagent_name()) as text|null
+ if(!name)
+ return
+ name = reject_bad_text(name)
var/obj/item/weapon/reagent_containers/food/condiment/pack/P = new/obj/item/weapon/reagent_containers/food/condiment/pack(src.loc)
if(!name) name = reagents.get_master_reagent_name()
P.originalname = name
@@ -598,13 +608,20 @@
else if (href_list["createpatch"] || href_list["createpatch_multiple"])
if(!condi)
var/count = 1
- if (href_list["createpatch_multiple"]) count = isgoodnumber(input("Select the number of patches to make.", 10, patchamount) as num)
+ if (href_list["createpatch_multiple"])
+ count = input("Select the number of patches to make.", 10, patchamount) as num|null
+ if(count == null)
+ return
+ count = isgoodnumber(count)
if(!count || count <= 0)
return
if (count > 20) count = 20 //Pevent people from creating huge stacks of patches easily. Maybe move the number to defines?
var/amount_per_patch = reagents.total_volume/count
if (amount_per_patch > 40) amount_per_patch = 40
- var/name = reject_bad_text(input(usr,"Name:","Name your patch!","[reagents.get_master_reagent_name()] ([amount_per_patch] units)"))
+ var/name = input(usr,"Name:","Name your patch!","[reagents.get_master_reagent_name()] ([amount_per_patch] units)") as text|null
+ if(!name)
+ return
+ name = reject_bad_text(name)
while (count--)
var/obj/item/weapon/reagent_containers/pill/patch/P = new/obj/item/weapon/reagent_containers/pill/patch(src.loc)
if(!name) name = reagents.get_master_reagent_name()
@@ -614,7 +631,10 @@
reagents.trans_to(P,amount_per_patch)
else if (href_list["createbottle"])
if(!condi)
- var/name = reject_bad_text(input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name()))
+ var/name = input(usr,"Name:","Name your bottle!",reagents.get_master_reagent_name()) as text|null
+ if(!name)
+ return
+ name = reject_bad_text(name)
var/obj/item/weapon/reagent_containers/glass/bottle/P = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc)
if(!name) name = reagents.get_master_reagent_name()
P.name = "[name] bottle"
diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm
index ac37f82fe31..698f27350bb 100644
--- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm
+++ b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_food.dm
@@ -42,8 +42,8 @@
name = "Soy Sauce"
id = "soysauce"
result = "soysauce"
- required_reagents = list("soymilk" = 2, "flour" = 1, "sodiumchloride" = 1, "water" = 3)
- result_amount = 7
+ required_reagents = list("soymilk" = 1,"sodiumchloride" = 1, "water" = 8)
+ result_amount = 10
cheesewheel
name = "Cheesewheel"
diff --git a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm
index 8cfd61cd1dc..b44ffa066c4 100644
--- a/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm
+++ b/code/modules/reagents/oldchem/chemical_reaction/chemical_reaction_slime.dm
@@ -433,7 +433,7 @@
required_reagents = list("plasma" = 5)
required_other = 1
on_reaction(var/datum/reagents/holder)
- var/obj/item/weapon/slimepotion2/P = new /obj/item/weapon/slimepotion2
+ var/obj/item/weapon/sentience_potion/P = new /obj/item/weapon/sentience_potion
P.loc = get_turf(holder.my_atom)
//Adamantine
slimegolem
diff --git a/code/modules/reagents/oldchem/reagents/_reagent_base.dm b/code/modules/reagents/oldchem/reagents/_reagent_base.dm
index 0dcf2e98c30..c84b0f327e9 100644
--- a/code/modules/reagents/oldchem/reagents/_reagent_base.dm
+++ b/code/modules/reagents/oldchem/reagents/_reagent_base.dm
@@ -12,6 +12,7 @@
var/color = "#000000" // rgb: 0, 0, 0 (does not support alpha channels - yet!)
var/shock_reduction = 0
var/penetrates_skin = 0 //Whether or not a reagent penetrates the skin
+ var/can_grow_in_plants = 1 //Determines if the reagent can be grown in plants, 0 means it cannot be grown
//Processing flags, defines the type of mobs the reagent will affect
//By default, all reagents will ONLY affect organics, not synthetics. Re-define in the reagent's definition if the reagent is meant to affect synths
var/process_flags = ORGANIC
diff --git a/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm b/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm
index d33f4ab80e9..0dd38567ccc 100644
--- a/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm
+++ b/code/modules/reagents/oldchem/reagents/drink/reagents_alcohol.dm
@@ -6,6 +6,7 @@
reagent_state = LIQUID
nutriment_factor = 0 //So alcohol can fill you up! If they want to.
color = "#404030" // rgb: 64, 64, 48
+ can_grow_in_plants = 0 //Alcoholic drinks won't be grown in plants (would "water down" random seed chems too much)
var/datum/martial_art/drunk_brawling/F = new
var/dizzy_adj = 3
var/slurr_adj = 3
diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm
index fccc9008310..a09f058629c 100644
--- a/code/modules/research/designs/autolathe_designs.dm
+++ b/code/modules/research/designs/autolathe_designs.dm
@@ -386,6 +386,14 @@
build_path = /obj/item/weapon/reagent_containers/glass/beaker/large
category = list("initial", "Medical")
+/datum/design/healthanalyzer
+ name = "Health Analyzer"
+ id = "healthanalyzer"
+ build_type = AUTOLATHE
+ materials = list(MAT_METAL = 500, MAT_GLASS = 50)
+ build_path = /obj/item/device/healthanalyzer
+ category = list("initial", "Medical")
+
/datum/design/retractor
name = "Retractor"
id = "retractor"
@@ -410,6 +418,14 @@
build_path = /obj/item/weapon/surgicaldrill
category = list("initial", "Medical")
+/datum/design/bonesetter
+ name = "Bone Setter"
+ id = "bonesetter"
+ build_type = AUTOLATHE
+ materials = list(MAT_METAL = 4000)
+ build_path = /obj/item/weapon/bonesetter
+ category = list("initial", "Medical")
+
/datum/design/syringe
name = "Syringe"
id = "syringe"
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index cbffe884787..d0ed135176f 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -45,16 +45,6 @@
build_path = /obj/item/device/robotanalyzer
category = list("Medical")
-/datum/design/healthanalyzer
- name = "Health Analyzer"
- desc = "A hand-held body scanner able to distinguish vital signs of the subject."
- id = "healthanalyzer"
- req_tech = list("biotech" = 2, "magnets" = 2)
- build_type = PROTOLATHE
- materials = list(MAT_METAL = 20, MAT_GLASS = 20)
- build_path = /obj/item/device/healthanalyzer
- category = list("Medical")
-
/datum/design/healthanalyzer_upgrade
name = "Health Analyzer Upgrade"
desc = "An upgrade unit for expanding the functionality of a health analyzer."
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index 55389cfc4a9..1f874d35c01 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -623,10 +623,12 @@
var/realProc
var/cooldownMax = 60
var/cooldown
+ var/floof
/obj/item/weapon/relic/New()
icon_state = pick("shock_kit","armor-igniter-analyzer","infra-igniter0","infra-igniter1","radio-multitool","prox-radio1","radio-radio","timer-multitool0","radio-igniter-tank")
realName = "[pick("broken","twisted","spun","improved","silly","regular","badly made")] [pick("device","object","toy","illegal tech","weapon")]"
+ floof = pick(/mob/living/simple_animal/pet/corgi, /mob/living/simple_animal/pet/cat, /mob/living/simple_animal/pet/fox, /mob/living/simple_animal/mouse, /mob/living/simple_animal/pet/pug, /mob/living/simple_animal/lizard, /mob/living/simple_animal/diona, /mob/living/simple_animal/butterfly, /mob/living/carbon/human/monkey)
/obj/item/weapon/relic/proc/reveal()
@@ -635,7 +637,7 @@
revealed = TRUE
name = realName
cooldownMax = rand(60,300)
- realProc = pick("teleport","explode","rapidDupe","petSpray","flash","clean","corgicannon")
+ realProc = pick("teleport","explode","rapidDupe","petSpray","flash","clean","floofcannon")
/obj/item/weapon/relic/attack_self(mob/user)
if(revealed)
@@ -657,12 +659,12 @@
smoke.set_up(1,0, where, 0)
smoke.start()
-/obj/item/weapon/relic/proc/corgicannon(mob/user)
+/obj/item/weapon/relic/proc/floofcannon(mob/user)
playsound(src.loc, "sparks", rand(25,50), 1)
- var/mob/living/simple_animal/pet/corgi/C = new/mob/living/simple_animal/pet/corgi(get_turf(user))
+ var/mob/living/C = new floof(get_turf(user))
C.throw_at(pick(oview(10,user)),10,rand(3,8))
throwSmoke(get_turf(C))
- warn_admins(user, "Corgi Cannon", 0)
+ warn_admins(user, "Floof Cannon", 0)
/obj/item/weapon/relic/proc/clean(mob/user)
playsound(src.loc, "sparks", rand(25,50), 1)
diff --git a/code/modules/research/xenoarchaeology/master_controller.dm b/code/modules/research/xenoarchaeology/master_controller.dm
index a4421aa3e61..f64f8c32362 100644
--- a/code/modules/research/xenoarchaeology/master_controller.dm
+++ b/code/modules/research/xenoarchaeology/master_controller.dm
@@ -22,8 +22,8 @@
var/list/spawn_types_plant = list("/obj/item/seeds/walkingmushroommycelium",\
"/obj/item/seeds/killertomatoseed",\
- "/obj/item/seeds/shandseed",
- "/obj/item/seeds/mtearseed",
+ "/obj/item/seeds/comfreyseed",
+ "/obj/item/seeds/aloeseed",
"/obj/item/seeds/thaadra",\
"/obj/item/seeds/telriis",\
"/obj/item/seeds/jurlmah",\
diff --git a/code/stylesheet.dm b/code/stylesheet.dm
index a6ee7073d4e..caa1f6950af 100644
--- a/code/stylesheet.dm
+++ b/code/stylesheet.dm
@@ -103,6 +103,13 @@ h1.alert, h2.alert {color: #000000;}
.greentext {color: #00FF00; font-size: 3;}
.redtext {color: #FF0000; font-size: 3;}
+.revennotice {color: #1d2953;}
+.revenboldnotice {color: #1d2953; font-weight: bold;}
+.revenbignotice {color: #1d2953; font-weight: bold; font-size: 3;}
+.revenminor {color: #823abb}
+.revenwarning {color: #760fbb; font-style: italic;}
+.revendanger {color: #760fbb; font-weight: bold; font-size: 3;}
+
.memo {color: #638500; text-align: center;}
.memoedit {text-align: center; font-size: 2;}
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index 9648275ce43..0557b16cdf3 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi
index ca86e3b6814..8b1add2756b 100644
Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index 5112dc2543f..ba76739718d 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi
index b7ebe8a9c6e..e01e99ba040 100644
Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ
diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi
index 0aab96a6719..2e3d39e8f9f 100644
Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ
diff --git a/icons/mob/screen1_White.dmi b/icons/mob/screen1_White.dmi
index b474f443445..2b6e99bbb33 100644
Binary files a/icons/mob/screen1_White.dmi and b/icons/mob/screen1_White.dmi differ
diff --git a/icons/obj/harvest.dmi b/icons/obj/harvest.dmi
index 6ee1938368d..fb06ace12ef 100644
Binary files a/icons/obj/harvest.dmi and b/icons/obj/harvest.dmi differ
diff --git a/icons/obj/hydroponics_products.dmi b/icons/obj/hydroponics_products.dmi
index a43f486daaf..028bb4b9113 100644
Binary files a/icons/obj/hydroponics_products.dmi and b/icons/obj/hydroponics_products.dmi differ
diff --git a/icons/obj/lighting.dmi b/icons/obj/lighting.dmi
index 3beee849e02..779903709c9 100644
Binary files a/icons/obj/lighting.dmi and b/icons/obj/lighting.dmi differ
diff --git a/icons/obj/money.dmi b/icons/obj/money.dmi
index 7b8a5e09495..5a053c07e05 100644
Binary files a/icons/obj/money.dmi and b/icons/obj/money.dmi differ
diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi
index 3c70e86f81f..0e067d1e6f2 100644
Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ
diff --git a/icons/obj/toy.dmi b/icons/obj/toy.dmi
index 1fa7bc554d9..39b795fdc04 100644
Binary files a/icons/obj/toy.dmi and b/icons/obj/toy.dmi differ
diff --git a/nano/css/layout_default.css b/nano/css/layout_default.css
index 109beb2c72e..2493aca3bb0 100644
--- a/nano/css/layout_default.css
+++ b/nano/css/layout_default.css
@@ -87,7 +87,7 @@ body {
#uiMapContent {
position: absolute;
- bottom: 0px;
+ bottom: -13.5px;
left: 0px;
width: 256px;
height: 256px;
diff --git a/nano/templates/atmos_control_map_content.tmpl b/nano/templates/atmos_control_map_content.tmpl
index ab5319460d1..e1a513ba9f2 100644
--- a/nano/templates/atmos_control_map_content.tmpl
+++ b/nano/templates/atmos_control_map_content.tmpl
@@ -1,6 +1,6 @@
{{for data.alarms}}
{{if value.z == 1}}
-
+
{{:value.name}} ({{:helper.dangerToSpan(value.danger)}}, {{:value.area}}: {{:value.x}}, {{:value.y}})
diff --git a/paradise.dme b/paradise.dme
index 6cdef27dd04..dd5f8e8ccac 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -354,6 +354,7 @@
#include "code\game\gamemodes\mutiny\directives\vox_heist.dm"
#include "code\game\gamemodes\nations\nations.dm"
#include "code\game\gamemodes\nations\nationsdatums.dm"
+#include "code\game\gamemodes\nations\nationsprocs.dm"
#include "code\game\gamemodes\nuclear\nuclear.dm"
#include "code\game\gamemodes\nuclear\nuclearbomb.dm"
#include "code\game\gamemodes\nuclear\pinpointer.dm"
@@ -714,7 +715,6 @@
#include "code\game\objects\items\weapons\gift_wrappaper.dm"
#include "code\game\objects\items\weapons\handcuffs.dm"
#include "code\game\objects\items\weapons\holosign.dm"
-#include "code\game\objects\items\weapons\hydroponics.dm"
#include "code\game\objects\items\weapons\kitchen.dm"
#include "code\game\objects\items\weapons\legcuffs.dm"
#include "code\game\objects\items\weapons\lighters.dm"
diff --git a/sound/AI/intercept2.ogg b/sound/AI/intercept2.ogg
new file mode 100644
index 00000000000..ab106a7295a
Binary files /dev/null and b/sound/AI/intercept2.ogg differ