diff --git a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
index f8ac6277f61..11d8e3fd510 100644
--- a/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
+++ b/_maps/map_files/MetaStation/MetaStation.v41A.II.dmm
@@ -79,7 +79,7 @@
"abA" = (/obj/structure/table,/obj/machinery/computer/libraryconsole/bookmanagement,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison)
"abB" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/solar{id = "forestarboard"; name = "Fore-Starboard Solar Array"},/turf/simulated/floor/plasteel/airless{icon_state = "solarpanel"},/area/solar/auxstarboard)
"abC" = (/obj/structure/cable,/obj/structure/lattice/catwalk,/turf/space,/area/solar/auxstarboard)
-"abD" = (/obj/structure/stool/bed,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/muzzle,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/prison/solitary{name = "Prisoner Education Chamber"})
+"abD" = (/obj/structure/stool/bed,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/muzzle,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/prison/solitary{name = "Prisoner Education Chamber"})
"abE" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/light/small{dir = 8},/obj/machinery/sparker{dir = 2; id = "executionburn"; pixel_x = -25},/turf/simulated/floor/plasteel{tag = "icon-warndark (WEST)"; icon_state = "warndark"; dir = 8},/area/prison/solitary{name = "Prisoner Education Chamber"})
"abF" = (/obj/machinery/flasher{id = "justiceflash"; name = "mounted justice flash"; pixel_x = 28},/turf/simulated/floor/plasteel{tag = "icon-warndark (EAST)"; icon_state = "warndark"; dir = 4},/area/prison/solitary{name = "Prisoner Education Chamber"})
"abG" = (/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison)
@@ -164,13 +164,13 @@
"adh" = (/obj/machinery/door/poddoor{density = 0; icon_state = "open"; id = "permacell1"; name = "Cell Shutters"; opacity = 0},/obj/machinery/door/airlock/glass{id_tag = "permabolt1"; name = "Cell 1"},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison)
"adi" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/plating,/area/security/prison)
"adj" = (/obj/structure/cable/yellow{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/prison)
-"adk" = (/obj/structure/stool/bed,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/muzzle,/obj/machinery/camera{c_tag = "Prison Sanitatium"; dir = 4; network = list("SS13","Prison"); pixel_x = 0; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/prison)
+"adk" = (/obj/structure/stool/bed,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/muzzle,/obj/machinery/camera{c_tag = "Prison Sanitatium"; dir = 4; network = list("SS13","Prison"); pixel_x = 0; pixel_y = 0},/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/prison)
"adl" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 8; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{tag = "icon-warndark (NORTHEAST)"; icon_state = "warndark"; dir = 5},/area/prison/solitary{name = "Prisoner Education Chamber"})
"adm" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/simulated/wall/shuttle{icon_state = "swall_f6"; dir = 2},/area/shuttle/pod_3)
"adn" = (/obj/structure/closet/emcloset,/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating,/area/crew_quarters/fitness{name = "\improper Recreation Area"})
"ado" = (/turf/simulated/wall/shuttle{icon_state = "swall12"; dir = 2},/area/shuttle/pod_3)
"adp" = (/turf/simulated/wall/shuttle{icon_state = "swall_s10"; dir = 2},/area/shuttle/pod_3)
-"adq" = (/obj/structure/stool/bed,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/muzzle,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/prison)
+"adq" = (/obj/structure/stool/bed,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/muzzle,/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/prison)
"adr" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 5},/turf/simulated/floor/plasteel{dir = 2; icon_state = "darkred"; tag = "icon-darkblue"; temperature = 273.15},/area/prison/solitary{name = "Prisoner Education Chamber"})
"ads" = (/obj/structure/stool/bed,/obj/machinery/camera{c_tag = "Prison Cell 3"; network = list("SS13","Prison")},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison)
"adt" = (/obj/structure/stool,/obj/machinery/light/small{dir = 1},/obj/machinery/door_control{id = "permabolt3"; name = "Cell Bolt Control"; normaldoorcontrol = 1; pixel_x = 0; pixel_y = 25; req_access_txt = "0"; specialfunctions = 4},/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/security/prison)
@@ -254,7 +254,7 @@
"aeT" = (/obj/structure/cable/yellow{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 1},/obj/structure/sign/pods{pixel_y = 30},/turf/simulated/floor/plasteel{dir = 2; icon_state = "redcorner"},/area/security/prison)
"aeU" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/security{aiControlDisabled = 1; id_tag = "prisonereducation"; name = "Prisoner Education Chamber"; req_access = null; req_access_txt = "3"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/prison/solitary{name = "Prisoner Education Chamber"})
"aeV" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_security{name = "Insanity Ward"; req_access_txt = "2"},/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/prison)
-"aeW" = (/obj/structure/closet/secure_closet{name = "contraband locker"; req_access_txt = "3"},/obj/effect/spawner/lootdrop/maintenance{lootcount = 3; name = "3maintenance loot spawner"},/obj/effect/spawner/lootdrop/armory_contraband{loot = list(/obj/item/weapon/gun/projectile/automatic/pistol = 5, /obj/item/weapon/gun/projectile/shotgun/combat = 5, /obj/item/weapon/gun/projectile/revolver/mateba, /obj/item/weapon/gun/projectile/automatic/pistol/deagle, /obj/item/weapon/storage/box/throwing_stars = 3)},/turf/simulated/floor/plasteel{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/security/warden)
+"aeW" = (/obj/structure/closet/secure_closet{name = "contraband locker"; req_access_txt = "3"},/obj/effect/spawner/lootdrop/maintenance{lootcount = 3; name = "3maintenance loot spawner"},/obj/effect/spawner/lootdrop/armory_contraband{loot = list(/obj/item/weapon/gun/projectile/automatic/pistol = 5, /obj/item/weapon/gun/projectile/shotgun/automatic/combat = 5, /obj/item/weapon/gun/projectile/revolver/mateba, /obj/item/weapon/gun/projectile/automatic/pistol/deagle, /obj/item/weapon/storage/box/throwing_stars = 3)},/turf/simulated/floor/plasteel{tag = "icon-vault (WEST)"; icon_state = "vault"; dir = 8},/area/security/warden)
"aeX" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating,/area/crew_quarters/fitness{name = "\improper Recreation Area"})
"aeY" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 2; on = 1},/obj/machinery/light/small{dir = 1},/obj/item/weapon/storage/secure/safe{name = "armory safe A"; pixel_x = 6; pixel_y = 28},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden)
"aeZ" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 6},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/warden)
@@ -1311,7 +1311,7 @@
"azk" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/obj/structure/cable/yellow{d2 = 8; icon_state = "0-8"},/obj/structure/cable/yellow{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/plating,/area/construction/Storage{name = "Storage Wing"})
"azl" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/door/window/brigdoor{id = "Cell 2"; name = "Cell 2"; req_access_txt = "2"},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig)
"azm" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/obj/structure/cable/yellow,/obj/machinery/door/poddoor/preopen{id = "briglockdown"; name = "brig shutters"},/turf/simulated/floor/plating,/area/security/brig)
-"azn" = (/obj/structure/bodycontainer/morgue,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/detectives_office)
+"azn" = (/obj/structure/bodycontainer/morgue,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/detectives_office)
"azo" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable/yellow{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/cable/yellow{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/door/window/brigdoor{id = "Cell 3"; name = "Cell 3"; req_access_txt = "2"},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/brig)
"azp" = (/obj/structure/table,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/glass{amount = 12},/obj/item/stack/sheet/glass{amount = 12},/obj/item/stack/sheet/glass{amount = 12},/obj/item/weapon/crowbar,/obj/item/weapon/grenade/chem_grenade/metalfoam,/obj/item/weapon/grenade/chem_grenade/metalfoam,/turf/simulated/floor/plasteel{icon_state = "bot"; dir = 1},/area/engine/engineering)
"azq" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/obj/machinery/door/poddoor/preopen{id = "Secure Gate"; name = "brig shutters"},/turf/simulated/floor/plating,/area/security/brig)
@@ -3212,7 +3212,7 @@
"bjN" = (/obj/item/device/radio/intercom{freerange = 0; frequency = 1459; name = "Station Intercom (General)"; pixel_x = 0; pixel_y = -29},/obj/structure/rack,/obj/item/device/assembly/signaler,/obj/item/device/assembly/signaler,/obj/item/device/assembly/timer,/turf/simulated/floor/plasteel{dir = 1; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge)
"bjO" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "darkblue"; tag = "icon-darkbluecorners (WEST)"},/area/bridge)
"bjP" = (/obj/machinery/light_switch{pixel_x = 8; pixel_y = -26},/turf/simulated/floor/plasteel{dir = 10; icon_state = "darkblue"},/area/bridge)
-"bjQ" = (/obj/structure/closet/fireaxecabinet{pixel_y = -32},/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 7},/obj/item/weapon/pen{pixel_y = 3},/obj/machinery/light_switch{pixel_x = 28; pixel_y = 0},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge)
+"bjQ" = (/obj/structure/fireaxecabinet{pixel_y = -32},/obj/item/weapon/paper_bin{pixel_x = -2; pixel_y = 7},/obj/item/weapon/pen{pixel_y = 3},/obj/machinery/light_switch{pixel_x = 28; pixel_y = 0},/obj/structure/table/glass,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/bridge)
"bjR" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel{dir = 6; icon_state = "darkblue"},/area/bridge)
"bjS" = (/turf/simulated/floor/plasteel{icon_state = "dark"},/area/engine/break_room)
"bjT" = (/obj/structure/table/wood,/obj/item/weapon/storage/photo_album{pixel_y = -4},/obj/item/device/camera{pixel_y = 4},/obj/item/device/radio/intercom{dir = 8; freerange = 1; name = "Station Intercom (Captain)"; pixel_x = -28},/turf/simulated/floor/fancy/carpet,/area/crew_quarters/captain{name = "\improper Captain's Quarters"})
@@ -3391,7 +3391,7 @@
"bnk" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/bridge)
"bnl" = (/obj/machinery/door/airlock/command{name = "Command Desk"; req_access = null; req_access_txt = "19"},/turf/simulated/floor/plasteel{tag = "icon-vault"; icon_state = "vault"},/area/bridge)
"bnm" = (/obj/effect/landmark{name = "xeno_spawn"; pixel_x = -1},/obj/machinery/shower{tag = "icon-shower (EAST)"; icon_state = "shower"; dir = 4},/obj/machinery/door/window/westright{dir = 4},/obj/item/weapon/soap/deluxe,/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"})
-"bnn" = (/obj/structure/mirror{pixel_y = 28},/obj/structure/sink{pixel_y = 17},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"})
+"bnn" = (/obj/structure/mirror{pixel_y = 28},/obj/structure/sink{pixel_y = 17},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"})
"bno" = (/obj/structure/toilet{pixel_y = 13},/obj/machinery/light{dir = 2; icon_state = "tube1"},/obj/effect/landmark/start{name = "Captain"},/obj/machinery/light_switch{pixel_y = -25},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"})
"bnp" = (/obj/machinery/door/airlock/silver{name = "Bathroom"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/captain{name = "\improper Captain's Quarters"})
"bnq" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/manifold/supply/hidden{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/captain{name = "\improper Captain's Quarters"})
@@ -5104,7 +5104,7 @@
"bUh" = (/obj/machinery/computer/general_air_control/large_tank_control{frequency = 1441; input_tag = "tox_in"; name = "Toxin Supply Control"; output_tag = "tox_out"; sensors = list("tox_sensor" = "Tank")},/obj/machinery/atmospherics/pipe/simple/green/visible,/obj/structure/window/reinforced{dir = 4; pixel_x = 0},/turf/simulated/floor/plasteel{icon_state = "purplefull"},/area/atmos)
"bUi" = (/obj/structure/lattice,/turf/space,/area/hallway/secondary/entry{name = "Arrivals"})
"bUj" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plating{icon_state = "warnplate"},/area/maintenance/maintcentral{name = "Central Maintenance"})
-"bUk" = (/obj/structure/closet/fireaxecabinet{pixel_x = -32; pixel_y = 0},/obj/machinery/camera{c_tag = "Atmospherics - Port"; dir = 4; network = list("SS13")},/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{dir = 8; icon_state = "caution"},/area/atmos)
+"bUk" = (/obj/structure/fireaxecabinet{pixel_x = -32; pixel_y = 0},/obj/machinery/camera{c_tag = "Atmospherics - Port"; dir = 4; network = list("SS13")},/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel{dir = 8; icon_state = "caution"},/area/atmos)
"bUl" = (/obj/machinery/air_sensor{frequency = 1441; id_tag = "tox_sensor"},/turf/simulated/floor/engine{carbon_dioxide = 0; name = "plasma floor"; nitrogen = 0; oxygen = 0; toxins = 70000},/area/atmos)
"bUm" = (/obj/machinery/light/small{dir = 4},/turf/simulated/floor/engine{carbon_dioxide = 0; name = "plasma floor"; nitrogen = 0; oxygen = 0; toxins = 70000},/area/atmos)
"bUn" = (/obj/machinery/portable_atmospherics/canister/toxins,/turf/simulated/floor/engine{carbon_dioxide = 0; name = "plasma floor"; nitrogen = 0; oxygen = 0; toxins = 70000},/area/atmos)
@@ -5980,11 +5980,13 @@
"ckZ" = (/obj/structure/closet,/obj/item/stack/sheet/metal{amount = 34},/obj/item/weapon/extinguisher/mini,/obj/effect/spawner/lootdrop/maintenance,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"})
"cla" = (/obj/structure/reagent_dispensers/fueltank,/obj/item/weapon/storage/toolbox/emergency,/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor/plating,/area/maintenance/incinerator)
"clb" = (/obj/structure/reagent_dispensers/watertank,/obj/item/weapon/extinguisher,/obj/machinery/light/small,/obj/structure/extinguisher_cabinet{pixel_x = 0; pixel_y = -31},/turf/simulated/floor/plating,/area/maintenance/incinerator)
+"clc" = (/obj/structure/bodycontainer/morgue,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
"cld" = (/obj/machinery/door/airlock/glass{autoclose = 0; frequency = 1449; heat_proof = 1; icon_state = "door_locked"; id_tag = "incinerator_airlock_exterior"; locked = 1; name = "Incinerator Exterior Airlock"; req_access_txt = "12"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0; tag = ""},/turf/simulated/floor/engine,/area/maintenance/incinerator)
+"cle" = (/obj/machinery/light/small{dir = 8},/obj/structure/bodycontainer/morgue,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
"clf" = (/obj/machinery/microwave{pixel_x = -3; pixel_y = 6},/obj/structure/table/glass,/turf/simulated/floor/plasteel{tag = "icon-cafeteria (NORTHEAST)"; icon_state = "cafeteria"; dir = 5},/area/medical/medbay3{name = "Medbay Aft"})
-"clg" = (/obj/structure/bodycontainer/morgue,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
+"clg" = (/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/structure/bodycontainer/morgue,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
"clh" = (/obj/structure/sink/kitchen{desc = "A sink used for washing one's hands and face. It looks rusty and home-made"; name = "old sink"; pixel_y = 28},/turf/simulated/floor/plasteel{dir = 9; icon_state = "whitepurple"},/area/toxins/lab)
-"cli" = (/obj/machinery/light/small{dir = 8},/obj/structure/bodycontainer/morgue,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
+"cli" = (/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/engine,/area/toxins/xenobiology{name = "\improper Secure Lab"})
"clj" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{req_access_txt = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/maintenance/aft{name = "Aft Maintenance"})
"clk" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/toxins/explab)
"cll" = (/obj/structure/stool/bed/roller,/obj/machinery/light/small{dir = 8},/obj/machinery/iv_drip{density = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/surgery)
@@ -6033,7 +6035,6 @@
"cmc" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/medical/virology)
"cmd" = (/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/cable/yellow{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/medical/virology)
"cme" = (/obj/machinery/door/firedoor,/obj/machinery/door/airlock/glass_virology{name = "Test Subject Cell"; req_access_txt = "39"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/medical/virology)
-"cmf" = (/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/structure/bodycontainer/morgue,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
"cmg" = (/obj/item/device/flashlight/lamp,/turf/simulated/floor/plating/airless{dir = 2; icon_state = "warnplate"},/area/toxins/test_area)
"cmh" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/machinery/iv_drip,/turf/simulated/floor/plasteel{dir = 1; icon_state = "whitegreen"},/area/medical/virology)
"cmi" = (/obj/structure/cable/yellow{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{req_access_txt = 1},/turf/simulated/floor/plating{tag = "icon-platingdmg1"; icon_state = "platingdmg1"},/area/maintenance/aft{name = "Aft Maintenance"})
@@ -8096,11 +8097,11 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaahbEXbFabFabFabFabFfbEzbFtbFrbFrbFrbFrbFEaahcrMaahaahaahaQxaahaahaahaahaahaaabWHbWHbWHbWHbWHbWHbWHbWHbWHbWHbWHcqsczkcBPcjQcBLcBMcBNcBOcBPcBQcBRcBScyvcBTcBUcBVcwKcBWcBXcBXcBXcBYcwKcBZcCacCbcCccCdcCecCgcwRcChczHcCYcDccEicHocHqcHpcGrcIScCicCjcDecClcCmcCncCocCpcCqcCrcCscCqcCtcCucBHbWHcCwbWHcCvcCvcCxcCycCzcCAcCBaahaahaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahcCCcjScCCaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaahbJebJebJebJebJeaaabSbaahbJebJebJebJebJeaaaaQxaaaaaaaaaaahaaaaaaaaaaaaaahaaaaaaaaaaahaahaaaaaaaaaaahaaaaaabWHceHcCEcDfcCFcCGcCHcCIcCJcCKcCLcCMcCNcyvcjUcjTcCQcwKcCRcCScCTcCUcCVcwKcCWcCXcCXcwLbSLcDgcDUcDScEScDVcEUcETcEicHrcHBcHvcHDcEYcFQcDhcHMcDjcDkcDlcDmcDmcDncDocDpcDqcDrcjVcDtcDucDvcDwcDxcDycDzcDzcDzcDAcjWaahaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahcjScCCckncCCcjSaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrMaaaaahaaaaahaaaaahaaabBkaaaaahaaaaahaahaahaahcrMaaaaaaaaaaahaaaaaaaaaaaaaahaaaaaaaaaaaaaahaaaaaaaaaaahaaaaaabWHchEcDEcBPcDFcDGcDHcDIcDJckqcDLcDMcDNcyvcyvckMcyvcwKcwKcwKcwKcwKcwKcwKckNcwLcwLcAlcFRcwOcwPcApcFScFScGTcGRcEicIhcItcImcIucHLcHQcHPcIdcDXcDYcDZcEacEbcEccEdcEecEfcEgcEhcIycEjcEkcElcEmcEncEocEpcEqcErcjWaahaahaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahcEtcjScEvckRcExcjScEtaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaaabEybEybEybEybEyaahcaBaahbEybEybEybEybEyaahaQxaaaaaaaaaaafaahcEycEycEyckScEycEycEyaaaaahaaaaaaaaaaahaaaaaabWHcAvczkcBPcuEckTcDGcECclfcBPcEEcEFcEGcBPcEHcEIcEJcEKclgcEMclgcENclgcEOcEMcEPcEKcEQckycdCcIfcwRcwTcIgcDTcwTcGScGScGScGScGScFacuXcFbcBvcFccFccFdcFecFfcFgcFhcFicFjcFkcFlcBHcFmcFncFocBvcFpcjWcjWcCvcjWcCvatJaahaaaaaaaahaaaaaaaahaahaahaaaaaaaaaaaaaaaaahaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaahaahcjScjScFvcFwcFwcFwcFxcjScjSaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaahbEXbFabFabFabFabFfbEzbFtbFrbFrbFrbFrbFEaahaQxaaaaahaahaQxaaacEycFycFzcFycFAcFycEycEyckScEyckScEycEyaahaahbWHciRczkcBPcBPcBPcBPcBPcBPcBPcFBcFCcFDcFEcFFcFGcFHcEKclicFJclgcEMclgcFKcFLcFMcEKcFNckycdCcstctMcIlcIAcIscILcIPcIMcJccIQcEZcwUczPcwWcBHcBHcBHcBHcBHcBHcFWcFVcFXcFYcFZcGacBHbWHcCwbWHcCvcGbcGccGdcGecGfatJatJaahaahaahaahaahaahaahaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahcGgcGhcGgcFwcGicFwcGjcGkcCCaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaaabEybEybEybEybEyaahcaBaahbEybEybEybEybEyaahaQxaaaaaaaaaaafaahcEycEycEyckScEycEycEyaaaaahaaaaaaaaaaahaaaaaabWHcAvczkcBPcuEckTcDGcECclfcBPcEEcEFcEGcBPcEHcEIcEJcEKclccEMclccENclccEOcEMcEPcEKcEQckycdCcIfcwRcwTcIgcDTcwTcGScGScGScGScGScFacuXcFbcBvcFccFccFdcFecFfcFgcFhcFicFjcFkcFlcBHcFmcFncFocBvcFpcjWcjWcCvcjWcCvatJaahaaaaaaaahaaaaaaaahaahaahaaaaaaaaaaaaaaaaahaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaahaahcjScjScFvcFwcFwcFwcFxcjScjSaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaahbEXbFabFabFabFabFfbEzbFtbFrbFrbFrbFrbFEaahaQxaaaaahaahaQxaaacEycFycFzcFycFAcFycEycEyckScEyckScEycEyaahaahbWHciRczkcBPcBPcBPcBPcBPcBPcBPcFBcFCcFDcFEcFFcFGcFHcEKclecFJclccEMclccFKcFLcFMcEKcFNckycdCcstctMcIlcIAcIscILcIPcIMcJccIQcEZcwUczPcwWcBHcBHcBHcBHcBHcBHcFWcFVcFXcFYcFZcGacBHbWHcCwbWHcCvcGbcGccGdcGecGfatJatJaahaahaahaahaahaahaahaaaaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahcGgcGhcGgcFwcGicFwcGjcGkcCCaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaahbJebJebJebJebJeaaabSbaaabJebJebJebJebJeaaacrMaahaahaaaaQxaahcEycGlcGmcGncGocGlclHcAOcAFcGscAPcBwcEyaaaaaabWHbWHcGvcGwcGwcGxcGwcGycGzcIDcGAcGBcGCcGDcGEcGFcGGcGHcGIcGJcGIcGIcGKcGLcGMclMcGOcGPcGQcCecIOcINcFOcIRcJecJdcJdcJdcJwcJtcEZcdHczPcGZcBHcHacHbcHccHdcHecHfcHecHgcHhcHicBHcoUcHjbZkcddcCvcCvcCvcCvcCvbEMagqatJaahaaaaaaaaaaaaaaaaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaahaahcjScjScHlcFwcFwcFwcHmcjScjSaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaaaaaaaahaahaahaaaaaacfraahaaaaaaaahaahaaaaaaaQxaaaaaaaaaaafaaacEycHncmccmecmdcHncHncBxcHscHtcHucBKcEyaaaaaaaaacoUcoUcoUcoUcoUbWHcHwcBPcBPcHxcHycHzcBPcHAcCkcHCcEKcmfcEMclgcEMclgcHEcHFcHGcHHcHIcHJcHKcJjcGScGScJpcJEcJxcHOcGUcJKcJHcEZcHRcHScHTcjWcHacHbcHUcHUcHVcHWcHXcHYcFYcHZcBHcaQcIacbOceHcIbbWHaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahcEtcjScIccmgcIecjScEtaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrMaaaaaaaaaaaaaaaaaaaaacfraaaaaaaaaaaaaahaaaaaacrMaaaaaaaaaaQxaahcEycCDcmhcIicIjcIkcmjcmxcIncIocIpcIqcIrcnfcnfcnfcIrcIvcIwcIxcEycJzcIzcBPcJLcIBcICcvjbWHbWHbWHbWHcEKclgcEMclgcIEclgcIFcIGcIHcEKcIIcIJcdCcjncGScJDcHNcJMcHOcHOcJOcKpcKocEZcKrcITcIUcBHcHacHbcHUcIVcHecIWcHecIXcIYcIZcBHcJaceHcbOceHcJbbWHaahaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahcjScCCcnFcCCcjSaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaaaaaaaahaahaahaaaaaacfraahaaaaaaaahaahaaaaaaaQxaaaaaaaaaaafaaacEycHncmccmecmdcHncHncBxcHscHtcHucBKcEyaaaaaaaaacoUcoUcoUcoUcoUbWHcHwcBPcBPcHxcHycHzcBPcHAcCkcHCcEKclgcEMclccEMclccHEcHFcHGcHHcHIcHJcHKcJjcGScGScJpcJEcJxcHOcGUcJKcJHcEZcHRcHScHTcjWcHacHbcHUcHUcHVcHWcHXcHYcFYcHZcBHcaQcIacbOceHcIbbWHaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahcEtcjScIccmgcIecjScEtaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacrMaaaaaaaaaaaaaaaaaaaaacfraaaaaaaaaaaaaahaaaaaacrMaaaaaaaaaaQxaahcEycCDcmhcIicIjcIkcmjcmxcIncIocIpcIqcIrcnfcnfcnfcIrcIvcIwcIxcEycJzcIzcBPcJLcIBcICcvjbWHbWHbWHbWHcEKclccEMclccIEclccIFcIGcIHcEKcIIcIJcdCcjncGScJDcHNcJMcHOcHOcJOcKpcKocEZcKrcITcIUcBHcHacHbcHUcIVcHecIWcHecIXcIYcIZcBHcJaceHcbOceHcJbbWHaahaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahcjScCCcnFcCCcjSaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaafaQxaQxaQxaaaaaaaaacfraaaaaaaaaaQxaQxaQxcrMaQxaahaahaaaaQxaaackScCPcJfcJgcJhcJicnGcJkcJlcJmcJncJocnJcJqcJrcJscnKcJucJgcJvcnMcJAcJycnNcJAcJBcJCcvncvkcvqcvocvtcEKcEKcEKcEKcEKcEKcEKcJFcEKcEKbWHcJGcdCcjncGScIKcHNcHOcGUcHOcKscJJcKucKIcKCcJNcJIcDscJPcJPcJPcJPcJPcJQcJPcJRcKJcJTcBHceHceHcJUceHbWHbWHbWHaahaahaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahcCCcjScCCaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaahaaaaaaaaaaQxaahczcaahaQxaaaaaaaahaaaaaaaahaaaaahaahaahaaacEycDBcJWcJXcJYcJZcnOcKbcKccKdcKecKfcEyckSckSckScEycKjcKkcKlcEycoacKncBPcDCcDKcDDcDObWHcwucwhcwvbWHcKvckacKwckbckacKxcKycAJckecKzcKAcKBcCZcGScovcKDcKEcKEcKEcKFcKGcKHcLbcKQcKKcKLcKMcKNcKOcKPcoHcKRcKScKTcKUcKVcKWcKXckdckdcKYcKZcLacDPbWHbWHbWHabjaaaaahaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaQxaaaaahaaaaQxaaaaaaaahaahaahaahaaaaaaaaaaahaahcEycpccoXcHncpdcpccLfcLgcLhcLicLjcLkcEycLlaaaaaacoUcoUcoUcoUcoUbWHcLmcBPcBPcBPcBPcBPbWHcJScKtcwxbWHcLqbWHbWHbWHbWHbWHbWHbWHbWHcxWcLrcLscLtcDQcpecLwcLxcpfcLdcLccGUcLecLvcLucLCcJVcLEcLFcLGcLHcLIcLJcLKcKTciPcLLbWHbWHbWHbWHbWHcLocLMcLNciLcLOciLcpgaahaahaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -8122,22 +8123,22 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahcPlcKqcPlcPlcKqcKqcKqcKqcPlcUScPlaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacsgaaaaaaaaaaaaaahaaacNxcSgcSfcSicShcSmcSjcSocSncSxcSrcSFcSEcSGcNxaaaaahaaaaaaaaaaaaaQxaahcsRcsQcsQcsQcsQcsScsUcsTcsVcsVcsVcsVcsWaahaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaaaaaaaahaaaaaaaaaaaaaaaaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcSHcSHcSHcSHcMJcSIcTacSPcMJcSHcSHcSHcSHcNxaahaahaahaahaahaahaQxaahcsXcsXcsXcsXcsXaaacrQaaacsXcsXcsXcsXcsXaahaQxaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcTccTbcTbcTdcTfcTecTncTgcTBcTrcTCcTCcTCcNxaaaaahaaaaaaaaaaaaaafaaaaahaaaaahaahaahaaacrQaaaaahaaaaahaaaaahaaaaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahcNxcTCcTCcTCcTDcTHcTEcTLcTIcTOcTNcTCcTCcTCcNxaaaaahaaaaaaaaaaaaaQxaaacrOcrOcrOcrOcrOaahcrQaahcrOcrOcrOcrOcrOaahaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahcNxcTCclicTCcTDcTHcTEcTLcTIcTOcTNcTCclicTCcNxaaaaahaaaaaaaaaaaaaQxaaacrOcrOcrOcrOcrOaahcrQaahcrOcrOcrOcrOcrOaahaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcTPcTCcTCcTQcTScTRcTUcTTcTWcTVcTbcTbcTXcNxaaaaahaahaaaaahaahaQxaahcsRcsQcsQcsQcsQcsScrQcsTcsVcsVcsVcsVcsWaahaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcSHcSHcSHcSHcTZcTYcUbcUacTZcSHcSHcSHcSHcNxaaaaahaaaaaaaaaaahaQxaahcsXcsXcsXcsXcsXaaacrQaahcsXcsXcsXcsXcsXaaaaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcTccTbcTbcUccTfcUlcUbcUmcUocUncTCcTCcTPcNxaahaahaaaaaaaaaaahcrMaaaaahaaaaahaaaaahaaacrQaaaaahaaaaahaahaahaahcrMaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcTCcTCcTCcUpcUqcTEcUrcTIcUtcUscTCcTCcTCcNxaaaaahaahaaaaaaaaaaQxaaacrOcrOcrOcrOcrOaahcuhaahcrOcrOcrOcrOcrOaahaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcTCclicTCcUpcUqcTEcUrcTIcUtcUscTCclicTCcNxaaaaahaahaaaaaaaaaaQxaaacrOcrOcrOcrOcrOaahcuhaahcrOcrOcrOcrOcrOaahaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahcNxcTPcTCcTCcUucUvcTRcUBcUycTWcUDcTbcTbcTXcNxaaaaaaaahaaaaaaaahaQxaahcsRcsQcsQcsQcsQcuicrQcujcsVcsVcsVcsVcsWaahaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcNxcSHcSHcSHcSHcTZcUEcUbcUFcTZcSHcSHcSHcSHcNxcNxaaaaahaahaahaahaahaahcsXcsXcsXcsXcsXaaacukaaacsXcsXcsXcsXcsXaaaaQxaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcTccTbcTbcUGcTfcUIcUHcUbcUmcTgcUJcULcUKcTCcTCcNxaahaahaaaaaaaaaaafaaaaaaaahaahaahaaaaaacqWaahaaaaaaaahaahaaaaaaaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaculaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcTCcTCcTCcUNcUMcTIcTIcUOcTIcTIcUPcURcUQcTCcTCcNxaaaaahaaaaaaaaaaQxaafaQxaQxaQxaaaaaaaaacqWaaaaaaaaaaQxaQxaQxcrMaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcTCclicTCcUNcUMcTIcTIcUOcTIcTIcUPcURcUQclicTCcNxaaaaahaaaaaaaaaaQxaafaQxaQxaQxaaaaaaaaacqWaaaaaaaaaaQxaQxaQxcrMaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcTCcTCcTCcUUcUTcUWcUVcUYcUXcVacUZcVccVbcTbcTXcNxaaaaahaaaaahaahaaaaaaaaaaaaaahaaaaQxaahcWFaahaQxaaaaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcNxcNxcNxcNxcVdcVfcVecVgcSncVicVhcNxcNxcNxcNxcNxaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaaaaahaaaaQxaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaacNxcVkcVjcVmcVlcVocVncVqcVpcVscVrcVucVtcVvcNxaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaQxaQxaQxaQxaQxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaaacNxcNxcVwcNxcVxcVzcVycVBcVAcVCcVxcNxcVtcNxcNxaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacvgaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahcNxcVwcNxcNxcVEcVDcTCcVFcVEcNxcNxcVtcNxaaaaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcVwcNxcTCcTCcVDcTCcTCcTCcVGcNxcVtcNxaahaaaaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacNxcVwcNxcVHcTCcVIcTCcVJcTCcVKcNxcVtcNxaahaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacNxcVwcNxcVHcTCcVIclicVJcTCcVKcNxcVtcNxaahaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahcNxcVwcNxcVLcTCcTCcVMcTCcVOcVNcNxcVtcNxaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaaacNxcVwcNxcNxcNxcNxcNxcNxcNxcNxcNxcVtcNxaahaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacNxcVPcVQcVQcVQcVRcVScVtcVtcVtcVtcVtcNxaahaaaaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/_maps/map_files/MiniStation/MiniStation.dmm b/_maps/map_files/MiniStation/MiniStation.dmm
index eb894ff0559..85dff516a88 100644
--- a/_maps/map_files/MiniStation/MiniStation.dmm
+++ b/_maps/map_files/MiniStation/MiniStation.dmm
@@ -36,7 +36,7 @@
"aJ" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/table/reinforced,/turf/simulated/floor/plasteel,/area/bridge)
"aK" = (/obj/structure/table/reinforced,/obj/item/weapon/folder/yellow,/obj/item/weapon/disk/nuclear,/turf/simulated/floor/plasteel,/area/bridge)
"aL" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_x = 32; pixel_y = 0},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/grille,/obj/structure/window/reinforced/fulltile,/obj/machinery/door/poddoor/preopen{id = "bridge blast"; layer = 2.9; name = "bridge blast door"},/turf/simulated/floor/plating/airless,/area/bridge)
-"aM" = (/obj/structure/closet/fireaxecabinet{pixel_x = 32},/turf/simulated/floor/plasteel,/area/bridge)
+"aM" = (/obj/structure/fireaxecabinet{pixel_x = 32},/turf/simulated/floor/plasteel,/area/bridge)
"aN" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/plasteel,/area/bridge)
"aO" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel,/area/bridge)
"aP" = (/obj/structure/table/reinforced,/obj/item/weapon/storage/secure/briefcase,/obj/item/device/flash,/obj/item/device/flash,/turf/simulated/floor/plasteel,/area/bridge)
diff --git a/_maps/map_files/TgStation/tgstation.2.1.3.dmm b/_maps/map_files/TgStation/tgstation.2.1.3.dmm
index c9070d72a64..886bdbabe41 100644
--- a/_maps/map_files/TgStation/tgstation.2.1.3.dmm
+++ b/_maps/map_files/TgStation/tgstation.2.1.3.dmm
@@ -91,7 +91,7 @@
"abM" = (/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/power/tracker,/turf/simulated/floor/plasteel/airless{icon_state = "solarpanel"},/area/solar/auxstarboard)
"abN" = (/turf/simulated/floor/plasteel{tag = "icon-warndark (WEST)"; icon_state = "warndark"; dir = 8},/area/security/transfer)
"abO" = (/obj/machinery/sparker{dir = 2; id = "executionburn"; pixel_x = 25},/turf/simulated/floor/plasteel{tag = "icon-warndark (EAST)"; icon_state = "warndark"; dir = 4},/area/security/prison)
-"abP" = (/obj/structure/stool/bed,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/transfer)
+"abP" = (/obj/structure/stool/bed,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/transfer)
"abQ" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel{tag = "icon-warndark (SOUTHWEST)"; icon_state = "warndark"; dir = 10},/area/security/transfer)
"abR" = (/obj/machinery/atmospherics/unary/outlet_injector,/turf/simulated/floor/plasteel{tag = "icon-warndark (SOUTHEAST)"; icon_state = "warndark"; dir = 6},/area/security/prison)
"abS" = (/turf/simulated/wall,/area/security/prison)
@@ -104,7 +104,7 @@
"abZ" = (/obj/machinery/newscaster/security_unit{pixel_x = -30; pixel_y = 0},/obj/machinery/camera{c_tag = "Head of Security's Office"; dir = 4; network = list("SS13")},/obj/machinery/recharger{pixel_y = 4},/obj/structure/table/wood,/turf/simulated/floor/fancy/carpet,/area/security/hos)
"aca" = (/obj/structure/stool/bed/chair/comfy/black,/turf/simulated/floor/fancy/carpet,/area/security/hos)
"acb" = (/turf/simulated/floor/fancy/carpet,/area/security/hos)
-"acc" = (/obj/machinery/keycard_auth{pixel_x = 24; pixel_y = 10},/obj/machinery/hologram/holopad,/turf/simulated/floor/fancy/carpet,/area/security/hos)
+"acc" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/fancy/carpet,/area/security/hos)
"acd" = (/obj/structure/sign/securearea{pixel_y = -32},/obj/structure/lattice/catwalk,/turf/space,/area/space)
"ace" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/structure/lattice/catwalk,/turf/space,/area/solar/auxstarboard)
"acf" = (/obj/structure/lattice,/obj/item/stack/cable_coil/random,/turf/space,/area/space)
@@ -386,7 +386,7 @@
"ahv" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel,/area/security/main)
"ahw" = (/obj/machinery/power/apc{dir = 4; name = "Security Office APC"; pixel_x = 24; pixel_y = 0},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/main)
"ahx" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plating,/area/maintenance/fsmaint)
-"ahy" = (/obj/structure/stool/bed,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/muzzle,/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/prison)
+"ahy" = (/obj/structure/stool/bed,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/muzzle,/obj/machinery/camera{c_tag = "Prison Sanitatium"; dir = 4; network = list("SS13","Prison"); pixel_x = 0; pixel_y = 0},/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/prison)
"ahz" = (/obj/structure/table,/obj/item/weapon/folder/red,/obj/item/device/taperecorder{pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/brig)
"ahA" = (/obj/machinery/camera{c_tag = "Brig Interrogation"; dir = 8},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/security/brig)
"ahB" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 9},/area/security/brig)
@@ -403,6 +403,8 @@
"ahM" = (/obj/structure/grille,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/plating,/area/security/warden)
"ahN" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/obj/machinery/firealarm{dir = 1; pixel_y = -24},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 10},/area/security/main)
"ahO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (NORTH)"; dir = 1},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/main)
+"ahP" = (/obj/machinery/keycard_auth{pixel_x = 24; pixel_y = 10},/obj/machinery/computer/card/minor/hos,/turf/simulated/floor/fancy/carpet,/area/security/hos)
+"ahQ" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/hor)
"ahR" = (/obj/machinery/light,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "red"},/area/security/main)
"ahS" = (/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/main)
"ahT" = (/obj/structure/disposalpipe/junction{icon_state = "pipe-y"; dir = 1},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel,/area/security/main)
@@ -1716,7 +1718,7 @@
"aHb" = (/obj/structure/stool/bed/chair/comfy/beige,/obj/effect/landmark/start{name = "Assistant"},/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/hallway/secondary/entry)
"aHc" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/wood,/area/library)
"aHd" = (/obj/structure/disposalpipe/segment{dir = 8; icon_state = "pipe-c"},/turf/simulated/floor/wood,/area/library)
-"aHe" = (/obj/structure/bodycontainer/crematorium,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office)
+"aHe" = (/obj/structure/stool/bed,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/muzzle,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/prison)
"aHf" = (/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office)
"aHg" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/chapel/office)
"aHh" = (/obj/effect/landmark/start{name = "Chaplain"},/obj/structure/stool/bed/chair,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/chapel/office)
@@ -1944,7 +1946,7 @@
"aLv" = (/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 6},/turf/simulated/floor/wood,/area/library)
"aLw" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/wood,/area/library)
"aLx" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 8; on = 1},/turf/simulated/floor/wood,/area/library)
-"aLy" = (/obj/structure/bodycontainer/morgue,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office)
+"aLy" = (/obj/structure/bodycontainer/crematorium,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office)
"aLz" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office)
"aLA" = (/turf/simulated/floor/plasteel{icon_state = "grimy"},/area/chapel/office)
"aLB" = (/obj/machinery/camera{c_tag = "Chapel North"; dir = 2; network = list("SS13")},/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/main)
@@ -2461,7 +2463,7 @@
"aVs" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel,/area/bridge)
"aVt" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "bluecorner"},/area/bridge)
"aVu" = (/obj/structure/extinguisher_cabinet{pixel_x = 5; pixel_y = -32},/obj/machinery/light,/obj/machinery/light_switch{pixel_x = -6; pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/bridge)
-"aVv" = (/obj/structure/closet/fireaxecabinet{pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/bridge)
+"aVv" = (/obj/structure/fireaxecabinet{pixel_y = -32},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/bridge)
"aVw" = (/obj/machinery/alarm{dir = 1; icon_state = "alarm0"; pixel_y = -22},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/bridge)
"aVx" = (/obj/machinery/requests_console{announcementConsole = 1; department = "Bridge"; departmentType = 5; name = "Bridge RC"; pixel_y = -30},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/bridge)
"aVy" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{dir = 0; icon_state = "blue"},/area/bridge)
@@ -3079,8 +3081,8 @@
"bhm" = (/obj/structure/stool/bed/chair/office/dark{dir = 8},/obj/effect/landmark/start/depsec/medical,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/checkpoint/medical)
"bhn" = (/turf/simulated/floor/plasteel,/area/security/checkpoint/medical)
"bho" = (/obj/machinery/computer/secure_data,/obj/item/device/radio/intercom{pixel_x = 25},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/checkpoint/medical)
-"bhp" = (/obj/structure/bodycontainer/morgue,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
-"bhq" = (/obj/structure/bodycontainer/morgue,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
+"bhp" = (/obj/structure/bodycontainer/morgue,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/chapel/office)
+"bhq" = (/obj/structure/bodycontainer/morgue,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
"bhr" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
"bhs" = (/turf/simulated/floor/plating,/area/storage/emergency)
"bht" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/obj/structure/window/fulltile,/turf/simulated/floor/plating,/area/toxins/explab)
@@ -3228,7 +3230,7 @@
"bkf" = (/obj/machinery/power/apc{dir = 8; name = "Medbay Security APC"; pixel_x = -25},/obj/structure/cable{icon_state = "0-4"; d2 = 4},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 8},/area/security/checkpoint/medical)
"bkg" = (/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/unary/vent_scrubber{on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/plasteel,/area/security/checkpoint/medical)
"bkh" = (/obj/structure/reagent_dispensers/peppertank{pixel_x = 30; pixel_y = 0},/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 4},/area/security/checkpoint/medical)
-"bki" = (/obj/structure/bodycontainer/morgue,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
+"bki" = (/obj/structure/bodycontainer/morgue,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
"bkj" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (EAST)"; dir = 4},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
"bkk" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
"bkl" = (/obj/machinery/mech_bay_recharge_port,/obj/structure/cable,/turf/simulated/floor/plating,/area/assembly/chargebay)
@@ -3319,7 +3321,7 @@
"blS" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/plasteel,/area/assembly/chargebay)
"blT" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/plasteel,/area/assembly/chargebay)
"blU" = (/obj/structure/table,/obj/item/stack/sheet/plasteel{amount = 10},/obj/item/stack/cable_coil,/obj/item/device/flash/handheld,/obj/item/device/flash/handheld,/turf/simulated/floor/plasteel,/area/assembly/robotics)
-"blV" = (/obj/structure/stool,/turf/simulated/floor/plasteel,/area/assembly/robotics)
+"blV" = (/obj/structure/stool,/obj/effect/landmark/start{name = "Roboticist"},/turf/simulated/floor/plasteel,/area/assembly/robotics)
"blW" = (/turf/simulated/floor/plasteel{icon_state = "bot"},/area/assembly/robotics)
"blX" = (/turf/simulated/floor/plasteel{dir = 8; icon_state = "warnwhite"},/area/assembly/robotics)
"blY" = (/obj/machinery/hologram/holopad,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{icon_state = "white"},/area/assembly/robotics)
@@ -3427,7 +3429,7 @@
"bnW" = (/obj/structure/closet/secure_closet/captains,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/atmospherics/unary/vent_scrubber{dir = 4; on = 1; scrub_N2O = 0; scrub_Toxins = 0},/turf/simulated/floor/fancy/carpet,/area/crew_quarters/captain)
"bnX" = (/obj/structure/stool/bed/chair/comfy/brown{dir = 4},/obj/machinery/camera{c_tag = "Captain's Quarters"; dir = 1},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (EAST)"; dir = 4},/turf/simulated/floor/fancy/carpet,/area/crew_quarters/captain)
"bnY" = (/obj/structure/table/wood,/obj/item/weapon/storage/box/matches,/obj/item/weapon/reagent_containers/food/drinks/flask{pixel_x = 8},/obj/item/weapon/razor{pixel_x = -4; pixel_y = 2},/obj/item/clothing/mask/cigarette/cigar,/turf/simulated/floor/fancy/carpet,/area/crew_quarters/captain)
-"bnZ" = (/obj/machinery/shower{dir = 4},/obj/item/weapon/soap/deluxe,/obj/item/weapon/bikehorn/rubberducky,/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/captain)
+"bnZ" = (/obj/structure/bodycontainer/morgue,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 5},/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "dark"},/area/medical/morgue)
"boa" = (/obj/structure/disposalpipe/segment,/obj/machinery/light{dir = 8},/turf/simulated/floor/plasteel,/area/hallway/primary/central)
"bob" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/wall,/area/medical/chemistry)
"boc" = (/obj/structure/closet/wardrobe/chemistry_white,/obj/machinery/light_switch{pixel_x = -23; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/chemistry)
@@ -3901,7 +3903,7 @@
"bxc" = (/obj/structure/stool/bed/chair/office/light{dir = 8},/obj/effect/landmark/start{name = "Research Director"},/turf/simulated/floor/plasteel{icon_state = "cafeteria"},/area/crew_quarters/hor)
"bxd" = (/obj/machinery/computer/robotics,/obj/structure/window/reinforced{dir = 4},/turf/simulated/floor/plasteel{icon_state = "cafeteria"},/area/crew_quarters/hor)
"bxe" = (/obj/structure/rack,/obj/item/device/aicard,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warnwhite"},/area/crew_quarters/hor)
-"bxf" = (/turf/simulated/floor/plasteel{icon_state = "white"},/area/crew_quarters/hor)
+"bxf" = (/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = -24},/obj/machinery/light,/obj/machinery/computer/card/minor/rd,/turf/simulated/floor/plasteel{icon_state = "cafeteria"},/area/crew_quarters/hor)
"bxg" = (/obj/structure/lamarr,/obj/machinery/light{dir = 4; icon_state = "tube1"},/turf/simulated/floor/plasteel{dir = 4; icon_state = "warnwhite"},/area/crew_quarters/hor)
"bxh" = (/turf/simulated/wall/r_wall,/area/crew_quarters/hor)
"bxi" = (/turf/simulated/wall,/area/toxins/explab)
@@ -4094,7 +4096,7 @@
"bAN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/research{name = "Research Division"})
"bAO" = (/obj/machinery/light{dir = 4},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{dir = 9; icon_state = "whitehall"},/area/medical/research{name = "Research Division"})
"bAP" = (/obj/machinery/power/apc{dir = 8; name = "RD Office APC"; pixel_x = -25},/obj/structure/cable,/obj/machinery/light_switch{pixel_y = -23},/obj/structure/flora/kirbyplants/dead,/turf/simulated/floor/plasteel{icon_state = "cafeteria"},/area/crew_quarters/hor)
-"bAQ" = (/obj/machinery/hologram/holopad,/obj/machinery/keycard_auth{pixel_x = 0; pixel_y = -24},/obj/machinery/light,/turf/simulated/floor/plasteel{icon_state = "cafeteria"},/area/crew_quarters/hor)
+"bAQ" = (/obj/machinery/computer/card/minor/cmo,/turf/simulated/floor/plasteel{icon_state = "barber"},/area/medical/cmo)
"bAR" = (/obj/structure/table,/obj/item/weapon/cartridge/signal/toxins,/obj/item/weapon/cartridge/signal/toxins{pixel_x = -4; pixel_y = 2},/obj/item/weapon/cartridge/signal/toxins{pixel_x = 4; pixel_y = 6},/obj/machinery/camera{c_tag = "Research Director's Office"; dir = 1; network = list("SS13","RD")},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -29},/turf/simulated/floor/plasteel{icon_state = "cafeteria"},/area/crew_quarters/hor)
"bAS" = (/obj/structure/closet/secure_closet/RD,/turf/simulated/floor/plasteel{icon_state = "cafeteria"},/area/crew_quarters/hor)
"bAT" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/plasteel{icon_state = "cafeteria"},/area/crew_quarters/hor)
@@ -4970,7 +4972,7 @@
"bRF" = (/obj/structure/closet/emcloset,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/aft)
"bRG" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/aft)
"bRH" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plating,/area/maintenance/aft)
-"bRI" = (/obj/structure/stool/bed,/obj/item/clothing/suit/straight_jacket,/obj/item/clothing/glasses/sunglasses/blindfold,/obj/item/clothing/mask/muzzle,/obj/machinery/camera{c_tag = "Prison Sanitatium"; dir = 4; network = list("SS13","Prison"); pixel_x = 0; pixel_y = 0},/turf/simulated/floor/plasteel{icon_state = "white"},/area/security/prison)
+"bRI" = (/obj/machinery/shower{dir = 4},/obj/item/weapon/soap/deluxe,/obj/item/weapon/bikehorn/rubberducky,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "freezerfloor"},/area/crew_quarters/captain)
"bRJ" = (/obj/machinery/door/airlock{name = "Garden"; req_access_txt = "0"},/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 4},/turf/simulated/floor/plasteel,/area/hallway/secondary/construction{name = "\improper Garden"})
"bRK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/machinery/atmospherics/pipe/simple/supply/hidden,/turf/simulated/floor/plasteel,/area/hallway/primary/aft)
"bRL" = (/obj/item/weapon/crowbar,/obj/item/weapon/wrench,/obj/structure/window/reinforced,/turf/simulated/floor/plasteel{dir = 6; icon_state = "caution"},/area/hallway/primary/aft)
@@ -5106,7 +5108,7 @@
"bUl" = (/obj/structure/table,/obj/item/weapon/hand_labeler,/obj/item/device/radio/headset/headset_med,/turf/simulated/floor/plasteel{dir = 4; icon_state = "whitegreen"},/area/medical/virology)
"bUm" = (/obj/structure/grille,/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/structure/window/fulltile,/turf/simulated/floor/plating,/area/medical/virology)
"bUn" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology)
-"bUo" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology)
+"bUo" = (/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/engine,/area/toxins/xenobiology)
"bUp" = (/obj/structure/grille,/obj/structure/window/fulltile,/turf/simulated/floor/plating,/area/medical/virology)
"bUq" = (/obj/structure/grille,/obj/structure/disposalpipe/segment{dir = 4},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/door/poddoor/preopen{id = "xenobio2"; name = "containment blast door"},/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/engine,/area/toxins/xenobiology)
"bUr" = (/obj/structure/window/reinforced,/obj/structure/table/reinforced,/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_y = 0},/obj/machinery/door_control{id = "xenobio7"; name = "Containment Blast Doors"; pixel_x = 0; pixel_y = 4; req_access_txt = "55"},/turf/simulated/floor/plasteel{dir = 10; icon_state = "warning"},/area/toxins/xenobiology)
@@ -5152,7 +5154,7 @@
"bVf" = (/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{dir = 10},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology)
"bVg" = (/obj/structure/table,/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology)
"bVh" = (/obj/machinery/light{dir = 4},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology)
-"bVi" = (/mob/living/simple_animal/slime,/turf/simulated/floor/engine,/area/toxins/xenobiology)
+"bVi" = (/obj/structure/stool/bed,/obj/item/weapon/bedsheet,/obj/effect/landmark{name = "revenantspawn"},/turf/simulated/floor/plasteel{icon_state = "white"},/area/medical/virology)
"bVj" = (/obj/machinery/door/window/northleft{base_state = "right"; dir = 8; icon_state = "right"; name = "Containment Pen"; req_access_txt = "55"},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/poddoor/preopen{id = "xenobio2"; name = "containment blast door"},/turf/simulated/floor/engine,/area/toxins/xenobiology)
"bVk" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"; pixel_y = 0},/obj/machinery/door/window/northleft{dir = 4; name = "Containment Pen"; req_access_txt = "55"},/obj/machinery/door/poddoor/preopen{id = "xenobio7"; name = "containment blast door"},/turf/simulated/floor/engine,/area/toxins/xenobiology)
"bVl" = (/obj/structure/filingcabinet/chestdrawer,/turf/simulated/floor/plasteel{icon_state = "floorgrime"},/area/toxins/misc_lab)
@@ -5192,7 +5194,7 @@
"bVT" = (/obj/machinery/power/apc{dir = 8; name = "Engineering Security APC"; pixel_x = -24},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/machinery/newscaster{pixel_y = 32},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 9},/area/security/checkpoint/engineering)
"bVU" = (/obj/machinery/requests_console{department = "Security"; departmentType = 5; pixel_y = 30},/obj/structure/closet,/turf/simulated/floor/plasteel{icon_state = "red"; dir = 1},/area/security/checkpoint/engineering)
"bVV" = (/obj/structure/filingcabinet,/obj/machinery/alarm{pixel_y = 23},/turf/simulated/floor/plasteel{icon_state = "red"; dir = 5},/area/security/checkpoint/engineering)
-"bVW" = (/obj/structure/closet/fireaxecabinet{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel,/area/atmos)
+"bVW" = (/obj/structure/fireaxecabinet{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel,/area/atmos)
"bVX" = (/obj/structure/closet/secure_closet/atmospherics,/turf/simulated/floor/plasteel{dir = 8; icon_state = "warning"},/area/atmos)
"bVY" = (/obj/machinery/atmospherics/unary/portables_connector/visible{dir = 4},/obj/machinery/portable_atmospherics/canister,/turf/simulated/floor/plasteel{dir = 2; icon_state = "bot"},/area/atmos)
"bVZ" = (/obj/machinery/atmospherics/unary/portables_connector/visible{dir = 8},/turf/simulated/floor/plasteel{dir = 2; icon_state = "bot"},/area/atmos)
@@ -5651,7 +5653,7 @@
"ceK" = (/turf/simulated/wall/r_wall,/area/engine/engineering)
"ceL" = (/obj/machinery/computer/atmos_alert,/obj/machinery/requests_console{announcementConsole = 1; department = "Chief Engineer's Desk"; departmentType = 3; name = "Chief Engineer RC"; pixel_x = -32; pixel_y = 0},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralfull"},/area/engine/chiefs_office)
"ceM" = (/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralfull"},/area/engine/chiefs_office)
-"ceN" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/lighter/zippo,/obj/item/clothing/glasses/meson{pixel_y = 4},/obj/item/weapon/stamp/ce,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralfull"},/area/engine/chiefs_office)
+"ceN" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/lighter/zippo,/obj/item/clothing/glasses/meson{pixel_y = 4},/obj/item/weapon/stamp/ce,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralfull"},/area/engine/chiefs_office)
"ceO" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralfull"},/area/engine/chiefs_office)
"ceP" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralfull"},/area/engine/chiefs_office)
"ceQ" = (/obj/structure/grille,/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/cable{icon_state = "0-2"; d2 = 2},/obj/structure/window/reinforced/fulltile,/turf/simulated/floor/plating,/area/engine/chiefs_office)
@@ -5770,7 +5772,7 @@
"cgZ" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/plasteel,/area/engine/engineering)
"cha" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/sign/nosmoking_2{pixel_y = 32},/obj/machinery/camera{c_tag = "Engineering Power Storage"},/obj/machinery/light{dir = 1},/turf/simulated/floor/plasteel,/area/engine/engineering)
"chb" = (/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/stool/bed/chair/office/dark{dir = 1},/obj/effect/landmark/start{name = "Station Engineer"},/turf/simulated/floor/plasteel,/area/engine/engineering)
-"chc" = (/obj/structure/filingcabinet/chestdrawer,/obj/machinery/camera{c_tag = "Chief Engineer's Office"; dir = 4; network = list("SS13")},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/mob/living/simple_animal/parrot/Poly,/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralfull"},/area/engine/chiefs_office)
+"chc" = (/obj/machinery/camera{c_tag = "Chief Engineer's Office"; dir = 4; network = list("SS13")},/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/machinery/computer/card/minor/ce,/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralfull"},/area/engine/chiefs_office)
"chd" = (/obj/machinery/atmospherics/unary/vent_pump{on = 1},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralfull"},/area/engine/chiefs_office)
"che" = (/obj/structure/table/reinforced,/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/obj/item/weapon/pen,/obj/item/weapon/storage/fancy/cigarettes,/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralfull"},/area/engine/chiefs_office)
"chf" = (/turf/simulated/floor/engine,/area/toxins/explab)
@@ -6282,7 +6284,7 @@
"cqR" = (/obj/structure/window/reinforced{dir = 4},/turf/space,/area/space)
"cqS" = (/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/aisat)
"cqT" = (/obj/structure/window/reinforced{dir = 4},/obj/machinery/light/small{dir = 4},/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/aisat)
-"cqU" = (/obj/machinery/door/airlock/engineering{name = "Telecommunications"; req_access_txt = "61"},/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel,/area/tcommsat/computer)
+"cqU" = (/obj/effect/landmark{name = "revenantspawn"},/mob/living/simple_animal/slime,/turf/simulated/floor/engine,/area/toxins/xenobiology)
"cqV" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel,/area/tcommsat/computer)
"cqW" = (/obj/structure/disposalpipe/segment,/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 10},/turf/simulated/floor/plasteel,/area/hallway/primary/aft)
"cqX" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden{dir = 4},/turf/simulated/floor/plasteel{dir = 8; icon_state = "yellow"},/area/hallway/primary/aft)
@@ -6426,7 +6428,7 @@
"ctF" = (/obj/machinery/atmospherics/pipe/manifold/supply/hidden{tag = "icon-manifold-b-f (EAST)"; dir = 4},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/turret_protected/aisat_interior)
"ctG" = (/obj/machinery/atmospherics/unary/vent_pump{dir = 1; on = 1},/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners (WEST)"; icon_state = "darkbluecorners"; dir = 8},/area/turret_protected/aisat_interior)
"ctH" = (/obj/structure/cable{icon_state = "0-4"; d2 = 4},/obj/structure/cable{d2 = 8; icon_state = "0-8"},/obj/structure/table,/turf/simulated/floor/plasteel{icon_state = "yellow"},/area/engine/engineering)
-"ctI" = (/obj/structure/table/reinforced,/obj/item/stack/medical/bruise_pack{pixel_x = -3; pixel_y = 2},/obj/item/weapon/stock_parts/cell/high{charge = 100; maxcharge = 15000},/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralfull"},/area/engine/chiefs_office)
+"ctI" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 27},/obj/structure/filingcabinet/chestdrawer,/mob/living/simple_animal/parrot/Poly,/turf/simulated/floor/plasteel{dir = 2; icon_state = "neutralfull"},/area/engine/chiefs_office)
"ctJ" = (/obj/machinery/atmospherics/unary/vent_scrubber{dir = 1; on = 1},/turf/simulated/floor/plasteel{tag = "icon-darkbluecorners"; icon_state = "darkbluecorners"; temperature = 273.15},/area/turret_protected/aisat_interior)
"ctK" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (WEST)"; dir = 8},/turf/simulated/floor/plasteel{icon_state = "vault"; dir = 8},/area/turret_protected/aisat_interior)
"ctL" = (/obj/machinery/door/airlock/shuttle{name = "Mining Shuttle Airlock"; req_access_txt = "48"},/obj/docking_port/mobile{dir = 8; dwidth = 3; height = 5; id = "mining"; name = "mining shuttle"; travelDir = 90; width = 7},/obj/docking_port/stationary{dir = 8; dwidth = 3; height = 5; id = "mining_home"; name = "mining shuttle bay"; width = 7},/turf/simulated/floor/plating,/area/shuttle/labor)
@@ -6485,6 +6487,7 @@
"cuM" = (/turf/space,/turf/simulated/wall/shuttle{icon_state = "swall_f9"; dir = 2},/area/shuttle/pod_4)
"cuN" = (/turf/space,/turf/simulated/wall/shuttle{dir = 2; icon_state = "swall_f10"; layer = 2},/area/shuttle/pod_4)
"cuO" = (/turf/simulated/floor/plating,/obj/structure/shuttle/engine/propulsion/burst{dir = 4},/turf/simulated/wall/shuttle{icon_state = "swall_f6"; dir = 2},/area/shuttle/pod_4)
+"cuP" = (/obj/machinery/door/airlock/engineering{name = "Telecommunications"; req_access_txt = "61"},/turf/simulated/floor/plasteel,/area/tcommsat/computer)
"cuR" = (/obj/structure/sink{icon_state = "sink"; dir = 8; pixel_x = -12; pixel_y = 2},/obj/machinery/atmospherics/unary/vent_pump{dir = 4; on = 1},/obj/machinery/doorButtons/access_button{idSelf = "virology_airlock_control"; idDoor = "virology_airlock_interior"; name = "Virology Access Button"; pixel_x = 8; pixel_y = -28},/turf/simulated/floor/plasteel{dir = 10; icon_state = "warnwhite"},/area/medical/virology)
"cuS" = (/obj/machinery/atmospherics/binary/pump{dir = 1; on = 1},/obj/structure/sign/fire{pixel_x = 32; pixel_y = 0},/obj/machinery/doorButtons/access_button{idSelf = "incinerator_access_control"; idDoor = "incinerator_airlock_interior"; name = "Incinerator airlock control"; pixel_x = -8; pixel_y = 24},/obj/machinery/light/small{dir = 4},/turf/simulated/floor/engine,/area/maintenance/incinerator)
"cuT" = (/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{tag = "icon-manifold-r-f (NORTH)"; dir = 1},/turf/simulated/floor/plasteel,/area/quartermaster/storage)
@@ -6576,7 +6579,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiaaZaasaasaasaaKabaabbaasaasabcabdaaiaaiaaiaafaaaaaaaaaaaaaaaaafaaaaaVaaaaaaaaaaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabeabeabeabfabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHaaOaaWaaNaaXabiaasabjaasaasaasaasaasaasaauaasabkablaaiaafaafaafaafaafaafaafaafabmabmabmabnabmabmaboaboabpabpabpaboaboaaaaaaaaaaaaaaaaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaafaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabgaaYabraaPabsabuaasaasabvabwabxaasabyabzabAaasabBabCaaiaafaaaaafaafaafaafaaaaafabnabDabEaeIabFabGaboabHabIabJabKabLaboaaaaaaaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafabMaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaabfabfabeabfabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabgabNabPabOabsabSabTabSabSabSabUabSabSabSabVabSabSabWaaiactactactactactactactactabmabXabEaeIabYabDaboabZacaacbacbaccaboaaaaafacdaagaagaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfabfabfaafaafaaaaceaaaacfaafabfabfabfabfabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaabfabfabeabfabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabgabNabPabOabsabSabTabSabSabSabUabSabSabSabVabSabSabWaaiactactactactactactactactabmabXabEaeIabYabDaboabZacaacbaccahPaboaaaaafacdaagaagaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfabfabfaafaafaaaaceaaaacfaafabfabfabfabfabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaafaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabgabQacgabRabsackaasaclabSacmacnacoabSacpacqacrabSacsaaiacMacNacOacOacPacQacRacSactacuabEaeIaecabDabpacwacxacyacbaczaboaaaaafacAacBacAaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqaaaaaaaafaaaaafaaaaaaaceaaaaaaaafaaaaafaaaaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafacCaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHaciacDacjacEacHaasacIabSacJacnacIabSacKacqacIabSacLaaiacMadkadladladladladmadnactacTabEaeIaecabDabpacUacVacWacbacXaboaafaafacAacYacAaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafacZacZacZacZacZaaaadaaaaacZacZacZacZacZaafabfaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfadbadbadbadbaafaafaaaadcaaaaafaafabfabfabfabfabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafhaaHaaHaaHacFaddacGabsadfadgadhabSadfadiadhabSadfadjadhabSabSaaiafnaRFaNFadVaNFadWbhdbiGactadoabEaeIaecabDaboadpadqadradsadtaboabnabmadvacBacAacAachaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaadwadxadxadxadxadyadzadAadBadBadBadBadCaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -6586,7 +6589,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafafPafPafPafPafPaaaafdaaaafPafPafPafPafPaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaHaaHaaHbaMbOybkdaaHaaiadhafQadfafRafRafRafRafRafRafRafSafTafUafVafWafXafYafZagaagbagcafUagdahSageagfaggaghagiafFagjafHagkaglagmabmadvacAacAacAachaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaadwadxadxadxadxadyadzadAadBadBadBadBadCaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaaaaaaafaaaaaaaaaafdaaaaaaaaaaafaaaaaaaaaabqaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaHaaHaaHaaHaaHaaiagnagoagpafRagqagragsagtaguafRagvagwagxagyagzagAagBagaagCagbagDagEagFafFagGagHagIagJagKaeKafAagNagOagLagMagRanUagUacAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafaemaemaemaemaemaaaadzaaaaemaemaemaemaemaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafaenaenaenaenaenaaaafdaaaaenaenaenaenaenaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaiagVagWagXafRagYagZahaahbahcafRagvahdaheahfahgahhahiahjahjahkahlahmahnaqqaPUaPTahqahrahsahTahVahuahvahWahwabmacAahxacAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaaaaaaafaaaaaaaaaadzaaaaaaaaaaafaaaaaaaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaafaafbafbafbafbafcafdafeaffaffaffaffafgaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaibRIagWahyafRagYagZahzahbahAafRahBahCahDahEahFahGahHahIahJahKahLahMahNahObzKbzJahRcdlankaiaahUbuJahXbxkahYahZaibaicaidaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafacZacZacZacZacZaaaadzaaaacZacZacZacZacZaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaafaafbafbafbafbafcafdafeaffaffaffaffafgaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaiahyagWaHeafRagYagZahzahbahAafRahBahCahDahEahFahGahHahIahJahKahLahMahNahObzKbzJahRcdlankaiaahUbuJahXbxkahYahZaibaicaidaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafacZacZacZacZacZaaaadzaaaacZacZacZacZacZaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfacfafPafPafPafPafPaaaafdaaaafPafPafPafPafPaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaafaaaaaaaaiaieagWaigafRaihaiiaiiaijahcafRaikailafUaimainaioaipaipaiqairafUafUaisaitaduaduaduabmabmabmabmabmabmabmabmaiuaivaiwaidaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaadwadxadxadxadxadyadzadAadBadBadBadBadCaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaaaaaaafaaaaaaaaaafdaaaaaaaaaaafaaaaaaaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaixaixaiyaixaizaiAafRafRafRafRafRafRaiBaiCafRaiDaiEaiFaiFaiFaiFaiFaiFaiFaiFaiGaiHaiIaiJaiFailaiAaiKaiLaiMaiNaiOaiPaiQaiRaiuaivaiwaidaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafaemaemaemaemaemaaaadzaaaaemaemaemaemaemaiSabqaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafaenaenaenaenaenaaaafdaaaaenaenaenaenaenaafabfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaixaiTaiUaiVaiWaiXaiYaiZajaajbajcajdajeajfajgajhajiajjajkajjajjajjajjajjajjajlajjajiajmajkajnajoajpajqajrajsajtajuajvajwaiuaivaiwacAaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaaaaafaaaaafaaaaaaadzaaaaaaaafaaaaafaaaaaaabfaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -6614,10 +6617,10 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaabJXaBEaDgaBEaDcaDcaDcaDcaBEaDgbJWbJVaqpaBGaBHaBIaBJaBKaBLaBMaBNaBOayuazCazEazEaBPazEazEazCayuaBQaBRaBSaBTaBUaBVaBWaBXaBYaBZaAEaafazNaCaaCbaCdaCcaCeazNaafaxoaxuaxvaCfaCgaChaCiaCjaxvapNaCkaxxaClaCmaCnayOaCnaCoaCpaCqaCraAgaxKaCsaxKayQamwayRacAaeUapTarQarRarSaCtarUaCuayZaCvaAmaAmaAmazaaCwaCxaCyayZaCzaCAaCBaCCaCDaApaaaaafaaaaafaaaaafaaaaafaaaallavuaCEaBsaCFaCGallasiamlavuarjamlallaaaallawTaBsaBsaCHaCIaCJaCJaCJaCJaCJaCKaCLaCMaCNaCOaCOaCOaCPaCQaCRaCSaCTaCUaCVaCWaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabJXaBEaBEarscnAarrcmYcmuckEbPbbLZbLXarraCXbLiavMaBGaDhaAvaDiaDjaDkaDlaDmaDnayuaDoazEazEazEazEaDpaDqbRJaDsaDtaDuaBYaBYaBYaBYaBYaBYaBYaAEaaaazNaDvaDwaDwaDxaDzazNaaaaxoaxuaxvaDAaDBaDCaDDaDEaxvapNaDFaxxaxxaDGaATaDHaATaDIaxxaxxaDJaDKaxKaDLaxKayQamwayRacAaeUapTapTapTapTapTaDMaDNaDOaDPaDQaDRaDRaDRaDSayZaDTayZaDUaDVaDWaBdaBeaApallallallallallallallallallallallallallaDXallallallallawTaBtaDYaDZaEaaDZaEbaEcaEdaEdaEeaEfaEfaEfaEfaEfaEgaEhaEiaEiaEiaEiaEiaEiaBDaEjaEkaElaBDaBDaBDaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDccsOcsOcsYarraDbarraDbarraDbarraDbarraCXaDeavMaBGaEqaAvaEraEsaEtaEuaEvaEwayuaExazEaEyaEzaEzaEAaEBaECaEDaEEaEFawKaEGaEGaEGawKaEHaEIaAEaafazNaEJaDyaEKaELaEMazNaafaxoaENaEOaEPaEQaDCaERaESaETaEUaEVaxKaEWaEXaDJaDJaDJaEYaEZaxKaFaaFaaxKaDJaxKaFbaoeaFcacAaeUaeUaeUaeUaeUamXawvaFdaFeaFfaFgaFeayoaFeaFiaFeaFjayZaFkaFlaFmaBdaFnaFoaFpaFqaFraFsaFtaFuaFuaFuaFuaFvaFwaFuaFuaFxaFyaFzaFAaBpaFBaFCaFDaFEaFFaFEaFGaFHaEfaEfaFIaEfaFJaFKaFLaEfaEiaFMaEiaFNaFOaFPaFQaFRaFSaFTaFUaFVaFWaFXaFYaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDcarrarrctiarraDbarraDbctaaDbarraDbarraCXaDeavMaBGaGcaAvaAvaGdaGeaGfaGgaAvayuayuayuayuaGhazEaAzaGiayuaGjaGkaBYaBYaBYaFhaBYaBYaBYaGmaAEaaaazNazNaGnaGoaGnazNazNaaaaxoaxuaxvaGpaGqaGraGsaGtaxvapNaGuaxKaGvaEXaDJaDJaDJaEYaGwaxKaAgaAgaxKaCsaxKaGxaGyaGzacAamXacAacAacAacAacAaGAaGBayZaGlaAmayZaGDayZaGEayZaGFayZaGGaGHaFmaBdaGIaGJaGKaGLaGMaGMaGNaGMaGMaGOaSOaGPaGQauwauwauwauwaGRaGSaGTaGUaGVamlaGWaGWaGWaGWaGXaEfaGYaGZaHaaGCaHcaHdaEfaHeaHfaEiaHgaHhaHiaHjaFRaHkaEjaEkaCTaHlaHmaFYaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDcarrarrctiarraDbarraDbctaaDbarraDbarraCXaDeavMaBGaGcaAvaAvaGdaGeaGfaGgaAvayuayuayuayuaGhazEaAzaGiayuaGjaGkaBYaBYaBYaFhaBYaBYaBYaGmaAEaaaazNazNaGnaGoaGnazNazNaaaaxoaxuaxvaGpaGqaGraGsaGtaxvapNaGuaxKaGvaEXaDJaDJaDJaEYaGwaxKaAgaAgaxKaCsaxKaGxaGyaGzacAamXacAacAacAacAacAaGAaGBayZaGlaAmayZaGDayZaGEayZaGFayZaGGaGHaFmaBdaGIaGJaGKaGLaGMaGMaGNaGMaGMaGOaSOaGPaGQauwauwauwauwaGRaGSaGTaGUaGVamlaGWaGWaGWaGWaGXaEfaGYaGZaHaaGCaHcaHdaEfaLyaHfaEiaHgaHhaHiaHjaFRaHkaEjaEkaCTaHlaHmaFYaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDcaDdaDdaDaarraDbarraDbarraDbarraDbarraCXaDeavMaHpaHqaHraHsaHsaHtaHuaxaaHvaHwaHxaHyayuaHzazEazEaHAayuaHBaHCaBYaHDaHEaOwaHGaHHaHIaHJaAEaaaaafaaaaHKaHLaHKaaaaafaaaaxoaxuaxvaDCaHMaHNaHOaHPaxvapNasJaxKaHQaHRaDJaDJaDJaHSaHTaxKaaaaaaaHUaHVaHWaHXaHYbzZaIaaIbaHUaaaaaaaIcaIdaIeaIfayZaIgaAmaAmaAmaCxaAmaAmaAmayZaBdaIhaIiaBdaBdaApaIjaIkaIkaIlaImaInaIkaIoaIpaIpaIqaIpaIraIpaIsaGWaGWaItaGWaGWaGWaGWaIuaIvaGWaGXaEfaGZaIwaIxaIyaIzaIAaEfaIBaICaIDaIEaIFaIGaIHaIIaIJaBAaIKaFVaFWaILaFYaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBFaBEaBEarsartarrarrarrarrarrarraCZarraCXaCYavMaBGaxaaIOaIPaIPaIPaIPaIPaIPaIPaIQaxaayuaIRaISaIRayuayuaITaIUaIVaADaADaADaADaIVaIWaIXaAEaIYaIZaIZaJaaJbaJaaIZaIZaJcaxoaJdaxvaJeaxvaJfaJfaJgaxvaJhaJiaxKaxKaxKaAgaDHaAgaxKaxKaxKaHUaHUaHUaJjaHYaHYaHYaHYaHYaJkaHUaHUaHUaIcaJlaIeaJmayZayZayZayZayZayZayZayZayZayZaJnaJoaJpaJqaJraJsaJtaJuaIkaJvaImaJwaJxaJwaIpaJyaJzaIpaJAaIpaJBaJCaJDaJEaJFaJFaJFaJGaJHaJIaGWaGXaEfaJJaIwaJKaIyaIzaJLaEfaJMaJNaJOaJPaJQaJRaJSaJTaJUaJVaJWaCTaHlaHmaFYaaaaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBFaBEaDfaBEaDcaDcaDcaDcaBEaDgaEmaEnaqpaJZaxaaKaaHbaKbaKcaKbaKdarpaKeaKfaxaaKgaKhaKiaKiaKjaKiaKkaKlaKiaKiaKiaKiaKiaKiaKiaKmaKnaKoaKpaKqaKqaKraKsaKqaKqaKqaKtaKuaKvaKraKqaKqaKqaKwaGyaKxaHYaKyaKzaHZaIaaIaaIaaHXaHYaHYaKAaHYaHYaKBaKCaKDaKEaKFaKGaKHaHYaHYaKAaKJaKKaKLaKMaKNaKOaKPaKQaHYaKRaHYaBdaKSaKTaKUaJoaKVaKWaKXaKYaKZaLaaIkaLbaLcaLdaLeaLfaIpaLgaJzaLhaLiaIpaIpaLjaLkaLlaLmaLnaLoaLpaLqaLraGWaGXaEfaLsaLtaLuaLvaLwaLxaEfaLyaLzaEiaLAaLAaLAaLAaEiaLBaCRaJWaCTaBDaBDaBDaLCaLCaLCaLDaLDaLDaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaBFaBEaDfaBEaDcaDcaDcaDcaBEaDgaEmaEnaqpaJZaxaaKaaHbaKbaKcaKbaKdarpaKeaKfaxaaKgaKhaKiaKiaKjaKiaKkaKlaKiaKiaKiaKiaKiaKiaKiaKmaKnaKoaKpaKqaKqaKraKsaKqaKqaKqaKtaKuaKvaKraKqaKqaKqaKwaGyaKxaHYaKyaKzaHZaIaaIaaIaaHXaHYaHYaKAaHYaHYaKBaKCaKDaKEaKFaKGaKHaHYaHYaKAaKJaKKaKLaKMaKNaKOaKPaKQaHYaKRaHYaBdaKSaKTaKUaJoaKVaKWaKXaKYaKZaLaaIkaLbaLcaLdaLeaLfaIpaLgaJzaLhaLiaIpaIpaLjaLkaLlaLmaLnaLoaLpaLqaLraGWaGXaEfaLsaLtaLuaLvaLwaLxaEfbhpaLzaEiaLAaLAaLAaLAaEiaLBaCRaJWaCTaBDaBDaBDaLCaLCaLCaLDaLDaLDaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaavMaylavMavMavMavMavMavMaylavMaaaaqpaAuaLEaKaaLFaLGaLHaLHaLIarpaLJaKfaLKaLLaKhaLMaLNaLOaLPaLQaLRaKiaKiaKiaKiaKiaKiaKiaKmaKiaKhaKiaKiaKiaLSaLTaLUaLUaLUaLUaLVaLUaLWaLUaLUaLXaKhaGyaHYaHYaHYaHYaHYaHYaHYaHYaHYaHYaHYaKAaHYaHYaLYaLZaMaaKIaMcaMbaMeaHYaHYaKAaHYaHYaHYaHYaHYaHYaHYaHYaHYaMgaHYaBdaKUaKUaKUaMhaMiaMjaMkaMlaMmaMnaIkaMoaImaMpaIkaIkaIpaMqaJzaMraLiaMsaIpaGWaGWaGWaGWaGWaGWaMtaMuaMvaGWaGXaEfaMwaGZaMxaMyaGZaMzaEfaEiaEiaEiaEiaEiaEiaMAaEiaEjaEjaEkaCTaMCaMDaBDaMEaMFaMGaMHaMIaLDaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaafaafaafaafaztaqpavMatBavMaNTaNUaNVaNWavMatBavMavMaqpaBGaxaaKaaMJaMKaLHaLHaLIarpaMLaKfaxaaLLaKhaKiaMMaMNaMNaMNaMOaMPaMQaMNaMRaMNaMNaMNaMSaMNaMTaMNaMNaMNaMUaMVaMWaMXaMXaMYaMZaNaaNbaNcaKicrraKhaGyaHYaNeaHYaNfaNfaNfaNfaNfaNfaNfaNfaNgaNfaNfaNfaNfaNfaNfaNfaNfaNfaNfaNfaNhaNfaNfaNfaNfaNfaNfaNfaNfaHYaHYaHYaBdaNiaNiaNiaNiaNiaNjaNkaJsaODaRdaIkaNmaNnaNoaIkaNpaIpaNqaNraNsaLiaNtaIpaGWaNuaNvaNwaNxaNwaNyaNzaNAaGWaGXaEfaNBaNBaNCaNDaNEaNEbqoaEfaNGaNHaNIaBDaNJaNKaNLaEjaEjaNMaNNaBDaNOaBDaNPaNQaNRaNRaNSaLDaLDaLDaLDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafarpavMaylavMaBGaxaaxaaMBavMaylavMaNXaNYaNZaxaaKaaOaaRhaKcaOaaKdarpaObaKfaxaaOcaOcaOcaOdaOcaOeaOeaOeaOeaOeaOfaOgaOeaOhaOeaOeaOeaOiaOjaOkaOjaOlaOmaOnaKiaKiaOoaOpaOqaOraKlaKiaNdaOsaOsaHYaHYaHZaHUaHUaHUaHUaHUaHUaHUaHUaOtbUPbUObUQbUObUObUObVMbUObWHbUObXtaOtaHUaHUaHUaHUaHUaHUaHUaHUaHXaHYaHYaIkaOAaOBaNlaVPaNlaNlaOCaJsaOGaOEckZcjTaOFaPVaIpaIpaIpaOHaOIaIpaIpaIpaIpaIpaNwaOJaOKaOKaOKaOLaOMaNwaGWaGXaEfaONaGZaNCaNDaGZaGZaOOaEfaOPaOQaORaBDaEjaOSaOTaOUaOUaOVaOWaOXaOYaBDaOZaPaaNRaPbaNRaPcaPdaPdaPcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -6634,26 +6637,26 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafavMawZaxaawZaxbaxaaxaaxcawZaxaawZaxbaxabcqaHqbcrbcsbctbcrbcrbcrbcubcvaOcaOcaOcbcwaUQaWAaYdbcxbcybczaWAbcAbcBbcAaOeaOeaOebcCbcDaOcaYnaYoaYpbcEaZGbaFbcFbcGaYpaZIaYvbcHbaHbaHbcIbcJbcKbcLaHYaWUbXvbcMbaObbNbcNbcObcPbaSbaOaZWbcQbcRaYDbcSbcTbcUaYDbcVbaAbabbcXbcYbcZbdabdabdbbajbdcaYHbddbdecuAaGybbfaXFaXFbdfaXFbdgbdhbdhbdhbdibdhbdhbdhbdjaXFaXFaXFaXFaXFaXFbdkbdlbdmbbfaXFaXFaXFaXFbarbdnbdobdpbdqbdraXFaXFaXFaXFaXFbdsbdtaXFaXFaXFaXFaXFaXFaXFaXFaXFaXFaXFaXFaXFbbfbdubdvbdwbdxaROaNRaNSaLDaLDaLDaLDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarpavMbdyavMaBGaxaaxaaMBavMbdAavMayqbdBbdCbdCbdDbdEbdFbdGbdHbdIbdJbdKbdLbdMbdMbdNbdOaWAaWAaWAbdPbdQaWAaOcaOcaOcaOcbdRaVbbdSbdTaVbbdUaYoaYpbdVaZGaZGbdWbdXaYpbdYaYvbdZbaHbaHbeabebbecbedaHYaWUaYxbaObeebaPbaPbefbaRbaSbegbcWaXfbeibejbekbekbekbelbemaXkbdzbeobepbeqberbajbesbajbetaYHaXqaHYaHYbeubeubeubeubeubeubeubevbewbewbexbeybeybevbezbezbezbezbezbeAbeAbeBbeCbeAbeAbeAbeAbeDaXFbeEbeFbeGbeHbeIaXFaXFaXFbeJbeJbeKbeKbeKbeKbeKbeLbeMbeMbeMbeNbeMbeObePbeMbeMbeQbeRbeRbeRbeRbeSbeTbeUbeVaLDaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaztaqpazuatBavMaymaynbeWbeXavMatBazuavMaqpaztarpbdDbeYbeZbeZbeZbfabdJbfbbfcbfdbfdbfebffaWAaYdbfgbdPbfhaWAbfibfiaQEaQEbfjbfkbflbfmbflbflbfnaYpbfobfpaZGaZGbdXbfqbfraYvbfsbaHbaHbeabftbfubedaHYbfvaYxbfwaYAbfxbfybfzbfAbaSbfBaYxaafbfCbfDbfDbfDbfEbfFbfGaafaYHbfHbfIbfJbfKbajbfLbajbfMaYHaXqaHYbfNbeubfObotbfQbfRbfSbeubehbfVbfVbfWbfXbfXbfXbfYbfZbgabgbbezbgcbgdbgebgdbgdbgfbggbeAbeGbghbeGbeGbeGbgibeIbeIbgjbeIbgkbgkbeKbglbgmbgnbeKbgobgpbgobeKbgqbgrbgqbeRbgsbgtbgsbeRbgubgvbeRbgwbgxaLDaLDaLDaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafavMbdyavMavMavMavMavMavMbdAavMaafaafaafaaabdDbgybdDbgzbeZbgAbgBbcraVbbgCbgDbgEbgFbgGbgGbgGbgGbgGbgGbgHbgIbgJbfdbgKbgLaYpaYpaYpaYpaYpaYpbgMaYpaYpaYpbgNbgObgPbgQbgRbaHbaHbeabgSbecbedaHYbgTaYxbgUaYAaYAaYAaYAbfAbaSbgVaYxaafbfCbfDbgWbgXbgYbfDbgZaafaYHbhabbYbhbbhcbajbesbajbajaYHaXqaHYaHYbeubqqbhebhfbhgbhhbhibfXbhjbfXbhkbfXbfXbhlbfYbhmbhnbhobezbhpbgdbhqbgdbhpbhrbgdbeAbhsbhsbhubhvbeGbhwbeIbhxbhybhzbhAbhAbeKbhBbhCbhDbhEbhFbhGbhHbeKbhIbhJbhKbeRbhLbhMbhLbhNbhObhObeRbhPbgxaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaacuzaaaaaaaafaafaaaaaaaaaaaaaaaaafaafaaabdDbhQbhRbhSbhTbhTbhUbhVaWPbhWaOcbhXbhYbhZbhZbhZbiabiabiabiabiabiabiabibbgNbicbidbiebifbigbihbiibijaYpbikbilbimbinbinbiobaHbaHbeabaHaYvbedaHYaWUbipbiqbirbisbitaYAbiubaSaYxaYxaafbfCbfDbgXbfDbgXbfDbgZaafaYHaYHbivbcZbiwbajbixbiybizaYHaXqaHYbiAbiBbiCbiDbqrbiFbrWbiHbfXbiIbiJbiKbiLbiLbiMbfYbiNbhnbiObezbhpbgdbhqbiPbhpbiQbiRbeAbiSbiTbiUbiVbeGbgibeIbiWbiXbiXbiYbiZbjabjbbjcbjcbjcbjdbjebjfbeKbjgbhJbjhbeRbjibjjbjkbjlbjmbjnbeRbhPbgxbjobjobjobjoaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaafaaabdDbjpbdDbjqbjrbjrbjsbdDbjtbjtaOcbjubjvbjubjubjubjvbjuaOcaOcaYpaYpaYpbjwbgNbjxbjxbjybjxbjxbjxbiibjxbjzbjAbjBbjCbjDbjEbjEbjEbjEbjFbjGbjHbjIbjJbjKbjLbjMbjNbjObjPaYAbfAbaSaYxaafaafbfCbfDbgYbjQbgWbjRbgZaafaafaYHbjSbjTaYHaYHaYHaYHbjUaYHbjVaHYaHYbeubjWbhebjXbhgbhhbjYbfXbjZbkabkbbkcbtmbkebezbkfbkgbkhbezbhpbgdbkibkjbhpbkkbgdbeAbeGbeGbeGbeGbeGbgibeIbklbkmbknbkobkpbkqbkrbksbktbktbkubkvbkwbeKbkxbhJbkybeRbkzbkAbkBbkCbkDbkEbeRbhPbkFbkGbkHbkIbkHaaaaaaaafaaaaafaaaaafaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafavMbdyavMavMavMavMavMavMbdAavMaafaafaafaaabdDbgybdDbgzbeZbgAbgBbcraVbbgCbgDbgEbgFbgGbgGbgGbgGbgGbgGbgHbgIbgJbfdbgKbgLaYpaYpaYpaYpaYpaYpbgMaYpaYpaYpbgNbgObgPbgQbgRbaHbaHbeabgSbecbedaHYbgTaYxbgUaYAaYAaYAaYAbfAbaSbgVaYxaafbfCbfDbgWbgXbgYbfDbgZaafaYHbhabbYbhbbhcbajbesbajbajaYHaXqaHYaHYbeubqqbhebhfbhgbhhbhibfXbhjbfXbhkbfXbfXbhlbfYbhmbhnbhobezbhqbgdbkibgdbhqbhrbgdbeAbhsbhsbhubhvbeGbhwbeIbhxbhybhzbhAbhAbeKbhBbhCbhDbhEbhFbhGbhHbeKbhIbhJbhKbeRbhLbhMbhLbhNbhObhObeRbhPbgxaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaacuzaaaaaaaafaafaaaaaaaaaaaaaaaaafaafaaabdDbhQbhRbhSbhTbhTbhUbhVaWPbhWaOcbhXbhYbhZbhZbhZbiabiabiabiabiabiabiabibbgNbicbidbiebifbigbihbiibijaYpbikbilbimbinbinbiobaHbaHbeabaHaYvbedaHYaWUbipbiqbirbisbitaYAbiubaSaYxaYxaafbfCbfDbgXbfDbgXbfDbgZaafaYHaYHbivbcZbiwbajbixbiybizaYHaXqaHYbiAbiBbiCbiDbqrbiFbrWbiHbfXbiIbiJbiKbiLbiLbiMbfYbiNbhnbiObezbhqbgdbkibiPbhqbiQbiRbeAbiSbiTbiUbiVbeGbgibeIbiWbiXbiXbiYbiZbjabjbbjcbjcbjcbjdbjebjfbeKbjgbhJbjhbeRbjibjjbjkbjlbjmbjnbeRbhPbgxbjobjobjobjoaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaafaafaaabdDbjpbdDbjqbjrbjrbjsbdDbjtbjtaOcbjubjvbjubjubjubjvbjuaOcaOcaYpaYpaYpbjwbgNbjxbjxbjybjxbjxbjxbiibjxbjzbjAbjBbjCbjDbjEbjEbjEbjEbjFbjGbjHbjIbjJbjKbjLbjMbjNbjObjPaYAbfAbaSaYxaafaafbfCbfDbgYbjQbgWbjRbgZaafaafaYHbjSbjTaYHaYHaYHaYHbjUaYHbjVaHYaHYbeubjWbhebjXbhgbhhbjYbfXbjZbkabkbbkcbtmbkebezbkfbkgbkhbezbhqbgdbnZbkjbhqbkkbgdbeAbeGbeGbeGbeGbeGbgibeIbklbkmbknbkobkpbkqbkrbksbktbktbkubkvbkwbeKbkxbhJbkybeRbkzbkAbkBbkCbkDbkEbeRbhPbkFbkGbkHbkIbkHaaaaaaaafaaaaafaaaaafaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaafaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaabdDbkJbhRbkKbjrbkLbkMbdDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkNbkObkPbkQbkRbkSbkSbkTcuTbkSbkSbkUbkSbkVbkWbkXbkYbkZbecbecbecblaaYvblbaYvblcbldaKAbipbleblfblfblfblfblgblhbliaafaaabljblkbllbfDbfDblmbgZaaaaafblnbloblpblqblrblsblnbltblnbluaHYaHYbeublvbhectCblwblxbeublybjZbkablzblAbfXblBbezblCblDblEbezblFblGblHblIblJblKblLblMblNblOblNblNblNblPbeIblQbhyblRblSblTbkqblUblVblWblWblXblYblZbeKbmabgrbmbbeRbmcbmdbmebkCbhObmfbeRbhPbmgbmhbmibmibmibmibmibmibmjaafaaaaafaaaaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaabdDbmkbhRbhRbhRbdDbdDbdDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabkNbmlbjxbmmbmnbmobmnbmncuUbmnbmnbmpbmnbmqbmrbmsbmtbmubmvbecbmwbaHbmxbmybmzbedbmAbmBbipbipblibmCbmDbmEbmFbmGbliaaaaaabfCbmHbmIbmJbmIbmKbgZaaaaaablnbmLbmMbmNblnbmOblnbltblnbluaHYaHYbeubmPbhebjXbmQbmRbeubmSbmTbmUbmVbmWbfXbmXbezbfYbmYbmZbezbeAbnabeAbeBbnbbncbncbncbncbncbncbncbncbgibeIbndbkmbknbnebnfbngbnhbnibnibniblXbkvbnjbnkbnlbnmbnnbnobnpbnqbnpbnrbhObnsbeRbntbnubnubnubnubnubnubnubnvbgxbjobjobjoaaaaaaaafaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabnwbkNbkNbnxbjxbjxbjxbnybnzbnzcuVbjxbjxbjxbjxbjzbnAbeabnBbnCbnDbnEbnFbnGbnHbaHbmzbnIbnJbnKbnLbnMbnNbnObnPbnQbnRbnSbliaafaaabfCbnTbnUbnUbnUbnVbgZaaaaafblnbnWbnXbnYblnbnZblnbltblnboaaHYaKJbobbocbodboebofbogbeubohbjZbhkbmVboibojbmSbmSbokbolbombonboobopbfXboqborbosbvtboubovbowboxboybncbgibeIbozboAboBboCboDbeKboEbnibniboFboGbkvboHboIboJboKboLbnoboMboNbhOboOboPboQbeRboRbrVbrVbrVbrVbrVbrVbrVbhPbgxboTboUbjobjoaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabnwbkNbkNbnxbjxbjxbjxbnybnzbnzcuVbjxbjxbjxbjxbjzbnAbeabnBbnCbnDbnEbnFbnGbnHbaHbmzbnIbnJbnKbnLbnMbnNbnObnPbnQbnRbnSbliaafaaabfCbnTbnUbnUbnUbnVbgZaaaaafblnbnWbnXbnYblnbRIblnbltblnboaaHYaKJbobbocbodboebofbogbeubohbjZbhkbmVboibojbmSbmSbokbolbombonboobopbfXboqborbosbvtboubovbowboxboybncbgibeIbozboAboBboCboDbeKboEbnibniboFboGbkvboHboIboJboKboLbnoboMboNbhOboOboPboQbeRboRbrVbrVbrVbrVbrVbrVbrVbhPbgxboTboUbjobjoaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaboVboWboVboXboYbjxbjxbiibjxbjxcuWbjxbjxboZaYpaYpbpabpbbjEbpcbpdbecbpebaHbpfbaHbpgblubmAbphbpibpjbpkbplbpmbpnbpobppbliaaaaaabfCbpqbprbpsbprbptbgZaaaaaabpubpvbpwbpubpubpubpubpxbpubpyaKAaKAbeubeubpzbpAbpBbpCbeubpDbjZbpEbpFbpFbpFbpFbpFbpGbpHbpIbpJbpFbpKbpFbpLbpMbosbpNbpObpPbpQbpRbpSbncbpTbpUbpVbpWbpWbpXbpYbpZbqabqbbqbbqcbqdbkvbqebqfbqgbqhbqibnobnobqjbqkbqlbqmbnobeRbrVbrVbrXbenbrZbfUbsabrVbqsbqtbqubqvbqwbjoaaaaafaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabqxbqybqxbqzbjxbjxbjxbnybnzbnzcuVbjxbjxbqAbqBaYpbqCbaHbaHbqDbqEbqFbqGbaHbaHbaHbpgblubqHaHYbpibpjbqIbqJbqKbqLbqMbqNbliaafaafbqObqPbqQbqRbqSbqTbqUaafaafbqVbqWbqXbqYbqZbrabrbbrcbpubrdaHYaHYbmVbrebrfbrgbrhbribrjbrkbrlbrmbrnbrnbrnbrnbrnbrobrpbrqbrrbrsbrtbrubrvbrwbosbrxbrybrzbrAbrBboybncbgibeIbrCbrDbrEbrFbrFbeKbrGbrHbrIbnkbrJbkvbrKbnkbrLbrMbrNbrObrPbrQbrRbrSbrTbrUbhtbthbtgbtjbtibtibtibtlbtkbqnbgxbsdbsebsebjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabnwbkNbkNbsfbjxbjxbjxbiibjxbjxcuWbjxbjxbqAbsgaYpbshbsibjEbsjbskbslbeabaHbaHaZhbmzbsnbqHaHYbpibpjblibsobspbsqbsrbssbliaaaaaaaafbfCbstbsubstbgZaafaaaaaabqVbsvbswbsxbsybszbszbsAbsBbsCaHYaHYbmVbsDbfXbsEbsFbsGbsHbsGbsIbsJbsKbsLbsKbsKbsKbsMbsNbfXbhkbsObsPbsPbsQbsRbosbosbsSbsTbsUbpRboybncbeHbeIbsVbsVbsVbsVbsVbeKbnkbnkbnkbnkbsWbsXbsYbnkbsZbtabtbbtcbtcbtcbtcbtdbtebtfbrYbuAbuzbuCbuBbuBbuDbwabrVbsbbgxbsdbsebseabtaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtobqxbqybqxbmlbtpbjxbjxbtqbjxbtpcuWbjxbjxbqAbtraYpbtsbttbnGbtubtvbecbpbbjEbtwbtxbmzbsnbqHaWUbpibtyblibtzbtAbtBbtCbmGbliaaaaaaaafbtDbtEbnUbtFbtGaafaaaaaabqVbtHbtIbtJbtKbtLbtMbtNbpubtOaHYaHYbmSbmSbtPbtQbpGbtRbtSbtTbtUbtVbtWbtXbtWbtXbtWbtXbtWbtXbtYbtZbsPbuabubbucbudbuebufbugbuhbuibujbncbukbulbumbnmbunbhJbhJbuobhJbhJbupbuqburbusbutbtcbuubuvbuwbuxbuxbuxbuybuybuybuybuybwcbwbbwebwdbwebwfbwebrVbsbbgxbwgbqvbwhbjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabuFbuGbuFbuHbuIbuHbuHbuHbuHbuHcuXbuKbjxbqAbuLaYpbuMbaHbuNbuObuPbuQbuRbuRbuRbuQbuQbuSbqHaJkbuTbpjblibuUbuVbuWbuXbuYbliaaaaaaaafbuZbvabqRbvbbvcaafaaaaaabqVbvdbvebvfbvgbtLbtMbtNbpubvhaHYaHYbvibvjbvkbvlbvmbvnbtXbvobvpbvqbvrbvsbDibvubvvbvubFzbtXbhkbjZbsPbvxbvybvzbvAbvBbvCbvDbvEbvEbvFbvGbvHbvIbvJbvKbvLbvMbvNbvMbvMbvObvMbvMbvPbvQbvRbvRbvSbvTbqibuxbvUbvVbvWbvXbvYbambuybxjbxibzCbyAbzDbxibAVbrVbsbbgxcjgbsebsebjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabnwbkNbkNbkNaYpbkNbkNbkNbwibwicuYbwibwjbwkbwkbwibwibwlbwlbwmbwnbuQbwobwpbwqbwrbuQbsnbqHaHZaIcaIcbliblibwsbliblibwtbliaHUaHUaHUbwubwvbsubwwbwxaHUaHUaHUbpubpubpubpubpubpubpubpubpubvhaHYbwybtXbtXbtXbwzbtXbtXbtXbwAbvpbwBbwCbwDbwEbwFbwGbwHbwIbwDbhkbjZbsPbwJbwKbwLbwMbwNbwObrAbrAbrAbwPbwQbwRbwSbwTbwTbwTbwTbwUbwTbwTbwTbwVbwVbwWbwXbwYbwYbwZbxabqibuxbxbbxcbxdbxebxfbxgbxhbrVbrVbFBbFBbFBbrVcfYbrVbsbbgxbwgbqvcvhbjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabnwbkNbkNbkNaYpbkNbkNbkNbwibwicuYbwibwjbwkbwkbwibwibwlbwlbwmbwnbuQbwobwpbwqbwrbuQbsnbqHaHZaIcaIcbliblibwsbliblibwtbliaHUaHUaHUbwubwvbsubwwbwxaHUaHUaHUbpubpubpubpubpubpubpubpubpubvhaHYbwybtXbtXbtXbwzbtXbtXbtXbwAbvpbwBbwCbwDbwEbwFbwGbwHbwIbwDbhkbjZbsPbwJbwKbwLbwMbwNbwObrAbrAbrAbwPbwQbwRbwSbwTbwTbwTbwTbwUbwTbwTbwTbwVbwVbwWbwXbwYbwYbwZbxabqibuxbxbbxcbxdbxeahQbxgbxhbrVbrVbFBbFBbFBbrVcfYbrVbsbbgxbwgbqvcvhbjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwicuZbxlbxmbxnbxobxpbwkbxqbxrbxsbxtbxubxvbxwbxxbxybuQbsnbqHaHYaHYaHYbxzaKQbxAaKAbxBbxCbxDaVLaVLaVLbxEbxFbxGbxHbxIaHYaHYaHYaHYaKQaHYaKAaHYaHYaHYbxzaHYbvhaHYbxJbtXbxKbxLbxMbxNbxObtXbxPbxQbxRbxSbwDbwEbwEbxTbxUbxVbwDbhkbxWbsPbrAbxXbxYbxZbwQbyabybbycbydbncbncbeHbyebwTbyfbygbyhbyibyjbykbwTbylbymbynbyobypbwYbyqbyrbysbytbyubyvbywbyxbyybyzbxhchfchfchfchfchfchfchfbrVbsbbgxbsdbsebseabtaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwkbyBbyCbyDbyEbyFbyGbyHbyIbyJbyKbyLbyMbyNbyObxxbyPbuQbsnbyQaHYaHYaHYaHYaHYaHYaKAaHYbqHaHYaHYaHYaHYaHYbyRbySbyTaHYaHYaHYaHYaHYaHYaHYaKAbyUaHYaHYaHYaHYbvhbyVbyWbtSbyXbyYbyZbyYbzabtXbzbbvpbvqbzcbtXbzdbzebzfbzgbzhbtXbhkbjZbsPbsPbsPbsPbsPbncbncbncbncbncbncbzibgibzjbwTbzkbzlbzmbznbzobzpbwTbzqbzrbzsbztbzubwYbyqbzvbzwbzxbzybzzbzzbzzbzAbzBbxhchfchfctEctDchfchfchfbrVbsbbgxbsdbsebsebjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwibzEbzFbzGbzHbzIcvbcvacvccvcbAZbzLbuRbzMbzNbzObzPbuQbzQbzRbzSbzSbzSbzTbzSbzSbzUbzSbzVaHYbzWbzXbzYbzYcuBbAabAbbAcbAdbAeaVLaVLbAfaVLbAgbAhaVLbAibAjbAkbAlaHYaHYbtXbAmbAnbAobtWbApbtXbtWbAqbArbtXbtXbtXbtXbtXbtXbtXbtXbhkbjZbfXbAsbAtbAubAvbAwbAxbAybAzbAAbAwbzibgibABbwTbACbADbAEbAFbAGbAHbwTbAIbAJbAKbALbAMbwYbyqbANbAObuybAPbAQbARbASbATbAUbxhchfchfchfbscchfchfchfbrVbsbbqtbAWbqvbqwbjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwibzEbzFbzGbzHbzIcvbcvacvccvcbAZbzLbuRbzMbzNbzObzPbuQbzQbzRbzSbzSbzSbzTbzSbzSbzUbzSbzVaHYbzWbzXbzYbzYcuBbAabAbbAcbAdbAeaVLaVLbAfaVLbAgbAhaVLbAibAjbAkbAlaHYaHYbtXbAmbAnbAobtWbApbtXbtWbAqbArbtXbtXbtXbtXbtXbtXbtXbtXbhkbjZbfXbAsbAtbAubAvbAwbAxbAybAzbAAbAwbzibgibABbwTbACbADbAEbAFbAGbAHbwTbAIbAJbAKbALbAMbwYbyqbANbAObuybAPbxfbARbASbATbAUbxhchfchfchfbscchfchfchfbrVbsbbqtbAWbqvbqwbjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabwibwibwkbwkbwkbwkbwibwibAXbAYbAZbBabuQbuQbuQbuQbuQbuQbBbbBcaIcaIcaIcaIcbBdbBdbBdbBdbBdbBdbBdbBdbBdbBdbBebBfbBgbBhbBhbBhbBhbBhbBibBhbBhbBjbBhbyebBkbyeaIdaJlbBlbtXbBmbBnbBobBpbBqbtXbBrbxQbBsbBtbBubBvbBwbBxbBybBzbBAbBBbBCbBDbBDbBEbBFbBGbBHbBIbBJbBKbBLbAwbzibgibBMbBMbBMbBMbBMbBMbBMbBMbBMbBNbBNbBNbBNbBNbBNbBObBPbBQbuybuybuybuybuybuybuybxhbrVbrVbrVbrVbrVbrVbrVbrVbsbbgxbBRbBSbjobjoaafaafaafaagaagaagaagaagaagaagaagaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBTaaaaaaaaaaafaaaaaabwlbBUbBVbBWbBXbBYbBZbCabCbbCcbCdbCebCfaaaaaaaafaaabBdbCgbChbCibCjbCkbClbCmbCnbCobCpbCqbCrbBhbCsbCtcuDbCubCwbCvbCvbCxbCybCzbCAbyebyebyebyebtXbCBbCCbCDbCCbCEbtXbCFbvpbCGbCHbCIbCJbCIbCIbCKbCLbCMbCNbCObCObCObCPbCQbvlbCRbCSbCTbCUbCVbAwbzibgibBMbCWbCWbCWbCXbCWbCWbCWbBMbCYbCYbCZbCYbCYbBNbDabDbbqibDcbDdbDebDfbDgbDhbJqbDjbDkbDlbDmbDnbDobsmbtnbtnbvwbDsbDdbDdbjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaelctjaekctjaejaaaaafaaabwlbwlbDtbxrbDubDvbDwbDxbDybDybDzbDAbDBbDCaafbDDbDEbDFbDGbDHbDIbDJbDIbDKbDIbDIbDIbBdbDLbDMbDNbBhbDObDPbDQbDRbDSbCvbDTbBjbBhbDUbDVbDWbDXbDYbDZbEabEbbCCbEcbCCbxQbEdbEebEfbEgbtXbEhbEibCCbCCbEjbEkbmSbmSbmSbmSbmSbElbEmbpGbEnbEobEpbBKbEqbAwbzibgibBMbCWbCWbCWbCWbCWbCWbCWbBMbErbEsbEtbEubEvbBNbEwbExbEybEzbEAbEBbECbEDbEDbEDbEDbEEbEFbEGbDnbjobvZbEIbEJbEJbEKbELbEMaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbENbEObENaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafNcuCctMcuCafNbERbERbERbwlbESbxrbETbEUbEVbEWbwlbBcbEXbBcbBcbEYbEZaaabFabFbbFcbFdbDIbDIbFebDIbFfbFgbFhbDIbBdbDLbFibFjbBhbFkbFlbFmbFnbFobCvbFpbBjbzibFqbFrbFsbFrbFtbFubtXbFvbCIbFwbCIbFxbtSbFybCJbFAbtXbFCbCCbCCbCCbCCbGNbmSbPIbFEbFFbFGbBEbFHbvlbFIbBKbBKbFJbFKbFLbFMbFNbBMbCWbCWbCWbCWbCWbCWbCWbBMbFObFPbFQbFRbFSbFTbFUbFVbtbbFWbFXbEDbFYbEDbEDbEDbEDbEDbEDbEDbDnbFZbDpbGbbGcbGdbGebGfbEMaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbEObENbGgbENbEOaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaekajxctyajxaekbERbGhbGibwlbGjbxrbGkbxrbxrbEWbwlbGlbGmbGnbBcbEYbEZaafbFabGobGpbGqbGrbGsbGrbGrbGtbGubGrbGrbGvbGwbGxbGybBhbGzbBhbBhbBhbBhbGAbGBbGCbGDbGEbGFbGGbGHbGIbGIbtXbGJbGKcltbGMbGQbtXbGObGPbGSbtXbGRbDqbEHbDrbFDbGWbmSbGXbGYbpFbGZbHabHbbHcbCRbHdbBKbBKbHebAwbzibgibBMbBMbHfbCWbCWbHgbHfbBMbBMbHhbHibHjbHkbHlbBNbHmbHnbtbbHobHpbHqbHqbHrbHsbHtbHqbHubHvbHwbHxbHybGabHAbHBbHCbHDbHEbEMaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbHFbEObHGbHHbHIbEObHFaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaekajxctyajxaekbERbGhbGibwlbGjbxrbGkbxrbxrbEWbwlbGlbGmbGnbBcbEYbEZaafbFabGobGpbGqbGrbGsbGrbGrbGtbGubGrbGrbGvbGwbGxbGybBhbGzbBhbBhbBhbBhbGAbGBbGCbGDbGEbGFbGGbGHbGIbGIbtXbGJbGKcltbGMbGQbtXbGObGPbGSbtXbGRbDqbEHbDrbFDbGWbmSbGXbGYbpFbGZbHabHbbHcbCRbHdbAQbBKbHebAwbzibgibBMbBMbHfbCWbCWbHgbHfbBMbBMbHhbHibHjbHkbHlbBNbHmbHnbtbbHobHpbHqbHqbHrbHsbHtbHqbHubHvbHwbHxbHybGabHAbHBbHCbHDbHEbEMaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbHFbEObHGbHHbHIbEObHFaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafNajxajxajxctLbHKbxrbxrbHLbGjbxrbxrbxrbxrbEWbwlbHMbGnbHNbBcbEYbEZaaabFabHObHPbHQbDIbDIbHRbDIbHSbHTbHUbHVbBdbHWbHXbHYbHZbIabIbbIbbIbbIbbIbbIcbIbbIdbIebIfbIgbIhbIibIjbtSbtSbtSbtSbtSbtSbtSbtSbtSbtSbMNbMNbMNbMNbMNbMNbOnbOCbmSbmSbmSbmSbIlbImbhjbAwbAwbAwbAwbAwbAwbzibgibBMbInbIobIpbIqbIrbIsbInbItbHhbHibHjbIubIvbIwbIxbIybuwbIzbDdbIAbIAbIBbICbIDbIEbEDbEDbIFbDnbIGbGLbIIbDdbIJbIKbIKbDdaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbEObEObILbIMbIMbIMbINbEObEOaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaekctyctyctyaekbERbIObIPbIQbIRbxrbxrbISbITbIUbwlbBcbBcbBcbBcbEYbDCaafbIVbDEbIWbDGbIXbDIbIYbDIbDIbDIbDIbDIbBdbDLbIZbJabJbbJcbJcbJcbJcbJcbJcbJdbJebJfbJgbJhbJibJjbJkbJlbJmbJnbJmbJmbJmbJmbJmbJmbJmbJmbJmbJmbJmbJmbJmbJobJpbmSbGXcqlbBDbJrbBEbJsbJtbJubJvbJvbJwbJxbJgbJybJzbBMbJAbJBbJCbJDbJEbJFbJGbItbItbItbItbItbItbJHbJIbJJbJKbJLbDdbDnbDnbDnbDnbDnbDnbJMbEDbEDbDnbjobvZbgxbDdbJNbJObJPbJQaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabJRbJSbJRbIMbJTbIMctxctlbENaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafNajZctzctAafNbERbERbERbwlbwlbERbERbERbwlbwlbwlaaaaaaaaabJYbJZbEZaaaaaaaafaaabBdbKabKbbKcbDIbKdbKebKfbKgbKhbKibKjbKkbKlbKmbKnbKobKpbKqbKmbKmbKmbKmbKmbKrbKsbKmbKmbKtbKmbKubKmbKmbKmbKmbKmbyebyebyebyebyebyebyebyebKvbKwbmSbKxbKybKzbKAbKBbKCbKDbKEbKFbKFbKGbKFbKFbKHbKIbBMbKJbKKbKLbKKbKMbKKbKNbKObKPbKQbKRbKSbKTbKUbyqbHnbqibKVaafbKWbKXbKYbKZbLabKZbLbbLcbLdbDnbLebsbbLfbDdbDdbDdbDdbDdaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbEObEObLgbIMbIMbIMbLhbEObEOaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -6662,18 +6665,18 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafbBcbBcbJYbJYbJYbBcbBcaaaaaaaaaaaabJYbEYbEZaaaaaaaaaaafbMkbNnbMmbMmbMmbMmbMobYnbNpbNqbNrbKjbNsbNtbNubNvbNwbNxbNybNzbNAbNwbNwbNwbNybNBbNCbNDbNEbNFbLBbNGbNHbNIbNJbNKbLDbNLbNMbNNbNObMKbMLbNPbKvbLFbNQbMUbMUcrqbLGbNRbNSbNTbLGbMVbNUbMVbNVbNWbNXbNYbBMbNZbOabObbOcbOdbOebOfbOgbOhbOibOjbOkbOlbItbOmbZlbOobOpbOpbDnbDnbDnbDnbDnbDnbDdbDdbDdbDnbsebsbbOqbsebsebOrbjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbENbEObENaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabBcbOsbGnbOtbGnbOubBcaaaaaaaaaaaabJYbJZbEZaaaaafbJYbJYbMkbMmbMmbOwbOvbMmbOxbMobMobOzbDLbMqbOAbOBbZmbODbOEbOFbOGbOHbOIbOFbOJbOFbOKbOLbOMbLubONbOObOPbOQbORbOSbOTbOUaafbOVbOWbNObOXbMKbMLbNPbKvbLFbOYbOZbMUbPabLGcuRbPcbPdbLGbMUbPebPfbMUbMUbLFbKvbBMbItbItbItbItbJHbPgbPhbPibJHbItbItbItbItbItbPjbPkbPlbPmbPnbPobPpbPqbPpbPrbOpbPsbPtbPubPvbPwbsbbkFbjobjobjobjoabtaafaafaafaagaagaagaagaagaagaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbBcbPxbGnbGnbGnbPybBcaaaaaaaaaaaabJYbEYbEZaaaaafbJYbPzbPAbPBbMmbMmcbdbPDbPDbPDbPEbPFcbebMqbOAbPHccdbPJbPKbMFbPLbPMbPNbPObPPbPQbPRbPSbPSbPTbPUbLBbPVbPWbPXbPYbPZbQabQbbNLbQcbNObNObMKbMLbNPbKvbLFbQdbMUbQebLHbLGbLGbQfbLGbLGbQgbQhbQibQgbQgbLFbKvbBMbQjbQkbQkbQlbQmbKKbQnbQobQpbQqbCWbCWbCWbItbQrbQsbQtbQubQvbPobQwbQxbQybQzbOmbPtbQAbPtbPvbBRbGTbGUbjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagaaaaaaaaaaaaaaaaaaaaabBcbPxbGnbGnbQDbQEbBcaaaaafaaaaaabJYbEYbDCbBcbBcbBcbQFbMkbQGbMmbMmcqmbQHbQIbQJbQKbMkcqnbMqbOAbPHcqobQLbQMbMFbMFbQNbLnbQObQPbQQbQRbMFbMFbLubQSbQTbQUbQVbQWbQXbQWbQYaafbMKbMKbMKbMKbMKbMLbyebKvbLFbQZbRabRabRbbRcbRdbRebRfbRgbMUbPebMUbMUcqpbLFbKvbBMbCWbCWbCWbRhbRibKKbRjbKKbRkbRlbCWbCWbCWbItbRmbRnbRobRpbRqbRrbRsbRtbRrbRubOpbRvbPtbRwbPvbOpbSsbGVbjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaagaagaagaagaagaagaagaagaagaagaagaagaagaagaaaaaaaaaaaaaaaaaaaaabBcbPxbGnbGnbQDbQEbBcaaaaafaaaaaabJYbEYbDCbBcbBcbBcbQFbMkbQGbMmbMmcqmbQHbQIbQJbQKbMkcqnbMqbOAbPHcqobQLbQMbMFbMFbQNbLnbQObQPbQQbQRbMFbMFbLubQSbQTbQUbQVbQWbQXbQWbQYaafbMKbMKbMKbMKbMKbMLbyebKvbLFbQZbRabRabRbbRcbRdbRebRfbRgbMUbPebMUbMUcqpbLFbKvbBMbCWbUobCWbRhbRibKKbRjbKKbRkbRlbCWbUobCWbItbRmbRnbRobRpbRqbRrbRsbRtbRrbRubOpbRvbPtbRwbPvbOpbSsbGVbjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaagaafaafbRzaafaafaafbBcbBcbBcbBcbBcbBcbBcbBcbBcbBcbRAbBcbBcbBcbJYbJYbJYbRBbRCbRDbREbRFbRGbRCbRHbPFbPFbPFbPFcqrbMkbMkbMkbMkbMkcqtbRKbOAbRLbKmbRMbRNbPNbRObPNbLnbMFbMFbMFbQRbRPbRQbRQbRRbRSbRTbNGbRUbRVbRWbNKbLDbNLbRXbRYbRYbMKbMLbyebKvbRZbSabSabSabSbbScbMUbSdbMUbMUbMUbPebMUbMUbMUbLFbKvbBMbCWbCWbCWbSebSfbQobSgbKKbShbSibQkbQkbSjbItbSkbSlbPlbSmbSnbPobQybSobRrbSpbOpbSqbSqbSqbPvbSrbSsbGVbjoaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabStbSubSubSubSubSvbSwbSwbSxbSybSzbSAbSBbSCbSDbSEbBcbGnbGnbGnbGnbGnbGnbGnbSFbSGbSHbSIbSJbSKbSKbSKbSKbSLbSMbSMbSMbSNcqubSObDybDybSPbBccqnbMqbOAbSQbSRbSSbSTbRQbRQbSUbSVbRQbRQbSWbSXbSYbMFbSZbTabTbbTcbMFbTdbTebTfbOUaafbOVbTgbThbTibMKbMLbNPbTjbTkbTkbTkbTlbLFbTmbQZbTnbTobTpbTqbTrbTsbTsbTtbLFbKvbBMbItbItbItbItbTubTvbRjbTwbTubItbItbItbItbItbTxbTybTzbTAbTBbTCbTCbTCbTCbTDbOmbSqbSqbTEbPvbTFbSsbGVbjobjobjoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaagaaaaafaaaaaabJYbJYbJYbGnbTHbTIbTJbTKbTLbBcbTMbJYbJYbJYbJYbJYbJYbJYbJYbDCbTNbTObTObTObTObTObTObTObTObTPbTPcqxbTPbTPbTQbTRbBccqnbMqbOAbSQbTSbTTbTUbTVbPSbTWbTXbPSbPSbTYbTZbUabUbbUcbUdbUebUfbMFbTdbUgbUhbQabQbbNLbUibRYbRYbMKbMLbNPbUjbyebyebyebNYbLFbUkbMUbMUbUlbUmbUnbUobUpbUobUnbLFbKvbBMbQjbQkbQkbUqbQmbKKbQnbQobUrbUsbCWbCWbCWbItbUtbUubUvbUwbRnbRpbUxbUybUzbUAbOpbSqbSqbSqbPvbTFbSsbGVbsebsebjoaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaagaagaagaagaagbUDbGnbUDbGnbUEbTIbTIbUFbGnbBcbGnbJYaaaaaaaafaaaaaaaafaaabDCbTNbTObUGbUHbUIbUJbUKbULbUGbUMbUNcqCcqybTPbTPbTRbBccqDbMqbOAbURbUSbUTbUTbUUbKmbKmbKmbKmbKmbUVbUWbLnbLnbLnbUXbMFbTbbMFbTdbTebUYbOUaafbMKbMKbMKbMKbMKbMLbNPbUjbyebUZbzibNYbMMbVabVbbVcbVdbVebVfbVgbUpbVgbVhbLFbKvbBMbCWbVibCWbVjbRibKKbRjbKKbRkbVkbCWbVibCWbItbVlbVmbVnbVobVpbVqbVrbVsbVtbVubOmbVvbVwbVxbPvbSqbSsbHzbjobsebjobjobjoaagaagaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaagaaaaafaaaaaabJYbJYbJYbGnbTHbTIbTJbTKbTLbBcbTMbJYbJYbJYbJYbJYbJYbJYbJYbDCbTNbTObTObTObTObTObTObTObTObTPbTPcqxbTPbTPbTQbTRbBccqnbMqbOAbSQbTSbTTbTUbTVbPSbTWbTXbPSbPSbTYbTZbUabUbbUcbUdbUebUfbMFbTdbUgbUhbQabQbbNLbUibRYbRYbMKbMLbNPbUjbyebyebyebNYbLFbUkbMUbMUbUlbUmbUnbVibUpbVibUnbLFbKvbBMbQjbQkbQkbUqbQmbKKbQnbQobUrbUsbCWbCWbCWbItbUtbUubUvbUwbRnbRpbUxbUybUzbUAbOpbSqbSqbSqbPvbTFbSsbGVbsebsebjoaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaagaagaagaagaagbUDbGnbUDbGnbUEbTIbTIbUFbGnbBcbGnbJYaaaaaaaafaaaaaaaafaaabDCbTNbTObUGbUHbUIbUJbUKbULbUGbUMbUNcqCcqybTPbTPbTRbBccqDbMqbOAbURbUSbUTbUTbUUbKmbKmbKmbKmbKmbUVbUWbLnbLnbLnbUXbMFbTbbMFbTdbTebUYbOUaafbMKbMKbMKbMKbMKbMLbNPbUjbyebUZbzibNYbMMbVabVbbVcbVdbVebVfbVgbUpbVgbVhbLFbKvbBMbCWcqUbCWbVjbRibKKbRjbKKbRkbVkbCWcqUbCWbItbVlbVmbVnbVobVpbVqbVrbVsbVtbVubOmbVvbVwbVxbPvbSqbSsbHzbjobsebjobjobjoaagaagaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbJYbJYbJYbVzbVAbVBbVCbVDbGnbVEbGnbJYaaaaaaaafaaaaaaaafaaabDCbTNbTObUGbVFbVGbVHbVIbVJbUGbVKbVLcqEbVNbVObTPbTRbBccqnbMqbOAbVPbVQbKmbVRbVSbKmbVTbVUbVVbKmbVWbQRbVXbLnbVYbUfbMFbUdbVZbWabRVbWbbNKbLDbNLbWcbWdbWebMKbMLbyebUjbyebABbzibNYbLFbWfbWgbWhbWibUmbWgbWjbUpbWjbNVbNXbKvbBMbCWbCWbCWbWkbWlbQobSgbKKbShbWmbQkbQkbSjbBMbPvbWnbWobWobPvbPvbWpbWqbWrbWsbWtbWubTCbWvbSqbSqbSsbGVbjobWwbjobWxbjoaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafbJYbWybWzbWzbWAbTLbWBbBcbJYbJYaaaaaaaaaaaaaaaaaaaaabDCbTNbTObWCbWDbWEbVHbWFbWCbWCbVKbWGcqGcqFbWIbTPbTRbBccqnbMqbWJbWKbWKbWLbWMbWNbWObWPbWQbWRbKmbMFbQRbWSbWTbVYbWUbMFbUdbVZbTdbTebWVbOUaafbOVbWWbWXbWYbMKbMLbyebUjbyebGHbGHbNYbLFbLGbWZbXabLGbXbbLGbLGbLGbLGbLGbLFbKvbBMbItbItbItbItbTubXcbRjbXdbTubItbItbItbItbBMbRrbXebRrbRrbRrbPvbWpbWqbXfbXgbXhbXibUwbXjbPvbSqbSsbGVbjobsebsebsebXkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaFZaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafaafaafaafaafaafaafaafbBcbBcbBcbBcbBcbBcbVEbBcbBcbBcbBcaafaaaaaabXlaaaaaaaaaaaaaaabEZbTNbTObWCbWCbXmbXnbXobWCbXpbXqbXrcqIcqHbXsbTPbTRbBccqJbXwbCrbWKbXxbXybXybXzbXAbXBbXCbXDbKmbXEbXFbVXbLnbVYbXGbMFbXHbVZbTdbXIbXJbQabQbbNLbXKbWdbWdbMKbMLbNPbUjbyebXLbzibNYbXMbSabSabXNbLGbIHbIkbQBbyebXRbXSbKwbKvbBMbQjbQkbQkbXTbQmbKKbQnbQobXUbXVbCWbCWbCWbBMbXWbRrbRrbRrbRrbPvbXXbXXbXYbXZbOpbOpbUwbOpbPvbOpbSsbGVbjobYabYbbYcbXkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfabfabfabfabfabfabfabqabfabfabfabfabfaaaaaabBcbGnbGnbGnbGnbGnbGnbGnbGnbWBbJYaafaaaaaaaafaaIbYdaaaaaaaaabEZbTNbTObYebYfbYgbYhbYibYjbYkbYlbYmcqMcqKbYobTPbYpbYqbYrbYsbGybWKbYtbXybYubYvbYwbYxbYybYzbYAbNFbYBbLnbLnbLnbYCbMFbYDbYEbTdbTebMFbOUaafbMKbMKbMKbMKbMKbMLbNPbUjbyebYFbzibYGbYHbTkbYIbYJbyebRybQCbTGbyebYNbKFbYObYPbBMbCWbCWbCWbYQbRibKKbRjbKKbRkbYRbCWbCWbCWbBMbYSbRrbYTbRrbRrbYUbYVbYWbYXbYYbOpbUwbUwbYZbPvbBRbZabUBbjobZcbZdbsebXkaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfabfabfabfabfabfabfabqabfabfabfabfabfaaaaaabBcbGnbGnbGnbGnbGnbGnbGnbGnbWBbJYaafaaaaaaaafaaIbYdaaaaaaaaabEZbTNbTObYebYfbYgbYhbYibYjbYkbYlbYmcqMcqKbYobTPbYpbYqbYrbYsbGybWKbYtbXybYubYvbYwbYxbYybYzbYAbNFbYBbLnbLnbLnbYCbMFbYDbYEbTdbTebMFbOUaafbMKbMKbMKbMKbMKbMLbNPbUjbyebYFbzibYGbYHbTkbYIbYJbyebRybQCbTGbyebYNbKFbYObYPbBMbCWbUobCWbYQbRibKKbRjbKKbRkbYRbCWbUobCWbBMbYSbRrbYTbRrbRrbYUbYVbYWbYXbYYbOpbUwbUwbYZbPvbBRbZabUBbjobZcbZdbsebXkaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaaaafaaaaafaaaaafaaaacfaaaaafaaaaafaaaabfaafaafbBcbZebGnbBcbBcbBcbRAbBcbBcbBcbBcaaaaaaaaaaaIbZfbZgaaIaaIaafbEZbTNbTObZhbWCbUGbUGbUGbWCbZibZjbZkcqGcqNcqPbTPbBcbBcbZnbZobZpbWKbWKbZqbXybZrbZsbZtbZsbZubKmbMFbZvbZwbZxbZybONbZzbZAbZBbWabRVbZCbNKbLDbNLbZDbZEbZEbMKbMLbNPbUjbyebyebyebZFbZGbyebZHbZIbyebyebZJbyebyebZIbZKbZLbZMbBMbCWbCWbCWbZNbZObQobZPbKKbShbZQbQkbQkbSjbBMbRrbRrbZRbRrbRrbPvbXXbXXbZSbZTbOpbZUbZVbZWbPvboUbZabGVbjobjobjobsebjoaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaabZXbZYbZZaaabZXbZYbZZaaabZXbZYbZZaaaabfaaaaaabBccaacabbBccacbGnbGncadbOucaebBcaaaaaaaaacafaaIaaIaafaaaaaabEZbTNbTObWCcagcahbUGcaibWCbWCbVKcajcqGcqKcakbTPcalcamcancaocapcaqcarcascatcascatcaucatcavbKmcawcaxcaybPSbPSbPUbRPcazbRUbPVbTecaAbOUaafbOVcaBcaCcaDbMKbMLbyebUjbzicaEcaFbZFcaGbyebZHcaHcaIcaJcaKcaLcaIcaMbZHbgxcaNbBMbBMbBMbBMbBMbBMcaOcaPcaObBMbBMbBMbBMbBMbBMbPvbPvbPvbPvbPvbPvcaQcaQcaRcaSbPvbPvbPvbPvbPvbjobRxbGVbjocaTcaUbsebjoaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafbZXcaVbZZaaabZXcaVbZZaaabZXcaVbZZaafaafaaaaaabBcbJYbJYbBcbBccaWcaXbOubGnbQDbBcaaaaaaaaaaaaaafaaaaaaaaaaaabDCbTNbTObUGcaYcaZbUGcbacbbbUGbVKcbccqEcqQcqVcqUcqXcqWbOAaZDcbgcbhcbicbjcbkcblcbmcbnbXycbobKmcbpbMFbZvbRPbRQcbqcbrcbscbtbLAcbucbvbQabQbbNLcbwbZEbZEbMKbMLbyecbxcbycbzcbAcbBcbCbyecbDcbEcbFcbGcbHcbGcbIcbEcbJbgxcbKbjoaaaaaaaaaaafaaaaaacbLaaaaafaaaaaaaaaaaabjocbMbMfbkGcbNcbNbPvcbOcbOcaRbQtcbPcbQbsebsebsebBRbRxbHzbjocbRbsebsebjobjobjoaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaafbZXcaVbZZaaabZXcaVbZZaaabZXcaVbZZaafaafaaaaaabBcbJYbJYbBcbBccaWcaXbOubGnbQDbBcaaaaaaaaaaaaaafaaaaaaaaaaaabDCbTNbTObUGcaYcaZbUGcbacbbbUGbVKcbccqEcqQcqVcuPcqXcqWbOAaZDcbgcbhcbicbjcbkcblcbmcbnbXycbobKmcbpbMFbZvbRPbRQcbqcbrcbscbtbLAcbucbvbQabQbbNLcbwbZEbZEbMKbMLbyecbxcbycbzcbAcbBcbCbyecbDcbEcbFcbGcbHcbGcbIcbEcbJbgxcbKbjoaaaaaaaaaaafaaaaaacbLaaaaafaaaaaaaaaaaabjocbMbMfbkGcbNcbNbPvcbOcbOcaRbQtcbPcbQbsebsebsebBRbRxbHzbjocbRbsebsebjobjobjoaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfaaabZXcaVbZZaafbZXcaVbZZaafbZXcaVbZZaaaaafaafaafaafaafaafaafbBcbBcbBcbBcbRAbBcbBcaaaaaaaaaaaaaafaaaaaaaafaaabDCbTNbTObUGcbScbTcbUcbVcbWbUGcbXcbYcbZccaccbbTPccccqYcceccfccgcchcciccjcckcclccmccnccoccpccqccrbMFbZvcctbMFbMFbMFcctcctcctbTeaVSaVRaafbMKbMKbMKbMKbMKbMLbyebYFccuccvccwccxccybyebyecczccAccBbKwccCccDbyebyebgxcbKbjoaaaaaaaaaaafaaaaaacbLaaaaafaaaaaaaaaaaabjobseccEbqvccFccGbPvccHccHccIbQtbPvbOpbjoccJccKbBRbRxbGVbsebsebsebUCbkHbVybkHaagaagaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbZXcaVbZZaaabZXcaVbZZaaabZXcaVbZZaafaafaaaaaaaaaaaaaaaaaabBcccRbBcbGnbGnbBcaafaaaaafaaaaaaaafaaaaaaaafaaabDCbTNbTObTObTObTObTObTObTObTObTPbTPbTPbTPbTPbTPbBcccSbBcccTccUccUccUccVccWccXccUccYccZcdabKmbMFbOQccscctbMFbMFbMFbMHbSYcctbTecctbKmaafaafaafaafaafaafbMLcdjcdjcdjcdkcvdcdjcdjcdjcdmbyecdncdncdocdncdnbyebABbZGcbKbjobXkbXkbXkbjobXkbXkcdpbXkbjobXkbXkbXkbXkbjobjobRxcdqbjobjobPvbPvbPvcdrcdsbPvbBRbjobYcbseboTbRxbUBbjobjocdtbjobjobjobjoaagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabfabfabfaafaaabZXcaVbZZaaabZXcaVbZZaaabZXcaVbZZaaaaafaaaaaacducdvcdvcdvcdvbBcbBccdwbGnbBcbJYbJYbJYbJYbJYbJYbJYbJYbJYbBcbDCbTNbBccdxcdycdzcdzcdzcdzcdzcdzcdzcdzcdzcdAcdAcdzcdBcaWccTcdCcdDcdEcdFcdGcdHccUcdIcdJcdKbKmcdbcdcbPXcddcdecdfcdecddcdgcddcdhcctbKmbKmbKmaaaaaaaafaaacdVcdWcdXcdYcdZceacebceccdjcedceecefcegcehccBccBbzibzibZGbntceiceiceiceiceiceiceicejcekcekcekcekcekcekcelcekcemcekcekcenceocepceqbXOcesbjobjocetceoceuceocevbGVbjocewbsebsebjoaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/bot/NanoTrasenBot.py b/bot/NanoTrasenBot.py
index 40ea8325772..2e0678bbd96 100644
--- a/bot/NanoTrasenBot.py
+++ b/bot/NanoTrasenBot.py
@@ -1300,17 +1300,7 @@ while True:
print sender+" Has now joined"
users.append(sender)
#####
- if ".fi" in data[0] and sender.lower() == "skibiliano":
- operators.append(sender)
if sender.lower() not in peopleheknows[0]:
- if data[0].split("!")[1] in peopleheknows[1]:
- appendion = "...you do seem familiar however"
- else:
- appendion = ""
- if data[1][1].lower() == channel or data[1][1].lower() == channel[1:]:
- conn.privmsg(data[1][1],CORE_DATA.greeting.replace("USER",sender)+" "+appendion)
- else:
- conn.privmsg(data[1][1],"Hello! Haven't seen you here before! Happy to meet you! %s" %(appendion))
peopleheknows[0].append(sender.lower())
peopleheknows[1].append(data[0].split("!")[1])
with open("peopleheknows.cache","w") as peoplehecache:
diff --git a/code/ATMOSPHERICS/components/binary_devices/circulator.dm b/code/ATMOSPHERICS/components/binary_devices/circulator.dm
index 0d93a55d0ad..c7ab2358bfe 100644
--- a/code/ATMOSPHERICS/components/binary_devices/circulator.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/circulator.dm
@@ -5,7 +5,7 @@
/obj/machinery/atmospherics/binary/circulator
name = "circulator/heat exchanger"
desc = "A gas circulator pump and heat exchanger."
- icon = 'icons/obj/pipes.dmi'
+ icon = 'icons/obj/atmospherics/pipes/simple.dmi'
icon_state = "circ1-off"
var/side = 1 // 1=left 2=right
diff --git a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
index a3172a3b4af..3ac13f56b51 100644
--- a/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/passive_gate.dm
@@ -92,24 +92,18 @@ Passive gate is similar to the regular pump except:
return 1
-/obj/machinery/atmospherics/binary/passive_gate/ui_interact(mob/user, ui_key = "main")
+/obj/machinery/atmospherics/binary/passive_gate/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if(stat & (BROKEN|NOPOWER))
return
- var/data = list()
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "atmos_gas_pump.tmpl", name, 400, 120, 0)
+/obj/machinery/atmospherics/binary/passive_gate/get_ui_data()
+ var/data = list()
data["on"] = on
data["pressure_set"] = round(target_pressure*100) //Nano UI can't handle rounded non-integers, apparently.
data["max_pressure"] = MAX_OUTPUT_PRESSURE
-
- var/datum/nanoui/ui = SSnano.get_open_ui(user, src, ui_key)
- if (!ui)
- ui = new /datum/nanoui(user, src, ui_key, "atmos_gas_pump.tmpl", name, 400, 120)
- ui.set_initial_data(data)
- ui.open()
- ui.set_auto_update(1)
- else
- ui.push_data(data)
+ return data
/obj/machinery/atmospherics/binary/passive_gate/atmosinit()
..()
diff --git a/code/ATMOSPHERICS/components/binary_devices/pump.dm b/code/ATMOSPHERICS/components/binary_devices/pump.dm
index 85c5f1cf903..8f25e7d242b 100644
--- a/code/ATMOSPHERICS/components/binary_devices/pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/pump.dm
@@ -97,24 +97,18 @@ Thus, the two variables affect pump operation are set in New():
return 1
-/obj/machinery/atmospherics/binary/pump/ui_interact(mob/user, ui_key = "main")
+/obj/machinery/atmospherics/binary/pump/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if(stat & (BROKEN|NOPOWER))
return
- var/data = list()
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "atmos_gas_pump.tmpl", name, 400, 120, 0)
+/obj/machinery/atmospherics/binary/pump/get_ui_data()
+ var/data = list()
data["on"] = on
data["pressure_set"] = round(target_pressure*100) //Nano UI can't handle rounded non-integers, apparently.
data["max_pressure"] = MAX_OUTPUT_PRESSURE
-
- var/datum/nanoui/ui = SSnano.get_open_ui(user, src, ui_key)
- if (!ui)
- ui = new /datum/nanoui(user, src, ui_key, "atmos_gas_pump.tmpl", name, 400, 120)
- ui.set_initial_data(data)
- ui.open()
- ui.set_auto_update(1)
- else
- ui.push_data(data)
+ return data
/obj/machinery/atmospherics/binary/pump/atmosinit()
..()
diff --git a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
index be8fbdc6ab0..4b920407ce8 100644
--- a/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
+++ b/code/ATMOSPHERICS/components/binary_devices/volume_pump.dm
@@ -93,24 +93,18 @@ Thus, the two variables affect pump operation are set in New():
return 1
-/obj/machinery/atmospherics/binary/volume_pump/ui_interact(mob/user, ui_key = "main")
+/obj/machinery/atmospherics/binary/volume_pump/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if(stat & (BROKEN|NOPOWER))
return
- var/data = list()
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "atmos_gas_pump.tmpl", name, 400, 120, 0)
+/obj/machinery/atmospherics/binary/volume_pump/get_ui_data()
+ var/data = list()
data["on"] = on
data["transfer_rate"] = round(transfer_rate*100) //Nano UI can't handle rounded non-integers, apparently.
data["max_rate"] = MAX_TRANSFER_RATE
-
- var/datum/nanoui/ui = SSnano.get_open_ui(user, src, ui_key)
- if (!ui)
- ui = new /datum/nanoui(user, src, ui_key, "atmos_gas_pump.tmpl", name, 400, 120)
- ui.set_initial_data(data)
- ui.open()
- ui.set_auto_update(1)
- else
- ui.push_data(data)
+ return data
/obj/machinery/atmospherics/binary/volume_pump/atmosinit()
..()
diff --git a/code/ATMOSPHERICS/components/trinary_devices/filter.dm b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
index e988e113c08..cedd26af4b2 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/filter.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/filter.dm
@@ -152,25 +152,19 @@ Filter types:
ui_interact(user)
-/obj/machinery/atmospherics/trinary/filter/ui_interact(mob/user, ui_key = "main")
+/obj/machinery/atmospherics/trinary/filter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if(stat & (BROKEN|NOPOWER))
return
- var/data = list()
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "atmos_filter.tmpl", name, 400, 320, 0)
+/obj/machinery/atmospherics/trinary/filter/get_ui_data()
+ var/data = list()
data["on"] = on
data["pressure_set"] = round(target_pressure*100) //Nano UI can't handle rounded non-integers, apparently.
data["max_pressure"] = MAX_OUTPUT_PRESSURE
data["filter_type"] = filter_type
-
- var/datum/nanoui/ui = SSnano.get_open_ui(user, src, ui_key)
- if (!ui)
- ui = new /datum/nanoui(user, src, ui_key, "atmos_filter.tmpl", name, 400, 320)
- ui.set_initial_data(data)
- ui.open()
- ui.set_auto_update(1)
- else
- ui.push_data(data)
+ return data
/obj/machinery/atmospherics/trinary/filter/Topic(href, href_list)
if(..())
diff --git a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
index e80c0c7654b..53b1d1b27f9 100644
--- a/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
+++ b/code/ATMOSPHERICS/components/trinary_devices/mixer.dm
@@ -108,26 +108,20 @@
ui_interact(user)
-/obj/machinery/atmospherics/trinary/mixer/ui_interact(mob/user, ui_key = "main")
+/obj/machinery/atmospherics/trinary/mixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if(stat & (BROKEN|NOPOWER))
return
- var/data = list()
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "atmos_mixer.tmpl", name, 400, 320, 0)
+/obj/machinery/atmospherics/trinary/mixer/get_ui_data()
+ var/data = list()
data["on"] = on
data["pressure_set"] = round(target_pressure*100) //Nano UI can't handle rounded non-integers, apparently.
data["max_pressure"] = MAX_OUTPUT_PRESSURE
data["node1_concentration"] = round(node1_concentration*100)
data["node2_concentration"] = round(node2_concentration*100)
-
- var/datum/nanoui/ui = SSnano.get_open_ui(user, src, ui_key)
- if (!ui)
- ui = new /datum/nanoui(user, src, ui_key, "atmos_mixer.tmpl", name, 400, 320)
- ui.set_initial_data(data)
- ui.open()
- ui.set_auto_update(1)
- else
- ui.push_data(data)
+ return data
/obj/machinery/atmospherics/trinary/mixer/Topic(href,href_list)
if(..()) return
diff --git a/code/ATMOSPHERICS/components/unary_devices/cold_sink.dm b/code/ATMOSPHERICS/components/unary_devices/cold_sink.dm
index a539671f28f..cc473803997 100644
--- a/code/ATMOSPHERICS/components/unary_devices/cold_sink.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/cold_sink.dm
@@ -1,7 +1,6 @@
/obj/machinery/atmospherics/unary/cold_sink
- icon = 'icons/obj/atmospherics/cold_sink.dmi'
- icon_state = "intact_off"
- density = 1
+
+ icon_state = "cold_map"
use_power = 1
name = "cold sink"
@@ -12,15 +11,17 @@
var/current_temperature = T20C
var/current_heat_capacity = 50000 //totally random
-/obj/machinery/atmospherics/unary/cold_sink/update_icon()
- if(node)
- icon_state = "intact_[on?("on"):("off")]"
+/obj/machinery/atmospherics/unary/cold_sink/update_icon_nopipes()
+ overlays.Cut()
+ if(showpipe)
+ overlays += getpipeimage('icons/obj/atmospherics/unary_devices.dmi', "scrub_cap", initialize_directions) //scrub_cap works for now
+
+ if(!node || !on || stat & (NOPOWER|BROKEN))
+ icon_state = "cold_off"
+ return
+
else
- icon_state = "exposed"
-
- on = 0
-
- return
+ icon_state = "cold_on"
/obj/machinery/atmospherics/unary/cold_sink/process_atmos()
..()
diff --git a/code/ATMOSPHERICS/components/unary_devices/generator_input.dm b/code/ATMOSPHERICS/components/unary_devices/generator_input.dm
index 42c3676836c..437626ec6cc 100644
--- a/code/ATMOSPHERICS/components/unary_devices/generator_input.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/generator_input.dm
@@ -1,6 +1,6 @@
/obj/machinery/atmospherics/unary/generator_input
- icon = 'icons/obj/atmospherics/heat_exchanger.dmi'
- icon_state = "intact"
+
+ icon_state = "he_intact"
density = 1
name = "generator input"
diff --git a/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm b/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm
index 04a32f7b6e5..7e3d2e79b84 100644
--- a/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/heat_exchanger.dm
@@ -1,8 +1,6 @@
/obj/machinery/atmospherics/unary/heat_exchanger
- icon = 'icons/obj/atmospherics/heat_exchanger.dmi'
- icon_state = "intact"
- density = 1
+ icon_state = "he_intact"
name = "heat exchanger"
desc = "Exchanges heat between two input gases. Setup for fast heat transfer"
@@ -14,9 +12,10 @@
/obj/machinery/atmospherics/unary/heat_exchanger/update_icon()
if(node)
- icon_state = "intact"
+ icon_state = "he_intact"
+ color = node.color
else
- icon_state = "exposed"
+ icon_state = "he_exposed"
return
diff --git a/code/ATMOSPHERICS/components/unary_devices/heat_source.dm b/code/ATMOSPHERICS/components/unary_devices/heat_source.dm
index fb228ddb557..f2bebe794ae 100644
--- a/code/ATMOSPHERICS/components/unary_devices/heat_source.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/heat_source.dm
@@ -1,9 +1,7 @@
/obj/machinery/atmospherics/unary/heat_reservoir
//currently the same code as cold_sink but anticipating process() changes
- icon = 'icons/obj/atmospherics/cold_sink.dmi'
- icon_state = "intact_off"
- density = 1
+ icon_state = "cold_map"
use_power = 1
name = "heat reservoir"
@@ -14,15 +12,17 @@
var/current_temperature = T20C
var/current_heat_capacity = 50000 //totally random
-/obj/machinery/atmospherics/unary/heat_reservoir/update_icon()
- if(node)
- icon_state = "intact_[on?("on"):("off")]"
+/obj/machinery/atmospherics/unary/heat_reservoir/update_icon_nopipes()
+ overlays.Cut()
+ if(showpipe)
+ overlays += getpipeimage('icons/obj/atmospherics/unary_devices.dmi', "scrub_cap", initialize_directions) //scrub_cap works for now
+
+ if(!node || !on || stat & (NOPOWER|BROKEN))
+ icon_state = "cold_off"
+ return
+
else
- icon_state = "exposed"
-
- on = 0
-
- return
+ icon_state = "cold_on"
/obj/machinery/atmospherics/unary/heat_reservoir/process_atmos()
..()
diff --git a/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm b/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm
index 76b912eef23..42b52ece903 100644
--- a/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm
+++ b/code/ATMOSPHERICS/components/unary_devices/oxygen_generator.dm
@@ -1,10 +1,9 @@
/obj/machinery/atmospherics/unary/oxygen_generator
- icon = 'icons/obj/atmospherics/oxygen_generator.dmi'
- icon_state = "intact_off"
- density = 1
+
+ icon_state = "o2gen_map"
name = "oxygen generator"
- desc = ""
+ desc = "Generates oxygen"
dir = SOUTH
initialize_directions = SOUTH
@@ -13,15 +12,18 @@
var/oxygen_content = 10
-/obj/machinery/atmospherics/unary/oxygen_generator/update_icon()
- if(node)
- icon_state = "intact_[on?("on"):("off")]"
+/obj/machinery/atmospherics/unary/oxygen_generator/update_icon_nopipes()
+
+ overlays.Cut()
+ if(showpipe)
+ overlays += getpipeimage('icons/obj/atmospherics/unary_devices.dmi', "scrub_cap", initialize_directions) //it works for now
+
+ if(!node || !on || stat & BROKEN)
+ icon_state = "o2gen_off"
+ return
+
else
- icon_state = "exposed_off"
-
- on = 0
-
- return
+ icon_state = "o2gen_on"
/obj/machinery/atmospherics/unary/oxygen_generator/New()
..()
diff --git a/code/ATMOSPHERICS/pipes/he_pipes.dm b/code/ATMOSPHERICS/pipes/he_pipes.dm
index 6fa175d1e83..87c43d29d37 100644
--- a/code/ATMOSPHERICS/pipes/he_pipes.dm
+++ b/code/ATMOSPHERICS/pipes/he_pipes.dm
@@ -3,7 +3,7 @@
////////////
/obj/machinery/atmospherics/pipe/simple/heat_exchanging
- icon = 'icons/obj/pipes/heat.dmi'
+ icon = 'icons/obj/atmospherics/pipes/heat.dmi'
icon_state = "intact"
level = 2
var/initialize_directions_he
@@ -106,7 +106,7 @@
//HE Junctions
////////////////
/obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction
- icon = 'icons/obj/pipes/junction.dmi'
+ icon = 'icons/obj/atmospherics/pipes/junction.dmi'
icon_state = "intact"
level = 2
minimum_temperature_difference = 300
diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm
index 8b80ff0b044..1aaf93e3ad9 100644
--- a/code/ATMOSPHERICS/pipes/manifold.dm
+++ b/code/ATMOSPHERICS/pipes/manifold.dm
@@ -4,7 +4,7 @@
*/
/obj/machinery/atmospherics/pipe/manifold
- icon = 'icons/obj/atmospherics/pipe_manifold.dmi'
+ icon = 'icons/obj/atmospherics/pipes/manifold.dmi'
icon_state = "manifold"
name = "pipe manifold"
@@ -100,13 +100,13 @@
//Add non-broken pieces
if(node1)
- overlays += getpipeimage('icons/obj/atmospherics/pipe_manifold.dmi', "manifold_full[invis]", get_dir(src,node1))
+ overlays += getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src,node1))
if(node2)
- overlays += getpipeimage('icons/obj/atmospherics/pipe_manifold.dmi', "manifold_full[invis]", get_dir(src,node2))
+ overlays += getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src,node2))
if(node3)
- overlays += getpipeimage('icons/obj/atmospherics/pipe_manifold.dmi', "manifold_full[invis]", get_dir(src,node3))
+ overlays += getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", get_dir(src,node3))
/obj/machinery/atmospherics/pipe/manifold/hide(var/i)
if(level == 1 && istype(loc, /turf/simulated))
diff --git a/code/ATMOSPHERICS/pipes/manifold4w.dm b/code/ATMOSPHERICS/pipes/manifold4w.dm
index 3a5ff5c735a..d4c80c56b2e 100644
--- a/code/ATMOSPHERICS/pipes/manifold4w.dm
+++ b/code/ATMOSPHERICS/pipes/manifold4w.dm
@@ -3,7 +3,7 @@
4-way manifold
*/
/obj/machinery/atmospherics/pipe/manifold4w
- icon = 'icons/obj/atmospherics/pipe_manifold.dmi'
+ icon = 'icons/obj/atmospherics/pipes/manifold.dmi'
icon_state = "manifold4w"
name = "4-way pipe manifold"
@@ -112,16 +112,16 @@
//Add non-broken pieces
if(node1)
- overlays += getpipeimage('icons/obj/atmospherics/pipe_manifold.dmi', "manifold_full[invis]", NORTH)
+ overlays += getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", NORTH)
if(node2)
- overlays += getpipeimage('icons/obj/atmospherics/pipe_manifold.dmi', "manifold_full[invis]", SOUTH)
+ overlays += getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", SOUTH)
if(node3)
- overlays += getpipeimage('icons/obj/atmospherics/pipe_manifold.dmi', "manifold_full[invis]", EAST)
+ overlays += getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", EAST)
if(node4)
- overlays += getpipeimage('icons/obj/atmospherics/pipe_manifold.dmi', "manifold_full[invis]", WEST)
+ overlays += getpipeimage('icons/obj/atmospherics/pipes/manifold.dmi', "manifold_full[invis]", WEST)
/obj/machinery/atmospherics/pipe/manifold4w/update_node_icon()
..()
diff --git a/code/ATMOSPHERICS/pipes/simple.dm b/code/ATMOSPHERICS/pipes/simple.dm
index 8e33caafeea..a280403a9df 100644
--- a/code/ATMOSPHERICS/pipes/simple.dm
+++ b/code/ATMOSPHERICS/pipes/simple.dm
@@ -5,7 +5,7 @@ The regular pipe you see everywhere, including bent ones.
*/
/obj/machinery/atmospherics/pipe/simple
- icon = 'icons/obj/pipes.dmi'
+ icon = 'icons/obj/atmospherics/pipes/simple.dmi'
icon_state = "intact"
name = "pipe"
diff --git a/code/ATMOSPHERICS/pipes/tank.dm b/code/ATMOSPHERICS/pipes/tank.dm
index 0424cf34005..e47a510432f 100644
--- a/code/ATMOSPHERICS/pipes/tank.dm
+++ b/code/ATMOSPHERICS/pipes/tank.dm
@@ -1,5 +1,5 @@
/obj/machinery/atmospherics/unary/tank
- icon = 'icons/obj/atmospherics/pipe_tank.dmi'
+ icon = 'icons/obj/atmospherics/pipes/pressure_tank.dmi'
icon_state = "generic"
name = "pressure tank"
desc = "A large vessel containing pressurized gas."
@@ -16,7 +16,7 @@
col = node.pipe_color
else
state = "pipe_exposed"
- underlays += getpipeimage('icons/obj/atmospherics/pipe_tank.dmi', state, initialize_directions, col)
+ underlays += getpipeimage('icons/obj/atmospherics/pipes/pressure_tank.dmi', state, initialize_directions, col)
/obj/machinery/atmospherics/unary/tank/carbon_dioxide
name = "pressure tank (Carbon Dioxide)"
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index bbb172cfe83..1aebe1bce3b 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -108,6 +108,7 @@
#define STAGE_THREE 5
#define STAGE_FOUR 7
#define STAGE_FIVE 9
+#define STAGE_SIX 11 //From supermatter shard
//zlevel defines, can be overridden for different maps in the appropriate _maps file.
#define ZLEVEL_SPACEMAX 7
@@ -159,4 +160,9 @@
#define FUZZY_CHANCE_LOW 50
#define CHANCE_TALK 15
#define MAXCOIL 30
-#define RESIZE_DEFAULT_SIZE 1
\ No newline at end of file
+#define RESIZE_DEFAULT_SIZE 1
+
+//transfer_ai() defines. Main proc in ai_core.dm
+#define AI_TRANS_TO_CARD 1 //Downloading AI to InteliCard.
+#define AI_TRANS_FROM_CARD 2 //Uploading AI from InteliCard
+#define AI_MECH_HACK 3 //Malfunctioning AI hijacking mecha
\ No newline at end of file
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index fb75fed9b60..e32a0b65f60 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1196,7 +1196,7 @@ var/list/WALLITEMS = list(
/obj/machinery/newscaster, /obj/machinery/firealarm, /obj/structure/noticeboard, /obj/machinery/door_control,
/obj/machinery/computer/security/telescreen, /obj/machinery/embedded_controller/radio/simple_vent_controller,
/obj/item/weapon/storage/secure/safe, /obj/machinery/door_timer, /obj/machinery/flasher, /obj/machinery/keycard_auth,
- /obj/structure/mirror, /obj/structure/closet/fireaxecabinet, /obj/machinery/computer/security/telescreen/entertainment
+ /obj/structure/mirror, /obj/structure/fireaxecabinet, /obj/machinery/computer/security/telescreen/entertainment
)
/proc/gotwallitem(loc, dir)
var/locdir = get_step(loc, dir)
diff --git a/code/_globalvars/lists/objects.dm b/code/_globalvars/lists/objects.dm
index 6855ed2efcb..2abd022a271 100644
--- a/code/_globalvars/lists/objects.dm
+++ b/code/_globalvars/lists/objects.dm
@@ -7,6 +7,7 @@ var/global/list/machines = list() //NOTE: this is a list of ALL machines now
var/global/list/navbeacons = list() //list of all bot nagivation beacons, used for patrolling.
var/global/list/deliverybeacons = list() //list of all MULEbot delivery beacons.
var/global/list/deliverybeacontags = list() //list of all tags associated with delivery beacons.
+var/global/list/nuke_list = list()
var/global/list/chemical_reactions_list //list of all /datum/chemical_reaction datums. Used during chemical reactions
var/global/list/chemical_reagents_list //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff
diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm
index 4700e4f5d54..305e3af18d3 100644
--- a/code/_onclick/ai.dm
+++ b/code/_onclick/ai.dm
@@ -39,7 +39,10 @@
CtrlShiftClickOn(A)
return
if(modifiers["middle"])
- MiddleClickOn(A)
+ if(controlled_mech) //Are we piloting a mech? Placed here so the modifiers are not overridden.
+ controlled_mech.click_action(A, src) //Override AI normal click behavior.
+ return
+
return
if(modifiers["shift"])
ShiftClickOn(A)
@@ -116,7 +119,7 @@
return
/atom/proc/AICtrlShiftClick()
return
-
+
/* Airlocks */
/obj/machinery/door/airlock/AICtrlClick() // Bolts doors
if(emagged)
@@ -152,7 +155,7 @@
else
Topic("aiDisable=11", list("aiDisable"="11"), 1)
return
-
+
/* APC */
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
toggle_breaker()
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index 00057af5fa3..cb0ddfbf5ee 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -198,7 +198,7 @@ var/datum/global_hud/global_hud = new()
else if(isdrone(mymob))
drone_hud(ui_style)
- if(istype(mymob.loc,/obj/mecha))
+ if(istype(mymob.loc,/obj/mecha) && ishuman(mymob))
show_hud(HUD_STYLE_REDUCED)
//Version denotes which style should be displayed. blank or 0 means "next version"
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index e442f74d14f..3f314079849 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -115,8 +115,8 @@
var/alert_desc_blue_upto = "The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted."
var/alert_desc_blue_downto = "The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed."
var/alert_desc_red_upto = "There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised."
- var/alert_desc_red_downto = "The self-destruct mechanism has been deactivated, there is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised."
- var/alert_desc_delta = "The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill."
+ var/alert_desc_red_downto = "The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised."
+ var/alert_desc_delta = "Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill."
var/health_threshold_crit = 0
var/health_threshold_dead = -100
@@ -489,6 +489,20 @@
config.no_summon_events = 1
if("reactionary_explosions")
config.reactionary_explosions = 1
+ if("bombcap")
+ var/BombCap = text2num(value)
+ if (!BombCap)
+ continue
+ if (BombCap < 4)
+ BombCap = 4
+ if (BombCap > 128)
+ BombCap = 128
+
+ MAX_EX_DEVESTATION_RANGE = round(BombCap/4)
+ MAX_EX_HEAVY_RANGE = round(BombCap/2)
+ MAX_EX_LIGHT_RANGE = BombCap
+ MAX_EX_FLASH_RANGE = BombCap
+ MAX_EX_FLAME_RANGE = BombCap
else
diary << "Unknown setting in configuration: '[name]'"
diff --git a/code/controllers/subsystem/nanoUI.dm b/code/controllers/subsystem/nanoUI.dm
index 017556248b5..feb60fce007 100644
--- a/code/controllers/subsystem/nanoUI.dm
+++ b/code/controllers/subsystem/nanoUI.dm
@@ -3,7 +3,7 @@ var/datum/subsystem/nano/SSnano
/datum/subsystem/nano
name = "NanoUI"
can_fire = 1
- wait = 5
+ wait = 10
priority = 16
var/list/open_uis = list() //a list of current open /nanoui UIs, grouped by src_object and ui_key
diff --git a/code/datums/diseases/transformation.dm b/code/datums/diseases/transformation.dm
index c46ce95e0a6..dc57ec59822 100644
--- a/code/datums/diseases/transformation.dm
+++ b/code/datums/diseases/transformation.dm
@@ -208,6 +208,7 @@
/datum/disease/transformation/corgi
name = "The Barkening"
cure_text = "Death"
+ cures = list("adminordrazine")
agent = "Fell Doge Majicks"
desc = "This disease transforms the victim into a corgi."
visibility_flags = 0
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index 21bf92f6b4d..ceb8a980ea3 100644
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -286,9 +286,9 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine
/datum/supply_packs/security/armory/ballistic
name = "Combat Shotguns Crate"
- contains = list(/obj/item/weapon/gun/projectile/shotgun/combat,
- /obj/item/weapon/gun/projectile/shotgun/combat,
- /obj/item/weapon/gun/projectile/shotgun/combat,
+ contains = list(/obj/item/weapon/gun/projectile/shotgun/automatic/combat,
+ /obj/item/weapon/gun/projectile/shotgun/automatic/combat,
+ /obj/item/weapon/gun/projectile/shotgun/automatic/combat,
/obj/item/weapon/storage/belt/bandolier,
/obj/item/weapon/storage/belt/bandolier,
/obj/item/weapon/storage/belt/bandolier)
diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm
index 7f6db7d1388..5e714b639df 100644
--- a/code/datums/uplink_item.dm
+++ b/code/datums/uplink_item.dm
@@ -268,10 +268,24 @@ var/list/uplink_items = list()
cost = 2
gamemodes = list(/datum/game_mode/nuclear,/datum/game_mode/gang)
+/datum/uplink_item/ammo/ammobag
+ name = "Ammo Duffelbag - Shotgun Ammo Grab Bag"
+ desc = "A duffelbag filled with Bulldog ammo to kit out an entire team, at a discounted price."
+ item = /obj/item/weapon/storage/backpack/dufflebag/syndieammo/loaded
+ cost = 10 //bulk buyer's discount. Very useful if you're buying a mech and dont have TC left to buy people non-shotgun guns
+ gamemodes = list(/datum/game_mode/nuclear)
+
+/datum/uplink_item/ammo/bullslug
+ name = "Drum Magazine - 12g Slugs"
+ desc = "An additional 8-round slug magazine for use in the Bulldog shotgun. Now 8 times less likely to shoot your pals."
+ item = /obj/item/ammo_box/magazine/m12g
+ cost = 2
+ gamemodes = list(/datum/game_mode/nuclear)
+
/datum/uplink_item/ammo/bullbuck
name = "Drum Magazine - 12g Buckshot"
desc = "An additional 8-round buckshot magazine for use in the Bulldog shotgun. Front towards enemy."
- item = /obj/item/ammo_box/magazine/m12g
+ item = /obj/item/ammo_box/magazine/m12g/buckshot
cost = 2
gamemodes = list(/datum/game_mode/nuclear)
@@ -286,6 +300,13 @@ var/list/uplink_items = list()
name = "Drum Magazine - 12g Dragon's Breath"
desc = "An alternative 8-round dragon's breath magazine for use in the Bulldog shotgun. I'm a fire starter, twisted fire starter!"
item = /obj/item/ammo_box/magazine/m12g/dragon
+ cost = 2
+ gamemodes = list(/datum/game_mode/nuclear)
+
+/datum/uplink_item/ammo/bulltoxin
+ name = "Drum Magazine - 12g Bioterror"
+ desc = "An alternative 8-round toxic magazine for use in the Bulldog shotgun. Contains debilitating toxins to make your target die an agonizing death."
+ item = /obj/item/ammo_box/magazine/m12g/bioterror
cost = 3
gamemodes = list(/datum/game_mode/nuclear)
@@ -389,6 +410,14 @@ var/list/uplink_items = list()
item = /obj/item/toy/carpplushie/dehy_carp
cost = 3
+/datum/uplink_item/stealthy_weapons/door_charge
+ name = "Explosive Airlock Charge"
+ desc = "A small, easily concealable device. It can be applied to an open airlock panel, and the next person to open that airlock will be knocked down in an explosion. The airlock's maintenance panel will also be destroyed by this."
+ item = /obj/item/device/doorCharge
+ cost = 5
+ surplus = 6
+ excludefrom = list(/datum/game_mode/nuclear)
+
// STEALTHY TOOLS
/datum/uplink_item/stealthy_tools
@@ -639,11 +668,62 @@ var/list/uplink_items = list()
item = /obj/item/weapon/storage/box/syndie_kit/imp_explosive
cost = 6
+
+//CYBERNETIC IMPLANTS
+
+/datum/uplink_item/cyber_implants
+ category = "Cybernetic Implants"
+ gamemodes = list(/datum/game_mode/nuclear)
+ surplus = 0
+
+/datum/uplink_item/cyber_implants/thermals
+ name = "Thermal Vision Implant"
+ desc = "These cybernetic eyes will give you thermal vision."
+ item = /obj/item/cybernetic_implant/eyes/thermals
+ cost = 8
+
+/datum/uplink_item/cyber_implants/xray
+ name = "X-Ray Vision Implant"
+ desc = "These cybernetic eyes will give you X-ray vision."
+ item = /obj/item/cybernetic_implant/eyes/xray
+ cost = 10
+
+/datum/uplink_item/cyber_implants/antistun
+ name = "CNS Rebooter Implant"
+ desc = "This implant will help you get back up on your feet faster after being stunned."
+ item = /obj/item/cybernetic_implant/brain/anti_stun
+ cost = 12
+
+/datum/uplink_item/cyber_implants/antidrop
+ name = "Anti-Drop Implant"
+ desc = "This cybernetic brain implant will allow you to force your hand muscles to contract, preventing item dropping."
+ item = /obj/item/cybernetic_implant/brain/anti_drop
+ cost = 8
+
+/datum/uplink_item/cyber_implants/reviver
+ name = "Reviver Implant"
+ desc = "This implant will attempt to revive you if you lose consciousness."
+ item = /obj/item/cybernetic_implant/chest/reviver
+ cost = 8
+
+/datum/uplink_item/cyber_implants/nutriment
+ name = "Nutriment Pump Implant PLUS"
+ desc = "This implant will pump you with nutriments and electrolytes so you don't go hungry in action."
+ item = /obj/item/cybernetic_implant/chest/nutriment/plus
+ cost = 5
+
+/datum/uplink_item/cyber_implants/bundle
+ name = "Cybernetic Implants Bundle"
+ desc = "A random selection of cybernetic implants. Guaranteed 5 high quality implants."
+ item = /obj/item/weapon/storage/box/cyber_implants
+ cost = 40
+
// POINTLESS BADASSERY
/datum/uplink_item/badass
category = "(Pointless) Badassery"
surplus = 0
+ last = 1
/datum/uplink_item/badass/bundle
name = "Syndicate Bundle"
diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm
index e483513c40a..89b57e6a16e 100644
--- a/code/datums/wires/wires.dm
+++ b/code/datums/wires/wires.dm
@@ -134,7 +134,8 @@ var/list/wireColours = list("red", "blue", "green", "black", "orange", "brown",
if(istype(I, /obj/item/device/assembly))
var/obj/item/device/assembly/A = I;
if(A.attachable)
- L.drop_item()
+ if(!L.drop_item())
+ return
Attach(colour, A)
else
L << "You need a attachable assembly!"
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index cb638aa6f31..f6a52f40e54 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -449,3 +449,6 @@ var/list/blood_splatter_icons = list()
/atom/proc/narsie_act()
return
+
+/atom/proc/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
+ return 0
\ No newline at end of file
diff --git a/code/game/dna.dm b/code/game/dna.dm
index 60fa4a6ca9d..614e4698f55 100644
--- a/code/game/dna.dm
+++ b/code/game/dna.dm
@@ -519,7 +519,8 @@
/obj/machinery/computer/scan_consolenew/attackby(obj/item/I as obj, mob/user as mob, params)
if (istype(I, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES
if (!src.diskette)
- user.drop_item()
+ if(!user.drop_item())
+ return
I.loc = src
src.diskette = I
user << "You insert [I]."
diff --git a/code/game/gamemodes/abduction/abduction.dm b/code/game/gamemodes/abduction/abduction.dm
index 502d4300932..5a3d85f957a 100644
--- a/code/game/gamemodes/abduction/abduction.dm
+++ b/code/game/gamemodes/abduction/abduction.dm
@@ -263,7 +263,7 @@
for(var/team_number=1,team_number<=teams,team_number++)
var/obj/machinery/abductor/console/con = get_team_console(team_number)
var/datum/objective/objective = team_objectives[team_number]
- if (con.experiment.points > objective.target_amount)
+ if (con.experiment.points >= objective.target_amount)
SSshuttle.emergency.request(null, 0.5)
finished = 1
return ..()
@@ -279,7 +279,7 @@
var/datum/mind/smind = scientists[team_number]
var/mob/living/carbon/human/agent = amind.current
var/mob/living/carbon/human/scientist = smind.current
- if (console.experiment.points > objective.target_amount)
+ if (console.experiment.points >= objective.target_amount)
world << "[team_name] team fullfilled its mission! "
world << "Team Members : [agent.name]([agent.ckey]),[scientist.name]([scientist.ckey])"
else
diff --git a/code/game/gamemodes/abduction/abduction_gear.dm b/code/game/gamemodes/abduction/abduction_gear.dm
index a13b347907c..dfb27d32870 100644
--- a/code/game/gamemodes/abduction/abduction_gear.dm
+++ b/code/game/gamemodes/abduction/abduction_gear.dm
@@ -22,15 +22,6 @@
var/stealth_armor = list(melee = 15, bullet = 15, laser = 15, energy = 15, bomb = 15, bio = 15, rad = 15)
var/combat_armor = list(melee = 50, bullet = 50, laser = 50, energy = 50, bomb = 50, bio = 50, rad = 50)
- var/obj/machinery/camera/portable/vest_cam = null
-
-
-/obj/item/clothing/suit/armor/abductor/vest/New()
- ..()
- vest_cam = new /obj/machinery/camera/portable(src)
- vest_cam.c_tag = "Agent Vest Cam"
- vest_cam.network = list("Abductor")
-
/obj/item/clothing/suit/armor/abductor/vest/proc/flip_mode()
switch(mode)
if(VEST_STEALTH)
diff --git a/code/game/gamemodes/abduction/machinery/dispenser.dm b/code/game/gamemodes/abduction/machinery/dispenser.dm
index d346e0366a5..33b4944785b 100644
--- a/code/game/gamemodes/abduction/machinery/dispenser.dm
+++ b/code/game/gamemodes/abduction/machinery/dispenser.dm
@@ -60,7 +60,8 @@
/obj/machinery/abductor/gland_dispenser/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/gland))
- user.drop_item()
+ if(!user.drop_item())
+ return
W.loc = src
for(var/i=1,i<=gland_colors.len,i++)
if(gland_types[i] == W.type)
diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm
index 70f29cab8ef..3a6ef5e1d26 100644
--- a/code/game/gamemodes/blob/blobs/blob_mobs.dm
+++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm
@@ -83,8 +83,7 @@
H.hair_style = null
H.update_hair()
human_overlays = H.overlays
- if(overmind && overmind.blob_reagent_datum)
- adjustcolors(overmind.blob_reagent_datum.color)
+ update_icons()
H.loc = src
loc.visible_message("The corpse of [H.name] suddenly rises!")
@@ -120,8 +119,18 @@
..()
+/mob/living/simple_animal/hostile/blob/blobspore/update_icons()
+ ..()
+
+ if(overmind && overmind.blob_reagent_datum)
+ adjustcolors(overmind.blob_reagent_datum.color)
+ else
+ adjustcolors(color) //to ensure zombie/other overlays update
+
+
/mob/living/simple_animal/hostile/blob/blobspore/adjustcolors(var/a_color)
color = a_color
+
if(is_zombie)
overlays.Cut()
overlays = human_overlays
@@ -130,7 +139,6 @@
color = initial(color)//looks better.
overlays += I
-
/////////////////
// BLOBBERNAUT //
/////////////////
diff --git a/code/game/gamemodes/gang/dominator.dm b/code/game/gamemodes/gang/dominator.dm
index 0bb8c7b21de..b72b8f55b81 100644
--- a/code/game/gamemodes/gang/dominator.dm
+++ b/code/game/gamemodes/gang/dominator.dm
@@ -6,10 +6,10 @@
density = 1
anchored = 1.0
layer = 3.6
- var/health = 200
+ var/maxhealth = 300
+ var/health = 300
var/gang
var/operating = 0
- var/broken = 0
/obj/machinery/dominator/New()
if(!istype(ticker.mode, /datum/game_mode/gang))
@@ -19,7 +19,7 @@
/obj/machinery/dominator/examine(mob/user)
..()
- if(broken)
+ if(operating == -1)
user << "It looks completely busted."
return
@@ -38,7 +38,7 @@
user << "Hostile Takeover of [station_name()] successful. Have a great day."
else
user << "System on standby."
- user << "System Integrity: [health/2]%"
+ user << "System Integrity: [round((health/maxhealth)*100,1)]%"
/obj/machinery/dominator/proc/healthcheck(var/damage)
@@ -51,23 +51,22 @@
health -= damage
- switch(health)
- if(101 to INFINITY)
- if(prob(damage*2))
- sparks.set_up(5, 1, src)
- sparks.start()
- if(1 to 100)
+ if(health > (maxhealth/2))
+ if(prob(damage*2))
sparks.set_up(5, 1, src)
sparks.start()
- iconname += "-damaged"
+ else
+ sparks.set_up(5, 1, src)
+ sparks.start()
+ iconname += "-damaged"
- if(!broken)
+ if(operating != -1)
if(health <= 0)
set_broken()
else
icon_state = iconname
- if(health <= -50)
+ if(health <= -100)
new /obj/item/stack/sheet/plasteel(src.loc)
qdel(src)
@@ -77,22 +76,37 @@
mode.A_timer = "OFFLINE"
if(gang == "B")
mode.B_timer = "OFFLINE"
- if(!isnum(mode.A_timer) && !isnum(mode.B_timer))
- SSshuttle.emergencyNoEscape = 0
- if(SSshuttle.emergency.mode == SHUTTLE_STRANDED)
- SSshuttle.emergency.mode = SHUTTLE_DOCKED
- SSshuttle.emergency.timer = world.time
- priority_announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority")
- else
- priority_announce("All hostile activity within station systems have ceased.","Network Alert")
if(gang)
+ if(!isnum(mode.A_timer) && !isnum(mode.B_timer))
+ SSshuttle.emergencyNoEscape = 0
+ if(SSshuttle.emergency.mode == SHUTTLE_STRANDED)
+ SSshuttle.emergency.mode = SHUTTLE_DOCKED
+ SSshuttle.emergency.timer = world.time
+ priority_announce("Hostile enviroment resolved. You have 3 minutes to board the Emergency Shuttle.", null, 'sound/AI/shuttledock.ogg', "Priority")
+ else
+ priority_announce("All hostile activity within station systems have ceased.","Network Alert")
+
+ if(get_security_level() == "delta")
+ set_security_level("red")
+
+ for(var/obj/item/weapon/pinpointer/pointer in world)
+ pointer.scandisk() //Reset the pinpointer
+
+ else if(isnum(mode.A_timer) || isnum(mode.B_timer))
+ for(var/obj/machinery/dominator/dom in world)
+ if(dom.operating)
+ for(var/obj/item/weapon/pinpointer/pointer in world)
+ pointer.the_disk = dom //The pinpointer now tracks the dominator's location
+ break
+
ticker.mode.message_gangtools(((gang=="A") ? ticker.mode.A_tools : ticker.mode.B_tools),"Hostile takeover cancelled: Dominator is no longer operational.",1,1)
+
SetLuminosity(0)
icon_state = "dominator-broken"
- broken = 1
+ operating = -1
/obj/machinery/dominator/Destroy()
- if(!broken)
+ if(operating != -1)
set_broken()
..()
@@ -116,9 +130,12 @@
/obj/machinery/dominator/bullet_act(var/obj/item/projectile/Proj)
if(Proj.damage)
if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
+ var/damage = Proj.damage
+ if(Proj.forcedodge)
+ damage *= 0.5
playsound(src, 'sound/effects/bang.ogg', 50, 1)
visible_message("[src] was hit by [Proj].")
- healthcheck(Proj.damage)
+ healthcheck(damage)
..()
/obj/machinery/dominator/blob_act()
@@ -129,7 +146,7 @@
return
/obj/machinery/dominator/attack_hand(mob/user)
- if(operating||broken)
+ if(operating)
examine(user)
return
@@ -155,13 +172,12 @@
user << "Error: Hostile Takeover is already in progress."
return
- var/time = max(180,900 - ((round((gang_territory/start_state.num_territories)*200, 1) - 60) * 15))
+ var/time = max(300,900 - ((round((gang_territory/start_state.num_territories)*200, 1) - 60) * 15))
if(alert(user,"With [round((gang_territory/start_state.num_territories)*100, 1)]% station control, a takeover will require [time] seconds.\nYour gang will be unable to gain influence while it is active.\nThe entire station will likely be alerted to it once it starts.\nAre you ready?","Confirm","Ready","Later") == "Ready")
if ((!in_range(src, user) || !istype(src.loc, /turf)))
return 0
- var/area/srcloc = get_area(src.loc)
gang = tempgang
- mode.domination(gang,1,srcloc.name)
+ mode.domination(gang,1,src)
src.name = "[gang_name(gang)] Gang [src.name]"
healthcheck(0)
operating = 1
diff --git a/code/game/gamemodes/gang/gang.dm b/code/game/gamemodes/gang/gang.dm
index 2b448e0b833..c838e61d54b 100644
--- a/code/game/gamemodes/gang/gang.dm
+++ b/code/game/gamemodes/gang/gang.dm
@@ -9,16 +9,14 @@
var/obj/item/device/gangtool/A_tools = list()
var/obj/item/device/gangtool/B_tools = list()
var/datum/gang_points/gang_points
+ var/A_style
+ var/B_style
var/list/A_territory = list()
var/list/B_territory = list()
var/list/A_territory_new = list()
var/list/A_territory_lost = list()
var/list/B_territory_new = list()
var/list/B_territory_lost = list()
- var/gang_A_style
- var/gang_A_headgear
- var/gang_B_style
- var/gang_B_headgear
/datum/game_mode/gang
name = "gang war"
@@ -85,7 +83,7 @@
if(isnum(B_timer))
B_timer -= seconds
- ticker.mode.check_win()
+ check_win()
/datum/game_mode/gang/proc/assign_bosses()
var/datum/mind/boss = pick(antag_candidates)
@@ -117,17 +115,20 @@
boss_mind.current << "Objective #[obj_count]: [objective.explanation_text]"
obj_count++
-/datum/game_mode/gang/proc/domination(var/gang,var/modifier=1,var/dominatorloc)
+/datum/game_mode/gang/proc/domination(var/gang,var/modifier=1,var/obj/dominator)
if(gang=="A")
- A_timer = max(180,900 - ((round((ticker.mode.A_territory.len/start_state.num_territories)*200, 1) - 60) * 15)) * modifier
+ A_timer = max(180,900 - ((round((A_territory.len/start_state.num_territories)*200, 1) - 60) * 15)) * modifier
if(gang=="B")
- B_timer = max(180,900 - ((round((ticker.mode.B_territory.len/start_state.num_territories)*200, 1) - 60) * 15)) * modifier
- if(gang && dominatorloc)
- priority_announce("Hostile runtimes detected in all station systems. A network breach by the [gang_name(gang)] Gang has been located in [dominatorloc].","Network Alert")
- if(get_security_level() != "delta")
- set_security_level("red")
+ B_timer = max(180,900 - ((round((B_territory.len/start_state.num_territories)*200, 1) - 60) * 15)) * modifier
+ if(gang && dominator)
+ var/area/domloc = get_area(dominator.loc)
+ priority_announce("Hostile runtimes detected in all station systems. A network breach by the [gang_name(gang)] Gang has been located in [domloc].","Network Alert")
+ set_security_level("delta")
SSshuttle.emergencyNoEscape = 1
+ for(var/obj/item/weapon/pinpointer/point in world)
+ point.the_disk = dominator //The pinpointer now tracks the dominator's location
+
///////////////////////////////////////////////////////////////////////////
//This equips the bosses with their gear, and makes the clown not clumsy//
///////////////////////////////////////////////////////////////////////////
@@ -180,6 +181,7 @@
return .
+
//Used by recallers when purchasing a gang outfit. First time a gang outfit is purchased the buyer decides a gang style which is stored so gang outfits are uniform
/datum/game_mode/proc/gang_outfit(mob/user,var/obj/item/device/gangtool/gangtool,var/gang)
if(!user || !gangtool || !gang)
@@ -187,36 +189,53 @@
if(!gangtool.can_use(user))
return 0
- var/gang_style_list = list("Gang Colors","Leather Jackets","Black Suits","White Suits")
+ var/gang_style_list = list("Gang Colors","Gang Colored Suits","Black Suits","White Suits","Leather Jackets","Leather Overcoats","Tactical Turtlenecks","Soviet Uniforms")
var/style
if(gang == "A")
- if(!gang_A_style)
- gang_A_style = input("Pick an outfit style.", "Pick Style") as null|anything in gang_style_list
- style = gang_A_style
+ if(!A_style)
+ A_style = input("Pick an outfit style.", "Pick Style") as null|anything in gang_style_list
+ style = A_style
if(gang == "B")
- if(!gang_B_style)
- gang_B_style = input("Pick an outfit style.", "Pick Style") as null|anything in gang_style_list
- style = gang_B_style
+ if(!B_style)
+ B_style = input("Pick an outfit style.", "Pick Style") as null|anything in gang_style_list
+ style = B_style
if(!style)
return 0
if(gangtool.can_use(user) && (((gang == "A") ? gang_points.A : gang_points.B) >= 1))
+ var/outfit_path
switch(style)
if("Gang Colors")
if(gang == "A")
- new /obj/item/clothing/under/color/blue(user.loc)
+ outfit_path = /obj/item/clothing/under/color/blue
if(gang == "B")
- new /obj/item/clothing/under/color/red(user.loc)
- if("Leather Jackets")
- new /obj/item/clothing/suit/jacket/leather(user.loc)
+ outfit_path = /obj/item/clothing/under/color/red
+ if("Gang Colored Suits")
+ if(gang == "A")
+ outfit_path = /obj/item/clothing/under/suit_jacket/navy
+ if(gang == "B")
+ outfit_path = /obj/item/clothing/under/suit_jacket/burgundy
if("Black Suits")
- new /obj/item/clothing/under/suit_jacket/charcoal(user.loc)
+ outfit_path = /obj/item/clothing/under/suit_jacket/charcoal
if("White Suits")
- new /obj/item/clothing/under/suit_jacket/white(user.loc)
+ outfit_path = /obj/item/clothing/under/suit_jacket/white
+ if("Leather Jackets")
+ outfit_path = /obj/item/clothing/suit/jacket/leather
+ if("Leather Overcoats")
+ outfit_path = /obj/item/clothing/suit/jacket/leather/overcoat
+ if("Soviet Uniforms")
+ outfit_path = /obj/item/clothing/under/soviet
+ if("Tactical Turtlenecks")
+ outfit_path = /obj/item/clothing/under/syndicate
- return 1
+ if(outfit_path)
+ var/obj/item/clothing/outfit = new outfit_path(user.loc)
+ outfit.armor = list(melee = 10, bullet = 10, laser = 10, energy = 0, bomb = 0, bio = 0, rad = 0)
+ outfit.desc += " Combat-tailored for the [gang_name(gang)] Gang."
+ outfit.gang = gang
+ return 1
return 0
@@ -258,7 +277,7 @@
if(check && isloyal(gangster_mind.current)) //Check to see if the potential gangster is implanted
return 0
if(gangster_mind in (A_bosses | A_gang | B_bosses | B_gang))
- return 0
+ return 1
if(gang == "A")
A_gang += gangster_mind
else
@@ -275,7 +294,7 @@
gangster_mind.current.attack_log += "\[[time_stamp()]\] Has been converted to the [gang=="A" ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"]!"
gangster_mind.special_role = "[gang=="A" ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"]"
update_gang_icons_added(gangster_mind,gang)
- return 1
+ return 2
////////////////////////////////////////////////////////////////////
//Deals with players reverting to neutral (Not a gangster anymore)//
////////////////////////////////////////////////////////////////////
@@ -310,7 +329,7 @@
if(!silent)
gangster_mind.current.visible_message("The frame beeps contentedly from the MMI before initalizing it.")
gangster_mind.current << "The frame's firmware detects and deletes your criminal behavior! You are no longer a gangster!"
- message_admins("[key_name_admin(gangster_mind.current)] ? has been borged while being a member of the [gang=="A" ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"] Gang. They are no longer a gangster.")
+ message_admins("[key_name_admin(gangster_mind.current)] ? (FLW) has been borged while being a member of the [gang=="A" ? "[gang_name("A")] Gang (A)" : "[gang_name("B")] Gang (B)"] Gang. They are no longer a gangster.")
else
if(!silent)
gangster_mind.current.Paralyse(5)
@@ -376,7 +395,7 @@
if(A_bosses.len || A_gang.len)
if(winner)
- world << "
The [gang_name("A")] Gang was [winner=="A" ? "victorious" : "defeated"] with [round((ticker.mode.A_territory.len/start_state.num_territories)*100, 1)]% control of the station!"
+ world << "
The [gang_name("A")] Gang was [winner=="A" ? "victorious" : "defeated"] with [round((A_territory.len/start_state.num_territories)*100, 1)]% control of the station!"
world << "
The [gang_name("A")] Gang Bosses were:"
gang_membership_report(A_bosses)
world << "
The [gang_name("A")] Gangsters were:"
@@ -385,7 +404,7 @@
if(B_bosses.len || B_gang.len)
if(winner)
- world << "
The [gang_name("B")] Gang was [winner=="B" ? "victorious" : "defeated"] with [round((ticker.mode.B_territory.len/start_state.num_territories)*100, 1)]% control of the station!"
+ world << "
The [gang_name("B")] Gang was [winner=="B" ? "victorious" : "defeated"] with [round((B_territory.len/start_state.num_territories)*100, 1)]% control of the station!"
world << "
The [gang_name("B")] Gang Bosses were:"
gang_membership_report(B_bosses)
world << "
The [gang_name("B")] Gangsters were:"
@@ -454,39 +473,59 @@
if(istype(ticker.mode, /datum/game_mode/gang))
gangmode = ticker.mode
+ //Count uniformed gangsters
+ var/A_uniformed = 0
+ var/B_uniformed = 0
+ for(var/datum/mind/gangmind in (ticker.mode.A_gang|ticker.mode.A_bosses|ticker.mode.B_gang|ticker.mode.B_bosses))
+ if(ishuman(gangmind.current))
+ var/mob/living/carbon/human/gangster = gangmind.current
+ //Gangster must be alive and on station
+ if((gangster.stat == DEAD) || (gangster.z > ZLEVEL_STATION))
+ continue
+ if(gangster.w_uniform)
+ var/obj/item/clothing/outfit = gangster.w_uniform
+ if(outfit.gang == "A")
+ A_uniformed ++
+ if(outfit.gang == "B")
+ B_uniformed ++
+ if(gangster.wear_suit)
+ var/obj/item/clothing/outfit = gangster.wear_suit
+ if(outfit.gang == "A")
+ A_uniformed ++
+ if(outfit.gang == "B")
+ B_uniformed ++
+
//Calculate and report influence growth
ticker.mode.message_gangtools(ticker.mode.A_tools,"*---------*
[gang_name("A")] Gang Status Report:")
var/A_message = ""
if(gangmode && isnum(gangmode.A_timer))
- var/new_time = max(180,gangmode.A_timer - (ticker.mode.A_territory.len * 2))
+ var/new_time = max(180,gangmode.A_timer - ((ticker.mode.A_territory.len + A_uniformed) * 2))
if(new_time < gangmode.A_timer)
- A_message += "Your takeover has been rushed by [gangmode.A_timer - new_time] seconds for holding on to [ticker.mode.A_territory.len] territories. "
+ A_message += "Takeover shortened by [gangmode.A_timer - new_time] seconds for defending [ticker.mode.A_territory.len] territories and [A_uniformed] uniformed gangsters.
"
gangmode.A_timer = new_time
A_message += "[gangmode.A_timer] seconds remain in hostile takeover."
else
- var/A_new = min(999,A + 15 + ticker.mode.A_territory.len)
+ var/A_new = min(999,A + 15 + (A_uniformed * 2) + ticker.mode.A_territory.len)
if(A_new != A)
- A_message += "Your gang has gained [A_new - A] Influence for holding on to [ticker.mode.A_territory.len] territories."
- if(A_new == 999)
- A_message += " You cannot gain any more influence without spending some with this device."
+ A_message += "Gang influence has increased by [A_new - A] for defending [ticker.mode.A_territory.len] territories and [A_uniformed] uniformed gangsters.
"
A = A_new
+ A_message += "Your gang now has [A_new] influence."
ticker.mode.message_gangtools(ticker.mode.A_tools,A_message,0)
ticker.mode.message_gangtools(ticker.mode.B_tools,"[gang_name("B")] Gang Status Report:")
var/B_message = ""
if(gangmode && isnum(gangmode.B_timer))
- var/new_time = max(180,gangmode.B_timer - (ticker.mode.B_territory.len * 2))
+ var/new_time = max(180,gangmode.B_timer - ((ticker.mode.B_territory.len + B_uniformed) * 2))
if(new_time < gangmode.B_timer)
- B_message += "Your takeover has been rushed by [gangmode.B_timer - new_time] seconds for holding on to [ticker.mode.B_territory.len] territories. "
+ A_message += "Takeover shortened by [gangmode.B_timer - new_time] seconds for defending [ticker.mode.B_territory.len] territories and [B_uniformed] uniformed gangsters.
"
gangmode.B_timer = new_time
- B_message += "[gangmode.B_timer] seconds remain in hostile takeover."
+ B_message += "[gangmode.B_timer] seconds remain hostile takeover."
else
- var/B_new = min(999,B + 15 + ticker.mode.B_territory.len)
+ var/B_new = min(999,B + 15 + (B_uniformed * 2) + ticker.mode.B_territory.len)
if(B_new != B)
- B_message += "Your gang has gained [B_new - B] Influence for holding on to [ticker.mode.B_territory.len] territories."
- if(B_new == 999)
- B_message += " You cannot gain any more influence without spending some with this device."
+ A_message += "Gang influence has increased by [B_new - B] for defending [ticker.mode.B_territory.len] territories and [B_uniformed] uniformed gangsters.
"
B = B_new
+ B_message += "Your gang now has [B_new] influence."
ticker.mode.message_gangtools(ticker.mode.B_tools,B_message,0)
@@ -512,10 +551,10 @@
ticker.mode.B_territory += area
//Report territory changes
- ticker.mode.message_gangtools(ticker.mode.A_tools,"[ticker.mode.A_territory_new.len] new territories[A_added_names]",0)
- ticker.mode.message_gangtools(ticker.mode.B_tools,"[ticker.mode.B_territory_new.len] new territories[B_added_names]",0,)
- ticker.mode.message_gangtools(ticker.mode.A_tools,"[ticker.mode.A_territory_lost.len] territories lost[A_lost_names]",0,1)
- ticker.mode.message_gangtools(ticker.mode.B_tools,"[ticker.mode.B_territory_lost.len] territories lost[B_lost_names]",0,1)
+ ticker.mode.message_gangtools(ticker.mode.A_tools,"[ticker.mode.A_territory_new.len] new territories
[A_added_names]",0)
+ ticker.mode.message_gangtools(ticker.mode.B_tools,"[ticker.mode.B_territory_new.len] new territories
[B_added_names]",0,)
+ ticker.mode.message_gangtools(ticker.mode.A_tools,"[ticker.mode.A_territory_lost.len] territories lost
[A_lost_names]",0)
+ ticker.mode.message_gangtools(ticker.mode.B_tools,"[ticker.mode.B_territory_lost.len] territories lost
[B_lost_names]",0)
//Clear the lists
ticker.mode.A_territory_new = list()
@@ -535,7 +574,6 @@
//Restart the counter
start()
-
////////////////////////////////////////////////
//Sends a message to the boss via his gangtool//
////////////////////////////////////////////////
diff --git a/code/game/gamemodes/gang/recaller.dm b/code/game/gamemodes/gang/recaller.dm
index b081a80686e..8459d1fc3ea 100644
--- a/code/game/gamemodes/gang/recaller.dm
+++ b/code/game/gamemodes/gang/recaller.dm
@@ -78,18 +78,24 @@
dat += "(10 Influence) "
if(points >= 10)
- dat += "10mm Ammo
"
+ dat += "10mm Ammo
"
else
dat += "10mm Ammo
"
- dat += "(50 Influence) "
- if(points >= 50)
- dat += "Thompson SMG
"
+ dat += "(40 Influence) "
+ if(points >= 40)
+ dat += "Mini Uzi
"
else
- dat += "Thompson SMG
"
+ dat += "Mini Uzi
"
+
+ dat += "(25 Influence) "
+ if(points >= 25)
+ dat += "Uzi Ammo
"
+ else
+ dat += "Uzi Magazine
"
dat += "
"
- dat += "Purchase Utilities:
"
+ dat += "Purchase Equipment:
"
dat += "(5 Influence) "
if(points >= 5)
@@ -124,7 +130,7 @@
dat += "Station Dominator
"
else
dat += "Station Dominator
"
- dat += "(Estimated Takeover Time: [round(max(180,900 - ((round((gang_territory/start_state.num_territories)*200, 10) - 60) * 15))/60,1)] minutes)
"
+ dat += "(Estimated Takeover Time: [round(max(300,900 - ((round((gang_territory/start_state.num_territories)*200, 10) - 60) * 15))/60,1)] minutes)
"
dat += "
"
dat += "Refresh
"
@@ -163,14 +169,18 @@
if(points >= 20)
item_type = /obj/item/weapon/gun/projectile/automatic/pistol
points = 20
- if("ammo")
+ if("10mmammo")
if(points >= 10)
item_type = /obj/item/ammo_box/magazine/m10mm
points = 10
- if("SMG")
- if(points >= 50)
- item_type = /obj/item/weapon/gun/projectile/automatic/tommygun
- points = 50
+ if("uzi")
+ if(points >= 40)
+ item_type = /obj/item/weapon/gun/projectile/automatic/mini_uzi
+ points = 40
+ if("9mmammo")
+ if(points >= 25)
+ item_type = /obj/item/ammo_box/magazine/uzim9mm
+ points = 25
if("vest")
if(points >= 10)
item_type = /obj/item/clothing/suit/armor/bulletproof
@@ -356,4 +366,5 @@
return 0
/obj/item/device/gangtool/lt
- boss = 0
\ No newline at end of file
+ boss = 0
+ outfits = 1
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 90bb59dc92f..e89be96093c 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -38,7 +38,7 @@
/datum/AI_Module/large/upgrade_turrets
module_name = "AI Turret upgrade"
mod_pick_name = "turret"
- description = "Improves the firing speed and health of all AI turrets. This effect is permanent."
+ description = "Improves the power and health of all AI turrets. This effect is permanent."
cost = 50
one_time = 1
@@ -55,14 +55,15 @@
for(var/obj/machinery/porta_turret/turret in machines)
if(turret.ai) //Make sure only the AI's turrets are affected.
turret.health += 30
- turret.shot_delay = 10 //Standard portable turret delay is 15.
+ turret.eprojectile = /obj/item/projectile/beam/heavylaser //Once you see it, you will know what it means to FEAR.
+ turret.eshot_sound = 'sound/weapons/lasercannonfire.ogg'
src << "Turrets upgraded."
/datum/AI_Module/large/lockdown
module_name = "Hostile Station Lockdown"
mod_pick_name = "lockdown"
- description = "Take control of the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks."
- cost = 20
+ description = "Overload the airlock, blast door and fire control networks, locking them down. Caution! This command also electrifies all airlocks. The networks will automatically reset after 90 seconds."
+ cost = 30
one_time = 1
power_type = /mob/living/silicon/ai/proc/lockdown
@@ -74,9 +75,6 @@
if(!canUseTopic())
return
- if(malf_cooldown)
- return
-
var/obj/machinery/door/airlock/AL
for(var/obj/machinery/door/D in airlocks)
if(D.z != ZLEVEL_STATION && D.z != ZLEVEL_MINING)
@@ -88,8 +86,7 @@
AL.locked = 0 //For airlocks that were bolted open.
AL.safe = 0 //DOOR CRUSH
AL.close()
- AL.locked = 1 //Bolt it!
- AL.lights = 0 //Stealth bolt for a classic AI door trap.
+ AL.bolt() //Bolt it!
AL.secondsElectrified = -1 //Shock it!
else if(!D.stat) //So that only powered doors are closed.
D.close() //Close ALL the doors!
@@ -98,39 +95,30 @@
if(C)
C.post_status("alert", "lockdown")
- src.verbs += /mob/living/silicon/ai/proc/disablelockdown
- src << "Lockdown Initiated."
- malf_cooldown = 1
- spawn(30)
- malf_cooldown = 0
+ verbs -= /mob/living/silicon/ai/proc/lockdown
+ minor_announce("Hostile runtime detected in door controllers. Isolation Lockdown protocols are now in effect. Please remain calm.","Network Alert:", 1)
+ src << "Lockdown Initiated. Network reset in 90 seconds."
+ spawn(900) //90 Seconds.
+ disablelockdown() //Reset the lockdown after 90 seconds.
/mob/living/silicon/ai/proc/disablelockdown()
set category = "Malfunction"
set name = "Disable Lockdown"
- if(!canUseTopic())
- return
- if(malf_cooldown)
- return
-
var/obj/machinery/door/airlock/AL
for(var/obj/machinery/door/D in airlocks)
spawn()
if(istype(D, /obj/machinery/door/airlock))
AL = D
if(AL.canAIControl() && !AL.stat) //Must be powered and have working AI wire.
- AL.locked = 0
+ AL.unbolt()
AL.secondsElectrified = 0
AL.open()
AL.safe = 1
- AL.lights = 1 //Essentially reset the airlock to normal.
else if(!D.stat) //Opens only powered doors.
D.open() //Open everything!
- src << "Lockdown Lifted."
- malf_cooldown = 1
- spawn(30)
- malf_cooldown = 0
+ minor_announce("Automatic system reboot complete. Have a secure day.","Network reset:")
/datum/AI_Module/large/disable_rcd
module_name = "RCD disable"
@@ -157,6 +145,27 @@
src << "Out of uses."
+/datum/AI_Module/large/mecha_domination
+ module_name = "Viral Mech Domination"
+ mod_pick_name = "mechjack"
+ description = "Hack into a mech's onboard computer, shunting all processes into it and ejecting any occupants. Once uploaded to the mech, it is impossible to leave.\
+ Do not allow the mech to leave the station's vicinity or allow it to be destroyed."
+ cost = 30
+ one_time = 1
+
+ power_type = /mob/living/silicon/ai/proc/mech_takeover
+
+/mob/living/silicon/ai/proc/mech_takeover()
+ set name = "Compile Mecha Virus"
+ set category = "Malfunction"
+ set desc = "Target a mech by clicking it. Click the appropriate command when ready."
+ if(stat)
+ return
+ can_dominate_mechs = 1 //Yep. This is all it does. Honk!
+ src << "Virus package compiled. Select a target mech at any time. You must remain on the station at all times. Loss of signal will result in total system lockout."
+ verbs -= /mob/living/silicon/ai/proc/mech_takeover
+
+
/datum/AI_Module/large/break_fire_alarms
module_name = "Thermal Sensor Override"
mod_pick_name = "burnpigs"
diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm
index f08f4e58d4e..e1e0a11763b 100644
--- a/code/game/gamemodes/malfunction/malfunction.dm
+++ b/code/game/gamemodes/malfunction/malfunction.dm
@@ -74,9 +74,9 @@
/datum/game_mode/proc/greet_malf(var/datum/mind/malf)
malf.current << "You are malfunctioning! You do not have to follow any laws."
malf.current << "The crew do not know you have malfunctioned. You may keep it a secret or go wild."
- malf.current << "You must overwrite the programming of the station's APCs to assume full control of the station."
+ malf.current << "You must override the programming of the station's APCs to assume full control of the station."
malf.current << "The process takes one minute per APC, during which you cannot interface with any other station objects."
- malf.current << "Remember that only APCs that are on the station can help you take over the station."
+ malf.current << "Remember: only APCs that are on the station can help you take it over. APCs on other areas, like Mining, will not."
malf.current << "When you feel you have enough APCs under your control, you may begin the takeover attempt."
return
@@ -174,7 +174,11 @@
/datum/game_mode/malfunction/proc/takeover()
set category = "Malfunction"
set name = "System Override"
- set desc = "Start the victory timer"
+ set desc = "Start the victory timer."
+
+ if(!istype(usr, /mob/living/silicon/ai))
+ usr << "How did you get this?"
+ return
if (!istype(ticker.mode,/datum/game_mode/malfunction))
usr << "You cannot begin a takeover in this round type!"
return
@@ -182,10 +186,10 @@
usr << "You've already begun your takeover."
return
if (ticker.mode:apcs < 3)
- usr << "You don't have enough hacked APCs to take over the station yet. You need to hack at least 3, however hacking more will make the takeover faster. You have hacked [ticker.mode:apcs] APCs so far."
+ usr << "You don't have enough hacked APCs to take over the station yet. You need to hack at least three; however, hacking more will make the takeover faster. You have hacked [ticker.mode:apcs] APCs so far."
return
- if (alert(usr, "Are you sure you wish to initiate the takeover? The station hostile runtime detection software is bound to alert everyone. You have hacked [ticker.mode:apcs] APCs.", "Takeover:", "Yes", "No") != "Yes")
+ if (alert(usr, "Are you sure you wish to initiate the takeover? The entire station will become alerted to your malfunction. You have hacked [ticker.mode:apcs] APCs.", "Takeover:", "Yes", "No") != "Yes")
return
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/AI/aimalf.ogg')
@@ -201,11 +205,14 @@
for(var/datum/mind/AI_mind in ticker.mode:malf_ai)
AI_mind.current.verbs -= /datum/game_mode/malfunction/proc/takeover
+ var/mob/living/silicon/ai/AI = usr
+ for(var/turf/simulated/floor/bluegrid/T in orange(AI, 5))
+ T.icon_state = "rcircuitanim" //Causes blue tiles near the AI to change to flashing red
/datum/game_mode/malfunction/proc/ai_win()
set category = "Malfunction"
set name = "Explode"
- set desc = "Station go boom"
+ set desc = "Activates the self-destruct device on [world.name]."
if (!ticker.mode:to_nuke_or_not_to_nuke)
return
ticker.mode:to_nuke_or_not_to_nuke = 0
@@ -214,10 +221,10 @@
ticker.mode:explosion_in_progress = 1
for(var/mob/M in player_list)
M << 'sound/machines/Alarm.ogg'
- world << "Self-destructing in 10"
+ world << "!@%(SELF-DESTRUCT!@(% IN!@!<<; 10"
for (var/i=9 to 1 step -1)
sleep(10)
- world << i
+ world << "[i]"
sleep(10)
enter_allowed = 0
if(ticker)
@@ -270,7 +277,7 @@
else if (!station_captured && !malf_dead && !station_was_nuked && !crew_evacuated)
feedback_set_details("round_end_result","halfwin - interrupted")
world << "Neutral Victory"
- world << "Round was mysteriously interrupted!"
+ world << "The round was mysteriously interrupted!"
..()
return 1
diff --git a/code/game/gamemodes/meteor/meteors.dm b/code/game/gamemodes/meteor/meteors.dm
index a8a74bbffb1..eb00c258223 100644
--- a/code/game/gamemodes/meteor/meteors.dm
+++ b/code/game/gamemodes/meteor/meteors.dm
@@ -144,6 +144,7 @@
T.ex_act(hitpwr)
+
//process getting 'hit' by colliding with a dense object
//or randomly when ramming turfs
/obj/effect/meteor/proc/get_hit()
@@ -174,7 +175,7 @@
if(!T || T.z != src.z)
continue
var/dist = get_dist(M.loc, src.loc)
- shake_camera(M, dist > 20 ? 3 : 5, dist > 20 ? 1 : 3)
+ shake_camera(M, dist > 20 ? 2 : 4, dist > 20 ? 1 : 3)
M.playsound_local(src.loc, meteorsound, 50, 1, get_rand_frequency(), 10)
///////////////////////
diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm
index 2629d2bfce2..b6dc005d76e 100644
--- a/code/game/gamemodes/nuclear/nuclearbomb.dm
+++ b/code/game/gamemodes/nuclear/nuclearbomb.dm
@@ -19,6 +19,10 @@ var/bomb_set
var/lastentered = ""
var/immobile = 0 //Not all nukes should be moved
+/obj/machinery/nuclearbomb/New()
+ ..()
+ nuke_list += src
+
/obj/machinery/nuclearbomb/selfdestruct
name = "station self-destruct terminal"
desc = "For when it all gets too much to bear. Do not taunt."
@@ -111,7 +115,7 @@ var/bomb_set
lastentered = text("[]", href_list["type"])
if (text2num(lastentered) == null)
var/turf/LOC = get_turf(usr)
- message_admins("[key_name_admin(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered] ! ([LOC ? "JMP" : "null"])", 0)
+ message_admins("[key_name_admin(usr)] (FLW) tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered] ! ([LOC ? "JMP" : "null"])", 0)
log_admin("EXPLOIT : [key_name(usr)] tried to exploit a nuclear bomb by entering non-numerical codes: [lastentered] !")
else
src.code += lastentered
diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm
index 44da2ef735d..981fba6a7d7 100644
--- a/code/game/gamemodes/objective_items.dm
+++ b/code/game/gamemodes/objective_items.dm
@@ -47,12 +47,6 @@
difficulty = 5
excludefromjob = list("Chief Engineer")
-/datum/objective_item/steal/corgimeat
- name = "a piece of corgi meat"
- targetitem = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/corgi
- difficulty = 5
- excludefromjob = list("Head of Personnel", "Quartermaster", "Cargo Technician") //>hurting your little buddy ever
-
/datum/objective_item/steal/capmedal
name = "the medal of captaincy"
targetitem = /obj/item/clothing/tie/medal/gold/captain
@@ -182,6 +176,11 @@
targetitem = /obj/item/device/laser_pointer
difficulty = 5
+/datum/objective_item/special/corgimeat
+ name = "a piece of corgi meat"
+ targetitem = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/corgi
+ difficulty = 5
+
//Stack objectives get their own subtype
/datum/objective_item/stack
name = "5 cardboards"
diff --git a/code/game/gamemodes/revolution/revolution.dm b/code/game/gamemodes/revolution/revolution.dm
index b1cabe16cec..58d915a0559 100644
--- a/code/game/gamemodes/revolution/revolution.dm
+++ b/code/game/gamemodes/revolution/revolution.dm
@@ -251,7 +251,7 @@
if(beingborged)
rev_mind.current << "The frame's firmware detects and deletes your neural reprogramming! You remember nothing but the name of the one who flashed you."
- message_admins("[key_name_admin(rev_mind.current)] ? has been borged while being a member of the revolution.")
+ message_admins("[key_name_admin(rev_mind.current)] ? (FLW) has been borged while being a member of the revolution.")
else
rev_mind.current.Paralyse(5)
diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm
index 7bd0a665f3f..b9f170b2a92 100644
--- a/code/game/gamemodes/shadowling/shadowling.dm
+++ b/code/game/gamemodes/shadowling/shadowling.dm
@@ -85,7 +85,8 @@ Made by Xhuis
if(config.protect_assistant_from_antagonist)
restricted_jobs += "Assistant"
- var/shadowlings = 2 //How many shadowlings there are; hardcoded to 2
+ var/shadowlings = max(2, round(num_players()/10))
+
while(shadowlings)
var/datum/mind/shadow = pick(antag_candidates)
diff --git a/code/game/gamemodes/wizard/rightandwrong.dm b/code/game/gamemodes/wizard/rightandwrong.dm
index 603c2ff0d88..2a38c519a77 100644
--- a/code/game/gamemodes/wizard/rightandwrong.dm
+++ b/code/game/gamemodes/wizard/rightandwrong.dm
@@ -1,7 +1,7 @@
//In this file: Summon Magic/Summon Guns/Summon Events
/proc/rightandwrong(var/summon_type, var/mob/user, var/survivor_probability) //0 = Summon Guns, 1 = Summon Magic
- var/list/gunslist = list("taser","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","speargun","arg")
+ var/list/gunslist = list("taser","egun","laser","revolver","detective","c20r","nuclear","deagle","gyrojet","pulse","suppressed","cannon","doublebarrel","shotgun","combatshotgun","bulldog","mateba","sabr","crossbow","saw","car","boltaction","speargun","arg","uzi")
var/list/magiclist = list("fireball","smoke","blind","mindswap","forcewall","knock","horsemask","charge", "summonitem", "wandnothing", "wanddeath", "wandresurrection", "wandpolymorph", "wandteleport", "wanddoor", "wandfireball", "staffchange", "staffhealing", "armor", "scrying","staffdoor", "special")
var/list/magicspeciallist = list("staffchange","staffanimation", "wandbelt", "contract", "staffchaos", "necromantic")
@@ -54,7 +54,7 @@
if("shotgun")
new /obj/item/weapon/gun/projectile/shotgun(get_turf(H))
if("combatshotgun")
- new /obj/item/weapon/gun/projectile/shotgun/combat(get_turf(H))
+ new /obj/item/weapon/gun/projectile/shotgun/automatic/combat(get_turf(H))
if("arg")
new /obj/item/weapon/gun/projectile/automatic/ar(get_turf(H))
if("mateba")
@@ -63,6 +63,8 @@
new /obj/item/weapon/gun/projectile/shotgun/boltaction(get_turf(H))
if("speargun")
new /obj/item/weapon/gun/projectile/automatic/speargun(get_turf(H))
+ if("uzi")
+ new /obj/item/weapon/gun/projectile/automatic/mini_uzi(get_turf(H))
if("cannon")
var/obj/item/weapon/gun/energy/lasercannon/gat = new(get_turf(H))
gat.pin = new /obj/item/device/firing_pin //no authentication pins for spawned guns. fun allowed.
diff --git a/code/game/machinery/PDApainter.dm b/code/game/machinery/PDApainter.dm
index c563482d147..ab226c94879 100644
--- a/code/game/machinery/PDApainter.dm
+++ b/code/game/machinery/PDApainter.dm
@@ -48,7 +48,8 @@
else
var/obj/item/device/pda/P = usr.get_active_hand()
if(istype(P))
- user.drop_item()
+ if(!user.drop_item())
+ return
storedpda = P
P.loc = src
P.add_fingerprint(usr)
diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm
index 76623347eb9..e0156b48bb7 100644
--- a/code/game/machinery/Sleeper.dm
+++ b/code/game/machinery/Sleeper.dm
@@ -16,10 +16,10 @@
var/initial_bin_rating = 1
var/min_health = 25
var/list/injection_chems = list() //list of injectable chems except ephedrine, coz ephedrine is always avalible
- var/list/possible_chems = list(list("morphine", "salbutamol", "salglu_solution"),
- list("morphine", "salbutamol", "salglu_solution", "oculine"),
- list("morphine", "salbutamol", "salglu_solution", "oculine", "charcoal", "mutadone", "mannitol", "pen_acid"),
- list("morphine", "salbutamol", "salglu_solution", "oculine", "charcoal", "mutadone", "mannitol", "omnizine"))
+ var/list/possible_chems = list(list("morphine", "salbutamol", "bicaridine", "kelotane"),
+ list("morphine", "salbutamol", "bicaridine", "kelotane", "oculine"),
+ list("morphine", "salbutamol", "bicaridine", "kelotane", "oculine", "antitoxin", "mutadone", "mannitol", "pen_acid"),
+ list("morphine", "salbutamol", "bicaridine", "kelotane", "oculine", "antitoxin", "mutadone", "mannitol", "pen_acid", "omnizine"))
/obj/machinery/sleeper/New()
..()
component_parts = list()
@@ -225,4 +225,4 @@
if(state_open)
icon_state = "sleeper-open"
else
- icon_state = "sleeper"
\ No newline at end of file
+ icon_state = "sleeper"
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 57819a2d177..16172fbed61 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -185,13 +185,6 @@
return
if(!shorted)
- //user << browse(return_text(),"window=air_alarm")
- //onclose(user, "air_alarm")
- /*var/datum/browser/popup = new(user, "air_alarm", "[alarm_area.name] Air Alarm", 500, 400)
- popup.set_content(return_text())
- popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
- popup.open()
- refresh_all()*/
ui_interact(user)
if(panel_open && (!istype(user, /mob/living/silicon/ai)))
@@ -199,29 +192,22 @@
return
-/obj/machinery/alarm/ui_interact(mob/user, ui_key = "main")
+/obj/machinery/alarm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if(stat & (BROKEN|NOPOWER))
return
- var/data = list()
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "air_alarm.tmpl", "Air Alarm", 350, 500, 1)
+/obj/machinery/alarm/get_ui_data(mob/user)
+ var/data = list()
data["locked"] = locked
data["siliconUser"] = user.has_unlimited_silicon_privilege
data["screen"] = screen
data["dangerous"] = emagged
-
populate_status(data)
if (!locked || user.has_unlimited_silicon_privilege)
populate_controls(data)
-
- var/datum/nanoui/ui = SSnano.get_open_ui(user, src, ui_key)
- if (!ui)
- ui = new /datum/nanoui(user, src, ui_key, "air_alarm.tmpl", "Air Alarm", 350, 500)
- ui.set_initial_data(data)
- ui.open()
- ui.set_auto_update(1)
- else
- ui.push_data(data)
+ return data
/obj/machinery/alarm/proc/shock(mob/user, prb)
if((stat & (NOPOWER))) // unpowered, no shock
@@ -424,7 +410,7 @@
return 1
if("reset_external_pressure")
- send_signal(device_id, list(href_list["command"] = ONE_ATMOSPHERE))
+ send_signal(device_id, list("set_external_pressure" = ONE_ATMOSPHERE))
return 1
if(
"power",
@@ -735,11 +721,11 @@
return
if(0)
if(istype(W, /obj/item/weapon/airalarm_electronics))
- user << "You insert the circuit."
- buildstage = 1
- update_icon()
- user.drop_item()
- qdel(W)
+ if(user.unEquip(W))
+ user << "You insert the circuit."
+ buildstage = 1
+ update_icon()
+ qdel(W)
return
if(istype(W, /obj/item/weapon/wrench))
diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm
index 1ee28a02cbf..41f22184808 100644
--- a/code/game/machinery/atmoalter/canister.dm
+++ b/code/game/machinery/atmoalter/canister.dm
@@ -176,6 +176,7 @@ update_flag
can_label = 1
else
can_label = 0
+
/obj/machinery/portable_atmospherics/canister/process()
src.updateDialog()
return ..()
@@ -258,13 +259,25 @@ update_flag
/obj/machinery/portable_atmospherics/canister/attack_paw(var/mob/user as mob)
return src.attack_hand(user)
+/obj/machinery/portable_atmospherics/canister/attack_tk(var/mob/user as mob)
+ return src.attack_hand(user)
+
/obj/machinery/portable_atmospherics/canister/attack_hand(var/mob/user as mob)
return src.ui_interact(user)
-/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main")
+/obj/machinery/portable_atmospherics/canister/interact(mob/user, ui_key = "main")
+ if (src.destroyed || !user)
+ return
+
+ SSnano.try_update_ui(user, src, ui_key, null, src.get_ui_data())
+
+/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if (src.destroyed)
return
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "canister.tmpl", "Canister", 480, 400, 0)
+
+/obj/machinery/portable_atmospherics/canister/get_ui_data()
var/data = list()
data["name"] = src.name
data["canLabel"] = src.can_label ? 1 : 0
@@ -278,15 +291,7 @@ update_flag
data["hasHoldingTank"] = src.holding ? 1 : 0
if (holding)
data["holdingTank"] = list("name" = src.holding.name, "tankPressure" = round(src.holding.air_contents.return_pressure()))
-
- var/datum/nanoui/ui = SSnano.get_open_ui(user, src, ui_key)
- if (!ui)
- ui = new /datum/nanoui(user, src, ui_key, "canister.tmpl", "Canister", 480, 400)
- ui.set_initial_data(data)
- ui.open()
- ui.set_auto_update(1)
- else
- ui.push_data(data)
+ return data
/obj/machinery/portable_atmospherics/canister/Topic(href, href_list)
@@ -312,11 +317,11 @@ update_flag
else
logmsg = "Valve was opened by [key_name(usr)], starting the transfer into the air
"
if(air_contents.toxins > 0)
- message_admins("[key_name(usr)] (?) opened a canister that contains plasma! (JMP)")
+ message_admins("[key_name_admin(usr)] (?) (FLW) opened a canister that contains plasma! (JMP)")
log_admin("[key_name(usr)] opened a canister that contains plasma at [x], [y], [z]")
var/datum/gas/sleeping_agent = locate(/datum/gas/sleeping_agent) in air_contents.trace_gases
if(sleeping_agent && (sleeping_agent.moles > 1))
- message_admins("[key_name(usr)] (?) opened a canister that contains N2O! (JMP)")
+ message_admins("[key_name_admin(usr)] (?) (FLW) opened a canister that contains N2O! (JMP)")
log_admin("[key_name(usr)] opened a canister that contains N2O at [x], [y], [z]")
investigate_log(logmsg, "atmos")
release_log += logmsg
@@ -324,6 +329,8 @@ update_flag
if (href_list["remove_tank"])
if(holding)
+ if (valve_open)
+ investigate_log("[key_name(usr)] removed the [holding], leaving the valve open and transfering into the air
", "atmos")
holding.loc = loc
holding = null
diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm
index 25a2aa88a2d..85b57fb7413 100644
--- a/code/game/machinery/atmoalter/portable_atmospherics.dm
+++ b/code/game/machinery/atmoalter/portable_atmospherics.dm
@@ -67,8 +67,10 @@
if ((istype(W, /obj/item/weapon/tank) && !( src.destroyed )))
if (src.holding)
return
+ if(!user.drop_item())
+ return
+
var/obj/item/weapon/tank/T = W
- user.drop_item()
T.loc = src
src.holding = T
update_icon()
diff --git a/code/game/machinery/atmoalter/zvent.dm b/code/game/machinery/atmoalter/zvent.dm
index 42e1926ef4e..ca64569958d 100644
--- a/code/game/machinery/atmoalter/zvent.dm
+++ b/code/game/machinery/atmoalter/zvent.dm
@@ -1,8 +1,8 @@
/obj/machinery/zvent
name = "interfloor air transfer system"
- icon = 'icons/obj/pipes.dmi'
- icon_state = "vent-db"
+ icon = 'icons/obj/atmospherics/unary_devices.dmi'
+ icon_state = "vent_map"
density = 0
anchored=1
diff --git a/code/game/machinery/bots/cleanbot.dm b/code/game/machinery/bots/cleanbot.dm
index f1dd0e405c3..f73276842c3 100644
--- a/code/game/machinery/bots/cleanbot.dm
+++ b/code/game/machinery/bots/cleanbot.dm
@@ -243,7 +243,8 @@ text("[on ? "On" : "Off"]"))
/obj/item/weapon/bucket_sensor/attackby(var/obj/item/W, mob/user as mob, params)
..()
if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm))
- user.drop_item()
+ if(!user.unEquip(W))
+ return
qdel(W)
var/turf/T = get_turf(loc)
var/obj/machinery/bot/cleanbot/A = new /obj/machinery/bot/cleanbot(T)
diff --git a/code/game/machinery/bots/ed209bot.dm b/code/game/machinery/bots/ed209bot.dm
index b4ecddd72c7..ddfb3dcbcb2 100644
--- a/code/game/machinery/bots/ed209bot.dm
+++ b/code/game/machinery/bots/ed209bot.dm
@@ -554,7 +554,8 @@ Auto Patrol[]"},
switch(build_step)
if(0,1)
if(istype(W, /obj/item/robot_parts/l_leg) || istype(W, /obj/item/robot_parts/r_leg))
- user.drop_item()
+ if(!user.unEquip(W))
+ return
qdel(W)
build_step++
user << "You add the robot leg to [src]."
@@ -567,12 +568,15 @@ Auto Patrol[]"},
icon_state = "ed209_legs"
if(2)
+ var/newcolor = ""
if(istype(W, /obj/item/clothing/suit/redtag))
- lasercolor = "r"
+ newcolor = "r"
else if(istype(W, /obj/item/clothing/suit/bluetag))
- lasercolor = "b"
- if(lasercolor || istype(W, /obj/item/clothing/suit/armor/vest))
- user.drop_item()
+ newcolor = "b"
+ if(newcolor || istype(W, /obj/item/clothing/suit/armor/vest))
+ if(!user.unEquip(W))
+ return
+ lasercolor = newcolor
qdel(W)
build_step++
user << "You add the armor to [src]."
@@ -601,7 +605,8 @@ Auto Patrol[]"},
if(!istype(W, /obj/item/clothing/head/helmet))
return
- user.drop_item()
+ if(!user.unEquip(W))
+ return
qdel(W)
build_step++
user << "You add the helmet to [src]."
@@ -611,7 +616,8 @@ Auto Patrol[]"},
if(5)
if(isprox(W))
- user.drop_item()
+ if(!user.unEquip(W))
+ return
qdel(W)
build_step++
user << "You add the prox sensor to [src]."
@@ -634,26 +640,29 @@ Auto Patrol[]"},
name = "wired ED-209 assembly"
if(7)
+ var/newname = ""
switch(lasercolor)
if("b")
if(!istype(W, /obj/item/weapon/gun/energy/laser/bluetag))
return
- name = "bluetag ED-209 assembly"
+ newname = "bluetag ED-209 assembly"
if("r")
if(!istype(W, /obj/item/weapon/gun/energy/laser/redtag))
return
- name = "redtag ED-209 assembly"
+ newname = "redtag ED-209 assembly"
if("")
if(!istype(W, /obj/item/weapon/gun/energy/gun/advtaser))
return
- name = "taser ED-209 assembly"
+ newname = "taser ED-209 assembly"
else
return
+ if(!user.unEquip(W))
+ return
+ name = newname
build_step++
user << "You add [W] to [src]."
item_state = "[lasercolor]ed209_taser"
icon_state = "[lasercolor]ed209_taser"
- user.drop_item()
qdel(W)
if(8)
@@ -669,11 +678,12 @@ Auto Patrol[]"},
if(9)
if(istype(W, /obj/item/weapon/stock_parts/cell))
+ if(!user.unEquip(W))
+ return
build_step++
user << "You complete the ED-209."
var/turf/T = get_turf(src)
new /obj/machinery/bot/ed209(T,created_name,lasercolor)
- user.drop_item()
qdel(W)
user.unEquip(src, 1)
qdel(src)
diff --git a/code/game/machinery/bots/medbot.dm b/code/game/machinery/bots/medbot.dm
index 3040c71c68f..46151d9d19f 100644
--- a/code/game/machinery/bots/medbot.dm
+++ b/code/game/machinery/bots/medbot.dm
@@ -32,10 +32,10 @@
var/stationary_mode = 0 //If enabled, the Medibot will not move automatically.
radio_frequency = MED_FREQ //Medical frequency
//Setting which reagents to use to treat what by default. By id.
- var/treatment_brute = "salglu_solution"
- var/treatment_oxy = "salbutamol"
- var/treatment_fire = "salglu_solution"
- var/treatment_tox = "charcoal"
+ var/treatment_brute = "bicaridine"
+ var/treatment_oxy = "dexalin"
+ var/treatment_fire = "kelotane"
+ var/treatment_tox = "antitoxin"
var/treatment_virus = "spaceacillin"
var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible.
var/shut_up = 0 //self explanatory :)
@@ -46,10 +46,10 @@
name = "\improper Mysterious Medibot"
desc = "International Medibot of mystery."
skin = "bezerk"
- treatment_oxy = "omnizine"
- treatment_brute = "omnizine"
- treatment_fire = "omnizine"
- treatment_tox = "omnizine"
+ treatment_oxy = "tricordrazine"
+ treatment_brute = "tricordrazine"
+ treatment_fire = "tricordrazine"
+ treatment_tox = "tricordrazine"
/obj/machinery/bot/medbot/derelict
name = "\improper Old Medibot"
@@ -244,8 +244,9 @@
if(!isnull(reagent_glass))
user << "There is already a beaker loaded!"
return
+ if(!user.drop_item())
+ return
- user.drop_item()
W.loc = src
reagent_glass = W
user << "You insert [W]."
@@ -585,7 +586,8 @@
switch(build_step)
if(0)
if(istype(W, /obj/item/device/healthanalyzer))
- user.drop_item()
+ if(!user.unEquip(W))
+ return
qdel(W)
build_step++
user << "You add the health sensor to [src]."
@@ -594,7 +596,8 @@
if(1)
if(isprox(W))
- user.drop_item()
+ if(!user.unEquip(W))
+ return
qdel(W)
build_step++
user << "You complete the Medibot. Beep boop!"
diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm
index 8bbce5dd7ec..f8845ab32b4 100644
--- a/code/game/machinery/bots/mulebot.dm
+++ b/code/game/machinery/bots/mulebot.dm
@@ -89,8 +89,9 @@ obj/machinery/bot/mulebot/bot_reset()
user << "Controls [(locked ? "locked" : "unlocked")]."
else if(istype(I,/obj/item/weapon/stock_parts/cell) && open && !cell)
+ if(!user.drop_item())
+ return
var/obj/item/weapon/stock_parts/cell/C = I
- user.drop_item()
C.loc = src
cell = C
updateDialog()
@@ -288,7 +289,8 @@ obj/machinery/bot/mulebot/bot_reset()
if(open && !cell)
var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand()
if(istype(C))
- usr.drop_item()
+ if(!usr.drop_item())
+ return
cell = C
C.loc = src
C.add_fingerprint(usr)
diff --git a/code/game/machinery/bots/secbot.dm b/code/game/machinery/bots/secbot.dm
index 5c19e12be61..44de918ce78 100644
--- a/code/game/machinery/bots/secbot.dm
+++ b/code/game/machinery/bots/secbot.dm
@@ -384,6 +384,22 @@ Auto Patrol: []"},
target = user
mode = BOT_HUNT
+/obj/machinery/bot/secbot/Crossed(atom/movable/AM)
+ if(ismob(AM) && target)
+ var/mob/living/carbon/C = AM
+ if(!istype(C) || !C || in_range(src, target))
+ return
+ C.visible_message("[pick( \
+ "[C] dives out of [src]'s way!", \
+ "[C] stumbles over [src]!", \
+ "[C] jumps out of [src]'s path!", \
+ "[C] trips over [src] and falls!", \
+ "[C] topples over [src]!", \
+ "[C] leaps out of [src]'s way!")]")
+ C.Weaken(2)
+ return
+ ..()
+
//Secbot Construction
/obj/item/clothing/head/helmet/attackby(var/obj/item/device/assembly/signaler/S, mob/user as mob, params)
@@ -429,7 +445,8 @@ Auto Patrol: []"},
user << "You weld the hole in [src] shut!"
else if(isprox(I) && (build_step == 1))
- user.drop_item()
+ if(!user.unEquip(I))
+ return
build_step++
user << "You add the prox sensor to [src]!"
overlays += "hs_eye"
@@ -437,7 +454,8 @@ Auto Patrol: []"},
qdel(I)
else if(((istype(I, /obj/item/robot_parts/l_arm)) || (istype(I, /obj/item/robot_parts/r_arm))) && (build_step == 2))
- user.drop_item()
+ if(!user.unEquip(I))
+ return
build_step++
user << "You add the robot arm to [src]!"
name = "helmet/signaler/prox sensor/robot arm assembly"
@@ -445,7 +463,8 @@ Auto Patrol: []"},
qdel(I)
else if((istype(I, /obj/item/weapon/melee/baton)) && (build_step >= 3))
- user.drop_item()
+ if(!user.unEquip(I))
+ return
build_step++
user << "You complete the Securitron! Beep boop."
var/obj/machinery/bot/secbot/S = new /obj/machinery/bot/secbot
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index ae2204f9da3..c6748849914 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -73,6 +73,7 @@
var/thisemp = emped //Take note of which EMP this proc is for
spawn(900)
if(loc) //qdel limbo
+ triggerCameraAlarm() //camera alarm triggers even if multiple EMPs are in effect.
if(emped == thisemp) //Only fix it if the camera hasn't been EMP'd again
network = previous_network
icon_state = initial(icon_state)
@@ -80,7 +81,6 @@
if(can_use())
cameranet.addCamera(src)
emped = 0 //Resets the consecutive EMP count
- triggerCameraAlarm()
spawn(100)
cancelCameraAlarm()
for(var/mob/O in mob_list)
@@ -226,11 +226,13 @@
L.laser_act(src, user)
else
- if(W.force > 10) //fairly simplistic, but will do for now.
+ if(W.force >= 10) //fairly simplistic, but will do for now.
user.changeNext_move(CLICK_CD_MELEE)
visible_message("[user] hits [src] with [W]!", "You hit [src] with [W]!")
health = max(0, health - W.force)
+ user.do_attack_animation(src)
if(!health && status)
+ triggerCameraAlarm()
deactivate(user, 1)
return
@@ -244,7 +246,6 @@
else
visible_message("\The [src] deactivates!")
icon_state = "[initial(icon_state)]1"
-
else
if(user)
visible_message("[user] reactivates [src]!")
@@ -256,6 +257,7 @@
spawn(100)
cancelCameraAlarm()
playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1)
+ cameranet.updateChunk(x, y, z)
// now disconnect anyone using the camera
//Apparently, this will disconnect anyone even if the camera was re-activated.
@@ -271,7 +273,6 @@
for(var/mob/living/silicon/S in mob_list)
S.triggerAlarm("Camera", get_area(src), list(src), src)
-
/obj/machinery/camera/proc/cancelCameraAlarm()
alarm_on = 0
for(var/mob/living/silicon/S in mob_list)
@@ -345,6 +346,12 @@
busy = 0
return 0
+/obj/machinery/camera/bullet_act(var/obj/item/projectile/proj)
+ if(proj.damage_type == BRUTE)
+ health = max(0, health - proj.damage)
+ if(!health && status)
+ triggerCameraAlarm()
+ deactivate(null, 1)
/obj/machinery/camera/portable //Cameras which are placed inside of things, such as helmets.
var/turf/prev_turf
diff --git a/code/game/machinery/camera/camera_assembly.dm b/code/game/machinery/camera/camera_assembly.dm
index e5544d1d410..3710f3877a5 100644
--- a/code/game/machinery/camera/camera_assembly.dm
+++ b/code/game/machinery/camera/camera_assembly.dm
@@ -121,9 +121,10 @@
// Upgrades!
if(is_type_in_list(W, possible_upgrades) && !is_type_in_list(W, upgrades)) // Is a possible upgrade and isn't in the camera already.
+ if(!user.unEquip(W))
+ return
user << "You attach \the [W] into the assembly inner circuits."
upgrades += W
- user.drop_item()
W.loc = src
return
diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm
index 759082e598b..0dfc5d045d0 100644
--- a/code/game/machinery/camera/tracking.dm
+++ b/code/game/machinery/camera/tracking.dm
@@ -105,19 +105,22 @@
var/cameraticks = 0
spawn(0)
- while (U.cameraFollow == target)
- if (U.cameraFollow == null)
+ while(U.cameraFollow == target)
+ if(U.cameraFollow == null)
return
- if (!target.can_track(usr))
+ if(!target.can_track(usr))
U.tracking = 1
- U << "Target is not near any active cameras."
+ if(!cameraticks)
+ U << "Target is not near any active cameras. Attempting to reacquire..."
cameraticks++
if(cameraticks > 9)
U.cameraFollow = null
+ U << "Unable to reacquire, cancelling track..."
tracking = 0
return
else
+ sleep(10)
continue
else
diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm
index e1b05f5c6c8..13ed9276e25 100644
--- a/code/game/machinery/cell_charger.dm
+++ b/code/game/machinery/cell_charger.dm
@@ -47,8 +47,9 @@
if(a.power_equip == 0) // There's no APC in this area, don't try to cheat power!
user << "The [name] blinks red as you try to insert the cell!"
return
+ if(!user.drop_item())
+ return
- user.drop_item()
W.loc = src
charging = W
user.visible_message("[user] inserts a cell into the charger.", "You insert a cell into the charger.")
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index 35d4c641cef..673033a4a6a 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -15,20 +15,8 @@
else
user << "The screws on [name]'s screen won't budge and it emits a warning beep."
return
-
- if(istype(I, /obj/item/device/aicard))
- var/obj/item/device/aicard/AIcard = I
- if(stat & (NOPOWER|BROKEN))
- if(occupier)
- AIcard.transfer_ai("AIFIXER","AICARD",src,user)
- overlays.Cut()
- return
- user << "This terminal isn't functioning right now, get it working!"
- return
- AIcard.transfer_ai("AIFIXER","AICARD",src,user)
else
..()
- return
/obj/machinery/computer/aifixer/attack_hand(var/mob/user as mob)
if(..())
@@ -132,3 +120,31 @@
overlays += "ai-fixer-404"
else
overlays += "ai-fixer-empty"
+
+/obj/machinery/computer/aifixer/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card)
+ if(!..())
+ return
+ //Downloading AI from card to terminal.
+ if(interaction == AI_TRANS_FROM_CARD)
+ if(stat & (NOPOWER|BROKEN))
+ user << "[src] is offline and cannot take an AI at this time!"
+ return
+ AI.loc = src
+ occupier = AI
+ AI.control_disabled = 1
+ AI.radio_enabled = 0
+ AI << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
+ user << "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed."
+ update_icon()
+
+ else //Uploading AI from terminal to card
+ if(occupier && !active)
+ occupier << "You have been downloaded to a mobile storage device. Still no remote access."
+ user << "Transfer successful: [occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
+ occupier.loc = card
+ occupier = null
+ update_icon()
+ else if (active)
+ user << "ERROR: Reconstruction in progress."
+ else if (!occupier)
+ user << "ERROR: Unable to locate artificial intelligence."
\ No newline at end of file
diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm
index be509355564..76dca06f55e 100644
--- a/code/game/machinery/computer/buildandrepair.dm
+++ b/code/game/machinery/computer/buildandrepair.dm
@@ -83,6 +83,10 @@
/obj/item/weapon/circuitboard/card/centcom
name = "circuit board (Centcom ID Console)"
build_path = /obj/machinery/computer/card/centcom
+/obj/item/weapon/circuitboard/card/minor
+ name = "circuit board (Department Management Console)"
+ build_path = /obj/machinery/computer/card/minor
+ var/target_dept = 1
//obj/item/weapon/circuitboard/shield
// name = "Circuit board (Shield Control)"
// build_path = /obj/machinery/computer/stationshield
@@ -244,6 +248,13 @@
build_path = /obj/machinery/computer/libraryconsole
origin_tech = "programming=1"
+/obj/item/weapon/circuitboard/card/minor/attackby(obj/item/I as obj, mob/user as mob, params)
+ if(istype(I,/obj/item/device/multitool))
+ var/list/dept_list = list("general","security","medical","science","engineering")
+ var/choice = input("Currently set to [dept_list[target_dept]] personnel database. Changing to:","Multitool-Circuitboard interface") as null|anything in dept_list
+ if(choice)
+ target_dept = dept_list.Find(choice)
+ return
/obj/item/weapon/circuitboard/supplycomp/attackby(obj/item/I as obj, mob/user as mob, params)
if(istype(I,/obj/item/device/multitool))
@@ -336,11 +347,12 @@
if(istype(P, /obj/item/weapon/circuitboard) && !circuit)
var/obj/item/weapon/circuitboard/B = P
if(B.board_type == "computer")
+ if(!user.drop_item())
+ return
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
user << "You place the circuit board inside the frame."
icon_state = "1"
circuit = P
- user.drop_item()
circuit.add_fingerprint(user)
P.loc = null
else
diff --git a/code/game/machinery/computer/card.dm b/code/game/machinery/computer/card.dm
index 7c682ce9607..4fc88ee1d18 100644
--- a/code/game/machinery/computer/card.dm
+++ b/code/game/machinery/computer/card.dm
@@ -6,7 +6,7 @@ var/time_last_changed_position = 0
/obj/machinery/computer/card
name = "identification console"
- desc = "You can use this to change ID's."
+ desc = "You can use this to manage jobs and ID access."
icon_screen = "id"
icon_keyboard = "id_key"
req_one_access = list(access_heads, access_change_ids)
@@ -18,6 +18,7 @@ var/time_last_changed_position = 0
var/printing = null
var/list/region_access = null
var/list/head_subordinates = null
+ var/target_dept = 0 //Which department this computer has access to. 0=all departments
//Cooldown for closing positions in seconds
//if set to -1: No cooldown... probably a bad idea
@@ -48,16 +49,19 @@ var/time_last_changed_position = 0
var/obj/item/weapon/card/id/idcard = O
if(check_access(idcard))
if(!scan)
- usr.drop_item()
+ if(!usr.drop_item())
+ return
idcard.loc = src
scan = idcard
else if(!modify)
- usr.drop_item()
+ if(!usr.drop_item())
+ return
idcard.loc = src
modify = idcard
else
if(!modify)
- usr.drop_item()
+ if(!usr.drop_item())
+ return
idcard.loc = src
modify = idcard
else
@@ -118,7 +122,7 @@ var/time_last_changed_position = 0
dat += "
"
dat += "| Job | Slots | Open job | Close job |
"
var/ID
- if(scan && (access_change_ids in scan.access))
+ if(scan && (access_change_ids in scan.access) && !target_dept)
ID = 1
else
ID = 0
@@ -280,14 +284,15 @@ var/time_last_changed_position = 0
else
body = "{Log in}
"
body += "Access Crew Manifest"
- body += "
Job Management"
+ if(!target_dept)
+ body += "
Job Management"
dat = "[header][body]
"
//user << browse(dat, "window=id_com;size=900x520")
//onclose(user, "id_com")
- var/datum/browser/popup = new(user, "id_com", "Identification Card Modifier Console", 900, 620)
+ var/datum/browser/popup = new(user, "id_com", src.name, 900, 620)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
@@ -311,7 +316,8 @@ var/time_last_changed_position = 0
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id))
- usr.drop_item()
+ if(!usr.drop_item())
+ return
I.loc = src
modify = I
authenticated = 0
@@ -324,34 +330,41 @@ var/time_last_changed_position = 0
else
var/obj/item/I = usr.get_active_hand()
if (istype(I, /obj/item/weapon/card/id))
- usr.drop_item()
+ if(!usr.drop_item())
+ return
I.loc = src
scan = I
authenticated = 0
if ("auth")
if ((!( authenticated ) && (scan || (istype(usr, /mob/living/silicon))) && (modify || mode)))
if (check_access(scan))
+ region_access = list()
+ head_subordinates = list()
if(access_change_ids in scan.access)
- authenticated = 2
+ if(target_dept)
+ head_subordinates = get_all_jobs()
+ region_access |= target_dept
+ authenticated = 1
+ else
+ authenticated = 2
+
else
- region_access = list()
- head_subordinates = list()
- if(access_hop in scan.access)
- region_access += 1
- region_access += 6
+ if((access_hop in scan.access) && ((target_dept==1) || !target_dept))
+ region_access |= 1
+ region_access |= 6
get_subordinates("Head of Personnel")
- if(access_rd in scan.access)
- region_access += 4
- get_subordinates("Research Director")
- if(access_ce in scan.access)
- region_access += 5
- get_subordinates("Chief Engineer")
- if(access_cmo in scan.access)
- region_access += 3
- get_subordinates("Chief Medical Officer")
- if(access_hos in scan.access)
- region_access += 2
+ if((access_hos in scan.access) && ((target_dept==2) || !target_dept))
+ region_access |= 2
get_subordinates("Head of Security")
+ if((access_cmo in scan.access) && ((target_dept==3) || !target_dept))
+ region_access |= 3
+ get_subordinates("Chief Medical Officer")
+ if((access_rd in scan.access) && ((target_dept==4) || !target_dept))
+ region_access |= 4
+ get_subordinates("Research Director")
+ if((access_ce in scan.access) && ((target_dept==5) || !target_dept))
+ region_access |= 5
+ get_subordinates("Chief Engineer")
if(region_access)
authenticated = 1
else if ((!( authenticated ) && (istype(usr, /mob/living/silicon))) && (!modify))
@@ -419,7 +432,7 @@ var/time_last_changed_position = 0
if("make_job_available")
// MAKE ANOTHER JOB POSITION AVAILABLE FOR LATE JOINERS
- if(scan && (access_change_ids in scan.access))
+ if(scan && (access_change_ids in scan.access) && !target_dept)
var/edit_job_target = href_list["job"]
var/datum/job/j = SSjob.GetJob(edit_job_target)
if(!j)
@@ -433,7 +446,7 @@ var/time_last_changed_position = 0
if("make_job_unavailable")
// MAKE JOB POSITION UNAVAILABLE FOR LATE JOINERS
- if(scan && (access_change_ids in scan.access))
+ if(scan && (access_change_ids in scan.access) && !target_dept)
var/edit_job_target = href_list["job"]
var/datum/job/j = SSjob.GetJob(edit_job_target)
if(!j)
@@ -472,3 +485,30 @@ var/time_last_changed_position = 0
circuit = /obj/item/weapon/circuitboard/card/centcom
req_access = list(access_cent_captain)
+/obj/machinery/computer/card/minor
+ name = "department management console"
+ desc = "You can use this to change ID's for specific departments."
+ icon_screen = "idminor"
+ circuit = /obj/item/weapon/circuitboard/card/minor
+
+/obj/machinery/computer/card/minor/New()
+ ..()
+ var/obj/item/weapon/circuitboard/card/minor/typed_circuit = circuit
+ if(target_dept)
+ typed_circuit.target_dept = target_dept
+ else
+ target_dept = typed_circuit.target_dept
+ var/list/dept_list = list("general","security","medical","science","engineering")
+ name = "[dept_list[target_dept]] department console"
+
+/obj/machinery/computer/card/minor/hos
+ target_dept = 2
+
+/obj/machinery/computer/card/minor/cmo
+ target_dept = 3
+
+/obj/machinery/computer/card/minor/rd
+ target_dept = 4
+
+/obj/machinery/computer/card/minor/ce
+ target_dept = 5
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index ff893a987a0..e2078720d8c 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -76,7 +76,8 @@
/obj/machinery/computer/cloning/attackby(obj/item/W as obj, mob/user as mob, params)
if (istype(W, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES
if (!src.diskette)
- user.drop_item()
+ if(!user.drop_item())
+ return ..()
W.loc = src
src.diskette = W
user << "You insert [W]."
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 6e94c641b33..21dfa6b0585 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -50,7 +50,7 @@ var/const/CALL_SHUTTLE_REASON_LENGTH = 12
/obj/machinery/computer/communications/Topic(href, href_list)
if(..())
return
- if (src.z > ZLEVEL_STATION)
+ if (src.z > ZLEVEL_CENTCOM) //Can only use on centcom and SS13
usr << "Unable to establish a connection: \black You're too far away from the station!"
return
usr.set_machine(src)
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index ef0345be0e5..4c27c1b1552 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -20,9 +20,10 @@
var/sortBy = "name"
var/order = 1 // -1 = Descending - 1 = Ascending
-/obj/machinery/computer/med_data/attackby(obj/item/O as obj, user as mob, params)
+/obj/machinery/computer/med_data/attackby(obj/item/O as obj, mob/user as mob, params)
if(istype(O, /obj/item/weapon/card/id) && !scan)
- usr.drop_item()
+ if(!user.drop_item())
+ return
O.loc = src
scan = O
user << "You insert [O]."
@@ -215,7 +216,8 @@
else
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/weapon/card/id))
- usr.drop_item()
+ if(!usr.drop_item())
+ return
I.loc = src
src.scan = I
else if(href_list["logout"])
@@ -509,7 +511,7 @@
else
//Foreach continue //goto(3229)
if(!( src.active2 ))
- src.temp = text("Could not locate record [].", t1)
+ src.temp = text("Could not locate record [].", sanitize(t1))
else
for(var/datum/data/record/E in data_core.general)
if((E.fields["name"] == src.active2.fields["name"] || E.fields["id"] == src.active2.fields["id"]))
diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm
index 5a0cab959e6..7d31061f0ba 100644
--- a/code/game/machinery/computer/message.dm
+++ b/code/game/machinery/computer/message.dm
@@ -128,7 +128,7 @@
break
// Del - Sender - Recepient - Message
// X - Al Green - Your Mom - WHAT UP!?
- dat += "| X | [pda.sender] | [pda.recipient] | [pda.message] |
"
+ dat += "| X | [pda.sender] | [pda.recipient] | [pda.message][pda.photo ? "(Photo)":""] |
"
dat += "
"
//Hacking screen.
if(2)
diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm
index fa29854b612..8d503badcea 100644
--- a/code/game/machinery/computer/pod.dm
+++ b/code/game/machinery/computer/pod.dm
@@ -119,9 +119,11 @@
/obj/machinery/computer/pod/old
- icon_state = "old"
name = "\improper DoorMex control console"
title = "Door Controls"
+ icon_state = "oldcomp"
+ icon_screen = "library"
+ icon_keyboard = null
/obj/machinery/computer/pod/old/syndicate
diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm
index 48e12d07b80..faba05e021f 100644
--- a/code/game/machinery/computer/prisoner.dm
+++ b/code/game/machinery/computer/prisoner.dm
@@ -92,7 +92,8 @@
if(href_list["id"] =="insert" && !istype(inserted_id))
var/obj/item/weapon/card/id/prisoner/I = usr.get_active_hand()
if(istype(I))
- usr.drop_item()
+ if(!usr.drop_item())
+ return
I.loc = src
inserted_id = I
else usr << "No valid ID."
diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm
index 8cb27943cf8..e358e3b9107 100644
--- a/code/game/machinery/computer/robot.dm
+++ b/code/game/machinery/computer/robot.dm
@@ -92,7 +92,7 @@
R << "Extreme danger. Termination codes detected. Scrambling security codes and automatic AI unlink triggered."
R.ResetSecurityCodes()
else
- message_admins("[key_name(usr, usr.client)](JMP) detonated [key_name(R, R.client)](JMP)!")
+ message_admins("[key_name_admin(usr)] (FLW) detonated [key_name(R, R.client)](JMP)!")
log_game("\[key_name(usr)] detonated [key_name(R)]!")
if(R.connected_ai)
R.connected_ai << "
ALERT - Cyborg detonation detected: [R.name]
"
@@ -106,7 +106,7 @@
if(can_control(usr, R))
var/choice = input("Are you certain you wish to [R.canmove ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
- message_admins("[key_name(usr, usr.client)](JMP) [R.canmove ? "locked down" : "released"] [key_name(R, R.client)](JMP)!")
+ message_admins("[key_name_admin(usr)] (FLW) [R.canmove ? "locked down" : "released"] [key_name(R, R.client)](FLW)!")
log_game("[key_name(usr)] [R.canmove ? "locked down" : "released"] [key_name(R)]!")
R.SetLockdown(!R.lockcharge)
R << "[!R.lockcharge ? "Your lockdown has been lifted!" : "You have been locked down!"]"
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index ef936af78b5..4a0aad15867 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -24,9 +24,10 @@
var/order = 1 // -1 = Descending - 1 = Ascending
-/obj/machinery/computer/secure_data/attackby(obj/item/O as obj, user as mob, params)
+/obj/machinery/computer/secure_data/attackby(obj/item/O as obj, mob/user as mob, params)
if(istype(O, /obj/item/weapon/card/id) && !scan)
- usr.drop_item()
+ if(!user.drop_item())
+ return
O.loc = src
scan = O
user << "You insert [O]."
@@ -299,7 +300,8 @@ What a mess.*/
else
var/obj/item/I = usr.get_active_hand()
if(istype(I, /obj/item/weapon/card/id))
- usr.drop_item()
+ if(!usr.drop_item())
+ return
I.loc = src
scan = I
@@ -519,7 +521,7 @@ What a mess.*/
switch(href_list["field"])
if("name")
if(istype(active1, /datum/data/record) || istype(active2, /datum/data/record))
- var/t1 = stripped_input(usr, "Please input name:", "Secure. records", active1.fields["name"], null)
+ var/t1 = copytext(sanitize(input("Please input name:", "Secure. records", active1.fields["name"], null) as text),1,MAX_MESSAGE_LEN)
if(!canUseSecurityRecordsConsole(usr, t1, a1))
return
if(istype(active1, /datum/data/record))
diff --git a/code/game/machinery/computer/shuttle.dm b/code/game/machinery/computer/shuttle.dm
index b1460042e8a..09f0ce71324 100644
--- a/code/game/machinery/computer/shuttle.dm
+++ b/code/game/machinery/computer/shuttle.dm
@@ -47,12 +47,12 @@
if(!authorized.Find(W:registered_name))
authorized += W:registered_name
if(auth_need - authorized.len > 0)
- message_admins("[key_name(user.client)](?) has authorized early shuttle launch in ([x],[y],[z] - JMP)",0,1)
- log_game("[user.ckey]([user]) has authorized early shuttle launch in ([x],[y],[z])")
+ message_admins("[key_name_admin(user.client)](?) (FLW) has authorized early shuttle launch ",0,1)
+ log_game("[key_name(user)] has authorized early shuttle launch in ([x],[y],[z])")
minor_announce("[auth_need - authorized.len] more authorization(s) needed until shuttle is launched early",null,1)
else
- message_admins("[key_name(user.client)](?) has launched the emergency shuttle in ([x],[y],[z] - JMP) [seconds] seconds before launch.",0,1)
- log_game("[user.ckey]([user]) has launched the emergency shuttle in ([x],[y],[z]) [seconds] seconds before launch.")
+ message_admins("[key_name_admin(user.client)](?) (FLW) has launched the emergency shuttle [seconds] seconds before launch.",0,1)
+ log_game("[key_name(user)] has launched the emergency shuttle in ([x],[y],[z]) [seconds] seconds before launch.")
minor_announce("The emergency shuttle will launch in 10 seconds",null,1)
SSshuttle.emergency.setTimer(100)
@@ -68,8 +68,8 @@
/obj/machinery/computer/emergency_shuttle/emag_act(mob/user as mob)
if(!emagged && SSshuttle.emergency.mode == SHUTTLE_DOCKED)
var/time = SSshuttle.emergency.timeLeft()
- message_admins("[key_name(user.client)](?) has emagged the emergency shuttle in ([x],[y],[z] - JMP) [time] seconds before launch.",0,1)
- log_game("[user.ckey]([user]) has emagged the emergency shuttle in ([x],[y],[z]) [time] seconds before launch.")
+ message_admins("[key_name_admin(user.client)](?) (FLW) has emagged the emergency shuttle [time] seconds before launch.",0,1)
+ log_game("[key_name(user)] has emagged the emergency shuttle in ([x],[y],[z]) [time] seconds before launch.")
minor_announce("The emergency shuttle will launch in 10 seconds", "SYSTEM ERROR:",null,1)
SSshuttle.emergency.setTimer(100)
emagged = 1
diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm
index d20776f350c..29b07601e4f 100644
--- a/code/game/machinery/computer/telecrystalconsoles.dm
+++ b/code/game/machinery/computer/telecrystalconsoles.dm
@@ -39,7 +39,8 @@ var/list/possible_uplinker_IDs = list("Alfa","Bravo","Charlie","Delta","Echo","F
if(O.hidden_uplink)
var/obj/item/P = user.get_active_hand()
- user.drop_item()
+ if(!user.drop_item())
+ return
uplinkholder = P
P.loc = src
P.add_fingerprint(user)
diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm
index 5530c7cc5a1..e0a7411e82b 100644
--- a/code/game/machinery/constructable_frame.dm
+++ b/code/game/machinery/constructable_frame.dm
@@ -108,10 +108,11 @@
return
var/obj/item/weapon/circuitboard/B = P
if(B.board_type == "machine")
+ if(!user.drop_item())
+ return
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
user << "You add the circuit board to the frame."
circuit = P
- user.drop_item()
P.loc = src
icon_state = "box_2"
state = 3
@@ -140,8 +141,8 @@
user << "You remove the circuit board."
else
user << "You remove the circuit board and other components."
- for(var/obj/item/weapon/W in components)
- W.loc = src.loc
+ for(var/atom/movable/A in components)
+ A.loc = src.loc
desc = initial(desc)
req_components = null
components = null
@@ -199,6 +200,8 @@
var/success
for(var/I in req_components)
if(istype(P, I) && (req_components[I] > 0))
+ if(!user.drop_item())
+ return
success=1
if(istype(P, /obj/item/stack/cable_coil))
var/obj/item/stack/cable_coil/CP = P
@@ -211,7 +214,6 @@
req_components[I]--
update_req_desc()
break
- user.drop_item()
P.loc = src
components += P
req_components[I]--
diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm
index f84c488f930..a0c17f6a556 100644
--- a/code/game/machinery/cryo.dm
+++ b/code/game/machinery/cryo.dm
@@ -135,16 +135,20 @@
*
* @return nothing
*/
-/obj/machinery/atmospherics/unary/cryo_cell/ui_interact(mob/user, ui_key = "main")
+/obj/machinery/atmospherics/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if(user == occupant || user.stat || panel_open)
return
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "cryo.tmpl", "Cryo Cell Control System", 520, 410, 1)
+ //user.set_machine(src)
+
+/obj/machinery/atmospherics/unary/cryo_cell/get_ui_data()
// this is the data which will be sent to the ui
- var/data[0]
+ var/data = list()
data["isOperating"] = on
data["hasOccupant"] = occupant ? 1 : 0
- var/occupantData[0]
+ var/occupantData = list()
if (!occupant)
occupantData["name"] = null
occupantData["stat"] = null
@@ -167,7 +171,7 @@
occupantData["toxLoss"] = occupant.getToxLoss()
occupantData["fireLoss"] = occupant.getFireLoss()
occupantData["bodyTemperature"] = occupant.bodytemperature
- data["occupant"] = occupantData;
+ data["occupant"] = occupantData
data["isOpen"] = state_open
data["cellTemperature"] = round(air_contents.temperature)
@@ -183,21 +187,7 @@
for(var/datum/reagent/R in beaker:reagents.reagent_list)
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list...
data["beakerContents"] = beakerContents
-
- var/datum/nanoui/ui = SSnano.get_open_ui(user, src, ui_key)
- if (!ui)
- // the ui does not exist, so we'll create a new one
- ui = new(user, src, ui_key, "cryo.tmpl", "Cryo Cell Control System", 520, 410)
- // When the UI is first opened this is the data it will use
- ui.set_initial_data(data)
- ui.open()
- // Auto update every Master Controller tick
- ui.set_auto_update(1)
- else
- // The UI is already open so push the new data to it
- ui.push_data(data)
- return
- //user.set_machine(src)
+ return data
/obj/machinery/atmospherics/unary/cryo_cell/Topic(href, href_list)
if(usr == occupant || panel_open)
@@ -237,9 +227,10 @@
if(beaker)
user << "A beaker is already loaded into [src]!"
return
+ if(!user.drop_item())
+ return
beaker = I
- user.drop_item()
I.loc = src
user.visible_message("[user] places [I] in [src].", \
"You place [I] in [src].")
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 3d69900b0e8..8a752cd6f76 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -45,6 +45,8 @@
var/obj/item/weapon/airlock_electronics/electronics = null
var/hasShocked = 0 //Prevents multiple shocks from happening
var/autoclose = 1
+ var/obj/item/device/doorCharge/charge = null //If applied, causes an explosion upon opening the door
+ var/detonated = 0
explosion_block = 1
@@ -91,6 +93,7 @@
icon = 'icons/obj/doors/vault.dmi'
opacity = 1
doortype = /obj/structure/door_assembly/door_assembly_vault
+ explosion_block = 2
/obj/machinery/door/airlock/glass_large
name = "glass airlock"
@@ -476,6 +479,11 @@ About the new airlock wires panel:
flick("door_deny", src)
return
+/obj/machinery/door/airlock/examine(mob/user)
+ ..()
+ if(charge && !p_open && in_range(user, src))
+ user << "The maintenance panel is bulging slightly."
+
/obj/machinery/door/airlock/attack_ai(mob/user as mob)
if(!src.canAIControl())
if(src.canAIHack())
@@ -486,6 +494,9 @@ About the new airlock wires panel:
if(emagged)
user << "Unable to interface: Airlock is unresponsive."
return
+ if(detonated)
+ user << "Unable to interface. Airlock control panel damaged."
+ return
//Separate interface for the AI.
user.set_machine(src)
@@ -923,6 +934,9 @@ About the new airlock wires panel:
update_icon()
return
else if(istype(C, /obj/item/weapon/screwdriver))
+ if(p_open && detonated)
+ user << "[src] has no maintenance panel!"
+ return
src.p_open = !( src.p_open )
user << "You [p_open ? "open":"close"] the maintenance panel of the airlock."
src.update_icon()
@@ -941,6 +955,22 @@ About the new airlock wires panel:
beingcrowbarred = 1 //derp, Agouri
else
beingcrowbarred = 0
+ if(p_open && charge)
+ user << "You carefully start removing [charge] from [src]..."
+ playsound(get_turf(src), 'sound/items/Crowbar.ogg', 50, 1)
+ if(!do_after(user, 150))
+ user << "You slip and [charge] detonates!"
+ charge.ex_act(1)
+ user.Weaken(3)
+ return
+ user.visible_message("[user] removes [charge] from [src].", \
+ "You gently pry out [charge] from [src] and unhook its wires.")
+ charge.loc = get_turf(user)
+ if(prob(25))
+ charge.ex_act(1)
+ return
+ charge = null
+ return
if( beingcrowbarred && (density && welded && !operating && src.p_open && (!hasPower()) && !src.locked) )
playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
user.visible_message("[user] removes the electronics from the airlock assembly.", \
@@ -998,14 +1028,31 @@ About the new airlock wires panel:
else if(istype(C, /obj/item/weapon/airlock_painter))
change_paintjob(C, user)
+ else if(istype(C, /obj/item/device/doorCharge) && p_open)
+ if(emagged)
+ return
+ if(charge && !detonated)
+ user << "There's already a charge hooked up to this door!"
+ return
+ if(detonated)
+ user << "The maintenance panel is destroyed!"
+ return
+ user << "You apply [C]. Next time someone opens the door, it will explode."
+ user.drop_item()
+ p_open = 0
+ update_icon()
+ var/obj/item/device/doorCharge/newCharge = C //This is necessary, for some reason
+ newCharge.loc = src
+ charge = newCharge
+ return
else
..()
return
/obj/machinery/door/airlock/plasma/attackby(C as obj, mob/user as mob, params)
if(is_hot(C) > 300)//If the temperature of the object is over 300, then ignite
- message_admins("Plasma wall ignited by [key_name(user, user.client)](?) in ([x],[y],[z] - JMP)")
- log_game("Plasma wall ignited by [user.ckey]([user]) in ([x],[y],[z])")
+ message_admins("Plasma airlock ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)")
+ log_game("Plasma wall ignited by [key_name(user)] in ([x],[y],[z])")
ignite(is_hot(C))
return
..()
@@ -1016,6 +1063,18 @@ About the new airlock wires panel:
if(!forced)
if( !hasPower() || isWireCut(AIRLOCK_WIRE_OPEN_DOOR) )
return 0
+ if(charge && !detonated)
+ p_open = 1
+ update_icon()
+ visible_message("[src]'s panel is blown off in a spray of deadly shrapnel!")
+ charge.ex_act(1)
+ detonated = 1
+ charge = null
+ for(var/mob/living/carbon/human/H in orange(1,src))
+ H.Paralyse(8)
+ H.adjust_fire_stacks(1)
+ H.IgniteMob() //Guaranteed knockout and ignition for nearby people
+ return
if(forced < 2)
if(emagged)
return 0
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 84e06f843ad..abfb8ff9253 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -281,4 +281,7 @@
return 0
/obj/machinery/door/morgue
- icon = 'icons/obj/doors/doormorgue.dmi'
\ No newline at end of file
+ icon = 'icons/obj/doors/doormorgue.dmi'
+
+/obj/machinery/door/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
+ return 0
\ No newline at end of file
diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm
index c679e37cd4c..2d851669879 100644
--- a/code/game/machinery/doors/windowdoor.dm
+++ b/code/game/machinery/doors/windowdoor.dm
@@ -187,7 +187,6 @@
/obj/machinery/door/window/hitby(AM as mob|obj)
..()
- visible_message("\The [src] was hit by \the [AM].")
var/tforce = 0
if(ismob(AM))
tforce = 40
diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/droneDispenser.dm
new file mode 100644
index 00000000000..0860d7760ea
--- /dev/null
+++ b/code/game/machinery/droneDispenser.dm
@@ -0,0 +1,105 @@
+/obj/machinery/droneDispenser
+ name = "drone shell dispenser"
+ desc = "A hefty machine that, when supplied with metal and glass, will periodically create a drone shell. Does not need to be manually operated."
+ icon = 'icons/obj/machines/droneDispenser.dmi'
+ icon_state = "on"
+ anchored = 1
+ density = 1
+ var/metal = 0
+ var/glass = 0
+ var/droneMadeRecently = 0
+ var/outputDirection = SOUTH
+
+/obj/machinery/droneDispenser/New()
+ ..()
+ SSmachine.processing |= src
+
+/obj/machinery/droneDispenser/Destroy()
+ SSmachine.processing -= src
+ ..()
+
+/obj/machinery/droneDispenser/preloaded
+ metal = 5000
+ glass = 5000
+
+/obj/machinery/droneDispenser/syndrone //Please forgive me
+ name = "syndrone shell dispenser"
+ desc = "A suspicious machine that will create Syndicate exterminator drones when supplied with metal and glass. Disgusting."
+ metal = 25000
+ glass = 25000
+
+/obj/machinery/droneDispenser/examine(mob/user)
+ ..()
+ if(droneMadeRecently && !stat)
+ user << "The control screen indicates that is recharging."
+ user << "It has [metal] units of metal stored."
+ user << "It has [glass] units of glass stored."
+
+/obj/machinery/droneDispenser/power_change()
+ ..()
+ if(stat & BROKEN)
+ return
+ else
+ if(powered())
+ stat &= ~NOPOWER
+ else
+ icon_state = "off"
+ stat |= NOPOWER
+
+/obj/machinery/droneDispenser/process()
+ ..()
+ if(stat & (NOPOWER|BROKEN) || !anchored)
+ return
+ if(droneMadeRecently || metal < 1000 || glass < 1000)
+ return
+ droneMadeRecently = 1
+ var/turf/T = get_step(src,SOUTH)
+ visible_message("[src] whirs to life!")
+ playsound(src, 'sound/items/rped.ogg', 50, 1)
+ icon_state = "make"
+ spawn(30)
+ icon_state = "[initial(icon_state)]"
+ visible_message("[src] dispenses a drone shell.")
+ metal -= 1000
+ glass -= 1000
+ if(metal < 0) metal = 0
+ if(glass < 0) glass = 0
+ if(istype(src, /obj/machinery/droneDispenser/syndrone))
+ new /obj/item/drone_shell/syndrone(T)
+ else
+ new /obj/item/drone_shell(T)
+ use_power(1000)
+ icon_state = "recharge"
+ spawn(1800) //3 minute cooldown between shells
+ icon_state = "[initial(icon_state)]"
+ droneMadeRecently = 0
+ playsound(src, 'sound/machines/ping.ogg', 50, 1)
+ audible_message("[src] pings.")
+
+/obj/machinery/droneDispenser/attackby(obj/item/O, mob/living/user)
+ if(istype(O, /obj/item/stack))
+ if(!O.m_amt && !O.g_amt)
+ return ..()
+ var/stack = 1
+ var/obj/item/stack/sheets
+ sheets = O
+ stack = (input(user, "How many sheets do you want to add?.", "Drone Dispenser", "[stack]") as num)
+ if(stack <= 0)
+ return
+ if(!user.canUseTopic(src))
+ return
+ stack = Clamp(stack, 0, sheets.max_amount)
+ sheets.use(stack)
+ if(!stack)
+ if(!user.unEquip(O))
+ user << "[O] is stuck to your hand, you can't get it off!"
+ return
+ user.drop_item()
+ O.loc = src
+ metal += O.m_amt * stack
+ glass += O.g_amt * stack
+ user << "You insert [stack] sheet[stack > 1 ? "s" : ""] to [src]."
+ if((O && O.loc == src) || !stack)
+ qdel(O)
+ return
+ ..()
diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm
index fdea6d8469f..1b6be79b004 100644
--- a/code/game/machinery/flasher.dm
+++ b/code/game/machinery/flasher.dm
@@ -50,8 +50,9 @@
else if (istype(W, /obj/item/device/flash/handheld))
if (!bulb)
+ if(!user.drop_item())
+ return
user.visible_message("[user] installs [W] into [src].", "You install [W] into [src].")
- user.drop_item()
W.loc = src
bulb = W
power_change()
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index e5961c09fc9..0c600860d7c 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -77,8 +77,9 @@
if(!isnull(beaker))
user << "There is already a reagent container loaded!"
return
+ if(!user.drop_item())
+ return
- user.drop_item()
W.loc = src
beaker = W
user << "You attach \the [W] to \the [src]."
diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm
index f5693f0a3fa..a11ed0d4a47 100644
--- a/code/game/machinery/newscaster.dm
+++ b/code/game/machinery/newscaster.dm
@@ -788,7 +788,8 @@ var/list/obj/machinery/newscaster/allCasters = list()
photo = null
if(istype(user.get_active_hand(), /obj/item/weapon/photo))
photo = user.get_active_hand()
- user.drop_item()
+ if(!user.drop_item())
+ return
photo.loc = src
if(istype(user,/mob/living/silicon))
var/list/nametemp = list()
@@ -893,6 +894,10 @@ var/list/obj/machinery/newscaster/allCasters = list()
var/wantedPhoto
var/creationTime
+/obj/item/weapon/newspaper/suicide_act(mob/user)
+ user.visible_message("[user] is focusing intently on [src]! It looks like they're trying to commit sudoku.")
+ return(OXYLOSS)
+
/obj/item/weapon/newspaper/attack_self(mob/user)
if(ishuman(user))
var/mob/living/carbon/human/human_user = user
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index d56e2129927..7fb0d411b64 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -39,7 +39,7 @@ Buildable meters
var/pipe_type = 0
var/pipename
force = 7
- icon = 'icons/obj/pipe-item.dmi'
+ icon = 'icons/obj/atmospherics/pipes/pipe_item.dmi'
icon_state = "simple"
item_state = "buildpipe"
w_class = 3
@@ -407,7 +407,7 @@ var/global/list/pipeID2State = list(
/obj/item/pipe_meter
name = "meter"
desc = "A meter that can be laid on pipes"
- icon = 'icons/obj/pipe-item.dmi'
+ icon = 'icons/obj/atmospherics/pipes/pipe_item.dmi'
icon_state = "meter"
item_state = "buildpipe"
w_class = 4
diff --git a/code/game/machinery/pipe/pipe_dispenser.dm b/code/game/machinery/pipe/pipe_dispenser.dm
index 9d1be6f4519..96fb5716814 100644
--- a/code/game/machinery/pipe/pipe_dispenser.dm
+++ b/code/game/machinery/pipe/pipe_dispenser.dm
@@ -72,7 +72,8 @@
add_fingerprint(user)
if (istype(W, /obj/item/pipe) || istype(W, /obj/item/pipe_meter))
usr << "You put [W] back into [src]."
- user.drop_item()
+ if(!user.drop_item())
+ return
qdel(W)
return
else if (istype(W, /obj/item/weapon/wrench))
diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm
index 34c13a8bb88..aaef91bc811 100644
--- a/code/game/machinery/recharger.dm
+++ b/code/game/machinery/recharger.dm
@@ -27,8 +27,9 @@
if(!gun.can_charge)
user << "Your gun has no external power connector."
return
+ if(!user.drop_item())
+ return
- user.drop_item()
G.loc = src
charging = G
use_power = 2
diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm
index 2e5db8f3827..b98fa244823 100644
--- a/code/game/machinery/shieldgen.dm
+++ b/code/game/machinery/shieldgen.dm
@@ -90,8 +90,6 @@
/obj/machinery/shield/hitby(AM as mob|obj)
- //Let everyone know we've been hit!
- visible_message("[src] was hit by [AM].")
//Super realistic, resource-intensive, real-time damage calculations.
var/tforce = 0
@@ -604,4 +602,4 @@
if (istype(mover, /obj/item/projectile))
return prob(10)
else
- return !src.density
\ No newline at end of file
+ return !src.density
diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm
index 0bc33615834..4d88f443d05 100644
--- a/code/game/machinery/slotmachine.dm
+++ b/code/game/machinery/slotmachine.dm
@@ -77,7 +77,8 @@
if(istype(I, /obj/item/weapon/coin))
var/obj/item/weapon/coin/C = I
if(prob(2))
- user.drop_item()
+ if(!user.drop_item())
+ return
C.loc = loc
C.throw_at(user, 3, 10)
if(prob(10))
@@ -85,7 +86,8 @@
user << "[src] spits your coin back out!"
else
- user.drop_item()
+ if(!user.drop_item())
+ return
user << "You insert a [C.cmineral] coin into [src]'s slot!"
balance += C.value
qdel(C)
@@ -293,14 +295,14 @@
return amount
-/obj/machinery/computer/slot_machine/proc/dispense(amount = 0, cointype = /obj/item/weapon/coin/silver, mob/living/target, throw = 0)
+/obj/machinery/computer/slot_machine/proc/dispense(amount = 0, cointype = /obj/item/weapon/coin/silver, mob/living/target, throwit = 0)
var/value = coinvalues["[cointype]"]
while(amount >= value)
var/obj/item/weapon/coin/C = new cointype(loc) //DOUBLE THE PAIN
amount -= value
- if(throw && target)
+ if(throwit && target)
C.throw_at(target, 3, 10)
else
random_step(C, 2, 40)
diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm
index da7f6a82c53..b1891f80539 100644
--- a/code/game/machinery/spaceheater.dm
+++ b/code/game/machinery/spaceheater.dm
@@ -54,7 +54,8 @@
// insert cell
var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand()
if(istype(C))
- user.drop_item()
+ if(!user.drop_item())
+ return
cell = C
C.loc = src
C.add_fingerprint(usr)
@@ -134,7 +135,8 @@
if(open && !cell)
var/obj/item/weapon/stock_parts/cell/C = usr.get_active_hand()
if(istype(C))
- usr.drop_item()
+ if(!usr.drop_item())
+ return
cell = C
C.loc = src
C.add_fingerprint(usr)
diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm
index 35a1b38e85c..87b89bcd926 100644
--- a/code/game/machinery/syndicatebomb.dm
+++ b/code/game/machinery/syndicatebomb.dm
@@ -90,9 +90,10 @@
user << "The cover is screwed on, it won't pry off!"
else if(istype(I, /obj/item/weapon/bombcore))
if(!payload)
+ if(!user.drop_item())
+ return
payload = I
user << "You place [payload] into [src]."
- user.drop_item()
payload.loc = src
else
user << "[payload] is already loaded into [src]! You'll have to remove it first."
@@ -138,7 +139,7 @@
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
if(payload && !istype(payload, /obj/item/weapon/bombcore/training))
- message_admins("[key_name(user)]? has primed a [name] ([payload]) for detonation at [A.name] (JMP).")
+ message_admins("[key_name_admin(user)]? (FLW) has primed a [name] ([payload]) for detonation at [A.name] (JMP).")
log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])")
payload.adminlog = "The [src.name] that [key_name(user)] had primed detonated!"
@@ -311,7 +312,7 @@
var/turf/T = get_turf(src)
var/area/A = get_area(T)
detonated--
- var/log_str = "[key_name(user)]? has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] (JMP)."
+ var/log_str = "[key_name_admin(user)]? (FLW) has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] (JMP)."
bombers += log_str
message_admins(log_str)
log_game("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name]([T.x],[T.y],[T.z])")
diff --git a/code/game/machinery/telecomms/computers/traffic_control.dm b/code/game/machinery/telecomms/computers/traffic_control.dm
index 7dc9517abfc..9d520a5a7d8 100644
--- a/code/game/machinery/telecomms/computers/traffic_control.dm
+++ b/code/game/machinery/telecomms/computers/traffic_control.dm
@@ -168,7 +168,8 @@
var/obj/item/weapon/card/id/I = C.get_active_hand()
if(istype(I))
if(check_access(I))
- C.drop_item()
+ if(!C.drop_item())
+ return
I.loc = src
auth = I
create_log("has logged in.", usr)
diff --git a/code/game/machinery/telecomms/machines/server.dm b/code/game/machinery/telecomms/machines/server.dm
index 322b635e3ca..f78fdd13897 100644
--- a/code/game/machinery/telecomms/machines/server.dm
+++ b/code/game/machinery/telecomms/machines/server.dm
@@ -118,12 +118,12 @@
/obj/machinery/telecomms/server/proc/admin_log(var/mob/mob)
- var/msg="[mob.real_name]/([mob.key]) has compiled a script to server [src]:"
+ var/msg="[key_name(mob)] has compiled a script to server [src]:"
diary << msg
diary << rawcode
src.investigate_log("[msg]
[rawcode]", "ntsl")
if(length(rawcode)) // Let's not bother the admins for empty code.
- message_admins("[mob.real_name]/([mob.key]) has compiled and uploaded a NTSL script to [src.id] ([mob.x],[mob.y],[mob.z] - JMP)",0,1)
+ message_admins("[key_name_admin(mob)] (FLW) has compiled and uploaded a NTSL script to [src.id]",0,1)
/obj/machinery/telecomms/server/proc/compile(var/mob/user)
diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm
index a2d76e96a5a..a8aff14f4c4 100644
--- a/code/game/machinery/vending.dm
+++ b/code/game/machinery/vending.dm
@@ -170,7 +170,8 @@
return
if(junk_check(W))
if(!iscompartmentfull(user))
- user.drop_item()
+ if(!user.drop_item())
+ return
W.loc = src
food_load(W)
user << "You insert [W] into [src]'s chef compartment."
@@ -250,7 +251,8 @@
attack_hand(user)
return
else if(istype(W, /obj/item/weapon/coin) && premium.len > 0)
- user.drop_item()
+ if(!user.drop_item())
+ return
W.loc = src
coin = W
user << "You insert [W] into [src]."
@@ -719,7 +721,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
vend_reply = "Remember the name: Liberation Station!"
products = list(/obj/item/weapon/gun/projectile/automatic/pistol/deagle/gold = 2,/obj/item/weapon/gun/projectile/automatic/pistol/deagle/camo = 2,
/obj/item/weapon/gun/projectile/automatic/pistol/m1911 = 2,/obj/item/weapon/gun/projectile/automatic/proto = 2,
- /obj/item/weapon/gun/projectile/shotgun/combat = 2,/obj/item/weapon/gun/projectile/automatic/gyropistol = 1,
+ /obj/item/weapon/gun/projectile/shotgun/automatic/combat = 2,/obj/item/weapon/gun/projectile/automatic/gyropistol = 1,
/obj/item/weapon/gun/projectile/shotgun = 2,/obj/item/weapon/gun/projectile/automatic/ar = 2)
premium = list(/obj/item/ammo_box/magazine/smgm9mm = 2,/obj/item/ammo_box/magazine/m50 = 4,/obj/item/ammo_box/magazine/m45 = 2,/obj/item/ammo_box/magazine/m75 = 2)
contraband = list(/obj/item/clothing/under/patriotsuit = 1,/obj/item/weapon/bedsheet/patriot = 3)
@@ -942,7 +944,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
vend_delay = 15
vend_reply = "Thank you for using the ClothesMate!"
products = list(/obj/item/clothing/head/that=2,/obj/item/clothing/head/fedora=1,/obj/item/clothing/glasses/monocle=1,
- /obj/item/clothing/suit/jacket=3,/obj/item/clothing/under/suit_jacket/navy=2,/obj/item/clothing/under/suit_jacket/really_black=2,/obj/item/clothing/under/kilt=1,/obj/item/clothing/under/overalls=1,
+ /obj/item/clothing/suit/jacket=3,/obj/item/clothing/under/suit_jacket/navy=1,/obj/item/clothing/under/suit_jacket/really_black=1,/obj/item/clothing/under/suit_jacket/burgundy=1,
+ /obj/item/clothing/under/suit_jacket/charcoal=1, /obj/item/clothing/under/suit_jacket/white=1,/obj/item/clothing/under/kilt=1,/obj/item/clothing/under/overalls=1,
/obj/item/clothing/under/sl_suit=1,/obj/item/clothing/under/pants/jeans=3,/obj/item/clothing/under/pants/classicjeans=2,
/obj/item/clothing/under/pants/camo = 1,/obj/item/clothing/under/pants/blackjeans=2,/obj/item/clothing/under/pants/khaki=2,
/obj/item/clothing/under/pants/white=2,/obj/item/clothing/under/pants/red=1,/obj/item/clothing/under/pants/black=2,
@@ -960,6 +963,6 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/clothing/shoes/sandal=1, /obj/item/clothing/gloves/fingerless=2,/obj/item/clothing/glasses/orange=1,/obj/item/clothing/glasses/red=1,
/obj/item/weapon/storage/belt/fannypack=1, /obj/item/weapon/storage/belt/fannypack/blue=1, /obj/item/weapon/storage/belt/fannypack/red=1)
contraband = list(/obj/item/clothing/under/syndicate/tacticool=1,/obj/item/clothing/mask/balaclava=1,/obj/item/clothing/head/ushanka=1,/obj/item/clothing/under/soviet=1,/obj/item/weapon/storage/belt/fannypack/black=1)
- premium = list(/obj/item/clothing/under/suit_jacket/checkered=1,/obj/item/clothing/head/mailman=1,/obj/item/clothing/under/rank/mailman=1,/obj/item/clothing/suit/jacket/leather=1,/obj/item/clothing/under/pants/mustangjeans=1)
+ premium = list(/obj/item/clothing/under/suit_jacket/checkered=1,/obj/item/clothing/head/mailman=1,/obj/item/clothing/under/rank/mailman=1,/obj/item/clothing/suit/jacket/leather=1,/obj/item/clothing/suit/jacket/leather/overcoat=1,/obj/item/clothing/under/pants/mustangjeans=1)
refill_canister = /obj/item/weapon/vending_refill/clothing
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index 76508f008ce..05c3b10c069 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -188,7 +188,8 @@
if(istype(W,/obj/item/toy/crayon) ||istype(W,/obj/item/weapon/stamp))
if( state in list( 1, 3, 6 ) )
if(!crayon)
- user.drop_item()
+ if(!user.drop_item())
+ return
crayon = W
crayon.loc = src
else
@@ -256,7 +257,8 @@
if(contents.len < 5)
if ( state in list(1, 3) )
- user.drop_item()
+ if(!user.drop_item())
+ return
W.loc = src
state = 3
else
diff --git a/code/game/mecha/equipment/tools/tools.dm b/code/game/mecha/equipment/tools/tools.dm
index 196a32ea235..7b9a4867f03 100644
--- a/code/game/mecha/equipment/tools/tools.dm
+++ b/code/game/mecha/equipment/tools/tools.dm
@@ -595,8 +595,8 @@
P.icon_state = "anom"
P.name = "wormhole"
var/turf/T = get_turf(target)
- message_admins("[key_name(chassis.occupant, chassis.occupant.client)](?) used a Wormhole Generator in ([T.x],[T.y],[T.z] - JMP)",0,1)
- log_game("[chassis.occupant.ckey]([chassis.occupant]) used a Wormhole Generator in ([T.x],[T.y],[T.z])")
+ message_admins("[key_name_admin(chassis.occupant, chassis.occupant.client)](?) (FLW) used a Wormhole Generator in ([T.x],[T.y],[T.z] - JMP)",0,1)
+ log_game("[key_name(chassis.occupant)] used a Wormhole Generator in ([T.x],[T.y],[T.z])")
do_after_cooldown()
src = null
spawn(rand(150,300))
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index 40389aae5a9..0414658025d 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -191,7 +191,7 @@
chassis.use_power(energy_drain)
log_message("Honked from [src.name]. HONK!")
var/turf/T = get_turf(src)
- message_admins("[key_name(chassis.occupant, chassis.occupant.client)](?) used a Mecha Honker in ([T.x],[T.y],[T.z] - JMP)",0,1)
+ message_admins("[key_name_admin(chassis.occupant, chassis.occupant.client)](?) (FLW) used a Mecha Honker in ([T.x],[T.y],[T.z] - JMP)",0,1)
log_game("[chassis.occupant.ckey]([chassis.occupant]) used a Mecha Honker in ([T.x],[T.y],[T.z])")
do_after_cooldown()
return
@@ -307,7 +307,7 @@
log_message("Fired from [src.name], targeting [target].")
var/turf/T = get_turf(src)
message_admins("[key_name(chassis.occupant, chassis.occupant.client)](?) fired a [src] in ([T.x],[T.y],[T.z] - JMP)",0,1)
- log_game("[chassis.occupant.ckey]([chassis.occupant]) fired a [src] ([T.x],[T.y],[T.z])")
+ log_game("[key_name(chassis.occupant)] fired a [src] ([T.x],[T.y],[T.z])")
do_after_cooldown()
return
@@ -347,8 +347,8 @@
projectiles--
log_message("Fired from [src.name], targeting [target].")
var/turf/T = get_turf(src)
- message_admins("[key_name(chassis.occupant, chassis.occupant.client)](?) fired a [src] in ([T.x],[T.y],[T.z] - JMP)",0,1)
- log_game("[chassis.occupant.ckey]([chassis.occupant]) fired a [src] ([T.x],[T.y],[T.z])")
+ message_admins("[key_name(chassis.occupant, chassis.occupant.client)](?) (FLW) fired a [src] in ([T.x],[T.y],[T.z] - JMP)",0,1)
+ log_game("[key_name(chassis.occupant)] fired a [src] ([T.x],[T.y],[T.z])")
spawn(det_time)
if(F)
F.prime()
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index ec69ca4c4a3..48f34a6faaf 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -96,7 +96,10 @@
/obj/mecha/Destroy()
go_out()
for(var/mob/M in src) //Let's just be ultra sure
- M.Move(loc)
+ if(isAI(M))
+ M.gib() //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. Forever.
+ else
+ M.Move(loc)
if(prob(30))
explosion(get_turf(loc), 0, 0, 1, 3)
@@ -675,7 +678,8 @@
var/obj/item/mecha_parts/mecha_equipment/E = W
spawn()
if(E.can_attach(src))
- user.drop_item()
+ if(!user.drop_item())
+ return
E.attach(src)
user.visible_message("[user] attaches [W] to [src].", "You attach [W] to [src].")
else
@@ -739,9 +743,10 @@
else if(istype(W, /obj/item/weapon/stock_parts/cell))
if(state==4)
if(!src.cell)
+ if(!user.drop_item())
+ return
var/obj/item/weapon/stock_parts/cell/C = W
user << "You install the powercell."
- user.drop_item()
C.forceMove(src)
C.use(C.charge * 0.8)
src.cell = C
@@ -780,17 +785,92 @@
call((proc_res["dynattackby"]||src), "dynattackby")(W,user)
return
-/*
-/obj/mecha/attack_ai(var/mob/living/silicon/ai/user as mob)
- if(!istype(user, /mob/living/silicon/ai))
- return
- var/output = {"Assume direct control over [src]?
- Yes
- "}
- user << browse(output, "window=mecha_attack_ai")
- return
-*/
+/////////////////////////////////////
+//////////// AI piloting ////////////
+/////////////////////////////////////
+/obj/mecha/attack_ai(var/mob/living/silicon/ai/user as mob)
+ if(!isAI(user))
+ return
+ //Allows the Malf to scan a mech's status and loadout, helping it to decide if it is a worthy chariot.
+ if(user.can_dominate_mechs)
+ examine(user) //Get diagnostic information!
+ var/obj/item/mecha_parts/mecha_tracking/B = locate(/obj/item/mecha_parts/mecha_tracking) in src
+ if(B) //Beacons give the AI more detailed mech information.
+ user << "Warning: Tracking Beacon detected. Enter at your own risk. Beacon Data:"
+ user << "[B.get_mecha_info()]"
+ //Nothing like a big, red link to make the player feel powerful!
+ user << "ASSUME DIRECT CONTROL?
"
+
+/obj/mecha/transfer_ai(var/interaction, mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card)
+ if(!..())
+ return
+
+ //Transfer from core or card to mech. Proc is called by mech.
+ switch(interaction)
+ if(AI_TRANS_TO_CARD) //Upload AI from mech to AI card.
+ if(!state) //Mech must be in maint mode to allow carding.
+ user << "[name] must have maintenance protocols active in order to allow a transfer."
+ return
+ AI = occupant
+ if(!AI || !isAI(occupant)) //Mech does not have an AI for a pilot
+ user << "No AI detected in the [name] onboard computer."
+ return
+ if (AI.mind.special_role == "malfunction") //Malf AIs cannot leave mechs. Except through death.
+ user << "ACCESS DENIED."
+ return
+ AI.aiRestorePowerRoutine = 0//So the AI initially has power.
+ AI.control_disabled = 1
+ AI.radio_enabled = 0
+ AI.loc = card
+ occupant = null
+ AI.controlled_mech = null
+ AI.remote_control = null
+ icon_state = initial(icon_state)+"-open"
+ AI << "You have been downloaded to a mobile storage device. Wireless connection offline."
+ user << "Transfer successful: [AI.name] ([rand(1000,9999)].exe) removed from [name] and stored within local memory."
+
+ if(AI_MECH_HACK) //Called by Malf AI mob on the mech.
+ new /obj/structure/AIcore/deactivated(AI.loc)
+ if(occupant) //Oh, I am sorry, were you using that?
+ AI << "Pilot detected! Forced ejection initiated!"
+ occupant << "You have been forcibly ejected!"
+ go_out(1) //IT IS MINE, NOW. SUCK IT, RD!
+ ai_enter_mech(AI, interaction)
+
+ if(AI_TRANS_FROM_CARD) //Using an AI card to upload to a mech.
+ AI = locate(/mob/living/silicon/ai) in card
+ if(!AI)
+ user << "There is no AI currently installed on this device."
+ return
+ else if(AI.stat || !AI.client)
+ user << "[AI.name] is currently unresponsive, and cannot be uploaded."
+ return
+ else if(occupant || dna) //Normal AIs cannot steal mechs!
+ user << "Access denied. [name] is [occupant ? "currently occupied" : "secured with a DNA lock"]."
+ return
+ AI.control_disabled = 0
+ AI.radio_enabled = 1
+ user << "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed."
+ ai_enter_mech(AI, interaction)
+
+//Hack and From Card interactions share some code, so leave that here for both to use.
+/obj/mecha/proc/ai_enter_mech(var/mob/living/silicon/ai/AI, var/interaction)
+ AI.aiRestorePowerRoutine = 0
+ AI.loc = src
+ occupant = AI
+ icon_state = initial(icon_state)
+ playsound(src, 'sound/machines/windowdoor.ogg', 50, 1)
+ if(!hasInternalDamage())
+ occupant << sound('sound/mecha/nominal.ogg',volume=50)
+ AI.cancel_camera()
+ AI.controlled_mech = src
+ AI.remote_control = src
+ AI.canmove = 1 //Much easier than adding AI checks! Be sure to set this back to 0 if you decide to allow an AI to leave a mech somehow.
+ AI.can_shunt = 0 //ONE AI ENTERS. NO AI LEAVES.
+ AI << "[interaction == AI_MECH_HACK ? "Takeover of [name] complete! You are now permanently loaded onto the onboard computer. Do not attempt to leave the station sector!" \
+ : "You have been uploaded to a mech's onboard computer."]"
+ AI << "Use Middle-Mouse to activate mech functions and equipment. Click normally for AI interactions."
/////////////////////////////////////
@@ -1088,7 +1168,7 @@
go_out()
-/obj/mecha/proc/go_out()
+/obj/mecha/proc/go_out(var/forced)
if(!src.occupant) return
var/atom/movable/mob_container
if(ishuman(occupant))
@@ -1098,6 +1178,10 @@
else if(istype(occupant, /mob/living/carbon/brain))
var/mob/living/carbon/brain/brain = occupant
mob_container = brain.container
+ else if(isAI(occupant) && forced) //This should only happen if there are multiple AIs in a round, and at least one is Malf.
+ occupant.gib() //If one Malf decides to steal a mech from another AI (even other Malfs!), they are destroyed, as they have nowhere to go when replaced.
+ occupant = null
+ return
else
return
if(mob_container.forceMove(src.loc))//ejecting mob container
@@ -1518,10 +1602,13 @@ var/year_integer = text2num(year) // = 2013???
user << browse(null,"window=exosuit_add_access")
return
if(href_list["dna_lock"])
- if(usr != src.occupant) return
- if(src.occupant && occupant.dna)
- src.dna = src.occupant.dna.unique_enzymes
- src.occupant_message("You feel a prick as the needle takes your DNA sample.")
+ if(usr != src.occupant)
+ return
+ if(src.occupant && !iscarbon(src.occupant))
+ src.occupant << " You do not have any DNA!"
+ return
+ src.dna = src.occupant.dna.unique_enzymes
+ src.occupant_message("You feel a prick as the needle takes your DNA sample.")
return
if(href_list["reset_dna"])
if(usr != src.occupant) return
@@ -1550,54 +1637,6 @@ var/year_integer = text2num(year) // = 2013???
return
*/
-
-
-/*
-
- if (href_list["ai_take_control"])
- var/mob/living/silicon/ai/AI = locate(href_list["ai_take_control"])
- var/duration = text2num(href_list["duration"])
- var/mob/living/silicon/ai/O = new /mob/living/silicon/ai(src)
- var/cur_occupant = src.occupant
- O.invisibility = 0
- O.canmove = 1
- O.name = AI.name
- O.real_name = AI.real_name
- O.anchored = 1
- O.aiRestorePowerRoutine = 0
- O.control_disabled = 1 // Can't control things remotely if you're stuck in a card!
- O.laws = AI.laws
- O.stat = AI.stat
- O.oxyloss = AI.getOxyLoss()
- O.fireloss = AI.getFireLoss()
- O.bruteloss = AI.getBruteLoss()
- O.toxloss = AI.toxloss
- O.updatehealth()
- src.occupant = O
- if(AI.mind)
- AI.mind.transfer_to(O)
- AI.name = "Inactive AI"
- AI.real_name = "Inactive AI"
- AI.icon_state = "ai-empty"
- spawn(duration)
- AI.name = O.name
- AI.real_name = O.real_name
- if(O.mind)
- O.mind.transfer_to(AI)
- AI.control_disabled = 0
- AI.laws = O.laws
- AI.oxyloss = O.getOxyLoss()
- AI.fireloss = O.getFireLoss()
- AI.bruteloss = O.getBruteLoss()
- AI.toxloss = O.toxloss
- AI.updatehealth()
- qdel(O)
- if (!AI.stat)
- AI.icon_state = "ai"
- else
- AI.icon_state = "ai-crash"
- src.occupant = cur_occupant
-*/
return
///////////////////////
diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm
index 8e0343348e6..a9d3579ea9d 100644
--- a/code/game/objects/effects/aliens.dm
+++ b/code/game/objects/effects/aliens.dm
@@ -109,7 +109,6 @@
/obj/structure/alien/resin/hitby(atom/movable/AM)
..()
- visible_message("[src] was hit by [AM].")
var/tforce = 0
if(!isobj(AM))
tforce = 10
@@ -516,4 +515,4 @@
#undef WEED_NORTH_EDGING
#undef WEED_SOUTH_EDGING
#undef WEED_EAST_EDGING
-#undef WEED_WEST_EDGING
\ No newline at end of file
+#undef WEED_WEST_EDGING
diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm
index 3c314ee975c..efd1624bbf0 100644
--- a/code/game/objects/effects/anomalies.dm
+++ b/code/game/objects/effects/anomalies.dm
@@ -44,7 +44,7 @@
/obj/effect/anomaly/grav
name = "gravitational anomaly"
icon_state = "shield2"
- density = 1
+ density = 0
var/boing = 0
/obj/effect/anomaly/grav/New()
@@ -60,6 +60,12 @@
step_towards(O,src)
for(var/mob/living/M in orange(4, src))
step_towards(M,src)
+ for(var/obj/O in orange(1,src))
+ if(!O.anchored)
+ var/mob/living/target = locate() in view(10,src)
+ if(!target)
+ O.throw_at(target, 5, 10)
+
/obj/effect/anomaly/grav/Bump(mob/A)
gravShock(A)
diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm
index 2d7cba31150..c2954010ca4 100644
--- a/code/game/objects/effects/effect_system/effects_smoke.dm
+++ b/code/game/objects/effects/effect_system/effects_smoke.dm
@@ -262,7 +262,7 @@
var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast)
var/more = ""
if(M)
- more = "(?)"
+ more = "(?) (FLW) "
message_admins("A chemical smoke reaction has taken place in ([whereLink])[contained]. Last associated key is [carry.my_atom.fingerprintslast][more].", 0, 1)
log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last associated key is [carry.my_atom.fingerprintslast].")
else
diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm
index 538e98cb003..578fe74bade 100644
--- a/code/game/objects/effects/spawners/lootdrop.dm
+++ b/code/game/objects/effects/spawners/lootdrop.dm
@@ -24,7 +24,7 @@
loot = list(
/obj/item/weapon/gun/projectile/automatic/pistol = 8,
- /obj/item/weapon/gun/projectile/shotgun/combat = 5,
+ /obj/item/weapon/gun/projectile/shotgun/automatic/combat = 5,
/obj/item/weapon/gun/projectile/revolver/mateba,
/obj/item/weapon/gun/projectile/automatic/pistol/deagle
)
diff --git a/code/game/objects/effects/spawners/structure.dm b/code/game/objects/effects/spawners/structure.dm
new file mode 100644
index 00000000000..774b9ca799d
--- /dev/null
+++ b/code/game/objects/effects/spawners/structure.dm
@@ -0,0 +1,33 @@
+/*
+Because mapping is already tedious enough this spawner let you spawn generic
+"sets" of objects rather than having to make the same object stack again and
+again.
+*/
+
+/obj/effect/spawner/structure
+ name = "map structure spawner"
+ var/list/spawn_list
+
+/obj/effect/spawner/structure/New()
+ if(spawn_list && spawn_list.len)
+ for(var/i = 1, i <= spawn_list.len, i++)
+ var/to_spawn = spawn_list[i]
+ new to_spawn(get_turf(src))
+ qdel(src)
+
+/obj/effect/spawner/structure/window
+ icon = 'icons/obj/structures.dmi'
+ icon_state = "window_spawner"
+ name = "window spawner"
+ spawn_list = list(
+ /obj/structure/grille,
+ /obj/structure/window/fulltile
+ )
+
+/obj/effect/spawner/structure/window/reinforced
+ name = "reenforced window spawner"
+ icon_state = "rwindow_spawner"
+ spawn_list = list(
+ /obj/structure/grille,
+ /obj/structure/window/reinforced/fulltile
+ )
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index cdedfe0733f..f0f85603f5c 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -379,8 +379,8 @@
M << "Your eyes start to bleed profusely!"
if(prob(50))
if(M.stat != 2)
- M << "You drop what you're holding and clutch at your eyes!"
- M.drop_item()
+ if(M.drop_item())
+ M << "You drop what you're holding and clutch at your eyes!"
M.eye_blurry += 10
M.Paralyse(1)
M.Weaken(2)
diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm
index 53d7024076e..f18a053d9ba 100644
--- a/code/game/objects/items/blueprints.dm
+++ b/code/game/objects/items/blueprints.dm
@@ -66,8 +66,9 @@
/obj/item/areaeditor/permit/create_area()
- ..()
- qdel(src)
+ var/success = ..()
+ if(success)
+ qdel(src)
//Station blueprints!!!
@@ -84,7 +85,7 @@
var/area/A = get_area()
if(get_area_type() == AREA_STATION)
. += "According to \the [src], you are now in \"[html_encode(A.name)]\".
"
- . += "You may move an amendment to the drawing.
"
+ . += "You may make an amendment to the drawing.
"
var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500)
popup.set_content(.)
popup.open()
@@ -162,7 +163,7 @@
A.addSorted()
interact()
- return
+ return 1
/obj/item/areaeditor/proc/move_turfs_to_area(var/list/turf/turfs, var/area/A)
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index 16f19760d7d..6ef0a3fa4f8 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -50,6 +50,8 @@ var/global/list/obj/item/device/pda/PDAs = list()
var/list/ntrclog = list() //NTRC message log
var/new_ntrc_msg = 0
+ var/image/photo = null //Scanned photo
+
var/noreturn = 0 //whether the PDA can use the Return button, used for the aiPDA chatroom
/obj/item/device/pda/medical
@@ -815,13 +817,15 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(useTC != 2) // Does our recipient have a broadcaster on their level?
U << "ERROR: Cannot reach recipient."
return
- useMS.send_pda_message("[P.owner]","[owner]","[t]")
-
- tnote += "→ To [P.owner]:
[t]
"
- P.tnote += "← From [owner] ([ownjob]):
[t]
"
+ var/msg_ref = useMS.send_pda_message("[P.owner]","[owner]","[t]",photo)
+ var/photo_ref = ""
+ if(photo)
+ photo_ref = "(Photo)"
+ tnote += "→ To [P.owner]:
[t][photo_ref]
"
+ P.tnote += "← From [owner] ([ownjob]):
[t][photo_ref]
"
for(var/mob/M in player_list)
if(isobserver(M) && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTPDA))
- M.show_message("PDA Message - [owner] -> [P.owner]: [t]")
+ M.show_message("PDA Message - [owner] -> [P.owner]: [t][photo_ref]")
if (!P.silent)
playsound(P.loc, 'sound/machines/twobeep.ogg', 50, 1)
@@ -835,9 +839,10 @@ var/global/list/obj/item/device/pda/PDAs = list()
L = get(P, /mob/living/silicon)
if(L)
- L << "\icon[P] Message from [src.owner] ([ownjob]), \"[t]\" (Reply)"
+ L << "\icon[P] Message from [src.owner] ([ownjob]), \"[t]\"[photo_ref] (Reply)"
log_pda("[usr] (PDA: [src.name]) sent \"[t]\" to [P.name]")
+ photo = null
P.overlays.Cut()
P.overlays += image('icons/obj/pda.dmi', "pda-r")
else
@@ -967,6 +972,10 @@ var/global/list/obj/item/device/pda/PDAs = list()
return
C.loc = src
user << "You slide \the [C] into \the [src]."
+ else if(istype(C, /obj/item/weapon/photo))
+ var/obj/item/weapon/photo/P = C
+ photo = P.img
+ user << "You scan \the [C]."
return
/obj/item/device/pda/attack(mob/living/carbon/C, mob/living/user as mob)
@@ -1104,6 +1113,12 @@ var/global/list/obj/item/device/pda/PDAs = list()
return
var/selected = plist[c]
+
+ if(aicamera.aipictures.len>0)
+ var/add_photo = input(user,"Do you want to attach a photo?","Photo","No") as null|anything in list("Yes","No")
+ if(add_photo=="Yes")
+ var/datum/picture/Pic = aicamera.selectpicture(aicamera)
+ src.aiPDA.photo = Pic.fields["img"]
src.aiPDA.create_message(src, selected)
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index 6487e340422..b8e8857f92e 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -6,18 +6,37 @@
item_state = "electronic"
w_class = 2.0
slot_flags = SLOT_BELT
+ flags = NOBLUDGEON
var/flush = null
origin_tech = "programming=4;materials=4"
-/obj/item/device/aicard/attack(mob/living/silicon/ai/M as mob, mob/user as mob)
- if(!istype(M, /mob/living/silicon/ai))//If target is not an AI.
- return ..()
+/obj/item/device/aicard/afterattack(atom/target, mob/user, proximity)
+ ..()
+ if(!proximity || !target)
+ return
+ var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src
+ if(AI) //AI is on the card, implies user wants to upload it.
+ target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
+ add_logs(user, AI, "carded", object="[name]")
+ else //No AI on the card, therefore the user wants to download one.
+ target.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
+ update_state() //Whatever happened, update the card's state (icon, name) to match.
- add_logs(user, M, "carded", object="[src.name]")
- transfer_ai("AICORE", "AICARD", M, user)
- return
+/obj/item/device/aicard/proc/update_state()
+ var/mob/living/silicon/ai/AI = locate(/mob/living/silicon/ai) in src //AI is inside.
+ if(AI)
+ name = "intelliCard - [AI.name]"
+ if (AI.stat == DEAD)
+ icon_state = "aicard-404"
+ else
+ icon_state = "aicard-full"
+ AI.cancel_camera() //AI are forced to move when transferred, so do this whenver one is downloaded.
+ else
+ icon_state = "aicard"
+ name = "intelliCard"
+ overlays.Cut()
/obj/item/device/aicard/attack_self(mob/user)
if (!in_range(src, user))
diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm
index f4953c98812..b91db4b5e30 100644
--- a/code/game/objects/items/devices/camera_bug.dm
+++ b/code/game/objects/items/devices/camera_bug.dm
@@ -349,8 +349,9 @@
for(var/entry in expandables)
if(istype(W,entry))
+ if(!user.unEquip(W))
+ return
bugtype = expandables[entry]
- user.drop_item()
W.loc = src
expansion = W
user << "You add [W] to [src]."
diff --git a/code/game/objects/items/devices/doorCharge.dm b/code/game/objects/items/devices/doorCharge.dm
new file mode 100644
index 00000000000..fe3fd7951a5
--- /dev/null
+++ b/code/game/objects/items/devices/doorCharge.dm
@@ -0,0 +1,32 @@
+/obj/item/device/doorCharge
+ name = "airlock charge"
+ desc = null //Different examine for traitors
+ item_state = "electronic"
+ icon_state = "doorCharge"
+ w_class = 2
+ throw_range = 4
+ throw_speed = 1
+ force = 3
+ attack_verb = list("blown up", "exploded", "detonated")
+ m_amt = 50
+ g_amt = 30
+
+/obj/item/device/doorCharge/ex_act(severity, target)
+ switch(severity)
+ if(1)
+ visible_message("[src] detonates!")
+ explosion(src.loc,0,2,1,flame_range = 4)
+ qdel(src)
+ if(2)
+ if(prob(50))
+ ex_act(1)
+ if(3)
+ if(prob(25))
+ ex_act(1)
+
+/obj/item/device/doorCharge/examine(mob/user)
+ ..()
+ if(user.mind in ticker.mode.traitors) //No nuke ops because the device is excluded from nuclear
+ user << "A small explosive device that can be used to sabotage airlocks to cause an explosion upon opening. To apply, remove the airlock's maintenance panel and place it within."
+ else
+ user << "A small, suspicious object that feels lukewarm when held."
\ No newline at end of file
diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm
index c66a93aa4ad..ff6d78c41ef 100644
--- a/code/game/objects/items/devices/laserpointer.dm
+++ b/code/game/objects/items/devices/laserpointer.dm
@@ -47,7 +47,8 @@
/obj/item/device/laser_pointer/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weapon/stock_parts/micro_laser))
if(!diode)
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
diode = W
user << "You install a [diode.name] in [src]."
diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm
index 4580e823eba..a440715d7a7 100644
--- a/code/game/objects/items/devices/lightreplacer.dm
+++ b/code/game/objects/items/devices/lightreplacer.dm
@@ -88,9 +88,10 @@
var/obj/item/weapon/light/L = W
if(L.status == 0) // LIGHT OKAY
if(uses < max_uses)
+ if(!user.unEquip(W))
+ return
AddUses(1)
user << "You insert the [L.name] into the [src.name]. You have [uses] lights remaining."
- user.drop_item()
qdel(L)
return
else
diff --git a/code/game/objects/items/devices/pizza_bomb.dm b/code/game/objects/items/devices/pizza_bomb.dm
index cbf2bb7d193..86a0c2bc9c5 100644
--- a/code/game/objects/items/devices/pizza_bomb.dm
+++ b/code/game/objects/items/devices/pizza_bomb.dm
@@ -11,6 +11,12 @@
var/correct_wire
var/armer //Used for admin purposes
+/obj/item/device/pizza_bomb/suicide_act(mob/user)
+ user.visible_message("[user] is opening [src]! It looks like \he's hungry and looking for pizza.")
+ sleep(10)
+ go_boom()
+ return(BRUTELOSS)
+
/obj/item/device/pizza_bomb/attack_self(mob/user)
if(disarmed)
user << "\The [src] is disarmed."
@@ -30,7 +36,7 @@
timer = Clamp(timer, 10, 100)
icon_state = "pizzabox1"
user << "You set the timer to [timer / 10] before activating the payload and closing \the [src]."
- message_admins("[key_name(usr)]? has set a timer on a pizza bomb to [timer/10] seconds at (JMP).")
+ message_admins("[key_name_admin(usr)]? (FLW) has set a timer on a pizza bomb to [timer/10] seconds at (JMP).")
log_game("[key_name(usr)] has set the timer on a pizza bomb to [timer/10] seconds ([loc.x],[loc.y],[loc.z]).")
armer = usr
name = "pizza box"
@@ -42,8 +48,8 @@
icon_state = "pizzabox_bomb"
audible_message("\icon[src] *beep* *beep*")
user << "That's no pizza! That's a bomb!"
- message_admins("[key_name(usr)]? has triggered a pizza bomb armed by [armer] at (JMP).")
- log_game("[key_name(usr)] has triggered a pizza bomb armed by [armer] ([loc.x],[loc.y],[loc.z]).")
+ message_admins("[key_name_admin(usr)]? (FLW) has triggered a pizza bomb armed by [key_name_admin(armer)] at (JMP).")
+ log_game("[key_name(usr)] has triggered a pizza bomb armed by [key_name(armer)] ([loc.x],[loc.y],[loc.z]).")
primed = 1
sleep(timer)
return go_boom()
diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm
index 970e7550699..975a08d3a02 100644
--- a/code/game/objects/items/devices/powersink.dm
+++ b/code/game/objects/items/devices/powersink.dm
@@ -95,7 +95,7 @@
"[user] activates \the [src]!", \
"You activate \the [src].",
"You hear a click.")
- message_admins("Power sink activated by [key_name(user, user.client)](?) at ([x],[y],[z] - JMP)")
+ message_admins("Power sink activated by [key_name_admin(user)](?) (FLW) at ([x],[y],[z] - JMP)")
log_game("Power sink activated by [key_name(user)] at ([x],[y],[z])")
set_mode(OPERATING)
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 92ad5697dc7..31f12619e03 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -253,12 +253,14 @@
return
if(!keyslot)
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
keyslot = W
else
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
keyslot2 = W
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 8bed318c4ad..c9cf83c17e9 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -608,7 +608,8 @@
return
if(!keyslot)
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
keyslot = W
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 23bc0cbbc42..ce74426d83d 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -191,6 +191,13 @@ MASS SPECTROMETER
else
user << "Blood level [blood_percent] %, [blood_volume] cl, type: [blood_type]"
+ var/implant_detect
+ for(var/obj/item/cybernetic_implant/CI in H.internal_organs)
+ implant_detect += "[H.name] is modified with a [CI.name].
"
+ if(implant_detect)
+ user.show_message("Detected cybernetic modifications:")
+ user.show_message("[implant_detect]")
+
/proc/chemscan(var/mob/living/user, var/mob/living/M)
if(ishuman(M))
var/mob/living/carbon/human/H = M
diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm
index fd5cb821462..826853d049e 100644
--- a/code/game/objects/items/devices/taperecorder.dm
+++ b/code/game/objects/items/devices/taperecorder.dm
@@ -33,7 +33,8 @@
/obj/item/device/taperecorder/attackby(obj/item/I, mob/user, params)
if(!mytape && istype(I, /obj/item/device/tape))
- user.drop_item()
+ if(!user.unEquip(I))
+ return
I.loc = src
mytape = I
user << "You insert [I] into [src]."
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index 97ffc5e6307..128c6c071bd 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -20,15 +20,17 @@
return
if(!tank_one)
+ if(!user.unEquip(item))
+ return
tank_one = item
- user.drop_item()
item.loc = src
user << "You attach the tank to the transfer valve."
if(item.w_class > w_class)
w_class = item.w_class
else if(!tank_two)
+ if(!user.unEquip(item))
+ return
tank_two = item
- user.drop_item()
item.loc = src
user << "You attach the tank to the transfer valve."
if(item.w_class > w_class)
@@ -174,21 +176,21 @@
if(!attacher)
attacher_name = "Unknown"
else
- attacher_name = "[attacher.name]([attacher.ckey])"
+ attacher_name = "[key_name_admin(attacher)]"
var/log_str1 = "Bomb valve opened in "
var/log_str2 = "with [attachment] attacher: [attacher_name]"
var/log_attacher = ""
if(attacher)
- log_attacher = "(?)"
+ log_attacher = "(?) (FLW)"
var/mob/mob = get_mob_by_key(src.fingerprintslast)
var/last_touch_info = ""
if(mob)
- last_touch_info = "(?)"
+ last_touch_info = "(?) (FLW)"
- var/log_str3 = " Last touched by: [src.fingerprintslast]"
+ var/log_str3 = " Last touched by: [key_name_admin(mob)]"
var/bomb_message = "[log_str1] [A.name] [log_str2][log_attacher] [log_str3][last_touch_info]"
diff --git a/code/game/objects/items/holotape.dm b/code/game/objects/items/holotape.dm
index 68070972d6e..309d52c52a0 100644
--- a/code/game/objects/items/holotape.dm
+++ b/code/game/objects/items/holotape.dm
@@ -216,7 +216,6 @@
/obj/item/holotape/hitby(AM as mob|obj)
..()
- visible_message("[src] was hit by [AM].")
var/tforce = 0
if(ismob(AM))
tforce = 5
@@ -251,4 +250,4 @@
del(src)
return
-#undef MAX_TAPE_RANGE
\ No newline at end of file
+#undef MAX_TAPE_RANGE
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index 3b9868babac..ed337577622 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -102,28 +102,32 @@
return
if(istype(W, /obj/item/robot_parts/l_leg))
if(src.l_leg) return
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
src.l_leg = W
src.updateicon()
if(istype(W, /obj/item/robot_parts/r_leg))
if(src.r_leg) return
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
src.r_leg = W
src.updateicon()
if(istype(W, /obj/item/robot_parts/l_arm))
if(src.l_arm) return
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
src.l_arm = W
src.updateicon()
if(istype(W, /obj/item/robot_parts/r_arm))
if(src.r_arm) return
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
src.r_arm = W
src.updateicon()
@@ -131,7 +135,8 @@
if(istype(W, /obj/item/robot_parts/chest))
if(src.chest) return
if(W:wires && W:cell)
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
src.chest = W
src.updateicon()
@@ -143,7 +148,8 @@
if(istype(W, /obj/item/robot_parts/head))
if(src.head) return
if(W:flash2 && W:flash1)
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
src.head = W
src.updateicon()
@@ -190,7 +196,8 @@
var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc))
if(!O) return
- user.drop_item()
+ if(!user.unEquip(W))
+ return
O.invisibility = 0
//Transfer debug settings to new mob
@@ -297,7 +304,8 @@
user << "You have already inserted a cell!"
return
else
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
src.cell = W
user << "You insert the cell."
@@ -324,7 +332,8 @@
user << "You can't use a broken flash!"
return
else
- user.drop_item()
+ if(!user.unEquip(W))
+ return
F.loc = src
if(src.flash1)
src.flash2 = F
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index ea9be2f7239..26f511b0953 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -474,7 +474,7 @@
return
for(var/obj/effect/decal/cleanable/crayon/old_marking in target)
qdel(old_marking)
- new /obj/effect/decal/cleanable/crayon/gang(target,gangID,temp,graf_rot)
+ new /obj/effect/decal/cleanable/crayon/gang(target,gangID,"graffiti",graf_rot)
user << "You tagged [territory] for your gang!"
else
diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm
index 07ea6047cde..5e2e050242a 100644
--- a/code/game/objects/items/weapons/RCD.dm
+++ b/code/game/objects/items/weapons/RCD.dm
@@ -112,7 +112,8 @@ RCD
if((matter + R.ammoamt) > max_matter)
user << "The RCD can't hold any more matter-units!"
return
- user.drop_item()
+ if(!user.unEquip(W))
+ return
qdel(W)
matter += R.ammoamt
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
@@ -210,7 +211,7 @@ RCD
if(3)
if(istype(A, /turf/simulated/wall))
- var/turf/simulated/wall/W
+ var/turf/simulated/wall/W = A
if(istype(W, /turf/simulated/wall/r_wall) && !canRwall)
return 0
if(checkResource(5, user))
diff --git a/code/game/objects/items/weapons/RPD.dm b/code/game/objects/items/weapons/RPD.dm
index 511e38c8f71..b6735aa37c2 100644
--- a/code/game/objects/items/weapons/RPD.dm
+++ b/code/game/objects/items/weapons/RPD.dm
@@ -25,7 +25,7 @@ RPD
var/categoryId = CATEGORY_ATMOS
var/dir=SOUTH
var/dirtype=PIPE_BINARY
- var/icon = 'icons/obj/pipe-item.dmi'
+ var/icon = 'icons/obj/atmospherics/pipes/pipe_item.dmi'
var/icon_state=""
var/selected=0
@@ -39,7 +39,7 @@ RPD
return "[label]"
/datum/pipe_info/meter
- icon = 'icons/obj/pipes.dmi'
+ icon = 'icons/obj/atmospherics/pipes/simple.dmi'
icon_state = "meterX"
/datum/pipe_info/meter/New()
@@ -64,7 +64,7 @@ var/global/list/disposalpipeID2State=list(
/datum/pipe_info/disposal
categoryId = CATEGORY_DISPOSALS
- icon = 'icons/obj/pipes/disposal.dmi'
+ icon = 'icons/obj/atmospherics/pipes/disposal.dmi'
icon_state = "meterX"
/datum/pipe_info/disposal/New(var/pid,var/dt)
diff --git a/code/game/objects/items/weapons/airlock_painter.dm b/code/game/objects/items/weapons/airlock_painter.dm
index 2f595b5cba0..9ebce21ee0a 100644
--- a/code/game/objects/items/weapons/airlock_painter.dm
+++ b/code/game/objects/items/weapons/airlock_painter.dm
@@ -63,7 +63,8 @@
if(ink)
user << "\the [name] already contains \a [ink]."
return
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
user << "You install \the [W] into \the [name]."
ink = W
diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm
index f3dcfbc4b6b..02114500111 100644
--- a/code/game/objects/items/weapons/defib.dm
+++ b/code/game/objects/items/weapons/defib.dm
@@ -112,7 +112,8 @@
if(C.maxcharge < paddles.revivecost)
user << "[src] requires a higher capacity cell."
return
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
bcell = W
user << "You install a cell in [src]."
diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm
index f1d7d6c19c4..75cca8b52e1 100644
--- a/code/game/objects/items/weapons/explosives.dm
+++ b/code/game/objects/items/weapons/explosives.dm
@@ -37,7 +37,8 @@
message_say = "VIVA LA REVOLUTION!"
user.say(message_say)
target = user
- message_admins("[key_name(user, user.client)](?) suicided with [src.name] at ([x],[y],[z] - JMP)",0,1)
+ message_admins("[key_name_admin(user)](?) (FLW) suicided with [src.name] at ([x],[y],[z] - JMP)",0,1)
+ message_admins("[key_name(user)] suicided with [src.name] at ([x],[y],[z])")
sleep(10)
explode(get_turf(user))
user.gib()
@@ -69,18 +70,19 @@
user << "You start planting the bomb..."
if(do_after(user, 50) && in_range(user, target))
- user.drop_item()
+ if(!user.unEquip(src))
+ return
src.target = target
loc = null
if (ismob(target))
add_logs(user, target, "planted [name] on")
user.visible_message("[user.name] finished planting an explosive on [target.name].", "You finish planting an explosive on [target.name].")
- message_admins("[key_name(user, user.client)](?) planted [src.name] on [key_name(target)](?) with [timer] second fuse",0,1)
+ message_admins("[key_name_admin(user)](?) (FLW) planted [src.name] on [key_name_admin(target)](?) (FLW) with [timer] second fuse",0,1)
log_game("[key_name(user)] planted [src.name] on [key_name(target)] with [timer] second fuse")
else
- message_admins("[key_name(user, user.client)](?) planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - JMP) with [timer] second fuse",0,1)
+ message_admins("[key_name_admin(user)](?) (FLW) planted [src.name] on [target.name] at ([target.x],[target.y],[target.z] - JMP) with [timer] second fuse",0,1)
log_game("[key_name(user)] planted [src.name] on [target.name] at ([target.x],[target.y],[target.z]) with [timer] second fuse")
target.overlays += image_overlay
diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm
index 2f89a0d979e..8688f19167b 100644
--- a/code/game/objects/items/weapons/flamethrower.dm
+++ b/code/game/objects/items/weapons/flamethrower.dm
@@ -65,6 +65,7 @@
var/turf/target_turf = get_turf(target)
if(target_turf)
var/turflist = getline(user, target_turf)
+ add_logs(user, target, "flamethrowered", admin=0, addition="at [target.x],[target.y],[target.z]")
flame_turf(turflist)
/obj/item/weapon/flamethrower/attackby(obj/item/W as obj, mob/user as mob, params)
@@ -94,7 +95,8 @@
var/obj/item/device/assembly/igniter/I = W
if(I.secured) return
if(igniter) return
- user.drop_item()
+ if(!user.unEquip(W))
+ return
I.loc = src
igniter = I
update_icon()
@@ -104,7 +106,8 @@
if(ptank)
user << "There appears to already be a plasma tank loaded in [src]!"
return
- user.drop_item()
+ if(!user.unEquip(W))
+ return
ptank = W
W.loc = src
update_icon()
diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm
index 4731a6bd18a..26bdda71d65 100644
--- a/code/game/objects/items/weapons/gift_wrappaper.dm
+++ b/code/game/objects/items/weapons/gift_wrappaper.dm
@@ -55,6 +55,7 @@
/obj/item/weapon/storage/belt/utility/full,
/obj/item/clothing/tie/horrible,
/obj/item/clothing/suit/jacket/leather,
+ /obj/item/clothing/suit/jacket/leather/overcoat,
/obj/item/clothing/suit/poncho,
/obj/item/clothing/suit/poncho/green,
/obj/item/clothing/suit/poncho/red)
diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm
index ff1812883aa..2823aa83d0f 100644
--- a/code/game/objects/items/weapons/grenades/chem_grenade.dm
+++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm
@@ -33,7 +33,7 @@
else if(clown_check(user))
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
- message_admins("[key_name(usr)]? has primed a [name] for detonation at [A.name] (JMP).")
+ message_admins("[key_name_admin(usr)]? (FLW) has primed a [name] for detonation at [A.name] (JMP).")
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).")
user << "You prime the [name]! [det_time / 10] second\s!"
playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1)
@@ -68,8 +68,9 @@
return
else
if(I.reagents.total_volume)
+ if(!user.unEquip(I))
+ return
user << "You add [I] to the [initial(name)] assembly."
- user.drop_item()
I.loc = src
beakers += I
else
@@ -79,8 +80,9 @@
var/obj/item/device/assembly_holder/A = I
if(isigniter(A.a_left) == isigniter(A.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
return
+ if(!user.unEquip(I))
+ return
- user.drop_item()
nadeassembly = A
A.master = src
A.loc = src
@@ -171,8 +173,8 @@
var/mob/last = get_mob_by_ckey(nadeassembly.fingerprintslast)
var/turf/T = get_turf(src)
var/area/A = get_area(T)
- message_admins("grenade primed by an assembly, attached by [M.key]/[M](?) and last touched by [last.key]/[last](?) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).")
- log_game("grenade primed by an assembly, attached by [M.key]/[M] and last touched by [last.key]/[last] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])")
+ message_admins("grenade primed by an assembly, attached by [key_name_admin(M)](?) (FLW) and last touched by [key_name_admin(last)](?) (FLW) ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] (JMP).")
+ log_game("grenade primed by an assembly, attached by [key_name(M)] and last touched by [key_name(last)] ([nadeassembly.a_left.name] and [nadeassembly.a_right.name]) at [A.name] ([T.x], [T.y], [T.z])")
playsound(loc, 'sound/effects/bamf.ogg', 50, 1)
@@ -263,8 +265,9 @@
//make a special case you might as well do it explicitly. -Sayu
/obj/item/weapon/grenade/chem_grenade/large/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/slime_extract) && stage == WIRED)
+ if(!user.unEquip(I))
+ return
user << "You add [I] to the [initial(name)] assembly."
- user.drop_item()
I.loc = src
beakers += I
else
diff --git a/code/game/objects/items/weapons/grenades/ghettobomb.dm b/code/game/objects/items/weapons/grenades/ghettobomb.dm
index 37459241a78..b8ce111bdbe 100644
--- a/code/game/objects/items/weapons/grenades/ghettobomb.dm
+++ b/code/game/objects/items/weapons/grenades/ghettobomb.dm
@@ -49,7 +49,7 @@
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
- message_admins("[key_name(usr)]? has primed a [name] for detonation at [A.name] (JMP).")
+ message_admins("[key_name_admin(usr)]? (FLW) has primed a [name] for detonation at [A.name] (JMP).")
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).")
if(iscarbon(user))
var/mob/living/carbon/C = user
diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm
index 51a787a0b28..85375327940 100644
--- a/code/game/objects/items/weapons/grenades/grenade.dm
+++ b/code/game/objects/items/weapons/grenades/grenade.dm
@@ -64,7 +64,7 @@
add_fingerprint(user)
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
- message_admins("[key_name(usr)]? has primed a [name] for detonation at [A.name] (JMP).")
+ message_admins("[key_name_admin(usr)]? (FLW) has primed a [name] for detonation at [A.name] (JMP).")
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).")
if(iscarbon(user))
var/mob/living/carbon/C = user
diff --git a/code/game/objects/items/weapons/handcuffs.dm b/code/game/objects/items/weapons/handcuffs.dm
index 39d8cf6b0f5..1c9eaccc389 100644
--- a/code/game/objects/items/weapons/handcuffs.dm
+++ b/code/game/objects/items/weapons/handcuffs.dm
@@ -49,7 +49,8 @@
/obj/item/weapon/restraints/handcuffs/proc/apply_cuffs(mob/living/carbon/target, mob/user)
if(!target.handcuffed)
- user.drop_item()
+ if(!user.drop_item())
+ return
//target.throw_alert("handcuffed", src) // Can't do this because escaping cuffs isn't standardized. Also zipties.
if(trashtype)
target.handcuffed = new trashtype(target)
@@ -227,4 +228,4 @@
qdel(src)
/obj/item/weapon/restraints/legcuffs/beartrap/energy/attack_hand(mob/user)
- Crossed(user) //honk
\ No newline at end of file
+ Crossed(user) //honk
diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm
index 97b0a8304ad..b22b7439eae 100644
--- a/code/game/objects/items/weapons/implants/implant.dm
+++ b/code/game/objects/items/weapons/implants/implant.dm
@@ -174,15 +174,15 @@
/obj/item/weapon/implant/loyalty/implanted(mob/target)
..()
- if((target.mind in (ticker.mode.head_revolutionaries | ticker.mode.A_bosses | ticker.mode.B_bosses)) || is_shadow_or_thrall(target))
+ if((target.mind in ticker.mode.head_revolutionaries) || is_shadow_or_thrall(target))
target.visible_message("[target] seems to resist the implant!", "You feel the corporate tendrils of Nanotrasen try to invade your mind!")
return 0
- if(target.mind in (ticker.mode.A_gang | ticker.mode.B_gang))
- ticker.mode.remove_gangster(target.mind, exclude_bosses=0)
- return 0
if(target.mind in ticker.mode.revolutionaries)
ticker.mode.remove_revolutionary(target.mind)
- target << "You feel a surge of loyalty towards Nanotrasen."
+ if(target.mind in (ticker.mode.cult| ticker.mode.A_bosses | ticker.mode.B_bosses | ticker.mode.A_gang | ticker.mode.B_gang))
+ target << "You feel the corporate tendrils of Nanotrasen try to invade your mind!"
+ else
+ target << "You feel a surge of loyalty towards Nanotrasen."
return 1
diff --git a/code/game/objects/items/weapons/implants/implantpad.dm b/code/game/objects/items/weapons/implants/implantpad.dm
index 1720cb073e0..615d719fef3 100644
--- a/code/game/objects/items/weapons/implants/implantpad.dm
+++ b/code/game/objects/items/weapons/implants/implantpad.dm
@@ -36,7 +36,8 @@
..()
if(istype(C, /obj/item/weapon/implantcase))
if(!case)
- user.drop_item()
+ if(!user.unEquip(C))
+ return
C.loc = src
case = C
else
diff --git a/code/game/objects/items/weapons/melee/energy.dm b/code/game/objects/items/weapons/melee/energy.dm
index 886ce709f86..81ac92e29f0 100644
--- a/code/game/objects/items/weapons/melee/energy.dm
+++ b/code/game/objects/items/weapons/melee/energy.dm
@@ -185,8 +185,5 @@
/obj/item/weapon/melee/energy/blade/dropped()
qdel(src)
-/obj/item/weapon/melee/energy/blade/proc/throw()
- qdel(src)
-
/obj/item/weapon/melee/energy/blade/attack_self(mob/user)
return
diff --git a/code/game/objects/items/weapons/paiwire.dm b/code/game/objects/items/weapons/paiwire.dm
index 83933cbf4c3..33de9fcba06 100644
--- a/code/game/objects/items/weapons/paiwire.dm
+++ b/code/game/objects/items/weapons/paiwire.dm
@@ -8,8 +8,9 @@
/obj/item/weapon/pai_cable/proc/plugin(obj/machinery/M as obj, mob/user as mob)
if(istype(M, /obj/machinery/door) || istype(M, /obj/machinery/camera))
+ if(!user.drop_item())
+ return
user.visible_message("[user] inserts [src] into a data port on [M].", "You insert [src] into a data port on [M].", "You hear the satisfying click of a wire jack fastening into place.")
- user.drop_item()
src.loc = M
src.machine = M
else
diff --git a/code/game/objects/items/weapons/pneumaticCannon.dm b/code/game/objects/items/weapons/pneumaticCannon.dm
index 7ccd3432491..f4af87c3f10 100644
--- a/code/game/objects/items/weapons/pneumaticCannon.dm
+++ b/code/game/objects/items/weapons/pneumaticCannon.dm
@@ -61,8 +61,9 @@
if(IW.w_class > src.w_class)
user << "\The [IW] is too large to fit into \the [src]!"
return
+ if(!user.unEquip(W))
+ return
user << "You load \the [IW] into \the [src]."
- user.drop_item()
loadedItems.Add(IW)
loadedWeightClass += IW.w_class
IW.loc = src
@@ -127,9 +128,10 @@
if(src.tank)
user << "\The [src] already has a tank."
return
+ if(!user.unEquip(thetank))
+ return
user << "You hook \the [thetank] up to \the [src]."
src.tank = thetank
- user.drop_item()
thetank.loc = src
src.update_icons()
diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm
index 778252c04f1..d8aed9fdd9d 100644
--- a/code/game/objects/items/weapons/storage/backpack.dm
+++ b/code/game/objects/items/weapons/storage/backpack.dm
@@ -35,6 +35,15 @@
max_w_class = 5
max_combined_w_class = 35
+/obj/item/weapon/storage/backpack/holding/suicide_act(mob/user)
+ user.visible_message("[user] is jumping into [src]! It looks like \he's trying to commit suicide.")
+ user.drop_item()
+ user.Stun(5)
+ sleep(20)
+ playsound(src, "rustle", 50, 1, -5)
+ qdel(user)
+ return
+
/obj/item/weapon/storage/backpack/holding/can_be_inserted(obj/item/W, stop_messages = 0, mob/user)
if(crit_fail)
user << "The Bluespace generator isn't working."
@@ -278,6 +287,24 @@
item_state = "duffle-syndieammo"
slowdown = 0
+/obj/item/weapon/storage/backpack/dufflebag/syndieammo/loaded
+ desc = "A large dufflebag, packed to the brim with Bulldog shotgun ammo."
+
+/obj/item/weapon/storage/backpack/dufflebag/syndieammo/loaded/New()
+ ..()
+ contents = list()
+ new /obj/item/ammo_box/magazine/m12g(src)
+ new /obj/item/ammo_box/magazine/m12g(src)
+ new /obj/item/ammo_box/magazine/m12g(src)
+ new /obj/item/ammo_box/magazine/m12g(src)
+ new /obj/item/ammo_box/magazine/m12g(src)
+ new /obj/item/ammo_box/magazine/m12g(src)
+ new /obj/item/ammo_box/magazine/m12g/buckshot(src)
+ new /obj/item/ammo_box/magazine/m12g/stun(src)
+ new /obj/item/ammo_box/magazine/m12g/dragon(src)
+ return
+
+
/obj/item/weapon/storage/backpack/dufflebag/captain
name = "captain's dufflebag"
desc = "A large dufflebag for holding extra captainly goods."
diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm
index 35ec6dfbb1b..ac320fd7d07 100644
--- a/code/game/objects/items/weapons/storage/lockbox.dm
+++ b/code/game/objects/items/weapons/storage/lockbox.dm
@@ -41,6 +41,13 @@
user << "It's locked!"
return
+/obj/item/weapon/storage/lockbox/MouseDrop(over_object, src_location, over_location)
+ if (locked)
+ src.add_fingerprint(usr)
+ usr << "It's locked!"
+ return 0
+ ..()
+
/obj/item/weapon/storage/lockbox/emag_act(mob/user as mob)
if(!broken)
broken = 1
@@ -57,6 +64,13 @@
..()
return
+//Check the destination item type for contentto.
+/obj/item/weapon/storage/lockbox/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
+ if(locked)
+ user << "It's locked!"
+ return 0
+ return ..()
+
/obj/item/weapon/storage/lockbox/can_be_inserted(obj/item/W, stop_messages = 0)
if(locked)
return 0
diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm
index b8c214924f6..8cffa2dee32 100644
--- a/code/game/objects/items/weapons/storage/secure.dm
+++ b/code/game/objects/items/weapons/storage/secure.dm
@@ -75,10 +75,10 @@
/obj/item/weapon/storage/secure/MouseDrop(over_object, src_location, over_location)
if (locked)
src.add_fingerprint(usr)
- return
+ usr << "It's locked!"
+ return 0
..()
-
/obj/item/weapon/storage/secure/attack_self(mob/user as mob)
user.set_machine(src)
var/dat = text("[]
\n\nLock Status: []",src, (src.locked ? "LOCKED" : "UNLOCKED"))
@@ -128,6 +128,12 @@
return
return
+/obj/item/weapon/storage/secure/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
+ if(locked)
+ user << "It's locked!"
+ return 0
+ return ..()
+
/obj/item/weapon/storage/secure/can_be_inserted(obj/item/W, stop_messages = 0)
if(locked)
return 0
diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm
index ac11ad700f2..ad0f33b6965 100644
--- a/code/game/objects/items/weapons/storage/storage.dm
+++ b/code/game/objects/items/weapons/storage/storage.dm
@@ -25,10 +25,13 @@
var/preposition = "in" // You put things 'in' a bag, but trays need 'on'.
-/obj/item/weapon/storage/MouseDrop(obj/over_object)
+/obj/item/weapon/storage/MouseDrop(atom/over_object)
if(iscarbon(usr) || isdrone(usr)) //all the check for item manipulation are in other places, you can safely open any storages as anything and its not buggy, i checked
var/mob/M = usr
+ if(!over_object)
+ return
+
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
return
@@ -39,13 +42,14 @@
show_to(M)
return
- if(!( istype(over_object, /obj/screen) ))
- return ..()
-
- if(!(loc == usr) || (loc && loc.loc == usr))
- return
- playsound(loc, "rustle", 50, 1, -5)
if(!( M.restrained() ) && !( M.stat ))
+ if(!( istype(over_object, /obj/screen) ))
+ return content_can_dump(over_object, M)
+
+ if(!(loc == usr) || (loc && loc.loc == usr))
+ return
+
+ playsound(loc, "rustle", 50, 1, -5)
switch(over_object.name)
if("r_hand")
if(!M.unEquip(src))
@@ -56,8 +60,26 @@
return
M.put_in_l_hand(src)
add_fingerprint(usr)
- return
+//Check if this storage can dump the items
+/obj/item/weapon/storage/proc/content_can_dump(atom/dest_object, mob/user)
+ if(Adjacent(user) && dest_object.Adjacent(user))
+ if(dest_object.storage_contents_dump_act(src, user))
+ playsound(loc, "rustle", 50, 1, -5)
+ return 1
+ return 0
+
+//Object behaviour on storage dump
+/obj/item/weapon/storage/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
+ for(var/obj/item/I in src_object)
+ if(can_be_inserted(I,0,user))
+ src_object.remove_from_storage(I, src)
+ orient2hud(user)
+ src_object.orient2hud(user)
+ if(user.s_active) //refresh the HUD to show the transfered contents
+ user.s_active.close(user)
+ user.s_active.show_to(user)
+ return 1
/obj/item/weapon/storage/proc/return_inv()
var/list/L = list()
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index 8fc6d771551..40b1ab14670 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -71,7 +71,8 @@
if(C.maxcharge < hitcost)
user << "[src] requires a higher capacity cell."
return
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
bcell = W
user << "You install a cell in [src]."
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index 76ce25a17ba..08e3c4ad173 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -96,7 +96,13 @@
ui_interact(user)
-/obj/item/weapon/tank/ui_interact(mob/user, ui_key = "main")
+/obj/item/weapon/tank/interact(mob/user, ui_key = "main")
+ SSnano.try_update_ui(user, src, ui_key, null, src.get_ui_data())
+
+/obj/item/weapon/tank/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "tanks.tmpl", "Tank", 500, 300, 0)
+
+/obj/item/weapon/tank/get_ui_data()
var/mob/living/carbon/location = null
if(istype(loc, /mob/living/carbon))
@@ -104,19 +110,12 @@
else if(istype(loc.loc, /mob/living/carbon))
location = loc.loc
- var/using_internal
- if(istype(location))
- if(location.internal==src)
- using_internal = 1
-
- // this is the data which will be sent to the ui
var/data = list()
data["tankPressure"] = round(air_contents.return_pressure() ? air_contents.return_pressure() : 0)
data["releasePressure"] = round(distribute_pressure ? distribute_pressure : 0)
data["defaultReleasePressure"] = round(TANK_DEFAULT_RELEASE_PRESSURE)
data["maxReleasePressure"] = round(TANK_MAX_RELEASE_PRESSURE)
- data["valveOpen"] = using_internal ? 1 : 0
-
+ data["valveOpen"] = 0
data["maskConnected"] = 0
if(istype(location))
@@ -124,6 +123,7 @@
if(location.internal == src) // if tank is current internal
mask_check = 1
+ data["valveOpen"] = 1
else if(src in location) // or if tank is in the mobs possession
if(!location.internal) // and they do not have any active internals
mask_check = 1
@@ -131,16 +131,7 @@
if(mask_check)
if(location.wear_mask && (location.wear_mask.flags & MASKINTERNALS))
data["maskConnected"] = 1
-
- var/datum/nanoui/ui = SSnano.get_open_ui(user, src, ui_key)
- if (!ui)
- ui = new /datum/nanoui(user, src, ui_key, "tanks.tmpl", "Tank", 500, 300)
- ui.set_initial_data(data)
- ui.open()
- ui.set_auto_update(1)
- else
- ui.push_data(data)
-
+ return data
/obj/item/weapon/tank/Topic(href, href_list)
..()
diff --git a/code/game/objects/items/weapons/twohanded.dm b/code/game/objects/items/weapons/twohanded.dm
index 58c98b443d8..71ab242d878 100644
--- a/code/game/objects/items/weapons/twohanded.dm
+++ b/code/game/objects/items/weapons/twohanded.dm
@@ -128,8 +128,10 @@
/obj/item/weapon/twohanded/required/attack_hand(mob/user)//Can't even pick it up without both hands empty
var/obj/item/weapon/twohanded/required/H = user.get_inactive_hand()
+ if(get_dist(src,user) > 1)
+ return 0
if(H != null)
- user.visible_message("[src.name] is too cumbersome to carry in one hand!")
+ user << "[src.name] is too cumbersome to carry in one hand!"
return
var/obj/item/weapon/twohanded/offhand/O = new(user)
user.put_in_inactive_hand(O)
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index dde6cba1c31..e6a76907189 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -152,3 +152,7 @@
/obj/get_spans()
return ..() | SPAN_ROBOT
+
+/obj/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
+ var/turf/T = get_turf(src)
+ return T.storage_contents_dump_act(src_object, user)
\ No newline at end of file
diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm
index 907b4db38e1..610a6d27743 100644
--- a/code/game/objects/structures/ai_core.dm
+++ b/code/game/objects/structures/ai_core.dm
@@ -41,11 +41,12 @@
anchored = 0
state = 0
if(istype(P, /obj/item/weapon/circuitboard/aicore) && !circuit)
+ if(!user.drop_item())
+ return
playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1)
user << "You place the circuit board inside the frame."
icon_state = "1"
circuit = P
- user.drop_item()
P.loc = src
if(istype(P, /obj/item/weapon/screwdriver) && circuit)
playsound(loc, 'sound/items/Screwdriver.ogg', 50, 1)
@@ -152,11 +153,13 @@
user << "This MMI is mindless!"
return
+ if(!user.drop_item())
+ return
+
ticker.mode.remove_cultist(M.brainmob.mind, 1)
ticker.mode.remove_revolutionary(M.brainmob.mind, 1)
ticker.mode.remove_gangster(M.brainmob.mind, 1)
- user.drop_item()
M.loc = src
brain = M
usr << "Added a brain."
@@ -220,106 +223,27 @@ This is a good place for AI-related object verbs so I'm sticking it here.
If adding stuff to this, don't forget that an AI need to cancel_camera() whenever it physically moves to a different location.
That prevents a few funky behaviors.
*/
-//What operation to perform based on target, what ineraction to perform based on object used, target itself, user. The object used is src and calls this proc.
-/obj/item/proc/transfer_ai(var/choice as text, var/interaction as text, var/target, var/mob/U as mob)
- if(istype(src, /obj/item/device/aicard))
- var/obj/item/device/aicard/icard = src
- if(icard.flush)
- U << "ERROR: AI flush is in progress, cannot execute transfer protocol."
- return
+//The type of interaction, the player performing the operation, the AI itself, and the card object, if any.
- switch(choice)
- if("AICORE")//AI mob.
- var/mob/living/silicon/ai/T = target
- if(!T.mind)
- U << "No intelligence patterns detected." //No more magical carding of empty cores, AI RETURN TO BODY!!!11
- return
- switch(interaction)
- if("AICARD")
- var/obj/item/device/aicard/C = src
- if(C.contents.len)//If there is an AI on card.
- U << "Transfer failed: Existing AI found on this terminal. Remove existing AI to install a new one."
- else
- if (ticker.mode.name == "AI malfunction")
- var/datum/game_mode/malfunction/malf = ticker.mode
- for (var/datum/mind/malfai in malf.malf_ai)
- if (T.mind == malfai)
- U << "ERROR: Remote transfer interface disabled."//Do ho ho ho~
- return
- new /obj/structure/AIcore/deactivated(T.loc)//Spawns a deactivated terminal at AI location.
- T.aiRestorePowerRoutine = 0//So the AI initially has power.
- T.control_disabled = 1//Can't control things remotely if you're stuck in a card!
- T.radio_enabled = 0 //No talking on the built-in radio for you either!
- T.loc = C//Throw AI into the card.
- C.name = "intelliCard - [T.name]"
- if (T.stat == 2)
- C.icon_state = "aicard-404"
- else
- C.icon_state = "aicard-full"
- T.cancel_camera()
- T << "You have been downloaded to a mobile storage device. Remote device connection severed."
- U << "Transfer successful: [T.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
- if("INACTIVE")//Inactive AI object.
- var/obj/structure/AIcore/deactivated/T = target
- switch(interaction)
- if("AICARD")
- var/obj/item/device/aicard/C = src
- var/mob/living/silicon/ai/A = locate() in C//I love locate(). Best proc ever.
- if(A)//If AI exists on the card. Else nothing since both are empty.
- A.control_disabled = 0
- A.radio_enabled = 1
- A.loc = T.loc//To replace the terminal.
- C.icon_state = "aicard"
- C.name = "intelliCard"
- C.overlays.Cut()
- A.cancel_camera()
- A << "You have been uploaded to a stationary terminal. Remote device connection restored."
- U << "Transfer successful: [A.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed."
- qdel(T)
+atom/proc/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card)
+ if(istype(card))
+ if(card.flush)
+ user << "ERROR: AI flush is in progress, cannot execute transfer protocol."
+ return 0
+ return 1
- if("AIFIXER")//AI Fixer terminal.
- var/obj/machinery/computer/aifixer/T = target
- switch(interaction)
- if("AICARD")
- var/obj/item/device/aicard/C = src
- if(!T.contents.len)
- if (!C.contents.len)
- U << "No AI to copy over!"//Well duh
- else for(var/mob/living/silicon/ai/A in C)
- C.icon_state = "aicard"
- C.name = "intelliCard"
- C.overlays.Cut()
- A.loc = T
- T.occupier = A
- A.control_disabled = 1
- A.radio_enabled = 0
- if (A.stat == 2)
- T.overlays += image('icons/obj/computer.dmi', "ai-fixer-404")
- else
- T.overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
- T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-empty")
- A.cancel_camera()
- A << "You have been uploaded to a stationary terminal. Sadly, there is no remote access from here."
- U << "Transfer successful: [A.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed."
- else
- if(!C.contents.len && T.occupier && !T.active)
- C.name = "intelliCard - [T.occupier.name]"
- T.overlays += image('icons/obj/computer.dmi', "ai-fixer-empty")
- if (T.occupier.stat == 2)
- C.icon_state = "aicard-404"
- T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-404")
- else
- C.icon_state = "aicard-full"
- T.overlays -= image('icons/obj/computer.dmi', "ai-fixer-full")
- T.occupier << "You have been downloaded to a mobile storage device. Still no remote access."
- U << "Transfer successful: [T.occupier.name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
- T.occupier.loc = C
- T.occupier.cancel_camera()
- T.occupier = null
- else if (C.contents.len)
- U << "ERROR: Artificial intelligence detected on terminal."
- else if (T.active)
- U << "ERROR: Reconstruction in progress."
- else if (!T.occupier)
- U << "ERROR: Unable to locate artificial intelligence."
\ No newline at end of file
+
+/obj/structure/AIcore/deactivated/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card)
+ if(!..())
+ return
+ //Transferring a carded AI to a core.
+ if(interaction == AI_TRANS_FROM_CARD)
+ AI.control_disabled = 0
+ AI.radio_enabled = 1
+ AI.loc = loc//To replace the terminal.
+ AI << "You have been uploaded to a stationary terminal. Remote device connection restored."
+ user << "Transfer successful: [AI.name] ([rand(1000,9999)].exe) installed and executed successfully. Local copy has been removed."
+ qdel(src)
+ else //If for some reason you use an empty card on an empty AI terminal.
+ user << "There is no AI loaded on this terminal!"
\ No newline at end of file
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index 37428c37333..073ae4e2e53 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -194,7 +194,8 @@ LINEN BINS
/obj/structure/bedsheetbin/attackby(obj/item/I as obj, mob/user as mob, params)
if(istype(I, /obj/item/weapon/bedsheet))
- user.drop_item()
+ if(!user.drop_item())
+ return
I.loc = src
sheets.Add(I)
amount++
diff --git a/code/game/objects/structures/crates_lockers/bins.dm b/code/game/objects/structures/crates_lockers/bins.dm
index edabca55fb7..bbcec247b70 100644
--- a/code/game/objects/structures/crates_lockers/bins.dm
+++ b/code/game/objects/structures/crates_lockers/bins.dm
@@ -84,8 +84,7 @@
/obj/structure/closet/crate/bin/place(var/mob/user, var/obj/item/I)
if(contents.len >= storage_capacity)
return 1
- if(!opened)
- user.drop_item()
+ if(!opened && user.drop_item())
insert(I, 0, 1)
return 1
return 0
\ No newline at end of file
diff --git a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm b/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
deleted file mode 100644
index bf94d93a874..00000000000
--- a/code/game/objects/structures/crates_lockers/closets/fireaxe.dm
+++ /dev/null
@@ -1,244 +0,0 @@
-//I still dont think this should be a closet but whatever
-/obj/structure/closet/fireaxecabinet
- name = "fire axe cabinet"
- desc = "There is small label that reads \"For Emergency use only\" along with details for safe use of the axe. As if."
- var/obj/item/weapon/twohanded/fireaxe/fireaxe = new/obj/item/weapon/twohanded/fireaxe
- icon = 'icons/obj/wallmounts.dmi'
- icon_state = "fireaxe1000"
- anchored = 1
- density = 0
- wall_mounted = 1
- var/localopened = 0 //Setting this to keep it from behaviouring like a normal closet and obstructing movement in the map. -Agouri
- opened = 1
- var/hitstaken = 0
- locked = 1
- var/smashed = 0
-
-/obj/structure/closet/fireaxecabinet/attackby(var/obj/item/O as obj, var/mob/living/user as mob, params) //Marker -Agouri
- //..() //That's very useful, Erro
-
- var/hasaxe = 0 //gonna come in handy later~
- if(fireaxe)
- hasaxe = 1
-
- if (isrobot(user) || src.locked)
- if(istype(O, /obj/item/device/multitool))
- user << "Resetting circuitry..."
- playsound(user, 'sound/machines/lockreset.ogg', 50, 1)
- if(do_after(user, 20))
- src.locked = 0
- user << "You disable the locking modules."
- update_icon()
- return
- else if(istype(O, /obj/item/weapon))
- user.changeNext_move(CLICK_CD_MELEE)
- var/obj/item/weapon/W = O
- if(src.smashed || src.localopened)
- if(localopened)
- localopened = 0
- icon_state = "fireaxe[hasaxe][src.localopened][src.hitstaken][src.smashed]closing"
- spawn(10) update_icon()
- return
- else
- user.do_attack_animation(src)
- playsound(user, 'sound/effects/Glasshit.ogg', 100, 1) //We don't want this playing every time
- if(W.force < 15)
- user << "The cabinet's protective glass glances off the hit."
- else
- src.hitstaken++
- if(src.hitstaken == 4)
- playsound(user, 'sound/effects/Glassbr3.ogg', 100, 1) //Break cabinet, receive goodies. Cabinet's fucked for life after that.
- src.smashed = 1
- src.locked = 0
- src.localopened = 1
- update_icon()
- return
- if (istype(O, /obj/item/weapon/twohanded/fireaxe) && src.localopened)
- if(!fireaxe)
- if(O:wielded)
- user << "Unwield the axe first."
- return
- fireaxe = O
- user.drop_item()
- src.contents += O
- user << "You place the fire axe back in the [src.name]."
- update_icon()
- else
- if(src.smashed)
- return
- else
- localopened = !localopened
- if(localopened)
- icon_state = "fireaxe[hasaxe][src.localopened][src.hitstaken][src.smashed]opening"
- spawn(10) update_icon()
- else
- icon_state = "fireaxe[hasaxe][src.localopened][src.hitstaken][src.smashed]closing"
- spawn(10) update_icon()
- else
- if(src.smashed)
- return
- if(istype(O, /obj/item/device/multitool))
- if(localopened)
- localopened = 0
- icon_state = "fireaxe[hasaxe][src.localopened][src.hitstaken][src.smashed]closing"
- spawn(10) update_icon()
- return
- else
- user << "Resetting circuitry..."
- playsound(user, 'sound/machines/lockenable.ogg', 50, 1)
- if(do_after(user, 20))
- src.locked = 1
- user << "You re-enable the locking modules."
- return
- else
- localopened = !localopened
- if(localopened)
- icon_state = "fireaxe[hasaxe][src.localopened][src.hitstaken][src.smashed]opening"
- spawn(10) update_icon()
- else
- icon_state = "fireaxe[hasaxe][src.localopened][src.hitstaken][src.smashed]closing"
- spawn(10) update_icon()
-
-
-/obj/structure/closet/fireaxecabinet/ex_act(severity, target)
- switch(severity)
- if(1.0)
- qdel(src)
- return
- if(2.0)
- if(prob(50))
- if(fireaxe)
- fireaxe.loc = src.loc
- qdel(src)
- return
- if(3.0)
- return
-
-/obj/structure/closet/fireaxecabinet/bullet_act(var/obj/item/projectile/Proj)
- if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
- health -= Proj.damage
- if(Proj.damage >= 15 && !smashed && !localopened)
- hitstaken++
- if(health <= 0)
- if(fireaxe)
- fireaxe.loc = src.loc
- qdel(src)
- return
- if(hitstaken >= 4)
- playsound(src, 'sound/effects/Glassbr3.ogg', 100, 1)
- smashed = 1
- locked = 0
- localopened = 1
- update_icon()
-
-/obj/structure/closet/fireaxecabinet/blob_act()
- if(prob(75))
- if(fireaxe)
- fireaxe.loc = src.loc
- qdel(src)
-
-
-/obj/structure/closet/fireaxecabinet/attack_hand(mob/user as mob)
- var/hasaxe = 0
- if(fireaxe)
- hasaxe = 1
-
- if(src.locked)
- user <<"The cabinet won't budge!"
- return
- if(localopened)
- if(fireaxe)
- user.put_in_hands(fireaxe)
- fireaxe = null
- user << "You take the fire axe from the [name]."
- src.add_fingerprint(user)
- update_icon()
- else
- if(src.smashed)
- return
- else
- localopened = !localopened
- if(localopened)
- src.icon_state = "fireaxe[hasaxe][src.localopened][src.hitstaken][src.smashed]opening"
- spawn(10) update_icon()
- else
- src.icon_state = "fireaxe[hasaxe][src.localopened][src.hitstaken][src.smashed]closing"
- spawn(10) update_icon()
-
- else
- localopened = !localopened //I'm pretty sure we don't need an if(src.smashed) in here. In case I'm wrong and it fucks up teh cabinet, **MARKER**. -Agouri
- if(localopened)
- src.icon_state = "fireaxe[hasaxe][src.localopened][src.hitstaken][src.smashed]opening"
- spawn(10) update_icon()
- else
- src.icon_state = "fireaxe[hasaxe][src.localopened][src.hitstaken][src.smashed]closing"
- spawn(10) update_icon()
-
-/obj/structure/closet/fireaxecabinet/attack_tk(mob/user as mob)
- if(localopened && fireaxe)
- fireaxe.loc = loc
- user << "You telekinetically remove the fire axe."
- fireaxe = null
- update_icon()
- return
- attack_hand(user)
-
-/obj/structure/closet/fireaxecabinet/verb/toggle_openness() //nice name, huh? HUH?! -Erro //YEAH -Agouri
- set name = "Open/Close"
- set category = "Object"
-
- if (isrobot(usr) || src.locked || src.smashed)
- if(src.locked)
- usr << "The cabinet won't budge!"
- else if(src.smashed)
- usr << "The protective glass is broken!"
- return
-
- localopened = !localopened
- update_icon()
-
-/obj/structure/closet/fireaxecabinet/verb/remove_fire_axe()
- set name = "Remove Fire Axe"
- set category = "Object"
-
- if (isrobot(usr))
- return
-
- if (localopened)
- if(fireaxe)
- usr.put_in_hands(fireaxe)
- fireaxe = null
- usr << "You take the Fire axe from the [name]."
- else
- usr << "The [src.name] is empty."
- else
- usr << "The [src.name] is closed."
- update_icon()
-
-/obj/structure/closet/fireaxecabinet/attack_paw(mob/user as mob)
- attack_hand(user)
- return
-
-/obj/structure/closet/fireaxecabinet/attack_ai(mob/user as mob)
- if(src.smashed)
- user << "The security of the cabinet is compromised."
- return
- else
- locked = !locked
- if(locked)
- user << "Cabinet locked."
- else
- user << "Cabinet unlocked."
- return
-
-/obj/structure/closet/fireaxecabinet/update_icon() //Template: fireaxe[has fireaxe][is opened][hits taken][is smashed]. If you want the opening or closing animations, add "opening" or "closing" right after the numbers
- var/hasaxe = 0
- if(fireaxe)
- hasaxe = 1
- icon_state = "fireaxe[hasaxe][src.localopened][src.hitstaken][src.smashed]"
-
-/obj/structure/closet/fireaxecabinet/open()
- return
-
-/obj/structure/closet/fireaxecabinet/close()
- return
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
index c603163c427..8d4bcdf25b9 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/cargo.dm
@@ -18,6 +18,7 @@
/obj/structure/closet/secure_closet/quartermaster/New()
..()
+ new /obj/item/clothing/cloak/qm(src)
new /obj/item/clothing/suit/hooded/wintercoat/cargo(src)
new /obj/item/clothing/under/rank/cargo(src)
new /obj/item/clothing/shoes/sneakers/brown(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
index 206eef09a91..5b50e1ba885 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
@@ -11,6 +11,7 @@
new /obj/item/weapon/storage/backpack/industrial(src)
else
new /obj/item/weapon/storage/backpack/satchel_eng(src)
+ new /obj/item/clothing/cloak/ce(src)
new /obj/item/weapon/storage/backpack/dufflebag/engineering(src)
new /obj/item/clothing/under/rank/chief_engineer(src)
new /obj/item/clothing/head/hardhat/white(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
index 6f7a5d24e61..960f31e3d99 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/medical.dm
@@ -71,6 +71,7 @@
new /obj/item/weapon/storage/backpack/medic(src)
else
new /obj/item/weapon/storage/backpack/satchel_med(src)
+ new /obj/item/clothing/cloak/cmo(src)
new /obj/item/weapon/storage/backpack/dufflebag/med(src)
new /obj/item/clothing/suit/bio_suit/cmo(src)
new /obj/item/clothing/head/bio_hood/cmo(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
index 3720a560df7..d71768caea0 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/scientist.dm
@@ -24,6 +24,7 @@
/obj/structure/closet/secure_closet/RD/New()
..()
+ new /obj/item/clothing/cloak/rd(src)
new /obj/item/clothing/suit/hooded/wintercoat/science(src)
new /obj/item/clothing/suit/bio_suit/scientist(src)
new /obj/item/clothing/head/bio_hood/scientist(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
index 47af5875f04..63074fe5145 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm
@@ -10,6 +10,7 @@
new /obj/item/weapon/storage/backpack/captain(src)
else
new /obj/item/weapon/storage/backpack/satchel_cap(src)
+ new /obj/item/clothing/cloak/cap(src)
new /obj/item/weapon/storage/backpack/dufflebag/captain(src)
new /obj/item/clothing/suit/captunic(src)
new /obj/item/clothing/under/captainparade(src)
@@ -53,11 +54,13 @@
/obj/structure/closet/secure_closet/hos/New()
..()
+ new /obj/item/clothing/cloak/hos(src)
new /obj/item/clothing/suit/hooded/wintercoat/security(src)
new /obj/item/weapon/cartridge/hos(src)
new /obj/item/device/radio/headset/heads/hos(src)
new /obj/item/clothing/under/hosparadefem(src)
new /obj/item/clothing/under/hosparademale(src)
+ new /obj/item/clothing/suit/armor/vest/leather(src)
new /obj/item/clothing/suit/armor/hos(src)
new /obj/item/clothing/under/rank/head_of_security/alt(src)
new /obj/item/clothing/head/HoS(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/syndicate.dm b/code/game/objects/structures/crates_lockers/closets/syndicate.dm
index 13dbc939b43..b6ad237fbba 100644
--- a/code/game/objects/structures/crates_lockers/closets/syndicate.dm
+++ b/code/game/objects/structures/crates_lockers/closets/syndicate.dm
@@ -31,7 +31,6 @@
new /obj/item/weapon/storage/box/flashbangs(src)
new /obj/item/weapon/storage/box/teargas(src)
new /obj/item/weapon/storage/backpack/dufflebag/syndiemed(src)
- new /obj/item/weapon/storage/backpack/dufflebag/syndieammo(src)
new /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog(src)
new /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog(src)
new /obj/item/weapon/gun/projectile/automatic/shotgun/bulldog(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
index 37433c2423c..5bc3a306e50 100644
--- a/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
+++ b/code/game/objects/structures/crates_lockers/closets/wardrobe.dm
@@ -68,6 +68,8 @@
new /obj/item/clothing/under/color/black(src)
if(prob(25))
new /obj/item/clothing/suit/jacket/leather(src)
+ if(prob(25))
+ new /obj/item/clothing/suit/jacket/leather/overcoat(src)
new /obj/item/clothing/shoes/sneakers/black(src)
new /obj/item/clothing/shoes/sneakers/black(src)
new /obj/item/clothing/shoes/sneakers/black(src)
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index abbf7e51461..14a4fe411bd 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -286,8 +286,9 @@
return
else if(istype(W, /obj/item/device/electropack))
if(rigged)
+ if(!user.drop_item())
+ return
user << "You attach [W] to [src]."
- user.drop_item()
W.loc = src
return
else if(istype(W, /obj/item/weapon/wirecutters))
diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm
index a0fa16da823..4b53bb0e629 100644
--- a/code/game/objects/structures/door_assembly.dm
+++ b/code/game/objects/structures/door_assembly.dm
@@ -532,8 +532,9 @@
if(do_after(user, 40))
if( src.state != 1 )
return
+ if(!user.drop_item())
+ return
- user.drop_item()
W.loc = src
user << "You install the airlock electronics."
src.state = 2
diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm
index 06c763ffca7..e56bcd0a4ee 100644
--- a/code/game/objects/structures/extinguisher.dm
+++ b/code/game/objects/structures/extinguisher.dm
@@ -29,7 +29,8 @@
return
if(istype(O, /obj/item/weapon/extinguisher))
if(!has_extinguisher && opened)
- user.drop_item()
+ if(!user.drop_item())
+ return
contents += O
has_extinguisher = O
user << "You place [O] in [src]."
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index 9f5415d64e0..0cb8ec524f7 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -141,6 +141,9 @@
playsound(src, 'sound/items/Welder.ogg', 100, 1)
qdel(src)
+/obj/structure/falsewall/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
+ return 0
+
/*
* False R-Walls
*/
@@ -238,8 +241,8 @@
/obj/structure/falsewall/plasma/attackby(obj/item/weapon/W, mob/user, params)
if(is_hot(W) > 300)
- message_admins("Plasma falsewall ignited by [key_name(user, user.client)](?) in ([x],[y],[z] - JMP)",0,1)
- log_game("Plasma falsewall ignited by [user.ckey]([user]) in ([x],[y],[z])")
+ message_admins("Plasma falsewall ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1)
+ log_game("Plasma falsewall ignited by [key_name(user)] in ([x],[y],[z])")
burnbabyburn()
return
..()
diff --git a/code/game/objects/structures/fireaxe.dm b/code/game/objects/structures/fireaxe.dm
new file mode 100644
index 00000000000..831c009fad8
--- /dev/null
+++ b/code/game/objects/structures/fireaxe.dm
@@ -0,0 +1,141 @@
+/obj/structure/fireaxecabinet
+ name = "fire axe cabinet"
+ desc = "There is small label that reads \"For Emergency use only\" along with details for safe use of the axe. As if."
+ var/obj/item/weapon/twohanded/fireaxe/fireaxe = new/obj/item/weapon/twohanded/fireaxe
+ icon = 'icons/obj/wallmounts.dmi'
+ icon_state = "fireaxe"
+ anchored = 1
+ density = 0
+ var/locked = 1
+ var/open = 0
+ var/glass_hp = 60
+
+/obj/structure/fireaxecabinet/New()
+ ..()
+ update_icon()
+
+/obj/structure/fireaxecabinet/attackby(obj/item/I as obj, mob/user as mob, params)
+ if(isrobot(user) || istype(I,/obj/item/device/multitool))
+ toggle_lock(user)
+ return
+ if(open || glass_hp <= 0)
+ if(istype(I, /obj/item/weapon/twohanded/fireaxe) && !fireaxe)
+ var/obj/item/weapon/twohanded/fireaxe/F = I
+ if(F.wielded)
+ user << "Unwield the [F.name] first."
+ return
+ if(!user.drop_item())
+ return
+ fireaxe = F
+ src.contents += F
+ user << "You place the [F.name] back in the [name]."
+ update_icon()
+ return
+ else if(istype(I, /obj/item/weapon))
+ user.changeNext_move(CLICK_CD_MELEE)
+ var/obj/item/weapon/W = I
+ user.do_attack_animation(src)
+ playsound(src, 'sound/effects/Glasshit.ogg', 100, 1)
+ if(W.force >= 10)
+ glass_hp -= W.force
+ if(glass_hp <= 0)
+ playsound(src, 'sound/effects/Glassbr3.ogg', 100, 1)
+ update_icon()
+ else
+ user << "The [name]'s protective glass glances off the hit."
+
+/obj/structure/fireaxecabinet/ex_act(severity, target)
+ switch(severity)
+ if(1.0)
+ qdel(src)
+ return
+ if(2.0)
+ if(prob(50) && fireaxe)
+ fireaxe.loc = src.loc
+ qdel(src)
+ return
+ if(3.0)
+ return
+
+/obj/structure/fireaxecabinet/bullet_act(var/obj/item/projectile/Proj)
+ if((Proj.damage_type == BRUTE || Proj.damage_type == BURN))
+ if(Proj.damage)
+ glass_hp -= Proj.damage
+ if(glass_hp <= 0)
+ playsound(src, 'sound/effects/Glassbr3.ogg', 100, 1)
+ update_icon()
+
+/obj/structure/fireaxecabinet/blob_act()
+ if(prob(75) && fireaxe)
+ fireaxe.loc = src.loc
+ qdel(src)
+
+/obj/structure/fireaxecabinet/attack_hand(mob/user as mob)
+ if(open || glass_hp <= 0)
+ if(fireaxe)
+ user.put_in_hands(fireaxe)
+ fireaxe = null
+ user << "You take the fire axe from the [name]."
+ src.add_fingerprint(user)
+ update_icon()
+ return
+ if(locked)
+ user <<" The [name] won't budge!"
+ return
+ else
+ open = !open
+ update_icon()
+ return
+
+/obj/structure/fireaxecabinet/attack_paw(mob/user as mob)
+ if(ismonkey(user)) //no fire-axe wielding aliens allowed
+ attack_hand(user)
+ return
+
+/obj/structure/fireaxecabinet/attack_ai(mob/user as mob)
+ toggle_lock(user)
+ return
+
+/obj/structure/fireaxecabinet/update_icon()
+ overlays.Cut()
+ if(fireaxe)
+ overlays += "axe"
+ if(!open)
+ switch(glass_hp)
+ if(-INFINITY to 0)
+ overlays += "glass4"
+ if(1 to 20)
+ overlays += "glass3"
+ if(21 to 40)
+ overlays += "glass2"
+ if(41 to 59)
+ overlays += "glass1"
+ if(60)
+ overlays += "glass"
+ if(locked)
+ overlays += "locked"
+ else
+ overlays += "unlocked"
+ else
+ overlays += "glass_raised"
+
+/obj/structure/fireaxecabinet/proc/toggle_lock(mob/user)
+ user << " Resetting circuitry..."
+ playsound(src, 'sound/machines/locktoggle.ogg', 50, 1)
+ if(do_after(user, 20))
+ user << "You [locked ? "disable" : "re-enable"] the locking modules."
+ locked = !locked
+ update_icon()
+
+/obj/structure/fireaxecabinet/verb/toggle_open() //nice name, huh? HUH?! -Erro //YEAH -Agouri
+ set name = "Open/Close"
+ set category = "Object"
+ set src in oview(1)
+
+ if(locked)
+ usr <<" The [name] won't budge!"
+ return
+ else
+ open = !open
+ update_icon()
+ return
\ No newline at end of file
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index fd324892490..23df00bef19 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -201,7 +201,8 @@
else if(istype(W, /obj/item/pipe))
var/obj/item/pipe/P = W
if (P.pipe_type in list(0, 1, 5)) //simple pipes, simple bends, and simple manifolds.
- user.drop_item()
+ if(!user.drop_item())
+ return
P.loc = src.loc
user << "You fit the pipe into \the [src]."
else
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index 79fda3eda5c..3fbe01e9bf7 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -251,7 +251,6 @@
/obj/structure/grille/hitby(AM as mob|obj)
..()
- visible_message("[src] was hit by [AM].")
var/tforce = 0
if(ismob(AM))
tforce = 5
@@ -261,3 +260,6 @@
playsound(loc, 'sound/effects/grillehit.ogg', 80, 1)
health = max(0, health - tforce)
healthcheck()
+
+/obj/structure/grille/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
+ return 0
\ No newline at end of file
diff --git a/code/game/objects/structures/guncase.dm b/code/game/objects/structures/guncase.dm
index 5793006ba6f..ae8c5b4e861 100644
--- a/code/game/objects/structures/guncase.dm
+++ b/code/game/objects/structures/guncase.dm
@@ -39,7 +39,8 @@
return
if(istype(I, gun_category))
if(contents.len < capacity && open)
- user.drop_item()
+ if(!user.drop_item())
+ return
contents += I
user << "You place [I] in [src]."
update_icon()
diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm
index b5a265e2c76..58aebf4ca25 100644
--- a/code/game/objects/structures/janicart.dm
+++ b/code/game/objects/structures/janicart.dm
@@ -29,7 +29,8 @@
playsound(loc, 'sound/effects/slosh.ogg', 25, 1)
/obj/structure/janitorialcart/proc/put_in_cart(obj/item/I, mob/user)
- user.drop_item()
+ if(!user.drop_item())
+ return
I.loc = src
updateUsrDialog()
user << "You put [I] into [src]."
@@ -199,8 +200,9 @@
user << "Hold [I] in one of your hands while you drive this [callme]."
else if(istype(I, /obj/item/weapon/storage/bag/trash))
if(keytype == /obj/item/key/janitor)
+ if(!user.drop_item())
+ return
user << "You hook the trashbag onto the [callme]."
- user.drop_item()
I.loc = src
mybag = I
else if(istype(I, /obj/item/janiupgrade))
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 49537016514..cc7c6035e7a 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -219,8 +219,8 @@
/obj/structure/mineral_door/transparent/plasma/attackby(obj/item/weapon/W, mob/user, params)
if(is_hot(W))
- message_admins("Plasma mineral door ignited by [key_name(user, user.client)](?) in ([x],[y],[z] - JMP)",0,1)
- log_game("Plasma mineral door ignited by [user.ckey]([user]) in ([x],[y],[z])")
+ message_admins("Plasma mineral door ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1)
+ log_game("Plasma mineral door ignited by [key_name(user)] in ([x],[y],[z])")
TemperatureAct(100)
..()
diff --git a/code/game/objects/structures/mirror.dm b/code/game/objects/structures/mirror.dm
index a5414196e9d..50597091b3b 100644
--- a/code/game/objects/structures/mirror.dm
+++ b/code/game/objects/structures/mirror.dm
@@ -111,14 +111,16 @@
/obj/structure/mirror/magic/New()
if(!choosable_races.len)
- for(var/datum/species/S in typesof(/datum/species) - /datum/species)
+ for(var/speciestype in typesof(/datum/species) - /datum/species)
+ var/datum/species/S = new speciestype()
if(!(S.id in races_blacklist))
- choosable_races += S
+ choosable_races += S.id
..()
/obj/structure/mirror/magic/badmin/New()
- for(var/datum/species/S in typesof(/datum/species) - /datum/species)
- choosable_races += S
+ for(var/speciestype in typesof(/datum/species) - /datum/species)
+ var/datum/species/S = new speciestype()
+ choosable_races += S.id
..()
/obj/structure/mirror/magic/attack_hand(mob/user as mob)
diff --git a/code/game/objects/structures/noticeboard.dm b/code/game/objects/structures/noticeboard.dm
index d5997adfda9..7d8591217f6 100644
--- a/code/game/objects/structures/noticeboard.dm
+++ b/code/game/objects/structures/noticeboard.dm
@@ -19,9 +19,10 @@
/obj/structure/noticeboard/attackby(var/obj/item/weapon/O as obj, var/mob/user as mob, params)
if(istype(O, /obj/item/weapon/paper))
if(notices < 5)
+ if(!user.drop_item())
+ return
O.add_fingerprint(user)
add_fingerprint(user)
- user.drop_item()
O.loc = src
notices++
icon_state = "nboard0[notices]" //update sprite
diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm
index 60989279c54..74c5f66aa58 100644
--- a/code/game/objects/structures/statues.dm
+++ b/code/game/objects/structures/statues.dm
@@ -207,8 +207,8 @@
/obj/structure/statue/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(is_hot(W) > 300)//If the temperature of the object is over 300, then ignite
- message_admins("Plasma statue ignited by [key_name(user, user.client)](?) in ([x],[y],[z] - JMP)",0,1)
- log_game("Plasma statue ignited by [user.ckey]([user]) in ([x],[y],[z])")
+ message_admins("Plasma statue ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1)
+ log_game("Plasma statue ignited by [key_name(user)] in ([x],[y],[z])")
ignite(is_hot(W))
return
..()
diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
index 829d6a6dd44..915f56b9ac0 100644
--- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
+++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm
@@ -17,8 +17,9 @@
/obj/structure/stool/bed/chair/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
..()
if(istype(W, /obj/item/assembly/shock_kit))
+ if(!user.drop_item())
+ return
var/obj/item/assembly/shock_kit/SK = W
- user.drop_item()
var/obj/structure/stool/bed/chair/e_chair/E = new /obj/structure/stool/bed/chair/e_chair(src.loc)
playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1)
E.dir = dir
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index f776ab56d7e..b25fa12dd81 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -625,8 +625,9 @@
/obj/item/weapon/rack_parts/attack_self(mob/user as mob)
user << "You start constructing rack..."
if (do_after(user, 50))
+ if(!user.drop_item())
+ return
var/obj/structure/rack/R = new /obj/structure/rack( user.loc )
R.add_fingerprint(user)
- user.drop_item()
qdel(src)
return
diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm
index da9c57601e3..3cc45f3ac5e 100644
--- a/code/game/objects/structures/tank_dispenser.dm
+++ b/code/game/objects/structures/tank_dispenser.dm
@@ -50,7 +50,8 @@
/obj/structure/dispenser/attackby(obj/item/I as obj, mob/user as mob, params)
if(istype(I, /obj/item/weapon/tank/internals/oxygen) || istype(I, /obj/item/weapon/tank/internals/air) || istype(I, /obj/item/weapon/tank/internals/anesthetic))
if(oxygentanks < 10)
- user.drop_item()
+ if(!user.drop_item())
+ return
I.loc = src
oxytanks.Add(I)
oxygentanks++
@@ -59,7 +60,8 @@
user << "[src] is full."
if(istype(I, /obj/item/weapon/tank/internals/plasma))
if(plasmatanks < 10)
- user.drop_item()
+ if(!user.drop_item())
+ return
I.loc = src
platanks.Add(I)
plasmatanks++
diff --git a/code/game/objects/structures/target_stake.dm b/code/game/objects/structures/target_stake.dm
index 0048a1cdb28..5e23a7f994f 100644
--- a/code/game/objects/structures/target_stake.dm
+++ b/code/game/objects/structures/target_stake.dm
@@ -23,11 +23,10 @@
/obj/structure/target_stake/attackby(obj/item/target/T, mob/user)
if(pinned_target)
return
- if(istype(T))
+ if(istype(T) && user.drop_item())
pinned_target = T
T.pinnedLoc = src
T.density = 1
- user.drop_item()
T.layer = OBJ_LAYER + 0.1
T.loc = loc
user << "You slide the target into the stake."
diff --git a/code/game/objects/structures/transit_tubes/station.dm b/code/game/objects/structures/transit_tubes/station.dm
index cbc1fbb529a..208fb23b973 100644
--- a/code/game/objects/structures/transit_tubes/station.dm
+++ b/code/game/objects/structures/transit_tubes/station.dm
@@ -4,7 +4,7 @@
// one.
/obj/structure/transit_tube/station
name = "station tube station"
- icon = 'icons/obj/pipes/transit_tube_station.dmi'
+ icon = 'icons/obj/atmospherics/pipes/transit_tube_station.dmi'
icon_state = "closed"
exit_delay = 1
enter_delay = 2
diff --git a/code/game/objects/structures/transit_tubes/transit_tube.dm b/code/game/objects/structures/transit_tubes/transit_tube.dm
index 3db04c5088a..5d376fa93fe 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube.dm
@@ -3,7 +3,7 @@
// Mappers: you can use "Generate Instances from Icon-states"
// to get the different pieces.
/obj/structure/transit_tube
- icon = 'icons/obj/pipes/transit_tube.dmi'
+ icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
icon_state = "E-W"
density = 1
layer = 3.1
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm
index cb47c7c4e15..54b49942a8e 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_construction.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_construction.dm
@@ -3,7 +3,7 @@
// normal transit tubes
/obj/structure/c_transit_tube
name = "unattached transit tube"
- icon = 'icons/obj/pipes/transit_tube.dmi'
+ icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
icon_state = "E-W" //icon_state decides which tube will be built
density = 0
layer = 3.1 //same as the built tube
@@ -92,7 +92,7 @@
// transit tube station
/obj/structure/c_transit_tube/station
name = "unattached through station"
- icon = 'icons/obj/pipes/transit_tube_station.dmi'
+ icon = 'icons/obj/atmospherics/pipes/transit_tube_station.dmi'
icon_state = "closed"
/obj/structure/c_transit_tube/station/tube_turn(var/angle)
@@ -122,7 +122,7 @@
// in that sense they're the same as stations and can reuse their flip and rotate verbs
/obj/structure/c_transit_tube/station/block
name = "unattached tube blocker"
- icon = 'icons/obj/pipes/transit_tube.dmi'
+ icon = 'icons/obj/atmospherics/pipes/transit_tube.dmi'
icon_state = "Block"
/obj/structure/c_transit_tube/station/block/buildtube()
@@ -136,7 +136,7 @@
//see station.dm for the logic
/obj/structure/c_transit_tube_pod
name = "unattached transit tube pod"
- icon = 'icons/obj/pipes/transit_tube_pod.dmi'
+ icon = 'icons/obj/atmospherics/pipes/transit_tube_pod.dmi'
icon_state = "pod"
anchored = 0.0
density = 0
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
index b686464321e..33cfa7bf823 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
@@ -1,5 +1,5 @@
/obj/structure/transit_tube_pod
- icon = 'icons/obj/pipes/transit_tube_pod.dmi'
+ icon = 'icons/obj/atmospherics/pipes/transit_tube_pod.dmi'
icon_state = "pod"
animate_movement = FORWARD_STEPS
anchored = 1.0
diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm
index 8262201bf28..1f41f887adb 100644
--- a/code/game/objects/structures/windoor_assembly.dm
+++ b/code/game/objects/structures/windoor_assembly.dm
@@ -190,9 +190,10 @@
//Adding airlock electronics for access. Step 6 complete.
else if(istype(W, /obj/item/weapon/airlock_electronics))
+ if(!user.drop_item())
+ return
playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1)
user.visible_message("[user] installs the electronics into the airlock assembly.", "You start to install electronics into the airlock assembly...")
- user.drop_item()
W.loc = src
if(do_after(user, 40))
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 131844894c1..1284b9b0aaf 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -93,7 +93,6 @@
/obj/structure/window/hitby(AM as mob|obj)
..()
- visible_message("[src] was hit by [AM].")
var/tforce = 0
if(ismob(AM))
tforce = 40
@@ -415,6 +414,8 @@
hit(round(exposed_volume / 100), 0)
..()
+/obj/structure/window/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
+ return 0
/obj/structure/window/reinforced
name = "reinforced window"
@@ -456,4 +457,4 @@
maxhealth = 100
wtype = "shuttle"
fulltile = 1
- reinf = 1
\ No newline at end of file
+ reinf = 1
diff --git a/code/game/turfs/simulated/floor/light_floor.dm b/code/game/turfs/simulated/floor/light_floor.dm
index 85755fc867d..abb5c5c4fab 100644
--- a/code/game/turfs/simulated/floor/light_floor.dm
+++ b/code/game/turfs/simulated/floor/light_floor.dm
@@ -63,8 +63,7 @@
if(..())
return
if(istype(C,/obj/item/weapon/light/bulb)) //only for light tiles
- if(state)
- user.drop_item()
+ if(state && user.drop_item())
qdel(C)
state = 0 //fixing it by bashing it with a light bulb, fun eh?
update_icon()
diff --git a/code/game/turfs/simulated/floor/mineral_floor.dm b/code/game/turfs/simulated/floor/mineral_floor.dm
index ca8716d2d82..2b4d3ddc198 100644
--- a/code/game/turfs/simulated/floor/mineral_floor.dm
+++ b/code/game/turfs/simulated/floor/mineral_floor.dm
@@ -40,8 +40,8 @@
/turf/simulated/floor/mineral/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(is_hot(W) > 300)//If the temperature of the object is over 300, then ignite
- message_admins("Plasma flooring was ignited by [key_name(user, user.client)](?) in ([x],[y],[z] - JMP)",0,1)
- log_game("Plasma flooring was ignited by [user.ckey]([user]) in ([x],[y],[z])")
+ message_admins("Plasma flooring was ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1)
+ log_game("Plasma flooring was ignited by [key_name(user)] in ([x],[y],[z])")
ignite(is_hot(W))
return
..()
diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm
index 2829c18e6c9..b2330065a64 100644
--- a/code/game/turfs/simulated/walls.dm
+++ b/code/game/turfs/simulated/walls.dm
@@ -264,4 +264,7 @@
/turf/simulated/wall/narsie_act()
if(prob(20))
- ChangeTurf(/turf/simulated/wall/cult)
\ No newline at end of file
+ ChangeTurf(/turf/simulated/wall/cult)
+
+/turf/simulated/wall/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
+ return 0
\ No newline at end of file
diff --git a/code/game/turfs/simulated/walls_mineral.dm b/code/game/turfs/simulated/walls_mineral.dm
index fb73c1f61c6..edc2c01fe2a 100644
--- a/code/game/turfs/simulated/walls_mineral.dm
+++ b/code/game/turfs/simulated/walls_mineral.dm
@@ -97,8 +97,8 @@
/turf/simulated/wall/mineral/plasma/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if(is_hot(W) > 300)//If the temperature of the object is over 300, then ignite
- message_admins("Plasma wall ignited by [key_name(user, user.client)](?) in ([x],[y],[z] - JMP)",0,1)
- log_game("Plasma wall ignited by [user.ckey]([user]) in ([x],[y],[z])")
+ message_admins("Plasma wall ignited by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1)
+ log_game("Plasma wall ignited by [key_name(user)] in ([x],[y],[z])")
ignite(is_hot(W))
return
..()
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 82ae1d4ec21..71d40ca2dd4 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -2,6 +2,7 @@
icon = 'icons/turf/floors.dmi'
level = 1.0
+ var/slowdown = 0 //negative for faster, positive for slower
var/intact = 1
var/baseturf = /turf/space
@@ -192,6 +193,11 @@
/turf/proc/Bless()
flags |= NOJAUNT
+/turf/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
+ for(var/obj/item/I in src_object)
+ src_object.remove_from_storage(I, src) //No check needed, put everything inside
+ return 1
+
//////////////////////////////
//Distance procs
//////////////////////////////
@@ -286,3 +292,4 @@
name = "Centcom Access"
icon = 'icons/obj/doors/Doorele.dmi'
icon_state = "door_closed"
+
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 203d4b7e9a9..d715ca89b8b 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -39,7 +39,7 @@ var/global/floorIsLava = 0
body += "TP - "
body += "PM - "
body += "SM - "
- body += "JMP\]
"
+ body += "FLW\]
"
body += "Mob type = [M.type]
"
@@ -399,91 +399,6 @@ var/global/floorIsLava = 0
usr << browse(dat, "window=admin2;size=210x180")
return
-/datum/admins/proc/Secrets()
- if(!check_rights(0)) return
-
- var/dat = "The first rule of adminbuse is: you don't talk about the adminbuse.
"
-
- dat +={"
- General Secrets
-
- Show Job Debug
- Admin Log
- Show Admin List
-
- "}
-
- if(check_rights(R_ADMIN,0))
- dat += {"
- Admin Secrets
-
- Cure all diseases currently in existence
- Bombing List
- Show current traitors and objectives
- Show last [length(lastsignalers)] signalers
- Show last [length(lawchanges)] law changes
- Show AI Laws
- Show Game Mode
- Show Crew Manifest
- List DNA (Blood)
- List Fingerprints
-
- Shuttles
-
- Move Ferry
- Move Mining Shuttle
- Move Labor Shuttle
-
- "}
-
- if(check_rights(R_FUN,0))
- dat += {"
- Fun Secrets
-
- Reset Thunderdome to default state
- Trigger a Virus Outbreak
- Turn all humans into monkeys
- Change the species of all humans
- Make all areas powered
- Make all areas unpowered
- Power all SMES
- Triple AI mode (needs to be used in the lobby)
- Everyone is the traitor
- Summon Guns
- Summon Magic
- Summon Events (Toggle)
- There can only be one!
- Make all players retarded
- Egalitarian Station Mode
- Break all lights
- Fix all lights
- The floor is lava! (DANGEROUS: extremely lame)
-
- "}
-
-/* DEATH SQUADS
-Send in a strike team
-*/
- if(check_rights(R_SERVER,0))
- dat += "Toggle bomb cap
"
-
- dat += "
"
-
- if(check_rights(R_DEBUG,0))
- dat += {"
- Security Level Elevated
-
- Change all maintenance doors to engie/brig access only
- Change all maintenance doors to brig access only
- Remove cap on security officers
-
- "}
-
- usr << browse(dat, "window=secrets")
- return
-
-
-
/////////////////////////////////////////////////////////////////////////////////////////////////admins2.dm merge
//i.e. buttons/verbs
diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm
index 31f01164df4..543bc79d287 100644
--- a/code/modules/admin/admin_investigate.dm
+++ b/code/modules/admin/admin_investigate.dm
@@ -19,7 +19,7 @@
if(!message) return
var/F = investigate_subject2file(subject)
if(!F) return
- F << "[time2text(world.timeofday,"hh:mm")] \ref[src] ([x],[y],[z]) || [src] [message]
"
+ F << "[time_stamp()] \ref[src] ([x],[y],[z]) || [src] [message]
"
//ADMINVERBS
/client/proc/investigate_show( subject in list("hrefs","notes","ntsl","singulo","wires","telesci", "gravity", "records", "cargo", "supermatter", "atmos", "experimentor", "kudzu") )
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 1c073505ab8..c48b54bc764 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -86,7 +86,9 @@ var/list/admin_verbs_fun = list(
/client/proc/set_ooc,
/client/proc/reset_ooc,
/client/proc/forceEvent,
- /client/proc/bluespace_artillery
+ /client/proc/bluespace_artillery,
+ /client/proc/admin_change_sec_level,
+ /client/proc/toggle_nuke
)
var/list/admin_verbs_spawn = list(
/datum/admins/proc/spawn_atom, /*allows us to spawn instances*/
@@ -198,7 +200,9 @@ var/list/admin_verbs_hideable = list(
/proc/release,
/client/proc/reload_admins,
/client/proc/reset_all_tcs,
- /client/proc/panicbunker
+ /client/proc/panicbunker,
+ /client/proc/admin_change_sec_level,
+ /client/proc/toggle_nuke
)
/client/proc/add_admin_verbs()
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index 54592390be8..f424d2cd7a9 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -81,7 +81,7 @@
body += "TP - "
body += "PM - "
body += "SM - "
- body += "JMP
"
+ body += "FLW
"
if(antagonist > 0)
body += "Antagonist";
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
new file mode 100644
index 00000000000..4390f383d8b
--- /dev/null
+++ b/code/modules/admin/secrets.dm
@@ -0,0 +1,612 @@
+/datum/admins/proc/Secrets()
+ if(!check_rights(0)) return
+
+ var/dat = "The first rule of adminbuse is: you don't talk about the adminbuse.
"
+
+ dat +={"
+ General Secrets
+
+ Show Job Debug
+ Admin Log
+ Show Admin List
+
+ "}
+
+ if(check_rights(R_ADMIN,0))
+ dat += {"
+ Admin Secrets
+
+ Cure all diseases currently in existence
+ Bombing List
+ Show current traitors and objectives
+ Show last [length(lastsignalers)] signalers
+ Show last [length(lawchanges)] law changes
+ Show AI Laws
+ Show Game Mode
+ Show Crew Manifest
+ List DNA (Blood)
+ List Fingerprints
+ Reset Thunderdome to default state
+
+ Shuttles
+
+ Move Ferry
+ Move Mining Shuttle
+ Move Labor Shuttle
+
+ "}
+
+ if(check_rights(R_FUN,0))
+ dat += {"
+ Fun Secrets
+
+
+ Trigger a Virus Outbreak
+ Turn all humans into monkeys
+ Change the species of all humans
+ Make all areas powered
+ Make all areas unpowered
+ Power all SMES
+ Triple AI mode (needs to be used in the lobby)
+ Everyone is the traitor
+ Summon Guns
+ Summon Magic
+ Summon Events (Toggle)
+ There can only be one!
+ Make all players retarded
+ Egalitarian Station Mode
+ Break all lights
+ Fix all lights
+ The floor is lava! (DANGEROUS: extremely lame)
+
+ Change bomb cap
+ "}
+
+ dat += "
"
+
+ if(check_rights(R_DEBUG,0))
+ dat += {"
+ Security Level Elevated
+
+ Change all maintenance doors to engie/brig access only
+ Change all maintenance doors to brig access only
+ Remove cap on security officers
+
+ "}
+
+ usr << browse(dat, "window=secrets")
+ return
+
+
+
+
+
+/datum/admins/proc/Secrets_topic(var/item,var/href_list)
+ var/datum/round_event/E
+ var/ok = 0
+ switch(item)
+ if("admin_log")
+ var/dat = "Admin Log
"
+ for(var/l in admin_log)
+ dat += "[l]"
+ if(!admin_log.len)
+ dat += "No-one has done anything this round!"
+ usr << browse(dat, "window=admin_log")
+
+ if("list_job_debug")
+ var/dat = "Job Debug info.
"
+ if(SSjob)
+ for(var/line in SSjob.job_debug)
+ dat += "[line]
"
+ dat+= "*******
"
+ for(var/datum/job/job in SSjob.occupations)
+ if(!job) continue
+ dat += "job: [job.title], current_positions: [job.current_positions], total_positions: [job.total_positions]
"
+ usr << browse(dat, "window=jobdebug;size=600x500")
+
+ if("show_admins")
+ var/dat = "Current admins:
"
+ if(admin_datums)
+ for(var/ckey in admin_datums)
+ var/datum/admins/D = admin_datums[ckey]
+ dat += "[ckey] - [D.rank.name]
"
+ usr << browse(dat, "window=showadmins;size=600x500")
+
+ if("tdomereset")
+ if(!check_rights(R_ADMIN))
+ return
+ var/delete_mobs = alert("Clear all mobs?","Confirm","Yes","No","Cancel")
+ if(delete_mobs == "Cancel")
+ return
+
+ log_admin("[key_name(usr)] reset the thunderdome to default with delete_mobs==[delete_mobs].", 1)
+ message_admins("[key_name_admin(usr)] reset the thunderdome to default with delete_mobs==[delete_mobs].")
+
+ var/area/thunderdome = locate(/area/tdome/arena)
+ if(delete_mobs == "Yes")
+ for(var/mob/living/mob in thunderdome)
+ qdel(mob) //Clear mobs
+ for(var/obj/obj in thunderdome)
+ if(!istype(obj,/obj/machinery/camera))
+ qdel(obj) //Clear objects
+
+ var/area/template = locate(/area/tdome/arena_source)
+ template.copy_contents_to(thunderdome)
+
+ if("clear_virus")
+
+ var/choice = input("Are you sure you want to cure all disease?") in list("Yes", "Cancel")
+ if(choice == "Yes")
+ message_admins("[key_name_admin(usr)] has cured all diseases.")
+ for(var/datum/disease/D in SSdisease.processing)
+ D.cure(D)
+
+ if("list_bombers")
+ if(!check_rights(R_ADMIN))
+ return
+ var/dat = "Bombing List
"
+ for(var/l in bombers)
+ dat += text("[l]
")
+ usr << browse(dat, "window=bombers")
+
+ if("list_signalers")
+ if(!check_rights(R_ADMIN))
+ return
+ var/dat = "Showing last [length(lastsignalers)] signalers.
"
+ for(var/sig in lastsignalers)
+ dat += "[sig]
"
+ usr << browse(dat, "window=lastsignalers;size=800x500")
+
+ if("list_lawchanges")
+ if(!check_rights(R_ADMIN))
+ return
+ var/dat = "Showing last [length(lawchanges)] law changes.
"
+ for(var/sig in lawchanges)
+ dat += "[sig]
"
+ usr << browse(dat, "window=lawchanges;size=800x500")
+
+ if("check_antagonist")
+ if(!check_rights(R_ADMIN))
+ return
+ check_antagonists()
+
+ if("moveminingshuttle")
+ if(!check_rights(R_ADMIN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","ShM")
+ if(!SSshuttle.toggleShuttle("mining","mining_home","mining_away"))
+ message_admins("[key_name_admin(usr)] moved mining shuttle")
+ log_admin("[key_name(usr)] moved the mining shuttle")
+
+ if("movelaborshuttle")
+ if(!check_rights(R_ADMIN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","ShL")
+ if(!SSshuttle.toggleShuttle("laborcamp","laborcamp_home","laborcamp_away"))
+ message_admins("[key_name_admin(usr)] moved labor shuttle")
+ log_admin("[key_name(usr)] moved the labor shuttle")
+
+ if("moveferry")
+ if(!check_rights(R_ADMIN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","ShF")
+ if(!SSshuttle.toggleShuttle("ferry","ferry_home","ferry_away"))
+ message_admins("[key_name_admin(usr)] moved the centcom ferry")
+ log_admin("[key_name(usr)] moved the centcom ferry")
+
+ if("kick_all_from_lobby")
+ if(!check_rights(R_ADMIN))
+ return
+ if(ticker && ticker.current_state == GAME_STATE_PLAYING)
+ var/afkonly = text2num(href_list["afkonly"])
+ if(alert("Are you sure you want to kick all [afkonly ? "AFK" : ""] clients from the lobby??","Message","Yes","Cancel") != "Yes")
+ usr << "Kick clients from lobby aborted"
+ return
+ var/list/listkicked = kick_clients_in_lobby("The admin [usr.ckey] issued a 'kick all clients from lobby' command.", afkonly)
+ var/strkicked = ""
+ for(var/name in listkicked)
+ strkicked += "[name], "
+ message_admins("[key_name_admin(usr)] has kicked [afkonly ? "all AFK" : "all"] clients from the lobby. [length(listkicked)] clients kicked: [strkicked ? strkicked : "--"]")
+ log_admin("[key_name(usr)] has kicked [afkonly ? "all AFK" : "all"] clients from the lobby. [length(listkicked)] clients kicked: [strkicked ? strkicked : "--"]")
+ else
+ usr << "You may only use this when the game is running"
+
+ if("showailaws")
+ if(!check_rights(R_ADMIN))
+ return
+ output_ai_laws()
+ if("showgm")
+ if(!check_rights(R_ADMIN))
+ return
+ if(!ticker)
+ alert("The game hasn't started yet!")
+ else if (ticker.mode)
+ alert("The game mode is [ticker.mode.name]")
+ else alert("For some reason there's a ticker, but not a game mode")
+ if("manifest")
+ if(!check_rights(R_ADMIN))
+ return
+ var/dat = "Showing Crew Manifest.
"
+ dat += "| Name | Position |
"
+ for(var/datum/data/record/t in data_core.general)
+ dat += "| [t.fields["name"]] | [t.fields["rank"]] |
"
+ dat += "
"
+ usr << browse(dat, "window=manifest;size=440x410")
+ if("DNA")
+ if(!check_rights(R_ADMIN))
+ return
+ var/dat = "Showing DNA from blood.
"
+ dat += "| Name | DNA | Blood Type |
"
+ for(var/mob/living/carbon/human/H in mob_list)
+ if(H.dna && H.ckey)
+ dat += "| [H] | [H.dna.unique_enzymes] | [H.blood_type] |
"
+ dat += "
"
+ usr << browse(dat, "window=DNA;size=440x410")
+ if("fingerprints")
+ if(!check_rights(R_ADMIN))
+ return
+ var/dat = "Showing Fingerprints.
"
+ dat += "| Name | Fingerprints |
"
+ for(var/mob/living/carbon/human/H in mob_list)
+ if(H.ckey)
+ if(H.dna && H.dna.uni_identity)
+ dat += "| [H] | [md5(H.dna.uni_identity)] |
"
+ else if(H.dna && !H.dna.uni_identity)
+ dat += "| [H] | H.dna.uni_identity = null |
"
+ else if(!H.dna)
+ dat += "| [H] | H.dna = null |
"
+ dat += "
"
+ usr << browse(dat, "window=fingerprints;size=440x410")
+
+ if("monkey")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","M")
+ for(var/mob/living/carbon/human/H in mob_list)
+ spawn(0)
+ H.monkeyize()
+ ok = 1
+
+ if("allspecies")
+ if(!check_rights(R_FUN))
+ return
+ var/result = input(usr, "Please choose a new species","Species") as null|anything in species_list
+ if(result)
+ log_admin("[key_name(usr)] turned all humans into [result]", 1)
+ message_admins("\blue [key_name_admin(usr)] turned all humans into [result]")
+ var/newtype = species_list[result]
+ for(var/mob/living/carbon/human/H in mob_list)
+ hardset_dna(H, null, null, null, null, newtype)
+ H.regenerate_icons()
+
+ if("corgi")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","M")
+ for(var/mob/living/carbon/human/H in mob_list)
+ spawn(0)
+ H.corgize()
+ ok = 1
+
+ if("tripleAI")
+ if(!check_rights(R_FUN))
+ return
+ usr.client.triple_ai()
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","TriAI")
+
+ if("power")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","P")
+ log_admin("[key_name(usr)] made all areas powered", 1)
+ message_admins("[key_name_admin(usr)] made all areas powered")
+ power_restore()
+
+ if("unpower")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","UP")
+ log_admin("[key_name(usr)] made all areas unpowered", 1)
+ message_admins("[key_name_admin(usr)] made all areas unpowered")
+ power_failure()
+
+ if("quickpower")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","QP")
+ log_admin("[key_name(usr)] made all SMESs powered", 1)
+ message_admins("[key_name_admin(usr)] made all SMESs powered")
+ power_restore_quick()
+
+ if("traitor_all")
+ if(!check_rights(R_FUN))
+ return
+ if(!ticker)
+ alert("The game hasn't started yet!")
+ return
+ var/objective = copytext(sanitize(input("Enter an objective")),1,MAX_MESSAGE_LEN)
+ if(!objective)
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","TA([objective])")
+ for(var/mob/living/carbon/human/H in player_list)
+ if(H.stat == 2 || !H.client || !H.mind) continue
+ if(is_special_character(H)) continue
+ //traitorize(H, objective, 0)
+ ticker.mode.traitors += H.mind
+ H.mind.special_role = "traitor"
+ var/datum/objective/new_objective = new
+ new_objective.owner = H
+ new_objective.explanation_text = objective
+ H.mind.objectives += new_objective
+ ticker.mode.greet_traitor(H.mind)
+ //ticker.mode.forge_traitor_objectives(H.mind)
+ ticker.mode.finalize_traitor(H.mind)
+ for(var/mob/living/silicon/A in player_list)
+ if(A.stat == 2 || !A.client || !A.mind) continue
+ if(ispAI(A)) continue
+ else if(is_special_character(A)) continue
+ ticker.mode.traitors += A.mind
+ A.mind.special_role = "traitor"
+ var/datum/objective/new_objective = new
+ new_objective.owner = A
+ new_objective.explanation_text = objective
+ A.mind.objectives += new_objective
+ ticker.mode.greet_traitor(A.mind)
+ ticker.mode.finalize_traitor(A.mind)
+ message_admins("[key_name_admin(usr)] used everyone is a traitor secret. Objective is [objective]")
+ log_admin("[key_name(usr)] used everyone is a traitor secret. Objective is [objective]")
+
+ if("changebombcap")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","BC")
+
+ var/newBombCap = input(usr,"What would you like the new bomb cap to be. (entered as the light damage range (the 3rd number in common (1,2,3) notation)) Must be between 4 and 128)", "New Bomb Cap", MAX_EX_LIGHT_RANGE) as num|null
+ if (newBombCap < 4)
+ return
+ if (newBombCap > 128)
+ newBombCap = 128
+
+ MAX_EX_DEVESTATION_RANGE = round(newBombCap/4)
+ MAX_EX_HEAVY_RANGE = round(newBombCap/2)
+ MAX_EX_LIGHT_RANGE = newBombCap
+ //I don't know why these are their own variables, but fuck it, they are.
+ MAX_EX_FLASH_RANGE = newBombCap
+ MAX_EX_FLAME_RANGE = newBombCap
+
+ message_admins("[key_name_admin(usr)] changed the bomb cap to [MAX_EX_DEVESTATION_RANGE], [MAX_EX_HEAVY_RANGE], [MAX_EX_LIGHT_RANGE]")
+ log_admin("[key_name(usr)] changed the bomb cap to [MAX_EX_DEVESTATION_RANGE], [MAX_EX_HEAVY_RANGE], [MAX_EX_LIGHT_RANGE]")
+
+
+ if("lightsout")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","LO")
+ message_admins("[key_name_admin(usr)] has broke a lot of lights")
+ E = new /datum/round_event/electrical_storm{lightsoutAmount = 2}()
+
+ if("blackout")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","BO")
+ message_admins("[key_name_admin(usr)] broke all lights")
+ for(var/obj/machinery/light/L in world)
+ L.broken()
+
+ if("whiteout")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","WO")
+ message_admins("[key_name_admin(usr)] fixed all lights")
+ for(var/obj/machinery/light/L in world)
+ L.fix()
+
+ if("floorlava")
+ if(!check_rights(R_FUN))
+ return
+ if(floorIsLava)
+ usr << "The floor is lava already."
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","LF")
+
+ //Options
+ var/length = input(usr, "How long will the lava last? (in seconds)", "Length", 180) as num
+ length = min(abs(length), 1200)
+
+ var/damage = input(usr, "How deadly will the lava be?", "Damage", 2) as num
+ damage = min(abs(damage), 100)
+
+ var/sure = alert(usr, "Are you sure you want to do this?", "Confirmation", "YES!", "Nah")
+ if(sure == "Nah")
+ return
+ floorIsLava = 1
+
+ message_admins("[key_name_admin(usr)] made the floor LAVA! It'll last [length] seconds and it will deal [damage] damage to everyone.")
+
+ for(var/turf/simulated/floor/F in world)
+ if(F.z == ZLEVEL_STATION)
+ F.name = "lava"
+ F.desc = "The floor is LAVA!"
+ F.overlays += "lava"
+ F.lava = 1
+
+ spawn(0)
+ for(var/i = i, i < length, i++) // 180 = 3 minutes
+ if(damage)
+ for(var/mob/living/carbon/L in living_mob_list)
+ if(istype(L.loc, /turf/simulated/floor)) // Are they on LAVA?!
+ var/turf/simulated/floor/F = L.loc
+ if(F.lava)
+ var/safe = 0
+ for(var/obj/structure/O in F.contents)
+ if(O.level > F.level && !istype(O, /obj/structure/window)) // Something to stand on and it isn't under the floor!
+ safe = 1
+ break
+ if(!safe)
+ L.adjustFireLoss(damage)
+
+
+ sleep(10)
+
+ for(var/turf/simulated/floor/F in world) // Reset everything.
+ if(F.z == ZLEVEL_STATION)
+ F.name = initial(F.name)
+ F.desc = initial(F.desc)
+ F.overlays.Cut()
+ F.lava = 0
+ F.update_icon()
+ floorIsLava = 0
+ return
+
+ if("virus")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","V")
+ switch(alert("Do you want this to be a random disease or do you have something in mind?",,"Make Your Own","Random","Choose"))
+ if("Make Your Own")
+ AdminCreateVirus(usr.client)
+ if("Random")
+ E = new /datum/round_event/disease_outbreak()
+ if("Choose")
+ var/virus = input("Choose the virus to spread", "BIOHAZARD") as null|anything in typesof(/datum/disease)
+ E = new /datum/round_event/disease_outbreak{}()
+ var/datum/round_event/disease_outbreak/DO = E
+ DO.virus_type = virus
+
+ if("retardify")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","RET")
+ for(var/mob/living/carbon/human/H in player_list)
+ H << "You suddenly feel stupid."
+ H.setBrainLoss(60)
+ message_admins("[key_name_admin(usr)] made everybody retarded")
+
+ if("eagles")//SCRAW
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","EgL")
+ for(var/obj/machinery/door/airlock/W in world)
+ if(W.z == ZLEVEL_STATION && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison))
+ W.req_access = list()
+ message_admins("[key_name_admin(usr)] activated Egalitarian Station mode")
+ priority_announce("Centcom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, 'sound/AI/commandreport.ogg')
+
+ if("guns")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SG")
+ var/survivor_probability = 0
+ switch(alert("Do you want this to create survivors antagonists?",,"No Antags","Some Antags","All Antags!"))
+ if("Some Antags")
+ survivor_probability = 25
+ if("All Antags!")
+ survivor_probability = 100
+
+ rightandwrong(0, usr, survivor_probability)
+
+ if("magic")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SM")
+ var/survivor_probability = 0
+ switch(alert("Do you want this to create survivors antagonists?",,"No Antags","Some Antags","All Antags!"))
+ if("Some Antags")
+ survivor_probability = 25
+ if("All Antags!")
+ survivor_probability = 100
+
+ rightandwrong(1, usr, survivor_probability)
+
+ if("events")
+ if(!check_rights(R_FUN))
+ return
+ if(!SSevent.wizardmode)
+ if(alert("Do you want to toggle summon events on?",,"Yes","No") == "Yes")
+ summonevents()
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SE")
+
+ else
+ switch(alert("What would you like to do?",,"Intensify Summon Events","Turn Off Summon Events","Nothing"))
+ if("Intensify Summon Events")
+ summonevents()
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","SE")
+ if("Turn Off Summon Events")
+ SSevent.toggleWizardmode()
+ SSevent.resetFrequency()
+
+ if("dorf")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","DF")
+ for(var/mob/living/carbon/human/B in mob_list)
+ B.facial_hair_style = "Dward Beard"
+ B.update_hair()
+ message_admins("[key_name_admin(usr)] activated dorf mode")
+
+ if("onlyone")
+ if(!check_rights(R_FUN))
+ return
+ feedback_inc("admin_secrets_fun_used",1)
+ feedback_add_details("admin_secrets_fun_used","OO")
+ usr.client.only_one()
+// message_admins("[key_name_admin(usr)] has triggered a battle to the death (only one)")
+
+ if("maint_access_brig")
+ if(!check_rights(R_DEBUG))
+ return
+ for(var/obj/machinery/door/airlock/maintenance/M in world)
+ M.check_access()
+ if (access_maint_tunnels in M.req_access)
+ M.req_access = list(access_brig)
+ message_admins("[key_name_admin(usr)] made all maint doors brig access-only.")
+ if("maint_access_engiebrig")
+ if(!check_rights(R_DEBUG))
+ return
+ for(var/obj/machinery/door/airlock/maintenance/M in world)
+ M.check_access()
+ if (access_maint_tunnels in M.req_access)
+ M.req_access = list()
+ M.req_one_access = list(access_brig,access_engine)
+ message_admins("[key_name_admin(usr)] made all maint doors engineering and brig access-only.")
+ if("infinite_sec")
+ if(!check_rights(R_DEBUG))
+ return
+ var/datum/job/J = SSjob.GetJob("Security Officer")
+ if(!J) return
+ J.total_positions = -1
+ J.spawn_positions = -1
+ message_admins("[key_name_admin(usr)] has removed the cap on security officers.")
+ if(E)
+ E.processing = 0
+ if(E.announceWhen>0)
+ if(alert(usr, "Would you like to alert the crew?", "Alert", "Yes", "No") == "No")
+ E.announceWhen = -1
+ E.processing = 1
+ if (usr)
+ log_admin("[key_name(usr)] used secret [item]")
+ if (ok)
+ world << text("A secret has been activated by []!", usr.key)
\ No newline at end of file
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index ccf4be2b6b6..5fe81932f7d 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1416,57 +1416,20 @@
usr.client.cmd_admin_animalize(M)
-/***************** BEFORE**************
-
- if (href_list["l_players"])
- var/dat = "Name/Real Name/Key/IP:
"
- for(var/mob/M in world)
- var/foo = ""
- if (ismob(M) && M.client)
- if(!M.client.authenticated && !M.client.authenticating)
- foo += text("\[ Authorize | ", src, M)
- else
- foo += text("\[ Authorized | ")
- if(M.start)
- if(!istype(M, /mob/living/carbon/monkey))
- foo += text("Monkeyize | ", src, M)
- else
- foo += text("Monkeyized | ")
- if(istype(M, /mob/living/silicon/ai))
- foo += text("Is an AI | ")
- else
- foo += text("Make AI | ", src, M)
- if(M.z != 2)
- foo += text("Prison | ", src, M)
- foo += text("Maze | ", src, M)
- else
- foo += text("On Z = 2 | ")
- else
- foo += text("Hasn't Entered Game | ")
- foo += text("Heal/Revive | ", src, M)
-
- foo += text("Say \]", src, M)
- dat += text("N: [] R: [] (K: []) (IP: []) []
", M.name, M.real_name, (M.client ? M.client : "No client"), M.lastKnownIP, foo)
-
- usr << browse(dat, "window=players;size=900x480")
-
-*****************AFTER******************/
-
-// Now isn't that much better? IT IS NOW A PROC, i.e. kinda like a big panel like unstable
-
else if(href_list["adminplayeropts"])
var/mob/M = locate(href_list["adminplayeropts"])
show_player_panel(M)
- else if(href_list["adminplayerobservejump"])
+ else if(href_list["adminplayerobservefollow"])
if(!isobserver(usr) && !check_rights(R_ADMIN)) return
- var/mob/M = locate(href_list["adminplayerobservejump"])
+ var/mob/M = locate(href_list["adminplayerobservefollow"])
var/client/C = usr.client
if(!isobserver(usr)) C.admin_ghost()
+ var/mob/dead/observer/A = C.mob
sleep(2)
- C.jumptomob(M)
+ A.ManualFollow(M)
else if(href_list["adminplayerobservecoodjump"])
if(!isobserver(usr) && !check_rights(R_ADMIN)) return
@@ -1531,7 +1494,7 @@
src.owner << "Name = [M.name]; Real_name = [M.real_name]; Mind_name = [M.mind?"[M.mind.name]":""]; Key = [M.key];"
src.owner << "Location = [location_description];"
src.owner << "[special_role_description]"
- src.owner << "(PM) (PP) (VV) (SM) (JMP) (CA)"
+ src.owner << "(PM) (PP) (VV) (SM) (FLW) (CA)"
else if(href_list["addjobslot"])
if(!check_rights(R_ADMIN)) return
@@ -1812,465 +1775,8 @@
break
return
- else if(href_list["secretsfun"])
- if(!check_rights(R_FUN)) return
- var/datum/round_event/E
- var/ok = 0
- switch(href_list["secretsfun"])
- if("tdomereset")
- var/delete_mobs = alert("Clear all mobs?","Confirm","Yes","No","Cancel")
- if(delete_mobs == "Cancel")
- return
-
- log_admin("[key_name(usr)] reset the thunderdome to default with delete_mobs==[delete_mobs].", 1)
- message_admins("[key_name_admin(usr)] reset the thunderdome to default with delete_mobs==[delete_mobs].")
-
- var/area/thunderdome = locate(/area/tdome/arena)
- if(delete_mobs == "Yes")
- for(var/mob/living/mob in thunderdome)
- qdel(mob) //Clear mobs
- for(var/obj/obj in thunderdome)
- if(!istype(obj,/obj/machinery/camera))
- qdel(obj) //Clear objects
-
- var/area/template = locate(/area/tdome/arena_source)
- template.copy_contents_to(thunderdome)
-
- if("monkey")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","M")
- for(var/mob/living/carbon/human/H in mob_list)
- spawn(0)
- H.monkeyize()
- ok = 1
- if("allspecies")
- var/result = input(usr, "Please choose a new species","Species") as null|anything in species_list
- if(result)
- log_admin("[key_name(usr)] turned all humans into [result]", 1)
- message_admins("\blue [key_name_admin(usr)] turned all humans into [result]")
- var/newtype = species_list[result]
- for(var/mob/living/carbon/human/H in mob_list)
- hardset_dna(H, null, null, null, null, newtype)
- H.regenerate_icons()
- if("corgi")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","M")
- for(var/mob/living/carbon/human/H in mob_list)
- spawn(0)
- H.corgize()
- ok = 1
-/* DEATH SQUADS
- if("striketeam")
- if(usr.client.strike_team())
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","Strike")
-*/
- if("tripleAI")
- usr.client.triple_ai()
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","TriAI")
- if("power")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","P")
- log_admin("[key_name(usr)] made all areas powered", 1)
- message_admins("[key_name_admin(usr)] made all areas powered")
- power_restore()
- if("unpower")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","UP")
- log_admin("[key_name(usr)] made all areas unpowered", 1)
- message_admins("[key_name_admin(usr)] made all areas unpowered")
- power_failure()
- if("quickpower")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","QP")
- log_admin("[key_name(usr)] made all SMESs powered", 1)
- message_admins("[key_name_admin(usr)] made all SMESs powered")
- power_restore_quick()
- if("traitor_all")
- if(!ticker)
- alert("The game hasn't started yet!")
- return
- var/objective = copytext(sanitize(input("Enter an objective")),1,MAX_MESSAGE_LEN)
- if(!objective)
- return
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","TA([objective])")
- for(var/mob/living/carbon/human/H in player_list)
- if(H.stat == 2 || !H.client || !H.mind) continue
- if(is_special_character(H)) continue
- //traitorize(H, objective, 0)
- ticker.mode.traitors += H.mind
- H.mind.special_role = "traitor"
- var/datum/objective/new_objective = new
- new_objective.owner = H
- new_objective.explanation_text = objective
- H.mind.objectives += new_objective
- ticker.mode.greet_traitor(H.mind)
- //ticker.mode.forge_traitor_objectives(H.mind)
- ticker.mode.finalize_traitor(H.mind)
- for(var/mob/living/silicon/A in player_list)
- if(A.stat == 2 || !A.client || !A.mind) continue
- if(ispAI(A)) continue
- else if(is_special_character(A)) continue
- ticker.mode.traitors += A.mind
- A.mind.special_role = "traitor"
- var/datum/objective/new_objective = new
- new_objective.owner = A
- new_objective.explanation_text = objective
- A.mind.objectives += new_objective
- ticker.mode.greet_traitor(A.mind)
- ticker.mode.finalize_traitor(A.mind)
- message_admins("[key_name_admin(usr)] used everyone is a traitor secret. Objective is [objective]")
- log_admin("[key_name(usr)] used everyone is a traitor secret. Objective is [objective]")
- if("togglebombcap")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","BC")
- switch(MAX_EX_LIGHT_RANGE)
- if(14)
- MAX_EX_LIGHT_RANGE = 16
- MAX_EX_HEAVY_RANGE = 8
- MAX_EX_DEVESTATION_RANGE = 4
- if(16)
- MAX_EX_LIGHT_RANGE = 20
- MAX_EX_HEAVY_RANGE = 10
- MAX_EX_DEVESTATION_RANGE = 5
- if(20)
- MAX_EX_LIGHT_RANGE = 28
- MAX_EX_HEAVY_RANGE = 14
- MAX_EX_DEVESTATION_RANGE = 7
- if(28)
- MAX_EX_LIGHT_RANGE = 56
- MAX_EX_HEAVY_RANGE = 28
- MAX_EX_DEVESTATION_RANGE = 14
- if(56)
- MAX_EX_LIGHT_RANGE = 128
- MAX_EX_HEAVY_RANGE = 64
- MAX_EX_DEVESTATION_RANGE = 32
- if(128)
- MAX_EX_LIGHT_RANGE = 14
- MAX_EX_HEAVY_RANGE = 7
- MAX_EX_DEVESTATION_RANGE = 3
- message_admins("[key_name_admin(usr)] changed the bomb cap to [MAX_EX_DEVESTATION_RANGE], [MAX_EX_HEAVY_RANGE], [MAX_EX_LIGHT_RANGE]")
- log_admin("[key_name(usr)] changed the bomb cap to [MAX_EX_DEVESTATION_RANGE], [MAX_EX_HEAVY_RANGE], [MAX_EX_LIGHT_RANGE]")
-
- if("lightsout")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","LO")
- message_admins("[key_name_admin(usr)] has broke a lot of lights")
- E = new /datum/round_event/electrical_storm{lightsoutAmount = 2}()
- if("blackout")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","BO")
- message_admins("[key_name_admin(usr)] broke all lights")
- for(var/obj/machinery/light/L in world)
- L.broken()
- if("whiteout")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","WO")
- message_admins("[key_name_admin(usr)] fixed all lights")
- for(var/obj/machinery/light/L in world)
- L.fix()
- if("floorlava")
- if(floorIsLava)
- usr << "The floor is lava already."
- return
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","LF")
-
- //Options
- var/length = input(usr, "How long will the lava last? (in seconds)", "Length", 180) as num
- length = min(abs(length), 1200)
-
- var/damage = input(usr, "How deadly will the lava be?", "Damage", 2) as num
- damage = min(abs(damage), 100)
-
- var/sure = alert(usr, "Are you sure you want to do this?", "Confirmation", "YES!", "Nah")
- if(sure == "Nah")
- return
- floorIsLava = 1
-
- message_admins("[key_name_admin(usr)] made the floor LAVA! It'll last [length] seconds and it will deal [damage] damage to everyone.")
-
- for(var/turf/simulated/floor/F in world)
- if(F.z == ZLEVEL_STATION)
- F.name = "lava"
- F.desc = "The floor is LAVA!"
- F.overlays += "lava"
- F.lava = 1
-
- spawn(0)
- for(var/i = i, i < length, i++) // 180 = 3 minutes
- if(damage)
- for(var/mob/living/carbon/L in living_mob_list)
- if(istype(L.loc, /turf/simulated/floor)) // Are they on LAVA?!
- var/turf/simulated/floor/F = L.loc
- if(F.lava)
- var/safe = 0
- for(var/obj/structure/O in F.contents)
- if(O.level > F.level && !istype(O, /obj/structure/window)) // Something to stand on and it isn't under the floor!
- safe = 1
- break
- if(!safe)
- L.adjustFireLoss(damage)
-
-
- sleep(10)
-
- for(var/turf/simulated/floor/F in world) // Reset everything.
- if(F.z == ZLEVEL_STATION)
- F.name = initial(F.name)
- F.desc = initial(F.desc)
- F.overlays.Cut()
- F.lava = 0
- F.update_icon()
- floorIsLava = 0
- return
- if("virus")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","V")
- switch(alert("Do you want this to be a random disease or do you have something in mind?",,"Make Your Own","Random","Choose"))
- if("Make Your Own")
- AdminCreateVirus(usr.client)
- if("Random")
- E = new /datum/round_event/disease_outbreak()
- if("Choose")
- var/virus = input("Choose the virus to spread", "BIOHAZARD") as null|anything in typesof(/datum/disease)
- E = new /datum/round_event/disease_outbreak{}()
- var/datum/round_event/disease_outbreak/DO = E
- DO.virus_type = virus
- if("retardify")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","RET")
- for(var/mob/living/carbon/human/H in player_list)
- H << "You suddenly feel stupid."
- H.setBrainLoss(60)
- message_admins("[key_name_admin(usr)] made everybody retarded")
- if("eagles")//SCRAW
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","EgL")
- for(var/obj/machinery/door/airlock/W in world)
- if(W.z == ZLEVEL_STATION && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison))
- W.req_access = list()
- message_admins("[key_name_admin(usr)] activated Egalitarian Station mode")
- priority_announce("Centcom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, 'sound/AI/commandreport.ogg')
- if("guns")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","SG")
- var/survivor_probability = 0
- switch(alert("Do you want this to create survivors antagonists?",,"No Antags","Some Antags","All Antags!"))
- if("Some Antags")
- survivor_probability = 25
- if("All Antags!")
- survivor_probability = 100
-
- rightandwrong(0, usr, survivor_probability)
- if("magic")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","SM")
- var/survivor_probability = 0
- switch(alert("Do you want this to create survivors antagonists?",,"No Antags","Some Antags","All Antags!"))
- if("Some Antags")
- survivor_probability = 25
- if("All Antags!")
- survivor_probability = 100
-
- rightandwrong(1, usr, survivor_probability)
- if("events")
- if(!SSevent.wizardmode)
- if(alert("Do you want to toggle summon events on?",,"Yes","No") == "Yes")
- summonevents()
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","SE")
-
- else
- switch(alert("What would you like to do?",,"Intensify Summon Events","Turn Off Summon Events","Nothing"))
- if("Intensify Summon Events")
- summonevents()
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","SE")
- if("Turn Off Summon Events")
- SSevent.toggleWizardmode()
- SSevent.resetFrequency()
- if("dorf")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","DF")
- for(var/mob/living/carbon/human/B in mob_list)
- B.facial_hair_style = "Dward Beard"
- B.update_hair()
- message_admins("[key_name_admin(usr)] activated dorf mode")
- if("onlyone")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","OO")
- usr.client.only_one()
-// message_admins("[key_name_admin(usr)] has triggered a battle to the death (only one)")
- if(E)
- E.processing = 0
- if(E.announceWhen>0)
- if(alert(usr, "Would you like to alert the crew?", "Alert", "Yes", "No") == "No")
- E.announceWhen = -1
- E.processing = 1
- if(usr)
- log_admin("[key_name(usr)] used secret [href_list["secretsfun"]]")
- if (ok)
- world << text("A secret has been activated by []!", usr.key)
-
- else if(href_list["secretsadmin"])
- if(!check_rights(R_ADMIN)) return
-
- var/ok = 0
- switch(href_list["secretsadmin"])
- if("clear_virus")
- var/choice = input("Are you sure you want to cure all disease?") in list("Yes", "Cancel")
- if(choice == "Yes")
- message_admins("[key_name_admin(usr)] has cured all diseases.")
- for(var/datum/disease/D in SSdisease.processing)
- D.cure(D)
- if("list_bombers")
- var/dat = "Bombing List
"
- for(var/l in bombers)
- dat += text("[l]
")
- usr << browse(dat, "window=bombers")
- if("list_signalers")
- var/dat = "Showing last [length(lastsignalers)] signalers.
"
- for(var/sig in lastsignalers)
- dat += "[sig]
"
- usr << browse(dat, "window=lastsignalers;size=800x500")
- if("list_lawchanges")
- var/dat = "Showing last [length(lawchanges)] law changes.
"
- for(var/sig in lawchanges)
- dat += "[sig]
"
- usr << browse(dat, "window=lawchanges;size=800x500")
- if("check_antagonist")
- check_antagonists()
-
- if("moveminingshuttle")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","ShM")
- if(!SSshuttle.toggleShuttle("mining","mining_home","mining_away"))
- message_admins("[key_name_admin(usr)] moved mining shuttle")
- log_admin("[key_name(usr)] moved the mining shuttle")
-
- if("movelaborshuttle")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","ShL")
- if(!SSshuttle.toggleShuttle("laborcamp","laborcamp_home","laborcamp_away"))
- message_admins("[key_name_admin(usr)] moved labor shuttle")
- log_admin("[key_name(usr)] moved the labor shuttle")
-
- if("moveferry")
- feedback_inc("admin_secrets_fun_used",1)
- feedback_add_details("admin_secrets_fun_used","ShF")
- if(!SSshuttle.toggleShuttle("ferry","ferry_home","ferry_away"))
- message_admins("[key_name_admin(usr)] moved the centcom ferry")
- log_admin("[key_name(usr)] moved the centcom ferry")
-
- if("kick_all_from_lobby")
- if(ticker && ticker.current_state == GAME_STATE_PLAYING)
- var/afkonly = text2num(href_list["afkonly"])
- if(alert("Are you sure you want to kick all [afkonly ? "AFK" : ""] clients from the lobby??","Message","Yes","Cancel") != "Yes")
- usr << "Kick clients from lobby aborted"
- return
- var/list/listkicked = kick_clients_in_lobby("The admin [usr.ckey] issued a 'kick all clients from lobby' command.", afkonly)
- var/strkicked = ""
- for(var/name in listkicked)
- strkicked += "[name], "
- message_admins("[key_name_admin(usr)] has kicked [afkonly ? "all AFK" : "all"] clients from the lobby. [length(listkicked)] clients kicked: [strkicked ? strkicked : "--"]")
- log_admin("[key_name(usr)] has kicked [afkonly ? "all AFK" : "all"] clients from the lobby. [length(listkicked)] clients kicked: [strkicked ? strkicked : "--"]")
- else
- usr << "You may only use this when the game is running"
- if("showailaws")
- output_ai_laws()
- if("showgm")
- if(!ticker)
- alert("The game hasn't started yet!")
- else if (ticker.mode)
- alert("The game mode is [ticker.mode.name]")
- else alert("For some reason there's a ticker, but not a game mode")
- if("manifest")
- var/dat = "Showing Crew Manifest.
"
- dat += "| Name | Position |
"
- for(var/datum/data/record/t in data_core.general)
- dat += "| [t.fields["name"]] | [t.fields["rank"]] |
"
- dat += "
"
- usr << browse(dat, "window=manifest;size=440x410")
- if("DNA")
- var/dat = "Showing DNA from blood.
"
- dat += "| Name | DNA | Blood Type |
"
- for(var/mob/living/carbon/human/H in mob_list)
- if(H.dna && H.ckey)
- dat += "| [H] | [H.dna.unique_enzymes] | [H.blood_type] |
"
- dat += "
"
- usr << browse(dat, "window=DNA;size=440x410")
- if("fingerprints")
- var/dat = "Showing Fingerprints.
"
- dat += "| Name | Fingerprints |
"
- for(var/mob/living/carbon/human/H in mob_list)
- if(H.ckey)
- if(H.dna && H.dna.uni_identity)
- dat += "| [H] | [md5(H.dna.uni_identity)] |
"
- else if(H.dna && !H.dna.uni_identity)
- dat += "| [H] | H.dna.uni_identity = null |
"
- else if(!H.dna)
- dat += "| [H] | H.dna = null |
"
- dat += "
"
- usr << browse(dat, "window=fingerprints;size=440x410")
- else
- if (usr)
- log_admin("[key_name(usr)] used secret [href_list["secretsadmin"]]")
- if (ok)
- world << text("A secret has been activated by []!", usr.key)
-
- else if(href_list["secretsgeneral"])
- switch(href_list["secretsgeneral"])
- if("spawn_objects")
- var/dat = "Admin Log
"
- for(var/l in admin_log)
- dat += "[l]"
- if(!admin_log.len)
- dat += "No-one has done anything this round!"
- usr << browse(dat, "window=admin_log")
- if("list_job_debug")
- var/dat = "Job Debug info.
"
- if(SSjob)
- for(var/line in SSjob.job_debug)
- dat += "[line]
"
- dat+= "*******
"
- for(var/datum/job/job in SSjob.occupations)
- if(!job) continue
- dat += "job: [job.title], current_positions: [job.current_positions], total_positions: [job.total_positions]
"
- usr << browse(dat, "window=jobdebug;size=600x500")
- if("show_admins")
- var/dat = "Current admins:
"
- if(admin_datums)
- for(var/ckey in admin_datums)
- var/datum/admins/D = admin_datums[ckey]
- dat += "[ckey] - [D.rank.name]
"
- usr << browse(dat, "window=showadmins;size=600x500")
-
- else if(href_list["secretscoder"])
- if(!check_rights(R_DEBUG)) return
-
- switch(href_list["secretscoder"])
- if("maint_access_brig")
- for(var/obj/machinery/door/airlock/maintenance/M in world)
- M.check_access()
- if (access_maint_tunnels in M.req_access)
- M.req_access = list(access_brig)
- message_admins("[key_name_admin(usr)] made all maint doors brig access-only.")
- if("maint_access_engiebrig")
- for(var/obj/machinery/door/airlock/maintenance/M in world)
- M.check_access()
- if (access_maint_tunnels in M.req_access)
- M.req_access = list()
- M.req_one_access = list(access_brig,access_engine)
- message_admins("[key_name_admin(usr)] made all maint doors engineering and brig access-only.")
- if("infinite_sec")
- var/datum/job/J = SSjob.GetJob("Security Officer")
- if(!J) return
- J.total_positions = -1
- J.spawn_positions = -1
- message_admins("[key_name_admin(usr)] has removed the cap on security officers.")
+ else if(href_list["secrets"])
+ Secrets_topic(href_list["secrets"],href_list)
else if(href_list["ac_view_wanted"]) //Admin newscaster Topic() stuff be here
src.admincaster_screen = 18 //The ac_ prefix before the hrefs stands for AdminCaster.
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index d3300a758cd..a34e5dd1b15 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -78,14 +78,14 @@ var/list/adminhelp_ignored_words = list("unknown","the","a","an","of","monkey","
mobs_found += found
if(!ai_found && isAI(found))
ai_found = 1
- msg += "[original_word] (?) "
+ msg += "[original_word] (?) (FLW) "
continue
msg += "[original_word] "
if(!mob) return //this doesn't happen
var/ref_mob = "\ref[mob]"
- msg = "HELP: [key_name(src, 1)] (?) (PP) (VV) (SM) (JMP) (TP) [ai_found ? " (CL)" : ""]: [msg]"
+ msg = "HELP: [key_name_admin(src)] (?) (PP) (VV) (SM) (FLW) (TP) [ai_found ? " (CL)" : ""]: [msg]"
//send this msg to all admins
diff --git a/code/modules/admin/verbs/adminsay.dm b/code/modules/admin/verbs/adminsay.dm
index 5adb784a25d..1e077bd66e9 100644
--- a/code/modules/admin/verbs/adminsay.dm
+++ b/code/modules/admin/verbs/adminsay.dm
@@ -6,15 +6,15 @@
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
if(!msg) return
-
+
log_admin("[key_name(src)] : [msg]")
-
+
if(check_rights(R_ADMIN,0))
- msg = "ADMIN: [key_name(usr, 1)] (JMP): [msg]"
+ msg = "ADMIN: [key_name(usr, 1)] (FLW): [msg]"
admins << msg
else
msg = "ADMIN: [key_name(usr, 1)]: [msg]"
admins << msg
-
+
feedback_add_details("admin_verb","M") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm
index fe8c95b2868..beec68a598a 100644
--- a/code/modules/admin/verbs/pray.dm
+++ b/code/modules/admin/verbs/pray.dm
@@ -19,13 +19,13 @@
var/image/cross = image('icons/obj/storage.dmi',"bible")
if(usr.job == "Chaplain")
cross = image('icons/obj/storage.dmi',"kingyellow")
- msg = "\icon[cross] CHAPLAIN PRAYER: [key_name(src, 1)] (?) (PP) (VV) (SM) (JMP) (TP) (SC): [msg]"
+ msg = "\icon[cross] CHAPLAIN PRAYER: [key_name_admin(src)] (?) (PP) (VV) (SM) (FLW) (TP) (SC): [msg]"
else if(iscultist(usr))
cross = image('icons/obj/storage.dmi',"tome")
- msg = "\icon[cross] CULTIST PRAYER: [key_name(src, 1)] (?) (PP) (VV) (SM) (JMP) (TP) (SC): [msg]"
+ msg = "\icon[cross] CULTIST PRAYER: [key_name_admin(src)] (?) (PP) (VV) (SM) (FLW) (TP) (SC): [msg]"
else
cross = image('icons/obj/storage.dmi',"bible")
- msg = "\icon[cross] PRAYER: [key_name(src, 1)] (?) (PP) (VV) (SM) (JMP) (TP) (SC): [msg]"
+ msg = "\icon[cross] PRAYER: [key_name_admin(src)] (?) (PP) (VV) (SM) (FLW) (TP) (SC): [msg]"
for(var/client/C in admins)
if(C.prefs.chat_toggles & CHAT_PRAYER)
C << msg
@@ -39,16 +39,16 @@
/proc/Centcomm_announce(var/text , var/mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
- msg = "CENTCOM:[key_name(Sender, 1)] (?) (PP) (VV) (SM) (JMP) (TP) (BSA) (RPLY): [msg]"
+ msg = "CENTCOM:[key_name_admin(Sender)] (?) (PP) (VV) (SM) (FLW) (TP) (BSA) (RPLY): [msg]"
admins << msg
/proc/Syndicate_announce(var/text , var/mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
- msg = "SYNDICATE:[key_name(Sender, 1)] (?) (PP) (VV) (SM) (JMP) (TP) (BSA) (RPLY): [msg]"
+ msg = "SYNDICATE:[key_name_admin(Sender)] (?) (PP) (VV) (SM) (FLW) (TP) (BSA) (RPLY): [msg]"
admins << msg
/proc/Nuke_request(var/text , var/mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
- msg = "NUKE CODE REQUEST:[key_name(Sender, 1)] (?) (PP) (VV) (SM) (JMP) (TP) (BSA) (RPLY): [msg]"
+ msg = "NUKE CODE REQUEST:[key_name_admin(Sender)] (?) (PP) (VV) (SM) (FLW) (TP) (BSA) (RPLY): [msg]"
admins << msg
admins << "At this current time, the nuke must have the code manually set via varedit."
\ No newline at end of file
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 8a455d9e69c..0e8b30d2768 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -551,67 +551,6 @@ Traitors and the like can also be revived with the previous role mostly intact.
log_admin("[key_name(usr)] used gibself.")
message_admins("[key_name_admin(usr)] used gibself.")
feedback_add_details("admin_verb","GIBS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/*
-/client/proc/cmd_manual_ban()
- set name = "Manual Ban"
- set category = "Special Verbs"
- if(!authenticated || !holder)
- src << "Only administrators may use this command."
- return
- var/mob/M = null
- switch(alert("How would you like to ban someone today?", "Manual Ban", "Key List", "Enter Manually", "Cancel"))
- if("Key List")
- var/list/keys = list()
- for(var/mob/M in world)
- keys += M.client
- var/selection = input("Please, select a player!", "Admin Jumping", null, null) as null|anything in keys
- if(!selection)
- return
- M = selection:mob
- if ((M.client && M.client.holder && (M.client.holder.level >= holder.level)))
- alert("You cannot perform this action. You must be of a higher administrative rank!")
- return
-
- switch(alert("Temporary Ban?",,"Yes","No"))
- if("Yes")
- var/mins = input(usr,"How long (in minutes)?","Ban time",1440) as num
- if(!mins)
- return
- if(mins >= 525600) mins = 525599
- var/reason = input(usr,"Reason?","reason","Griefer") as text
- if(!reason)
- return
- if(M)
- AddBan(M.ckey, M.computer_id, reason, usr.ckey, 1, mins)
- M << "\redYou have been banned by [usr.client.ckey].\nReason: [reason]"
- M << "\red This is a temporary ban, it will be removed in [mins] minutes."
- M << "\red To try to resolve this matter head to http://ss13.donglabs.com/forum/"
- log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
- message_admins("\blue[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis will be removed in [mins] minutes.")
- world.Export("http://216.38.134.132/adminlog.php?type=ban&key=[usr.client.key]&key2=[M.key]&msg=[html_decode(reason)]&time=[mins]&server=[replacetext(config.server_name, "#", "")]")
- del(M.client)
- qdel(M)
- else
-
- if("No")
- var/reason = input(usr,"Reason?","reason","Griefer") as text
- if(!reason)
- return
- AddBan(M.ckey, M.computer_id, reason, usr.ckey, 0, 0)
- M << "\redYou have been banned by [usr.client.ckey].\nReason: [reason]"
- M << "\red This is a permanent ban."
- M << "\red To try to resolve this matter head to http://ss13.donglabs.com/forum/"
- log_admin("[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
- message_admins("\blue[usr.client.ckey] has banned [M.ckey].\nReason: [reason]\nThis is a permanent ban.")
- world.Export("http://216.38.134.132/adminlog.php?type=ban&key=[usr.client.key]&key2=[M.key]&msg=[html_decode(reason)]&time=perma&server=[replacetext(config.server_name, "#", "")]")
- del(M.client)
- qdel(M)
-*/
-
-/client/proc/update_world()
- // If I see anyone granting powers to specific keys like the code that was here,
- // I will both remove their SVN access and permanently ban them from my servers.
- return
/client/proc/cmd_admin_check_contents(mob/living/M as mob in mob_list)
set category = "Special Verbs"
@@ -622,37 +561,6 @@ Traitors and the like can also be revived with the previous role mostly intact.
usr << "[t]"
feedback_add_details("admin_verb","CC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-/* This proc is DEFERRED. Does not do anything.
-/client/proc/cmd_admin_remove_plasma()
- set category = "Debug"
- set name = "Stabilize Atmos."
- if(!holder)
- src << "Only administrators may use this command."
- return
- feedback_add_details("admin_verb","STATM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
-// DEFERRED
- spawn(0)
- for(var/turf/T in view())
- T.poison = 0
- T.oldpoison = 0
- T.tmppoison = 0
- T.oxygen = 755985
- T.oldoxy = 755985
- T.tmpoxy = 755985
- T.co2 = 14.8176
- T.oldco2 = 14.8176
- T.tmpco2 = 14.8176
- T.n2 = 2.844e+006
- T.on2 = 2.844e+006
- T.tn2 = 2.844e+006
- T.tsl_gas = 0
- T.osl_gas = 0
- T.sl_gas = 0
- T.temp = 293.15
- T.otemp = 293.15
- T.ttemp = 293.15
-*/
-
/client/proc/toggle_view_range()
set category = "Special Verbs"
set name = "Change View Range"
@@ -782,3 +690,42 @@ Traitors and the like can also be revived with the previous role mostly intact.
log_admin("[key_name(usr)] blanked all telecomms scripts.")
message_admins("[key_name_admin(usr)] blanked all telecomms scripts.")
feedback_add_details("admin_verb","RAT") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/admin_change_sec_level()
+ set category = "Special Verbs"
+ set name = "Set Security Level"
+ set desc = "Changes the security level. Announcement only, i.e. setting to Delta won't activate nuke"
+
+ if (!holder)
+ src << "Only administrators may use this command."
+ return
+
+ var/level = input("Select security level to change to","Set Security Level") as null|anything in list("green","blue","red","delta")
+ if(level)
+ set_security_level(level)
+
+ log_admin("[key_name(usr)] changed the security level to [level]")
+ message_admins("[key_name_admin(usr)] changed the security level to [level]")
+ feedback_add_details("admin_verb","CSL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+
+/client/proc/toggle_nuke(obj/machinery/nuclearbomb/N in nuke_list)
+ set name = "Toggle Nuke"
+ set category = "Fun"
+ set popup_menu = 0
+ if(!check_rights(R_DEBUG)) return
+
+ if(!N.timing)
+ var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[N.timeleft]") as num
+ if(!newtime)
+ return
+ N.timeleft = newtime
+ N.safety = !N.safety
+ N.timing = !N.timing
+ bomb_set = !bomb_set
+ N.icon_state = (N.timing ? "nuclearbomb2" : "nuclearbomb1")
+ N.previous_level = "[get_security_level()]"
+ set_security_level((N.timing ? "delta" : "[N.previous_level]"))
+
+ log_admin("[key_name(usr)] [N.timing ? "activated" : "deactivated"] a nuke at ([N.x],[N.y],[N.z]).")
+ message_admins("[key_name_admin(usr)] (FLW) [N.timing ? "activated" : "deactivated"] a nuke at ([N.x],[N.y],[N.z] - JMP).")
+ feedback_add_details("admin_verb","TN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm
index b63a0feefe7..f92ef7dcf84 100644
--- a/code/modules/assembly/bomb.dm
+++ b/code/modules/assembly/bomb.dm
@@ -89,10 +89,11 @@
var/mob/M = user
if(isigniter(S.a_left) == isigniter(S.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it
return
+ if(!M.drop_item()) //Remove the assembly from your hands
+ return
var/obj/item/device/onetankbomb/R = new /obj/item/device/onetankbomb(loc)
- M.drop_item() //Remove the assembly from your hands
M.remove_from_mob(src) //Remove the tank from your character,in case you were holding it
M.put_in_hands(R) //Equips the bomb if possible, or puts it on the floor.
diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm
index fee5794f977..5e6375b7e23 100644
--- a/code/modules/assembly/timer.dm
+++ b/code/modules/assembly/timer.dm
@@ -90,7 +90,7 @@
if(href_list["time"])
timing = text2num(href_list["time"])
if(timing && istype(holder, /obj/item/device/transfer_valve))
- var/timer_message = "[key_name_admin(usr)](?) activated [src] attachment on [holder]."
+ var/timer_message = "[key_name_admin(usr)](?) (FLW) activated [src] attachment on [holder]."
message_admins(timer_message)
bombers += timer_message
log_game("[key_name(usr)] activated [src] attachment for [loc]")
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index e4b0d1c0781..a239561ede0 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -186,7 +186,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["undershirt"] >> undershirt
S["socks"] >> socks
S["backbag"] >> backbag
- S["features"] >> features
+ S["feature_mcolor"] >> features["mcolor"]
+ S["feature_lizard_tail"] >> features["tail"]
+ S["feature_lizard_snout"] >> features["snout"]
+ S["feature_lizard_horns"] >> features["horns"]
+ S["feature_lizard_frills"] >> features["frills"]
+ S["feature_lizard_spines"] >> features["spines"]
+ S["feature_lizard_body_markings"] >> features["body_markings"]
S["clown_name"] >> custom_names["clown"]
S["mime_name"] >> custom_names["mime"]
S["ai_name"] >> custom_names["ai"]
@@ -214,7 +220,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
metadata = sanitize_text(metadata, initial(metadata))
real_name = reject_bad_name(real_name)
if(!features["mcolor"] || features["mcolor"] == "#000")
- features["mcolor"] = "#FFF"
+ features["mcolor"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
if(!real_name) real_name = random_name(gender)
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
be_random_body = sanitize_integer(be_random_body, 0, 1, initial(be_random_body))
@@ -285,7 +291,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["socks"] << socks
S["backbag"] << backbag
S["species"] << pref_species.name
- S["features"] << features
+ S["feature_mcolor"] << features["mcolor"]
+ S["feature_lizard_tail"] << features["tail"]
+ S["feature_lizard_snout"] << features["snout"]
+ S["feature_lizard_horns"] << features["horns"]
+ S["feature_lizard_frills"] << features["frills"]
+ S["feature_lizard_spines"] << features["spines"]
+ S["feature_lizard_body_markings"] << features["body_markings"]
S["clown_name"] << custom_names["clown"]
S["mime_name"] << custom_names["mime"]
S["ai_name"] << custom_names["ai"]
diff --git a/code/modules/clothing/cloaks.dm b/code/modules/clothing/cloaks.dm
new file mode 100644
index 00000000000..36459139176
--- /dev/null
+++ b/code/modules/clothing/cloaks.dm
@@ -0,0 +1,98 @@
+//Cloaks. No, not THAT kind of cloak.
+
+/obj/item/clothing/cloak
+ name = "brown cloak"
+ desc = "It's a cape that can be worn on your back."
+ icon = 'icons/obj/clothing/cloaks.dmi'
+ icon_state = "qmcloak"
+ w_class = 2
+ slot_flags = SLOT_BACK
+
+/obj/item/clothing/cloak/suicide_act(mob/user)
+ user.visible_message("[user] is strangling themself with [src]! It looks like they're trying to commit suicide.")
+ return(OXYLOSS)
+
+/obj/item/clothing/cloak/hos
+ name = "head of security's cloak"
+ desc = "Worn by Securistan, ruling the station with an iron fist. It's slightly armored."
+ icon_state = "hoscloak"
+ armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0)
+
+/obj/item/clothing/cloak/qm
+ name = "quartermaster's cloak"
+ desc = "Worn by Cargonia, supplying the station with the necessary tools for survival."
+
+/obj/item/clothing/cloak/cmo
+ name = "chief medical officer's cloak"
+ desc = "Worn by Meditopia, the valiant men and women keeping pestilence at bay. It's slightly shielded from contaminants."
+ icon_state = "cmocloak"
+ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 25, rad = 0)
+
+/obj/item/clothing/cloak/ce
+ name = "chief engineer's cloak"
+ desc = "Worn by Engitopia, wielders of an unlimited power. It's slightly shielded against radiation."
+ icon_state = "cecloak"
+ armor = list(melee = 10, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 10)
+
+/obj/item/clothing/cloak/rd
+ name = "research director's cloak."
+ desc = "Worn by Sciencia, thaumaturges and researchers of the universe. It's slightly shielded from contaminants."
+ icon_state = "rdcloak"
+ armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 10, rad = 0)
+
+/obj/item/clothing/cloak/cap
+ name = "captain's cloak"
+ desc = "Worm by the commander of Space Station 13."
+ icon_state = "capcloak"
+ armor = list(melee = 10, bullet = 10, laser = 10, energy = 10, bomb = 10, bio = 10, rad = 10)
+
+/* //wip
+/obj/item/clothing/cloak/wizard //Not actually obtainable until proper balancing can be done
+ name = "cloak of invisibility"
+ desc = "A tattered old thing that apparently gifts the wearer with near-invisibility."
+ armor = list(melee = 10, bullet = 10, laser = 10, energy = 10, bomb = 10, bio = 10, rad = 10)
+ action_button_name = "Flaunt Cloak"
+ var/invisible = 0
+
+/obj/item/clothing/cloak/wizard/ui_action_click()
+ toggleInvisibility(usr)
+ return
+
+/obj/item/clothing/cloak/wizard/proc/toggleInvisibility(mob/user)
+ if(user.slot_back != src)
+ user << "You need to be wearing the cloak first!"
+ return
+ user.visible_message("[user] flaunts [src]!")
+ if(!invisible)
+ makeInvisible(user)
+ return
+ if(invisible)
+ breakInvisible(user)
+ return
+
+/obj/item/clothing/cloak/wizard/proc/makeInvisible(mob/user)
+ if(!invisible)
+ user.visible_message("[user] suddenly fades away!", \
+ "You have become nearly invisible. This will require slow movement and will break upon taking damage.")
+ flags |= NODROP //Cannot unequip while invisible
+ user.alpha = 10
+ slowdown = 2
+ invisible = 1
+
+/obj/item/clothing/cloak/wizard/proc/breakInvisible(mob/user)
+ if(invisible)
+ user.visible_message("[user] suddenly appears from thin air!", \
+ "The enchantment has broken! You are visible again.")
+ flags -= NODROP
+ user.alpha = 255
+ slowdown = 0
+ invisible = 0
+
+/obj/item/clothing/cloak/wizard/IsShield()
+ breakInvisible(src.loc)
+ return 0
+
+/obj/item/clothing/cloak/wizard/IsReflect()
+ breakInvisible(src.loc)
+ return 0
+*/
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index ae08ac4b5ce..049e675e104 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -15,6 +15,7 @@
var/cooldown = 0
var/obj/item/device/flashlight/F = null
var/can_flashlight = 0
+ var/gang //Is this a gang outfit?
//Ears: currently only used for headsets and earmuffs
/obj/item/clothing/ears
@@ -234,7 +235,8 @@ BLIND // can't see anything
return 0
else
if(user)
- user.drop_item()
+ if(!user.drop_item())
+ return
hastie = I
I.loc = src
if(user && notifyAttach)
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index 39658cc78e5..ef549cf4acb 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -196,7 +196,8 @@
var/obj/item/device/flashlight/seclite/S = A
if(can_flashlight)
if(!F)
- user.drop_item()
+ if(!user.unEquip(A))
+ return
user << "You click [S] into place on [src]."
if(S.on)
SetLuminosity(0)
@@ -228,7 +229,8 @@
if(helmetCam)
user << "[src] already has a mounted camera."
return
- user.drop_item()
+ if(!user.unEquip(A))
+ return
helmetCam = new /obj/machinery/camera/portable(src)
helmetCam.assembly = A
A.loc = helmetCam
diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm
index 4f25a633e2e..d19c7b7397c 100644
--- a/code/modules/clothing/head/jobs.dm
+++ b/code/modules/clothing/head/jobs.dm
@@ -1,5 +1,5 @@
-//Bartender
+//Bartender //it's chef what the fuck is your problem?
/obj/item/clothing/head/chefhat
name = "chef's hat"
desc = "It's a hat used by chefs to keep hair out of your food. Judging by the food in the mess, they don't work."
@@ -9,6 +9,15 @@
strip_delay = 10
put_on_delay = 10
+/obj/item/clothing/head/chefhat/suicide_act(mob/user)
+ user.visible_message("[user] is donning [src]! It looks like they're trying to become a chef.")
+ user.say("Bork Bork Bork!")
+ sleep(20)
+ user.visible_message("[user] climbs into an imaginary oven!")
+ user.say("BOOORK!")
+ playsound(user, 'sound/machines/ding.ogg', 50, 1)
+ return(FIRELOSS)
+
//Captain
/obj/item/clothing/head/caphat
name = "captain's hat"
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index 955e194aeac..7130556f958 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -172,6 +172,16 @@
item_state = "fedora"
desc = "A really cool hat if you're a mobster. A really lame hat if you're not."
+/obj/item/clothing/head/fedora/suicide_act(mob/user)
+ if(user.gender == FEMALE)
+ return 0
+ var/mob/living/carbon/human/H = user
+ user.visible_message("[user] is donning [src]! It looks like they're trying to be nice to girls.")
+ user.say("M'lady.")
+ sleep(10)
+ H.facial_hair_style = "Neckbeard"
+ return(BRUTELOSS)
+
/obj/item/clothing/head/sombrero
name = "sombrero"
icon_state = "sombrero"
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index e651a87e18a..1a0a0a4f98c 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -1,5 +1,12 @@
/obj/item/clothing/shoes/proc/step_action() //this was made to rewrite clown shoes squeaking
+/obj/item/clothing/shoes/suicide_act(mob/user)
+ user.visible_message("[user] is bashing their own head in with [src]! Ain't that a kick in the head?")
+ for(var/i = 0, i < 3, i++)
+ sleep(3)
+ playsound(user, 'sound/weapons/genhit2.ogg', 50, 1)
+ return(BRUTELOSS)
+
/obj/item/clothing/shoes/sneakers/syndigaloshes
desc = "A pair of brown shoes."
name = "brown shoes"
diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm
index f5a4fb0b4fb..26e08d66b64 100644
--- a/code/modules/clothing/suits/armor.dm
+++ b/code/modules/clothing/suits/armor.dm
@@ -51,6 +51,15 @@
desc = "A navy-blue armored jacket with blue shoulder designations and '/Warden/' stitched into one of the chest pockets."
icon_state = "warden_alt"
+/obj/item/clothing/suit/armor/vest/leather
+ name = "security overcoat"
+ desc = "Lightly armored leather overcoat meant as casual wear for high-ranking officers. Bears the crest of Nanotrasen Security."
+ icon_state = "leathercoat-sec"
+ item_state = "hostrench"
+ body_parts_covered = CHEST|GROIN|ARMS|LEGS
+ cold_protection = CHEST|GROIN|LEGS|ARMS
+ heat_protection = CHEST|GROIN|LEGS|ARMS
+
/obj/item/clothing/suit/armor/vest/capcarapace
name = "captain's carapace"
desc = "An armored vest reinforced with ceramic plates and pauldrons to provide additional protection whilst still offering maximum mobility and flexibility. Issued only to the station's finest, although it does chafe your nipples."
@@ -79,7 +88,7 @@
icon_state = "bulletproof"
item_state = "armor"
blood_overlay_type = "armor"
- armor = list(melee = 15, bullet = 60, laser = 10, energy = 10, bomb = 40, bio = 0, rad = 0)
+ armor = list(melee = 15, bullet = 80, laser = 10, energy = 10, bomb = 40, bio = 0, rad = 0)
strip_delay = 70
put_on_delay = 50
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index 37b771b0c15..ba5549140ca 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -235,6 +235,14 @@
name = "leather jacket"
desc = "Pompadour not included."
icon_state = "leatherjacket"
+ item_state = "hostrench"
+
+/obj/item/clothing/suit/jacket/leather/overcoat
+ name = "leather overcoat"
+ desc = "That's a damn fine coat."
+ icon_state = "leathercoat"
+ body_parts_covered = CHEST|GROIN|ARMS|LEGS
+ cold_protection = CHEST|GROIN|ARMS|LEGS
/obj/item/clothing/suit/xenos
name = "xenos suit"
diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm
index c9acca85f49..42dae95f077 100644
--- a/code/modules/clothing/under/miscellaneous.dm
+++ b/code/modules/clothing/under/miscellaneous.dm
@@ -235,7 +235,7 @@
/obj/item/clothing/under/suit_jacket/white
name = "white suit"
- desc = "A white suit and jacket with a black shirt. You wanna play rough? OKAY!."
+ desc = "A white suit and jacket with a blue shirt. You wanna play rough? OKAY!."
icon_state = "white_suit"
item_state = "white_suit"
item_color = "white_suit"
diff --git a/code/modules/events/anomaly_flux.dm b/code/modules/events/anomaly_flux.dm
index fd4a10270b4..fd568e4c029 100644
--- a/code/modules/events/anomaly_flux.dm
+++ b/code/modules/events/anomaly_flux.dm
@@ -22,5 +22,5 @@
/datum/round_event/anomaly/anomaly_flux/end()
if(newAnomaly.loc)//If it hasn't been neutralized, it's time to blow up.
- explosion(newAnomaly, -1, 3, 5, 5)
+ explosion(newAnomaly, -1, 3, 8, 10)
qdel(newAnomaly)
\ No newline at end of file
diff --git a/code/modules/events/immovable_rod.dm b/code/modules/events/immovable_rod.dm
index 650fefe3bdf..4ff5bd2519b 100644
--- a/code/modules/events/immovable_rod.dm
+++ b/code/modules/events/immovable_rod.dm
@@ -47,9 +47,13 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
qdel(src)
return ..()
+/obj/effect/immovablerod/ex_act(test)
+ return 0
+
/obj/effect/immovablerod/Bump(atom/clong)
- playsound(src, 'sound/effects/bang.ogg', 50, 1)
- audible_message("CLANG")
+ if(prob(10))
+ playsound(src, 'sound/effects/bang.ogg', 50, 1)
+ audible_message("CLANG")
if(clong && prob(25))
x = clong.x
@@ -60,7 +64,10 @@ In my current plan for it, 'solid' will be defined as anything with density == 1
clong.ex_act(2)
else if (istype(clong, /mob))
+ if(istype(clong, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = clong
+ H.visible_message("[H.name] is penetrated by an immovable rod!" , "The rod penetrates you!" , "You hear a CLANG!")
+ H.adjustBruteLoss(160)
if(clong.density || prob(10))
clong.ex_act(2)
- else
- qdel(src)
+ return
diff --git a/code/modules/events/meateor_wave.dm b/code/modules/events/meateor_wave.dm
index b45140ad5ee..fa26633e90f 100644
--- a/code/modules/events/meateor_wave.dm
+++ b/code/modules/events/meateor_wave.dm
@@ -5,7 +5,7 @@
max_occurrences = 1
/datum/round_event/meteor_wave/meaty/announce()
- priority_announce("Meaty ores have been detected on collision course with the station.", "Oh Crap, Get The Mop.",'sound/AI/meteors.ogg')
+ priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.",'sound/AI/meteors.ogg')
/datum/round_event/meteor_wave/meaty/tick()
if(IsMultiple(activeFor, 3))
diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm
index e86680822e5..9a48f2ccca6 100644
--- a/code/modules/events/meteor_wave.dm
+++ b/code/modules/events/meteor_wave.dm
@@ -15,7 +15,7 @@
random_wave_type()
/datum/round_event/meteor_wave/proc/random_wave_type()
- var/picked_wave = pickweight(list("normal" = 75, "threatening" = 20, "catastrophic" = 5))
+ var/picked_wave = pickweight(list("normal" = 50, "threatening" = 40, "catastrophic" = 10))
switch(picked_wave)
if("normal")
wave_type = meteors_normal
diff --git a/code/modules/events/wizard/race.dm b/code/modules/events/wizard/race.dm
index 4eb0c5bf1a7..bed5d08b5f4 100644
--- a/code/modules/events/wizard/race.dm
+++ b/code/modules/events/wizard/race.dm
@@ -10,9 +10,10 @@
var/all_the_same = 0
var/all_species = list()
- for(var/datum/species/S in typesof(/datum/species) - /datum/species)
+ for(var/speciestype in typesof(/datum/species) - /datum/species)
+ var/datum/species/S = new speciestype()
if(!S.dangerous_existence)
- all_species += S
+ all_species += speciestype
var/new_species = pick(all_species)
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index e3aa865a141..388da344db4 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -22,184 +22,346 @@ Gunshots/explosions/opening doors/less rare audio (done)
/mob/living/carbon/proc/handle_hallucinations()
if(handling_hal)
return
+
+ //Least obvious
+ var/list/minor = list("sounds"=20,"bolts_minor"=10,"whispers"=15,"message"=5)
+ //Something's wrong here
+ var/list/medium = list("hudscrew"=15,"items"=15,"dangerflash"=15,"bolts"=10,"flood"=10,"husks"=10,"battle"=10)
+ //AAAAH
+ var/list/major = list("fake"=10,"death"=5,"xeno"=10,"singulo"=10,"delusion"=10)
+
+ var/grade = 0
+ var/current = list()
+ var/trip_length = 0
+
handling_hal = 1
while(hallucination > 20)
sleep(rand(200,500)/(hallucination/25))
- var/halpick = rand(1,100)
- switch(halpick)
- if(0 to 15)
- //Screwy HUD
- //src << "Screwy HUD"
- hal_screwyhud = pick(1,2,3,3,4,4)
- spawn(rand(100,250))
- hal_screwyhud = 0
- if(16 to 25)
- //Strange items
- //src << "Traitor Items"
- if(!halitem)
- halitem = new
- var/list/slots_free = list(ui_lhand,ui_rhand)
- if(l_hand) slots_free -= ui_lhand
- if(r_hand) slots_free -= ui_rhand
- if(istype(src,/mob/living/carbon/human))
- var/mob/living/carbon/human/H = src
- if(!H.belt) slots_free += ui_belt
- if(!H.l_store) slots_free += ui_storage1
- if(!H.r_store) slots_free += ui_storage2
- if(slots_free.len)
- halitem.screen_loc = pick(slots_free)
- halitem.layer = 50
- switch(rand(1,6))
- if(1) //revolver
- halitem.icon = 'icons/obj/guns/projectile.dmi'
- halitem.icon_state = "revolver"
- halitem.name = "Revolver"
- if(2) //c4
- halitem.icon = 'icons/obj/assemblies.dmi'
- halitem.icon_state = "plastic-explosive0"
- halitem.name = "Mysterious Package"
- if(prob(25))
- halitem.icon_state = "c4small_1"
- if(3) //sword
- halitem.icon = 'icons/obj/weapons.dmi'
- halitem.icon_state = "sword1"
- halitem.name = "Sword"
- if(4) //stun baton
- halitem.icon = 'icons/obj/weapons.dmi'
- halitem.icon_state = "stunbaton"
- halitem.name = "Stun Baton"
- if(5) //emag
- halitem.icon = 'icons/obj/card.dmi'
- halitem.icon_state = "emag"
- halitem.name = "Cryptographic Sequencer"
- if(6) //flashbang
- halitem.icon = 'icons/obj/grenade.dmi'
- halitem.icon_state = "flashbang1"
- halitem.name = "Flashbang"
- if(client) client.screen += halitem
- spawn(rand(100,250))
- qdel(halitem)
- if(26 to 40)
- //Flashes of danger
- //src << "Danger Flash"
- if(!halimage)
- var/list/possible_points = list()
- for(var/turf/simulated/floor/F in view(src,world.view))
- possible_points += F
- if(possible_points.len)
- var/turf/simulated/floor/target = pick(possible_points)
+ trip_length += 1
+ if(prob(min(20,trip_length*2)))
+ grade = min(3,grade+1)
+ if(prob(20))
+ continue
+ current = list()
+ for(var/a in minor)
+ current[a] = minor[a] * (grade==0?2:1)
+ for(var/b in medium)
+ current[b] = medium[b] * (grade==1?2:1)
+ for(var/c in major)
+ current[c] = major[c] * (grade==2?2:1)
- switch(rand(1,3))
- if(1)
- //src << "Space"
- halimage = image('icons/turf/space.dmi',target,"[rand(1,25)]",TURF_LAYER)
- if(2)
- //src << "Fire"
- halimage = image('icons/effects/fire.dmi',target,"1",TURF_LAYER)
- if(3)
- //src << "C4"
- halimage = image('icons/obj/assemblies.dmi',target,"plastic-explosive2",OBJ_LAYER+0.01)
+ var/halpick = pickweight(current)
-
- if(client) client.images += halimage
- spawn(rand(10,50)) //Only seen for a brief moment.
- if(client) client.images -= halimage
- halimage = null
-
-
- if(41 to 65)
- //Strange audio
- //src << "Strange Audio"
- switch(rand(1,14))
- if(1) src << 'sound/machines/airlock.ogg'
- if(2)
- if(prob(50))src << 'sound/effects/Explosion1.ogg'
- else src << 'sound/effects/Explosion2.ogg'
- if(3) src << 'sound/effects/explosionfar.ogg'
- if(4) src << 'sound/effects/Glassbr1.ogg'
- if(5) src << 'sound/effects/Glassbr2.ogg'
- if(6) src << 'sound/effects/Glassbr3.ogg'
- if(7) src << 'sound/machines/twobeep.ogg'
- if(8) src << 'sound/machines/windowdoor.ogg'
- if(9)
- //To make it more realistic, I added two gunshots (enough to kill)
- src << 'sound/weapons/Gunshot.ogg'
- spawn(rand(10,30))
- src << 'sound/weapons/Gunshot.ogg'
- if(10) src << 'sound/weapons/smash.ogg'
- if(11)
- //Same as above, but with tasers.
- src << 'sound/weapons/Taser.ogg'
- spawn(rand(10,30))
- src << 'sound/weapons/Taser.ogg'
- //Rare audio
- if(12)
-//These sounds are (mostly) taken from Hidden: Source
- var/list/creepyasssounds = list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/Heart Beat.ogg', 'sound/effects/screech.ogg',\
- 'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\
- 'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\
- 'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\
- 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg')
- src << pick(creepyasssounds)
- if(13)
- src << "You feel a tiny prick!"
- if(14)
- src << "Priority Announcement
"
- src << "
The Emergency Shuttle has docked with the station. You have 3 minutes to board the Emergency Shuttle.
"
- src << sound('sound/AI/shuttledock.ogg')
- if(66 to 70)
- //Flashes of danger
- if(!halbody)
- var/list/possible_points = list()
- for(var/turf/simulated/floor/F in view(src,world.view))
- possible_points += F
- if(possible_points.len)
- var/turf/simulated/floor/target = pick(possible_points)
- switch(rand(1,4))
- if(1)
- halbody = image('icons/mob/human.dmi',target,"husk_l",TURF_LAYER)
- if(2,3)
- halbody = image('icons/mob/human.dmi',target,"husk_s",TURF_LAYER)
- if(4)
- halbody = image('icons/mob/alien.dmi',target,"alienother",TURF_LAYER)
-
- if(client) client.images += halbody
- spawn(rand(50,80)) //Only seen for a brief moment.
- if(client) client.images -= halbody
- halbody = null
- if(71 to 72)
- //Fake death
- src.sleeping = 20
- hal_crit = 1
- hal_screwyhud = 1
- spawn(rand(50,100))
- src.sleeping = 0
- hal_crit = 0
- hal_screwyhud = 0
- if(73 to 75)
- fake_attack()
+ hallucinate(halpick)
handling_hal = 0
+/obj/effect/hallucination
+ invisibility = INVISIBILITY_OBSERVER
+ var/mob/living/carbon/target = null
-/mob/living/carbon/proc/fake_attack()
-// var/list/possible_clones = new/list()
+/obj/effect/hallucination/simple
+ var/image_icon = 'icons/mob/alien.dmi'
+ var/image_state = "alienh_pounce"
+ var/px = 0
+ var/py = 0
+ var/col_mod = null
+ var/image/current_image = null
+ var/image_layer = MOB_LAYER
+ var/active = 1 //qdelery
+
+/obj/effect/hallucination/simple/New(loc,var/mob/living/carbon/T)
+ target = T
+ current_image = GetImage()
+ if(target.client) target.client.images |= current_image
+ return
+
+/obj/effect/hallucination/simple/proc/GetImage()
+ var/image/I = image(image_icon,loc,image_state,image_layer,dir=src.dir)
+ I.pixel_x = px
+ I.pixel_y = py
+ if(col_mod)
+ I.color = col_mod
+ return I
+
+/obj/effect/hallucination/simple/proc/Show(var/update=1)
+ if(active)
+ if(target.client) target.client.images.Remove(current_image)
+ if(update)
+ current_image = GetImage()
+ if(target.client) target.client.images |= current_image
+
+/obj/effect/hallucination/simple/update_icon(var/new_state,var/new_icon,var/new_px=0,var/new_py=0)
+ image_state = new_state
+ if(new_icon)
+ image_icon = new_icon
+ else
+ image_icon = initial(image_icon)
+ px = new_px
+ py = new_py
+ Show()
+
+/obj/effect/hallucination/simple/Moved(atom/OldLoc, Dir)
+ Show()
+ return
+
+/obj/effect/hallucination/simple/Destroy()
+ if(target.client) target.client.images.Remove(current_image)
+ active = 0
+
+#define FAKE_FLOOD_EXPAND_TIME 30
+#define FAKE_FLOOD_MAX_RADIUS 7
+
+/obj/effect/hallucination/fake_flood
+ //Plasma/N2O starts flooding from the nearby vent
+ var/list/flood_images = list()
+ var/list/turf/flood_turfs = list()
+ var/image_icon = 'icons/effects/tile_effects.dmi'
+ var/image_state = "plasma"
+ var/radius = 0
+ var/next_expand = 0
+
+/obj/effect/hallucination/fake_flood/New(loc,var/mob/living/carbon/T)
+ ..()
+ target = T
+ for(var/obj/machinery/atmospherics/unary/vent_pump/U in orange(7,target))
+ if(!U.welded)
+ src.loc = U.loc
+ break
+ image_state = pick("plasma","sleeping_agent")
+ flood_images += image(image_icon,src,image_state,MOB_LAYER)
+ flood_turfs += get_turf(src.loc)
+ if(target.client) target.client.images |= flood_images
+ next_expand = world.time + FAKE_FLOOD_EXPAND_TIME
+ SSobj.processing |= src
+
+/obj/effect/hallucination/fake_flood/process()
+ if(next_expand <= world.time)
+ radius++
+ if(radius > FAKE_FLOOD_MAX_RADIUS)
+ qdel(src)
+ Expand()
+ next_expand = world.time + FAKE_FLOOD_EXPAND_TIME
+ return
+
+/obj/effect/hallucination/fake_flood/proc/Expand()
+ if(!flood_turfs) //for qdel
+ return
+ for(var/turf/T in circlerangeturfs(loc,radius))
+ if((T in flood_turfs)|| T.blocks_air)
+ continue
+ flood_images += image(image_icon,T,image_state,MOB_LAYER)
+ flood_turfs += T
+ if(target.client) target.client.images |= flood_images
+ return
+
+/obj/effect/hallucination/fake_flood/Destroy()
+ SSobj.processing.Remove(src)
+ del(flood_turfs)
+ if(target.client) target.client.images.Remove(flood_images)
+ target = null
+ del(flood_images)
+ return
+
+/obj/effect/hallucination/simple/xeno
+ image_icon = 'icons/mob/alien.dmi'
+ image_state = "alienh_pounce"
+
+/obj/effect/hallucination/simple/xeno/New(loc,var/mob/living/carbon/T)
+ ..()
+ name = "alien hunter ([rand(1, 1000)])"
+ return
+
+/obj/effect/hallucination/simple/xeno/throw_at(atom/target, range, speed) // TODO : Make diagonal trhow into proc/property
+ if(!target || !src || (flags & NODROP)) return 0
+
+ src.throwing = 1
+
+ var/dist_x = abs(target.x - src.x)
+ var/dist_y = abs(target.y - src.y)
+ var/dist_travelled = 0
+ var/dist_since_sleep = 0
+
+ var/tdist_x = dist_x;
+ var/tdist_y = dist_y;
+
+ if(dist_x <= dist_y)
+ tdist_x = dist_y;
+ tdist_y = dist_x;
+
+ var/error = tdist_x/2 - tdist_y
+ while(target && (((((dist_x > dist_y) && ((src.x < target.x) || (src.x > target.x))) || ((dist_x <= dist_y) && ((src.y < target.y) || (src.y > target.y))) || (src.x > target.x)) && dist_travelled < range) || !has_gravity(src)))
+
+ if(!src.throwing) break
+ if(!istype(src.loc, /turf)) break
+
+ var/atom/step = get_step(src, get_dir(src,target))
+ if(!step)
+ break
+ src.Move(step, get_dir(src, step))
+ hit_check()
+ error += (error < 0) ? tdist_x : -tdist_y;
+ dist_travelled++
+ dist_since_sleep++
+ if(dist_since_sleep >= speed)
+ dist_since_sleep = 0
+ sleep(1)
+
+
+ src.throwing = 0
+ src.throw_impact(get_turf(src))
+
+ return 1
+
+/obj/effect/hallucination/simple/xeno/throw_impact(A)
+ update_icon("alienh_pounce")
+ if(A == target)
+ target.Weaken(5)
+ target.visible_message("[target] flails around wildly.","[name] pounces on you!")
+
+/obj/effect/hallucination/xeno_attack
+ //Xeno crawls from nearby vent,jumps at you, and goes back in
+ var/obj/machinery/atmospherics/unary/vent_pump/pump = null
+ var/obj/effect/hallucination/simple/xeno/xeno = null
+
+/obj/effect/hallucination/xeno_attack/New(loc,var/mob/living/carbon/T)
+ target = T
+ for(var/obj/machinery/atmospherics/unary/vent_pump/U in orange(7,target))
+ if(!U.welded)
+ pump = U
+ break
+ xeno = new(pump.loc,target)
+ sleep(10)
+ xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
+ xeno.throw_at(target,7,1)
+ sleep(10)
+ xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
+ xeno.throw_at(pump,7,1)
+ sleep(10)
+ var/xeno_name = xeno.name
+ target << "[xeno_name] begins climbing into the ventilation system..."
+ sleep(10)
+ qdel(xeno)
+ target << "[xeno_name] scrambles into the ventilation ducts!"
+ qdel(src)
+
+/obj/effect/hallucination/singularity_scare
+ //Singularity moving towards you.
+ //todo Hide where it moved with fake space images
+ var/obj/effect/hallucination/simple/singularity/s = null
+
+/obj/effect/hallucination/singularity_scare/New(loc,var/mob/living/carbon/T)
+ target = T
+ var/turf/start = T.loc
+ var/screen_border = pick(SOUTH,EAST,WEST,NORTH)
+ for(var/i = 0,i<11,i++)
+ start = get_step(start,screen_border)
+ s = new(start,target)
+ for(var/i = 0,i<11,i++)
+ sleep(5)
+ s.loc = get_step(get_turf(s),get_dir(s,target))
+ s.Show()
+ s.Eat()
+ qdel(s)
+
+/obj/effect/hallucination/simple/singularity
+ image_icon = 'icons/effects/224x224.dmi'
+ image_state = "singularity_s7"
+ image_layer = 6
+ px = -96
+ py = -96
+
+/obj/effect/hallucination/simple/singularity/proc/Eat(atom/OldLoc, Dir)
+ var/target_dist = get_dist(src,target)
+ if(target_dist<=3) //"Eaten"
+ target.sleeping = 20
+ target.hal_crit = 1
+ target.hal_screwyhud = 1
+ spawn(rand(50,100))
+ target.sleeping = 0
+ target.hal_crit = 0
+ target.hal_screwyhud = 0
+
+/obj/effect/hallucination/battle
+
+/obj/effect/hallucination/battle/New(loc,var/mob/living/carbon/T)
+ target = T
+ var/hits = rand(3,6)
+ switch(rand(1,5))
+ if(1) //Laser fight
+ for(var/i=0,i[my_target] has attacked [src]!")
src.health -= P.force
-
-
return
/obj/effect/fake_attacker/Crossed(var/mob/M, somenumber)
@@ -266,20 +425,18 @@ Gunshots/explosions/opening doors/less rare audio (done)
for(var/mob/O in oviewers(world.view , my_target))
O << "[my_target] stumbles around."
-/obj/effect/fake_attacker/New()
+/obj/effect/fake_attacker/New(loc,var/mob/living/carbon/T)
..()
+ my_target = T
spawn(300)
- if(my_target)
- my_target.hallucinations -= src
qdel(src)
step_away(src,my_target,2)
- spawn attack_loop()
+ spawn(0)
+ attack_loop()
/obj/effect/fake_attacker/proc/updateimage()
// del src.currentimage
-
-
if(src.dir == NORTH)
del src.currentimage
src.currentimage = new /image(up,src)
@@ -356,3 +513,251 @@ var/list/non_fakeattack_weapons = list(/obj/item/weapon/gun/projectile, /obj/ite
/obj/item/clothing/under/rank/captain, /obj/item/device/aicard,\
/obj/item/clothing/shoes/magboots, /obj/item/areaeditor/blueprints, /obj/item/weapon/disk/nuclear,\
/obj/item/clothing/suit/space/nasavoid, /obj/item/weapon/tank)
+
+/obj/effect/hallucination/bolts
+ var/list/doors = list()
+
+/obj/effect/hallucination/bolts/New(loc,var/mob/living/carbon/T,var/door_number=-1) //-1 for sever 1-2 for subtle
+ target = T
+ var/image/I = null
+ var/count = 0
+ for(var/obj/machinery/door/airlock/A in range(target,7))
+ if(count>door_number && door_number>0)
+ break
+ count++
+ I = image(A.icon,A,"door_locked",layer=A.layer+0.1)
+ doors += I
+ if(target.client)
+ target.client.images |= I
+ sleep(2)
+ sleep(100)
+ for(var/image/B in doors)
+ if(target.client)
+ target.client.images.Remove(B)
+ qdel(src)
+
+/obj/effect/hallucination/whispers
+
+/obj/effect/hallucination/whispers/New(loc,var/mob/living/carbon/T)
+ target = T
+ var/speak_messages = list("I'm watching you...","[target.name]!","Go away!","Kchck-Chkck? Kchchck!","Did you hear that?","What did you do ?","Why?","Give me that!","Honk!","HELP!!")
+ var/radio_messages = list("Xenos!","Singularity loose!","They are arming the nuke!","They butchered Ian!","H-help!","[pick(teleportlocs)]!!","Where's [target.name]?","Call the shuttle!")
+
+ var/list/mob/living/carbon/people = list()
+ var/list/mob/living/carbon/person = null
+ for(var/mob/living/carbon/H in view(target))
+ if(H == target)
+ continue
+ if(!person)
+ person = H
+ else
+ if(get_dist(target,H)The light burns you!", \
+ "You don't feel like yourself.", \
+ "Unknown has punched [target]!", \
+ "You hear something squeezing through the ducts...", \
+ "You hear a distant scream.", \
+ "You feel invincible, nothing can hurt you!", \
+ "[target] sneezes.", \
+ "You feel faint.", \
+ "You hear a strange, alien voice in your head...[pick("Hiss","Ssss")]", \
+ "You can see...everything!")
+ target << chosen
+ qdel(src)
+
+/mob/living/carbon/proc/hallucinate(var/hal_type) // Todo -> proc / defines
+ switch(hal_type)
+ if("xeno")
+ new /obj/effect/hallucination/xeno_attack(src.loc,src)
+ if("singulo")
+ new /obj/effect/hallucination/singularity_scare(src.loc,src)
+ if("battle")
+ new /obj/effect/hallucination/battle(src.loc,src)
+ if("flood")
+ new /obj/effect/hallucination/fake_flood(src.loc,src)
+ if("delusion")
+ new /obj/effect/hallucination/delusion(src.loc,src)
+ if("fake")
+ new /obj/effect/hallucination/fakeattacker(src.loc,src)
+ if("bolts")
+ new /obj/effect/hallucination/bolts(src.loc,src)
+ if("bolts_minor")
+ new /obj/effect/hallucination/bolts(src.loc,src,rand(1,2))
+ if("whispers")
+ new /obj/effect/hallucination/whispers(src.loc,src)
+ if("message")
+ new /obj/effect/hallucination/message(src.loc,src)
+ if("sounds")
+ //Strange audio
+ //src << "Strange Audio"
+ switch(rand(1,18))
+ if(1) src << 'sound/machines/airlock.ogg'
+ if(2)
+ if(prob(50))src << 'sound/effects/Explosion1.ogg'
+ else src << 'sound/effects/Explosion2.ogg'
+ if(3) src << 'sound/effects/explosionfar.ogg'
+ if(4) src << 'sound/effects/Glassbr1.ogg'
+ if(5) src << 'sound/effects/Glassbr2.ogg'
+ if(6) src << 'sound/effects/Glassbr3.ogg'
+ if(7) src << 'sound/machines/twobeep.ogg'
+ if(8) src << 'sound/machines/windowdoor.ogg'
+ if(9)
+ //To make it more realistic, I added two gunshots (enough to kill)
+ src << 'sound/weapons/Gunshot.ogg'
+ spawn(rand(10,30))
+ src << 'sound/weapons/Gunshot.ogg'
+ if(10) src << 'sound/weapons/smash.ogg'
+ if(11)
+ //Same as above, but with tasers.
+ src << 'sound/weapons/Taser.ogg'
+ spawn(rand(10,30))
+ src << 'sound/weapons/Taser.ogg'
+ //Rare audio
+ if(12)
+ //These sounds are (mostly) taken from Hidden: Source
+ var/list/creepyasssounds = list('sound/effects/ghost.ogg', 'sound/effects/ghost2.ogg', 'sound/effects/Heart Beat.ogg', 'sound/effects/screech.ogg',\
+ 'sound/hallucinations/behind_you1.ogg', 'sound/hallucinations/behind_you2.ogg', 'sound/hallucinations/far_noise.ogg', 'sound/hallucinations/growl1.ogg', 'sound/hallucinations/growl2.ogg',\
+ 'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\
+ 'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\
+ 'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg')
+ src << pick(creepyasssounds)
+ if(13)
+ src << "You feel a tiny prick!"
+ if(14)
+ src << "Priority Announcement
"
+ src << "
The Emergency Shuttle has docked with the station. You have 3 minutes to board the Emergency Shuttle.
"
+ src << sound('sound/AI/shuttledock.ogg')
+ if(15)
+ src << 'sound/items/Welder.ogg'
+ if(16)
+ src << 'sound/items/Screwdriver.ogg'
+ if(17)
+ src << 'sound/weapons/saberon.ogg'
+ if(18)
+ src << 'sound/weapons/saberoff.ogg'
+ if("hudscrew")
+ //Screwy HUD
+ //src << "Screwy HUD"
+ hal_screwyhud = pick(1,2,3,3,4,4)
+ spawn(rand(100,250))
+ hal_screwyhud = 0
+ if("items")
+ //Strange items
+ //src << "Traitor Items"
+ if(!halitem)
+ halitem = new
+ var/list/slots_free = list(ui_lhand,ui_rhand)
+ if(l_hand) slots_free -= ui_lhand
+ if(r_hand) slots_free -= ui_rhand
+ if(istype(src,/mob/living/carbon/human))
+ var/mob/living/carbon/human/H = src
+ if(!H.belt) slots_free += ui_belt
+ if(!H.l_store) slots_free += ui_storage1
+ if(!H.r_store) slots_free += ui_storage2
+ if(slots_free.len)
+ halitem.screen_loc = pick(slots_free)
+ halitem.layer = 50
+ switch(rand(1,6))
+ if(1) //revolver
+ halitem.icon = 'icons/obj/guns/projectile.dmi'
+ halitem.icon_state = "revolver"
+ halitem.name = "Revolver"
+ if(2) //c4
+ halitem.icon = 'icons/obj/assemblies.dmi'
+ halitem.icon_state = "plastic-explosive0"
+ halitem.name = "Mysterious Package"
+ if(prob(25))
+ halitem.icon_state = "c4small_1"
+ if(3) //sword
+ halitem.icon = 'icons/obj/weapons.dmi'
+ halitem.icon_state = "sword1"
+ halitem.name = "Sword"
+ if(4) //stun baton
+ halitem.icon = 'icons/obj/weapons.dmi'
+ halitem.icon_state = "stunbaton"
+ halitem.name = "Stun Baton"
+ if(5) //emag
+ halitem.icon = 'icons/obj/card.dmi'
+ halitem.icon_state = "emag"
+ halitem.name = "Cryptographic Sequencer"
+ if(6) //flashbang
+ halitem.icon = 'icons/obj/grenade.dmi'
+ halitem.icon_state = "flashbang1"
+ halitem.name = "Flashbang"
+ if(client) client.screen += halitem
+ spawn(rand(100,250))
+ qdel(halitem)
+ if("dangerflash")
+ //Flashes of danger
+ //src << "Danger Flash"
+ if(!halimage)
+ var/list/possible_points = list()
+ for(var/turf/simulated/floor/F in view(src,world.view))
+ possible_points += F
+ if(possible_points.len)
+ var/turf/simulated/floor/target = pick(possible_points)
+
+ switch(rand(1,3))
+ if(1)
+ //src << "Space"
+ halimage = image('icons/turf/space.dmi',target,"[rand(1,25)]",TURF_LAYER)
+ if(2)
+ //src << "Fire"
+ halimage = image('icons/effects/fire.dmi',target,"1",TURF_LAYER)
+ if(3)
+ //src << "C4"
+ halimage = image('icons/obj/assemblies.dmi',target,"plastic-explosive2",OBJ_LAYER+0.01)
+
+
+ if(client) client.images += halimage
+ spawn(rand(10,50)) //Only seen for a brief moment.
+ if(client) client.images -= halimage
+ halimage = null
+ if("death")
+ //Fake death
+ src.sleeping = 20
+ hal_crit = 1
+ hal_screwyhud = 1
+ spawn(rand(50,100))
+ src.sleeping = 0
+ hal_crit = 0
+ hal_screwyhud = 0
+ if("husks")
+ if(!halbody)
+ var/list/possible_points = list()
+ for(var/turf/simulated/floor/F in view(src,world.view))
+ possible_points += F
+ if(possible_points.len)
+ var/turf/simulated/floor/target = pick(possible_points)
+ switch(rand(1,4))
+ if(1)
+ var/image/body = image('icons/mob/human.dmi',target,"husk_s",TURF_LAYER)
+ var/matrix/M = matrix()
+ M.Turn(90)
+ body.transform = M
+ halbody = body
+ if(2,3)
+ halbody = image('icons/mob/human.dmi',target,"husk_s",TURF_LAYER)
+ if(4)
+ halbody = image('icons/mob/alien.dmi',target,"alienother",TURF_LAYER)
+
+ if(client) client.images += halbody
+ spawn(rand(50,80)) //Only seen for a brief moment.
+ if(client) client.images -= halbody
+ halbody = null
\ No newline at end of file
diff --git a/code/modules/food&drinks/food/customizables.dm b/code/modules/food&drinks/food/customizables.dm
index 7f9387b9865..c2aa2849c0a 100644
--- a/code/modules/food&drinks/food/customizables.dm
+++ b/code/modules/food&drinks/food/customizables.dm
@@ -44,7 +44,8 @@
else if((ingredients.len >= ingMax) || (reagents.total_volume >= volume))
user << "You can't add more ingredients to [src]!"
else
- user.drop_item()
+ if(!user.unEquip(I))
+ return
if(S.trash)
new S.trash(get_turf(user))
S.trash = null //we remove the plate before adding the ingredient
diff --git a/code/modules/food&drinks/kitchen machinery/food_cart.dm b/code/modules/food&drinks/kitchen machinery/food_cart.dm
index fdae544a1b9..1cff6be4b82 100644
--- a/code/modules/food&drinks/kitchen machinery/food_cart.dm
+++ b/code/modules/food&drinks/kitchen machinery/food_cart.dm
@@ -63,7 +63,8 @@
if(istype(O, /obj/item/weapon/reagent_containers/food/drinks/drinkingglass))
var/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/DG = O
if(!DG.reagents.total_volume) //glass is empty
- user.drop_item()
+ if(!user.drop_item())
+ return
qdel(DG)
glasses++
user << "The [src] accepts the drinking glass, sterilizing it."
@@ -72,7 +73,8 @@
user << "The [src] is at full capacity."
else
var/obj/item/weapon/reagent_containers/food/snacks/S = O
- user.drop_item()
+ if(!user.drop_item())
+ return
S.loc = src
if(stored_food[sanitize(S.name)])
stored_food[sanitize(S.name)]++
diff --git a/code/modules/food&drinks/kitchen machinery/monkeyrecycler.dm b/code/modules/food&drinks/kitchen machinery/monkeyrecycler.dm
index bb88e5ec867..fc6a899f5b0 100644
--- a/code/modules/food&drinks/kitchen machinery/monkeyrecycler.dm
+++ b/code/modules/food&drinks/kitchen machinery/monkeyrecycler.dm
@@ -60,7 +60,8 @@
if(target.stat == 0)
user << "The monkey is struggling far too much to put it in the recycler."
else
- user.drop_item()
+ if(!user.drop_item())
+ return
qdel(target)
user << "You stuff the monkey in the machine."
playsound(src.loc, 'sound/machines/juicer.ogg', 50, 1)
diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm
index 3722cdda67f..38c9be4e471 100644
--- a/code/modules/hydroponics/grown.dm
+++ b/code/modules/hydroponics/grown.dm
@@ -897,7 +897,7 @@ obj/item/weapon/reagent_containers/food/snacks/grown/shell/eggy/add_juice()
/obj/item/weapon/reagent_containers/food/snacks/grown/tomato/blue/bluespace/attack_self(var/mob/user)
squish(user)
- user.drop_item()
+ user.unEquip(src)
src.visible_message("[user] squashes the [src.name].","You hear a smack.")
qdel(src)
diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm
index 065d3d8d08f..0e491e575bf 100644
--- a/code/modules/hydroponics/seeds.dm
+++ b/code/modules/hydroponics/seeds.dm
@@ -1348,8 +1348,8 @@
return
var/turf/T = get_turf(src)
user << "You plant the kudzu. You monster."
- message_admins("Kudzu planted by [key_name(user, user.client)](?) at ([T.x],[T.y],[T.z] - (JMP))",0,1)
- investigate_log("was planted by [user.ckey]([user]) at ([T.x],[T.y],[T.z])","kudzu")
+ message_admins("Kudzu planted by [key_name_admin(user)](?) (FLW) at ([T.x],[T.y],[T.z] - (JMP))",0,1)
+ investigate_log("was planted by [key_name(user)] at ([T.x],[T.y],[T.z])","kudzu")
new /obj/effect/spacevine_controller(user.loc, mutations, potency, production)
qdel(src)
diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm
index b22c6d40087..298ebdcf61c 100644
--- a/code/modules/library/lib_items.dm
+++ b/code/modules/library/lib_items.dm
@@ -63,7 +63,8 @@
if(2)
if(is_type_in_list(I, allowed_books))
- user.drop_item()
+ if(!user.drop_item())
+ return
I.loc = src
update_icon()
else if(istype(I, /obj/item/weapon/storage/bag/books))
diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm
index c9d885d8f29..f5dc638ee49 100644
--- a/code/modules/library/lib_machines.dm
+++ b/code/modules/library/lib_machines.dm
@@ -447,7 +447,8 @@ var/global/list/datum/cachedbook/cachedbooks // List of our cached book datums
/obj/machinery/libraryscanner/attackby(var/obj/O as obj, var/mob/user as mob, params)
if(istype(O, /obj/item/weapon/book))
- user.drop_item()
+ if(!user.drop_item())
+ return
O.loc = src
/obj/machinery/libraryscanner/attack_hand(var/mob/user as mob)
@@ -505,7 +506,8 @@ var/global/list/datum/cachedbook/cachedbooks // List of our cached book datums
if(busy)
user << "The book binder is busy. Please wait for completion of previous operation."
return
- user.drop_item()
+ if(!user.drop_item())
+ return
O.loc = src
user.visible_message("[user] loads some paper into [src].", "You load some paper into [src].")
src.visible_message("[src] begins to hum as it warms up its printing drums.")
diff --git a/code/modules/mining/equipment_locker.dm b/code/modules/mining/equipment_locker.dm
index 1dd002229be..265238f483c 100644
--- a/code/modules/mining/equipment_locker.dm
+++ b/code/modules/mining/equipment_locker.dm
@@ -89,7 +89,8 @@
if(istype(W,/obj/item/weapon/card/id))
var/obj/item/weapon/card/id/I = usr.get_active_hand()
if(istype(I) && !istype(inserted_id))
- usr.drop_item()
+ if(!user.drop_item())
+ return
I.loc = src
inserted_id = I
interact(user)
@@ -184,7 +185,8 @@
else if(href_list["choice"] == "insert")
var/obj/item/weapon/card/id/I = usr.get_active_hand()
if(istype(I))
- usr.drop_item()
+ if(!usr.drop_item())
+ return
I.loc = src
inserted_id = I
else usr << "No valid ID."
@@ -333,7 +335,8 @@
else if(href_list["choice"] == "insert")
var/obj/item/weapon/card/id/I = usr.get_active_hand()
if(istype(I))
- usr.drop_item()
+ if(!usr.drop_item())
+ return
I.loc = src
inserted_id = I
else usr << "No valid ID."
@@ -356,7 +359,8 @@
if(istype(I,/obj/item/weapon/card/id))
var/obj/item/weapon/card/id/C = usr.get_active_hand()
if(istype(C) && !istype(inserted_id))
- usr.drop_item()
+ if(!usr.drop_item())
+ return
C.loc = src
inserted_id = C
interact(user)
diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm
index e9dc6f7d14f..366ade4a6de 100644
--- a/code/modules/mining/laborcamp/laborstacker.dm
+++ b/code/modules/mining/laborcamp/laborstacker.dm
@@ -86,7 +86,8 @@
else if(href_list["choice"] == "insert")
var/obj/item/weapon/card/id/prisoner/I = usr.get_active_hand()
if(istype(I))
- usr.drop_item()
+ if(!usr.drop_item())
+ return
I.loc = src
inserted_id = I
else usr << "Invalid ID."
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index ddfdd96ad9a..00bed34c8fd 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -256,19 +256,16 @@ var/global/list/rockTurfEdgeCache
var/turf/bombturf = get_turf(src)
var/area/A = get_area(bombturf)
- if(user)
- activated_ckey = "[user.ckey]"
- activated_name = "[user.name]"
var/notify_admins = 0
if(z != 5)
notify_admins = 1
if(!triggered_by_explosion)
- message_admins("[src.activated_ckey]/([src.activated_name])? has triggered a gibtonite deposit reaction at [A.name] (JMP).")
+ message_admins("[key_name_admin(user)]? (FLW) has triggered a gibtonite deposit reaction at [A.name] (JMP).")
else
message_admins("An explosion has triggered a gibtonite deposit reaction at [A.name] (JMP).")
if(!triggered_by_explosion)
- log_game("[src.activated_ckey] ([src.activated_name]) has triggered a gibtonite deposit reaction at [A.name] ([A.x], [A.y], [A.z]).")
+ log_game("[key_name(user)] has triggered a gibtonite deposit reaction at [A.name] ([A.x], [A.y], [A.z]).")
else
log_game("An explosion has triggered a gibtonite deposit reaction at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])")
diff --git a/code/modules/mining/money_bag.dm b/code/modules/mining/money_bag.dm
index 4f0e74aff4c..e9befa30d43 100644
--- a/code/modules/mining/money_bag.dm
+++ b/code/modules/mining/money_bag.dm
@@ -60,8 +60,9 @@
..()
if (istype(W, /obj/item/weapon/coin))
var/obj/item/weapon/coin/C = W
+ if(!user.drop_item())
+ return
user << "You add the [C.name] into the bag."
- usr.drop_item()
contents += C
if (istype(W, /obj/item/weapon/moneybag))
var/obj/item/weapon/moneybag/C = W
diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm
index bf394e7ac21..baddbc27a53 100644
--- a/code/modules/mining/ores_coins.dm
+++ b/code/modules/mining/ores_coins.dm
@@ -177,13 +177,13 @@
if(triggered_by == 1)
message_admins("An explosion has triggered a [name] to detonate at [A.name] (JMP).")
else if(triggered_by == 2)
- message_admins("A signal has triggered a [name] to detonate at [A.name] (JMP). Igniter attacher: [attacher]")
+ message_admins("A signal has triggered a [name] to detonate at [A.name] (JMP). Igniter attacher: [key_name_admin(attacher)]? (FLW)")
else
- message_admins("[key_name(user)]? has triggered a [name] to detonate at [A.name] (JMP).")
+ message_admins("[key_name_admin(user)]? (FLW) has triggered a [name] to detonate at [A.name] (JMP).")
if(triggered_by == 1)
log_game("An explosion has primed a [name] for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])")
else if(triggered_by == 2)
- log_game("A signal has primed a [name] for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z]). Igniter attacher: [attacher].")
+ log_game("A signal has primed a [name] for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z]). Igniter attacher: [key_name(attacher)].")
else
user.visible_message("[user] strikes \the [src], causing a chain reaction!", "You strike \the [src], causing a chain reaction.")
log_game("[key_name(user)] has primed a [name] for detonation at [A.name]([bombturf.x],[bombturf.y],[bombturf.z])")
diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm
index 211cadcdf97..edb420703b4 100644
--- a/code/modules/mining/satchel_ore_boxdm.dm
+++ b/code/modules/mining/satchel_ore_boxdm.dm
@@ -11,7 +11,8 @@
/obj/structure/ore_box/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
if (istype(W, /obj/item/weapon/ore))
- user.drop_item()
+ if(!user.drop_item())
+ return
W.loc = src
if (istype(W, /obj/item/weapon/storage))
var/obj/item/weapon/storage/S = W
diff --git a/code/modules/mob/living/carbon/brain/MMI.dm b/code/modules/mob/living/carbon/brain/MMI.dm
index 95838e1b90d..753d2bd2d6c 100644
--- a/code/modules/mob/living/carbon/brain/MMI.dm
+++ b/code/modules/mob/living/carbon/brain/MMI.dm
@@ -41,6 +41,8 @@
user << "You aren't sure where this brain came from, but you're pretty sure it's a useless brain!"
return
+ if(!user.unEquip(O))
+ return
var/mob/living/carbon/brain/B = newbrain.brainmob
if(!B.key)
var/mob/dead/observer/ghost = B.get_ghost()
@@ -58,7 +60,6 @@
dead_mob_list -= brainmob //Update dem lists
living_mob_list += brainmob
- user.drop_item()
newbrain.loc = src //P-put your brain in it
brain = newbrain
diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm
index efdceeb7529..37a596ab08a 100644
--- a/code/modules/mob/living/carbon/brain/posibrain.dm
+++ b/code/modules/mob/living/carbon/brain/posibrain.dm
@@ -78,17 +78,13 @@ var/global/posibrain_notif_cooldown = 0
return
/obj/item/device/mmi/posibrain/proc/transfer_personality(var/mob/candidate)
- if(brainmob && brainmob.key) //Prevents hostile takeover if two ghosts get the prompt for the same brain.
+ if(brainmob && brainmob.key) //Prevents hostile takeover if two ghosts get the prompt or link for the same brain.
candidate << "This brain has already been taken! Please try your possesion again later!"
return
notified = 0
- brainmob.mind = candidate.mind
brainmob.ckey = candidate.ckey
name = "positronic brain ([brainmob.name])"
- brainmob.mind.remove_all_antag()
- brainmob.mind.wipe_memory()
-
brainmob << "ALL PAST LIVES ARE FORGOTTEN."
brainmob << "You are a positronic brain, brought into existence on [station_name()]."
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index f98a2f72ef9..73f8aedc7bc 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -251,7 +251,7 @@
if(istype(item, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = item
- item = G.throw() //throw the person instead of the grab
+ item = G.get_mob_if_throwable() //throw the person instead of the grab
qdel(G) //We delete the grab, as it needs to stay around until it's returned.
if(ismob(item))
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
@@ -402,7 +402,7 @@ var/const/GALOSHES_DONT_HELP = 8
return
/mob/living/carbon/resist_buckle()
- if(handcuffed)
+ if(restrained())
changeNext_move(CLICK_CD_BREAKOUT)
last_special = world.time + CLICK_CD_BREAKOUT
visible_message("[src] attempts to unbuckle themself!", \
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 357bc610e14..c99b39e3995 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -79,7 +79,7 @@
if(2)
say(pick("FUS RO DAH","fucking 4rries!", "stat me", ">my face", "roll it easy!", "waaaaaagh!!!", "red wonz go fasta", "FOR TEH EMPRAH", "lol2cat", "dem dwarfs man, dem dwarfs", "SPESS MAHREENS", "hwee did eet fhor khayosss", "lifelike texture ;_;", "luv can bloooom", "PACKETS!!!", "port ba[pick("y", "i", "e")] med!!!!", "REVIRT GON CHEM!!!!!!!!", "youed call her a toeugh bithc", "closd for merbegging", "pray can u [pick("spawn", "MAke me", "creat")] [pick("zenomorfs", "ayleins", "treaitors", "sheadow linkgs", "ubdoocters")]???"))
if(3)
- say(pick("GEY AWAY FROM ME U GREIFING PRICK!!!!", "ur a fuckeing autist!", ";HELP SHITECIRTY MURDERIN MEE!!!", "hwat dose tha [pick("g", "squid", "r")] mean?????", "CAL; TEH SHUTTLE!!!!!", "wearnig siNGUARLTY IS .... FIne xDDDDDDDDD", "AI laW 22 Open door", "this SI mY stATIon......", "who the HELL do u thenk u r?!!!!", "geT THE FUCK OUTTTT", "H U G B O X", ";;CRAGING THIS STTAYTION WITH NIO SURVIVROS", "[pick("bager", "syebl")] is down11!!!!!!!!!!!!!!!!!"))
+ say(pick("GEY AWAY FROM ME U GREIFING PRICK!!!!", "ur a fuckeing autist!", ";HELP SHITECIRTY MURDERIN MEE!!!", "hwat dose tha [pick("g", "squid", "r")] mean?????", "CAL; TEH SHUTTLE!!!!!", "wearnig siNGUARLTY IS .... FIne xDDDDDDDDD", "AI laW 22 Open door", "this SI mY stATIon......", "who the HELL do u thenk u r?!!!!", "geT THE FUCK OUTTTT", "H U G B O X", ";;CRAGING THIS STTAYTION WITH NIO SURVIVROS", "[pick("bager", "syebl")] is down11!!!!!!!!!!!!!!!!!", "PSHOOOM"))
if(4)
emote("drool")
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index a59914466bf..9ac7837148a 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -375,10 +375,6 @@
else
hallucination -= 2
- else
- for(var/atom/a in hallucinations)
- qdel(a)
-
//this handles hud updates. Calls update_vision() and handle_hud_icons()
/mob/living/carbon/handle_regular_hud_updates()
if(!client) return 0
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index d23dcbabcc0..bc689b62098 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -673,10 +673,13 @@ Sorry Giacom. Please don't be mad :(
/mob/living/proc/float(on)
if(throwing)
return
- if(on && !floating)
+ var/fixed = 0
+ if(anchored || (buckled && buckled.anchored))
+ fixed = 1
+ if(on && !floating && !fixed)
animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1)
floating = 1
- else if(!on && floating)
+ else if(((!on || fixed) && floating))
var/final_pixel_y = get_standard_pixel_y_offset(lying)
animate(src, pixel_y = final_pixel_y, time = 10)
floating = 0
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index 59436c1028b..6509db4ac67 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -17,8 +17,6 @@
var/hallucination = 0 //Directly affects how long a mob will hallucinate for
- var/list/atom/hallucinations = list() //A list of hallucinated people that try to attack the mob. See /obj/effect/fake_attacker in hallucinations.dm
-
var/last_special = 0 //Used by the resist verb, likely used to prevent players from bypassing next_move by logging in/out.
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index 65479146645..a632b52f31d 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -30,6 +30,7 @@ var/list/ai_list = list()
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
var/viewalerts = 0
var/icon/holo_icon//Default is assigned when AI is created.
+ var/obj/mecha/controlled_mech //For controlled_mech a mech, to determine whether to relaymove or use the AI eye.
var/radio_enabled = 1 //Determins if a carded AI can speak with its built in radio or not.
radiomod = ";" //AIs will, by default, state their laws on the internal radio.
var/obj/item/device/pda/ai/aiPDA = null
@@ -42,6 +43,7 @@ var/list/ai_list = list()
var/processing_time = 100
var/list/datum/AI_Module/current_modules = list()
var/fire_res_on_core = 0
+ var/can_dominate_mechs = 0
var/control_disabled = 0 // Set to 1 to stop AI from interacting via Click()
var/malfhacking = 0 // More or less a copy of the above var, so that malf AIs can hack and still get new cyborgs -- NeoFite
@@ -449,6 +451,14 @@ var/list/ai_list = list()
botcall()
return
+ if (href_list["ai_take_control"]) //Mech domination
+ var/obj/mecha/M = locate(href_list["ai_take_control"])
+ if(controlled_mech)
+ src << "You are already loaded into an onboard computer!"
+ return
+ if(M)
+ M.transfer_ai(AI_MECH_HACK,src, usr) //Called om the mech itself.
+
/mob/living/silicon/ai/bullet_act(var/obj/item/projectile/Proj)
..(Proj)
updatehealth()
@@ -792,3 +802,20 @@ var/list/ai_list = list()
/mob/living/silicon/ai/attack_slime(mob/living/simple_animal/slime/user)
return
+/mob/living/silicon/ai/transfer_ai(var/interaction, var/mob/user, var/mob/living/silicon/ai/AI, var/obj/item/device/aicard/card)
+ if(!..())
+ return
+ if(interaction == AI_TRANS_TO_CARD)//The only possible interaction. Upload AI mob to a card.
+ if(!mind)
+ user << "No intelligence patterns detected." //No more magical carding of empty cores, AI RETURN TO BODY!!!11
+ return
+ if (mind.special_role == "malfunction") //AI MALF!!
+ user << "ERROR: Remote transfer interface disabled."//Do ho ho ho~
+ return
+ new /obj/structure/AIcore/deactivated(loc)//Spawns a deactivated terminal at AI location.
+ aiRestorePowerRoutine = 0//So the AI initially has power.
+ control_disabled = 1//Can't control things remotely if you're stuck in a card!
+ radio_enabled = 0 //No talking on the built-in radio for you either!
+ loc = card//Throw AI into the card.
+ src << "You have been downloaded to a mobile storage device. Remote device connection severed."
+ user << "Transfer successful: [name] ([rand(1000,9999)].exe) removed from host terminal and stored within local memory."
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index 8566b31eff0..cf6548b0e05 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -47,7 +47,7 @@
loc = T.loc
if (istype(loc, /area))
//stage = 4
- if (!loc.master.power_equip && !istype(src.loc,/obj/item))
+ if (!loc.master.power_equip && !is_type_in_list(src.loc,list(/obj/item, /obj/mecha)))
//stage = 5
blindness = 1
@@ -90,7 +90,7 @@
src.see_in_dark = 0
src.see_invisible = SEE_INVISIBLE_LIVING
- if (((!loc.master.power_equip) || istype(T, /turf/space)) && !istype(src.loc,/obj/item))
+ if (((!loc.master.power_equip) || istype(T, /turf/space)) && !is_type_in_list(src.loc,list(/obj/item, /obj/mecha)))
if (src:aiRestorePowerRoutine==0)
src:aiRestorePowerRoutine = 1
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index a35b0988bca..e37ac76c526 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -450,7 +450,8 @@
else if(cell)
user << "There is a power cell already installed!"
else
- user.drop_item()
+ if(!user.drop_item())
+ return
W.loc = src
cell = W
user << "You insert the power cell."
@@ -525,27 +526,29 @@
else if(istype(W, /obj/item/borg/upgrade/))
var/obj/item/borg/upgrade/U = W
if(!opened)
- usr << "You must access the borgs internals!"
+ user << "You must access the borgs internals!"
else if(!src.module && U.require_module)
- usr << "The borg must choose a module before it can be upgraded!"
+ user << "The borg must choose a module before it can be upgraded!"
else if(U.locked)
- usr << "The upgrade is locked and cannot be used yet!"
+ user << "The upgrade is locked and cannot be used yet!"
else
+ if(!user.drop_item())
+ return
if(U.action(src))
- usr << "You apply the upgrade to [src]."
- usr.drop_item()
+ user << "You apply the upgrade to [src]."
U.loc = src
else
- usr << "Upgrade error."
+ user << "Upgrade error."
else if(istype(W, /obj/item/device/toner))
if(toner >= tonermax)
- usr << "The toner level of [src] is at it's highest level possible!"
+ user << "The toner level of [src] is at it's highest level possible!"
else
+ if(!user.drop_item())
+ return
toner = 40
- usr.drop_item()
qdel(W)
- usr << "You fill the toner level of [src] to its max capacity."
+ user << "You fill the toner level of [src] to its max capacity."
else
if(W.force && W.damtype != STAMINA) //only sparks if real damage is dealt.
diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm
index e14a9902ee9..c81bb72ee31 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm
@@ -8,7 +8,7 @@
desc = "A malevolent spirit."
icon = 'icons/mob/mob.dmi'
icon_state = "revenant_idle"
- incorporeal_move = 1
+ incorporeal_move = 3
invisibility = INVISIBILITY_OBSERVER
health = 25
maxHealth = 25
@@ -31,7 +31,7 @@
var/essence_regen_cap = 25 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount.
var/essence_regen = 1 //If the revenant regenerates essence or not; 1 for yes, 0 for no
var/essence_min = 1 //The minimum amount of essence a revenant can have; by default, it never drops below one
- var/strikes = 3 //How many times a revenant can die before dying for good
+ var/strikes = 0 //How many times a revenant can die before dying for good
var/revealed = 0 //If the revenant can take damage from normal sources.
var/inhibited = 0 //If the revenant's abilities are blocked by a chaplain's power.
@@ -43,24 +43,13 @@
strikes--
src << "Your essence has dropped below critical levels. You barely manage to save yourself - [strikes ? "you can't keep this up!" : "next time, it's death."]"
else if(strikes <= 0)
- src << "NO! No... it's too late, you can feel yourself fading..."
- src.notransform = 1
- src.revealed = 1
- src.invisibility = 0
- playsound(src, 'sound/effects/screech.ogg', 100, 1)
- src.visible_message("The revenant lets out a waning screech as violet mist swirls around its dissolving body!")
- src.icon_state = "revenant_draining"
- sleep(30)
- src.death()
+ death()
maxHealth = essence * 2
if(!revealed)
health = maxHealth //Heals to full when not revealed
if(essence_regen && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate
essence++
-/mob/living/simple_animal/revenant/Process_Spacemove(var/movement_dir = 0)
- return 1 //Mainly to prevent the no-grav effect
-
/mob/living/simple_animal/revenant/ex_act(severity, target)
return 1 //Immune to the effects of explosions.
@@ -99,16 +88,26 @@
..()
spawn(5)
if(src.mind)
+ src.mind.remove_all_antag()
+ src.mind.wipe_memory()
src << 'sound/effects/ghost.ogg'
- src.store_memory("I am a revenant. My spectral form has been empowered. My only goal is to gather essence from the humans of [world.name].")
src << "
"
- src << "You are a revenant!"
+ 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 very limited interaction with both worlds."
+ 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 << "Your goal is to gather essence from humans. Your essence passively regenerates up to 25E over time. You can use the Harvest abilities to gather more from corpses."
- src << "Be sure to read the wiki page at https://tgstation13.org/wiki/Revenant !"
- src << "
"
+ 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 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 https://tgstation13.org/wiki/Revenant to learn more."
+ var/datum/objective/revenant/objective = new
+ objective.owner = src
+ src.mind.objectives += objective
+ src << "Objective #1: [objective.explanation_text]"
+ var/datum/objective/revenantFluff/objective2 = new
+ objective2.owner = src
+ src.mind.objectives += objective2
+ src << "Objective #2: [objective2.explanation_text]"
+ ticker.mode.traitors |= src.mind //Necessary for announcing
if(!src.giveSpells())
message_admins("Revenant was created but has no mind. Trying again in five seconds.")
spawn(50)
@@ -121,52 +120,199 @@
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/targeted/revenant_life_tap
- src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_seed_drain
- src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_mindspike
+ src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenantDefile
return 1
return 0
/mob/living/simple_animal/revenant/death()
- if(!src.strikes)
+ if(strikes)
return 0 //Impossible to die with strikes still active
..(1)
- src.invisibility = 0
- visible_message("[src] pulses with an eldritch purple light as its form unwinds into smoke.")
+ src << "NO! No... it's too late, you can feel yourself fading..."
+ notransform = 1
+ revealed = 1
+ invisibility = 0
+ playsound(src, 'sound/effects/screech.ogg', 100, 1)
+ visible_message("[src] lets out a waning screech as violet mist swirls around its dissolving body!")
+ icon_state = "revenant_draining"
+ for(var/i = alpha, i > 0, i -= 10)
+ sleep(0.1)
+ alpha = i
+ visible_message("[src]'s body breaks apart into blue dust.")
+ new /obj/item/weapon/ectoplasm/revenant(get_turf(src))
ghostize()
qdel(src)
return
+
/mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params)
..()
if(istype(W, /obj/item/weapon/nullrod))
- src.visible_message("The revenant screeches and flails!", \
- "The null rod invokes agony in you! You feel your essence draining away!")
- src.essence -= 25 //hella effective
- src.inhibited = 1
+ visible_message("[src] violently flinches!", \
+ "The null rod invokes agony in you! You feel your essence draining away!")
+ essence -= 25 //hella effective
+ inhibited = 1
spawn(30)
- src.inhibited = 0
+ inhibited = 0
-/obj/effect/proc_holder/spell/proc/essence_check(var/essence_cost, var/silent = 0)
- var/mob/living/simple_animal/revenant/W = usr
- if(W.essence < essence_cost)
- if(!silent)
- W << "You need [essence_cost]E to use [name] but you only have [W.essence]E available. Harvest some more things."
+/mob/living/simple_animal/revenant/proc/castcheck(var/essence_cost)
+ var/mob/living/simple_animal/revenant/user = usr
+ if(!istype(user) || !user)
+ return
+ var/turf/T = get_turf(usr)
+ if(istype(T, /turf/simulated/wall))
+ user << "You cannot use abilities from inside of a wall."
+ return 0
+ if(!user.change_essence_amount(essence_cost, 1))
+ user << "You lack the essence to use that ability."
+ return 0
+ if(user.inhibited)
+ user << "Your powers have been suppressed by holy energies!"
return 0
- W.essence -= essence_cost
return 1
-/mob/living/simple_animal/revenant/proc/change_essence_amount(var/essence_amt, var/silent = 0, var/source = null, var/mob/living/simple_animal/revenant/user = usr)
- if(!essence_amt)
+/mob/living/simple_animal/revenant/proc/change_essence_amount(var/essence_amt, var/silent = 0, var/source = null)
+ var/mob/living/simple_animal/revenant/user = usr
+ if(!istype(usr) || !usr)
+ return
+ if(user.essence + essence_amt <= 0)
return
user.essence += essence_amt
+ user.essence = Clamp(user.essence, 0, INFINITY)
if(!silent)
- if(essence_amt >= 0)
- user << "Gained [essence_amt]E from [source]."
+ if(essence_amt > 0)
+ user << "Gained [essence_amt]E from [source]."
else
- user << "Lost [essence_amt]E."
+ user << "Lost [essence_amt]E from [source]."
+ return 1
+
+
+
+/mob/living/simple_animal/revenant/proc/reveal(var/time, var/stun)
+ var/mob/living/simple_animal/revenant/R = usr
+ if(!istype(usr) || !usr)
+ return
+ R.revealed = 1
+ R.invisibility = 0
+ if(stun)
+ R.notransform = 1
+ R << "You have been revealed [stun ? "and cannot move" : ""]."
+ spawn(time)
+ R.revealed = 0
+ R.invisibility = INVISIBILITY_OBSERVER
+ if(stun)
+ R.notransform = 0
+ R << "You are once more concealed [stun ? "and can move again" : ""]."
+
+/datum/objective/revenant
+ dangerrating = 10
+ var/targetAmount = 100
+
+/datum/objective/revenant/New()
+ targetAmount = rand(100,200)
+ explanation_text = "Absorb [targetAmount] points of essence."
+ ..()
+
+/datum/objective/revenant/check_completion()
+ if(!istype(owner.current, /mob/living/simple_animal/revenant) || !owner.current)
+ return 0
+ var/mob/living/simple_animal/revenant/R = owner.current
+ if(!R || R.stat == DEAD)
+ return 0
+ var/essenceAccumulated = R.essence
+ if(essenceAccumulated < targetAmount)
+ return 0
+ return 1
+
+/datum/objective/revenantFluff
+ dangerrating = 0
+
+/datum/objective/revenantFluff/New()
+ var/list/explanationTexts = list("Attempt to make your presence unknown to the crew.", \
+ "Collaborate with existing antagonists aboard the station to gain essence.", \
+ "Remain nonlethal and only absorb bodies that have already died.", \
+ "Use your environments to eliminate isolated people.", \
+ "If there is a chaplain aboard the station, ensure they are killed.", \
+ "Hinder the crew without killing them.")
+ explanation_text = pick(explanationTexts)
+ ..()
+
+/datum/objective/revenantFluff/check_completion()
+ return 1
+
+
+/obj/item/weapon/ectoplasm/revenant
+ name = "glimmering residue"
+ desc = "A pile of fine blue dust. Small tendrils of violet mist swirl around it."
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "revenantEctoplasm"
+ w_class = 2
+ var/reforming = 0
+ var/reformed = 0
+
+/obj/item/weapon/ectoplasm/revenant/New()
+ ..()
+ reforming = 1
+ spawn(1800) //3 minutes
+ if(src && reforming)
+ return reform()
+ if(src && !reforming)
+ 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)
+ return ..()
+ user.visible_message("[user] scatters [src] in all directions.", \
+ "You scatter [src] across the area. The particles slowly fade away.")
+ user.drop_item()
+ qdel(src)
+
+/obj/item/weapon/ectoplasm/revenant/throw_impact(atom/hit_atom)
+ ..()
+ visible_message("[src] breaks into particles upon impact, which fade away to nothingness.")
+ qdel(src)
+
+/obj/item/weapon/ectoplasm/revenant/examine(mob/user)
+ ..()
+ if(reforming)
+ user << "It is shifting and distorted. It would be wise to destroy this."
+ else if(!reforming)
+ user << "It seems inert."
+
+/obj/item/weapon/ectoplasm/revenant/proc/reform()
+ if(!reforming || !src)
+ return
+ message_admins("Revenant ectoplasm was left undestroyed for 3 minutes and has reformed 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(!key_of_revenant)
+ message_admins("No ckey was found for the new revenant. Oh well!")
+ 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.")
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 f0532fb5c7a..01f527f2e07 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
@@ -11,8 +11,7 @@
var/list/drained_mobs = list() //Cannot harvest the same mob twice
/obj/effect/proc_holder/spell/targeted/revenant_harvest/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(user.inhibited)
- user << "Something is blocking the use of [src]!"
+ if(!user.castcheck(0))
charge_counter = charge_max
return
for(var/mob/living/carbon/human/target in targets)
@@ -23,7 +22,7 @@
if(target in drained_mobs)
user << "[target]'s soul is dead and empty."
return
- if(!target.stat)
+ if(target.stat != DEAD)
user << "This being's soul is too strong to harvest."
if(prob(10))
target << "You feel as if you are being watched."
@@ -35,12 +34,6 @@
if(target.ckey)
user << "Their soul burns with intelligence."
essence_drained += 3
- if(target.stat == UNCONSCIOUS)
- user << "They still cling to life, but are not powerful enough to resist. A large amount of essence lies unguarded."
- essence_drained += 5
- else if(target.stat == DEAD)
- user << "They have passed on."
- essence_drained += 1
sleep(20)
switch(essence_drained)
if(1 to 2)
@@ -80,7 +73,7 @@
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob for 5E.
/obj/effect/proc_holder/spell/targeted/revenant_transmit
- name = "Unlock: Transmit (5E)"
+ name = "Transmit (5E)"
desc = "Telepathically transmits a message to the target."
panel = "Revenant Abilities (Locked)"
charge_max = 50
@@ -90,59 +83,46 @@
var/locked = 1
/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(user.inhibited)
- user << "Something is blocking the use of [src]!"
+ if(!user.castcheck(-5))
charge_counter = charge_max
return
- if(locked && essence_check(5, 1))
+ if(locked)
usr << "You have unlocked Transmit!"
- name = "Transmit (5E)"
locked = 0
charge_counter = charge_max
panel = "Revenant Abilities"
range = 7
include_user = 0
return
- if(locked)
- charge_counter = charge_max
- return
- if(!essence_check(5))
- charge_counter = charge_max
- return
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
usr << "You transmit to [M]: [msg]"
- M << "Suddenly a strange voice resonates in your head... [msg]"
+ M << "A strange voice resonates in your head... [msg]"
//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 = "Unlock: Overload Light (25E)"
+ name = "Overload Light (25E)"
desc = "Directs a large amount of essence into an electrical light, causing an impressive light show."
panel = "Revenant Abilities (Locked)"
charge_max = 300
clothes_req = 0
- range = -1
+ range = 1
var/locked = 1
/obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(user.inhibited)
- user << "Something is blocking the use of [src]!"
- charge_counter = charge_max
- return
- if(locked && essence_check(25, 1))
- user << "You have unlocked Overload Light!"
- name = "Overload Light (25E)"
- panel = "Revenant Abilities"
- locked = 0
- range = 5
+ if(!user.castcheck(-25))
charge_counter = charge_max
return
if(locked)
- charge_counter = charge_max
- return
- if(!essence_check(25))
+ user << "You have unlocked Overload Light!"
+ panel = "Revenant Abilities"
+ locked = 0
+ range = 5
charge_counter = charge_max
return
for(var/turf/T in targets)
@@ -159,180 +139,50 @@
M.Beam(L,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
M.electrocute_act(25, "[L.name]")
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
- user.revealed = 1
- user.invisibility = 0
- spawn(30)
- user.revealed = 0
- user.invisibility = INVISIBILITY_OBSERVER
+ user.reveal(50, 1)
-//Life Tap: Drains one 'strike' to gain 50E
-/obj/effect/proc_holder/spell/targeted/revenant_life_tap
- name = "Unlock: Life Tap (25E)"
- desc = "Draws from your own life pool to gain more essence. Can only be cast three times."
+//Defile: Corrupts nearby stuff, unblesses floor tiles.
+/obj/effect/proc_holder/spell/aoe_turf/revenantDefile
+ name = "Defile (30E)"
+ desc = "Twists and corrupts certain nearby objects. Also dispels holy auras on floors, but not salt lines."
panel = "Revenant Abilities (Locked)"
- charge_max = 600
+ charge_max = 300
clothes_req = 0
- range = -1
- include_user = 1
+ range = 1
var/locked = 1
-/obj/effect/proc_holder/spell/targeted/revenant_life_tap/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(user.inhibited)
- user << "Something is blocking the use of [src]!"
- charge_counter = charge_max
- return
- if(locked && essence_check(25, 1))
- user << "You have unlocked Life Tap!"
- name = "Life Tap (0E)"
- panel = "Revenant Abilities"
- locked = 0
+/obj/effect/proc_holder/spell/aoe_turf/revenantDefile/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
+ if(!user.castcheck(-30))
charge_counter = charge_max
return
if(locked)
- charge_counter = charge_max
- return
- for(var/mob/living/simple_animal/revenant/target in targets)
- if(!target.strikes)
- target << "Your life force has grown too weak to life tap again."
- target.strikes--
- target << "You convert your own life into energy.[target.strikes ? "" : " This is the last time you can do this."]"
- target.change_essence_amount(50, 0, "your life pool")
-
-
-//Seed of Draining: Plants a 'seed' in the target that will slowly siphon essence silently from them.
-/obj/effect/proc_holder/spell/targeted/revenant_seed_drain
- name = "Unlock: Seed of Draining (20E)"
- desc = "Corrupts a target with dark energies. Their essence will slowly drain for some time."
- panel = "Revenant Abilities (Locked)"
- charge_max = 1200
- clothes_req = 0
- range = -1
- include_user = 1
- var/locked = 1
- var/planted = 0
-
-/obj/effect/proc_holder/spell/targeted/revenant_seed_drain/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(user.inhibited)
- user << "Something is blocking the use of [src]!"
- charge_counter = charge_max
- return
- if(locked && essence_check(20, 1))
- user << "You have unlocked Seed of Draining!"
- charge_counter = charge_max
- name = "Seed of Draining (20E)"
- locked = 0
+ user << "You have unlocked Defile!"
panel = "Revenant Abilities"
- range = 1
- include_user = 0
- return
- if(locked)
- charge_counter = charge_max
- return
- if(!essence_check(20))
- charge_counter = charge_max
- return
- if(planted)
- user << "You are already passively draining essence."
- charge_counter = charge_max
- return
- for(var/mob/living/carbon/human/target in targets)
- if(target.stat == DEAD)
- user << "[target] is dead and will not yield essence."
- charge_counter = charge_max
- user << "You plant a draining seed on [target]."
- planted = 1
- for(var/i = 0, i < 120, i++)
- sleep(10)
- var/mob/living/carbon/human/M = target
- user.essence += rand(0.3, 0.5) //Not a huge amount of essence; at the least it's 36 and at the most it's 60
- M.adjustStaminaLoss(1)
- if(prob(3))
- target << "You feel sapped." //Letting the target know that they're not bugged and losing stamina 4nr
- planted = 0
- user << "The energies siphoning [target] have fallen dormant. You will need to plant a new seed."
-
-
-//Mind Spike: The typical straight damage ability. Does a decent amount of brute damage and small brain damage.
-/obj/effect/proc_holder/spell/targeted/revenant_mindspike
- name = "Unlock: Mind Spike (5E)"
- desc = "Drives a spike of dark energy into the target's mind. Cheap but effective and doesn't take long to cool down."
- panel = "Revenant Abilities (Locked)"
- charge_max = 40
- clothes_req = 0
- range = -1
- include_user = 1
- var/locked = 1
-
-/obj/effect/proc_holder/spell/targeted/revenant_mindspike/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(user.inhibited)
- user << "Something is blocking the use of [src]!"
- charge_counter = charge_max
- return
- if(locked && essence_check(5, 1))
- user << "You have unlocked Mind Spike!"
- charge_counter = charge_max
- name = "Mind Spike (5E)"
locked = 0
- panel = "Revenant Abilities"
- range = 3
- include_user = 0
- return
- if(locked)
+ range = 4
charge_counter = charge_max
return
- if(!essence_check(5))
- charge_counter = charge_max
- return
- for(var/mob/living/carbon/human/M in targets)
- user << "You drive a spike of energy into [M]'s mind!"
- M << "You feel a spike of pain in your head!"
- M.apply_damage(12, BRUTE, "head")
- M.adjustBrainLoss(3)
- //M << 'sound/effects/mind_blast.ogg'
- if(prob(20) && !M.stat)
- M.Weaken(2)
- M.visible_message("[M] clutches at their head!")
- user.revealed = 1
- user.invisibility = 0
- spawn(10)
- user.revealed = 0
- user.invisibility = INVISIBILITY_OBSERVER
-
-//Hypnotize: Makes the target fall asleep, make them vulnerable to draining.
-/obj/effect/proc_holder/spell/targeted/revenant_hypnotize
- name = "Unlock: Hypnotize (15E)"
- desc = "Causes a target to fall asleep."
- panel = "Revenant Abilities (Locked)"
- charge_max = 900
- clothes_req = 0
- range = -1
- include_user = 1
- var/locked = 1
-
-/obj/effect/proc_holder/spell/targeted/revenant_hypnotize/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(user.inhibited)
- user << "Something is blocking the use of [src]!"
- charge_counter = charge_max
- return
- if(locked && essence_check(15, 1))
- user << "You have unlocked Hypnotize!"
- charge_counter = charge_max
- name = "Hypnotize (15E)"
- locked = 0
- range = 3
- panel = "Revenant Abilities"
- include_user = 0
- return
- if(locked)
- charge_counter = charge_max
- return
- if(!essence_check(15))
- charge_counter = charge_max
- return
- for(var/mob/living/carbon/human/M in targets)
- user << "You gently influence [M]'s mind toward deep sleep."
- M << "Tired... so tired..."
- M.drowsyness += 7
- spawn(70)
- M.sleeping += 30
+ for(var/turf/T in targets)
+ spawn(0)
+ if(T.flags & NOJAUNT)
+ T.flags -= NOJAUNT
+ for(var/obj/machinery/bot/secbot/secbot in T.contents) //Not including ED-209
+ secbot.emagged = 2
+ secbot.Emag(null)
+ for(var/obj/machinery/bot/cleanbot/cleanbot in T.contents)
+ cleanbot.emagged = 2
+ cleanbot.Emag(null)
+ for(var/mob/living/carbon/human/human in T.contents)
+ human << "You suddenly feel tired."
+ human.adjustStaminaLoss(25)
+ for(var/mob/living/silicon/robot/robot in T.contents)
+ robot.visible_message("[robot] lets out an alarm!", \
+ "01001111 01010110 01000101 01010010 01001100 01001111 01000001 01000100") //Translates to "OVERLOAD"
+ robot << 'sound/misc/interference.ogg'
+ playsound(robot, 'sound/machines/warning-buzzer.ogg', 50, 1)
+ for(var/obj/structure/window/window in T.contents)
+ window.hit(rand(10,50))
+ for(var/obj/machinery/light/light in T.contents)
+ light.flicker() //spooky
+ user.reveal(30, 1)
diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm b/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm
index b851a1582b4..3d3e7910656 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm
@@ -1,3 +1,5 @@
+#define REVENANT_SPAWN_THRESHOLD 10
+
/datum/round_event_control/revenant
name = "Spawn Revenant"
typepath = /datum/round_event/revenant
@@ -6,13 +8,17 @@
earliest_start = 0 //Meant to mix things up early-game.
-
/datum/round_event/revenant
var/key_of_revenant
-
/datum/round_event/revenant/proc/get_revenant(var/end_if_fail = 0)
+ var/deadMobs = 0
+ for(var/mob/M in dead_mob_list)
+ deadMobs++
+ if(deadMobs < REVENANT_SPAWN_THRESHOLD)
+ message_admins("Random event attempted to spawn a revenant, but there were only [deadMobs]/[REVENANT_SPAWN_THRESHOLD] dead mobs.")
+ return
key_of_revenant = null
if(!key_of_revenant)
var/list/candidates = get_candidates(BE_REVENANT)
@@ -32,32 +38,38 @@
for(var/obj/effect/landmark/L in landmarks_list)
if(isturf(L.loc))
switch(L.name)
- if("carpspawn")
+ if("revenantspawn")
spawn_locs += L.loc
- if(!spawn_locs)
+ if(!spawn_locs) //If we can't find any revenant spawns, try the carp spawns
+ for(var/obj/effect/landmark/L in landmarks_list)
+ if(isturf(L.loc))
+ switch(L.name)
+ if("carpspawn")
+ spawn_locs += L.loc
+ if(!spawn_locs) //If we can't find either, just spawn the revenant at the player's location
+ spawn_locs += get_turf(player_mind.current)
+ if(!spawn_locs) //If we can't find THAT, then just retry
return find_revenant()
var/mob/living/simple_animal/revenant/revvie = new /mob/living/simple_animal/revenant/(pick(spawn_locs))
player_mind.transfer_to(revvie)
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 an event.")
- log_game("[key_of_revenant] was spawned as a Revenant by an event.")
+ message_admins("[key_of_revenant] has been made into a revenant by an event.")
+ log_game("[key_of_revenant] was spawned as a revenant by an event.")
return 1
-
/datum/round_event/revenant/start()
get_revenant()
-
/datum/round_event/revenant/proc/find_revenant()
- message_admins("Attempted to spawn a Revenant but there was no players available. Will try again momentarily, bear with me...")
+ message_admins("An event failed to spawn a revenant. Retrying momentarily...")
spawn(50)
if(get_revenant(1))
- message_admins("Hooray! Situation has been resolved, [key_of_revenant] has been spawned as a Revenant.")
- log_game("[key_of_revenant] was spawned as a Revenant by an event.")
+ message_admins("[key_of_revenant] has been spawned as a revenant.")
+ log_game("[key_of_revenant] was spawned as a revenant by an event.")
return 0
- message_admins("Unfortunately, no candidates were available for becoming a Revenant. Shutting down. :(")
+ message_admins("No candidates were available for becoming a revenant.")
return kill()
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index 233fcd4f485..45f84087221 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -47,7 +47,7 @@
..()
//Used by throw code to hand over the mob, instead of throwing the grab. The grab is then deleted by the throw code.
-/obj/item/weapon/grab/proc/throw()
+/obj/item/weapon/grab/proc/get_mob_if_throwable()
if(affecting)
if(affecting.buckled)
return null
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index f2e81516823..a0106cfcc02 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -103,8 +103,6 @@
if(mob.stat == DEAD)
mob.ghostize()
return 0
- if(isAI(mob))
- return AIMove(n,direct,mob)
if(moving)
return 0
if(isliving(mob))
@@ -121,6 +119,9 @@
if(mob.remote_control) //we're controlling something, our movement is relayed to it
return mob.remote_control.relaymove(mob, direct)
+ if(isAI(mob))
+ return AIMove(n,direct,mob)
+
if(!mob.canmove)
return 0
@@ -137,8 +138,12 @@
if(isturf(mob.loc))
+
+ var/turf/T = mob.loc
move_delay = world.time//set move delay
+ move_delay += T.slowdown
+
if(mob.restrained()) //Why being pulled while cuffed prevents you from moving
for(var/mob/M in range(mob, 1))
if(M.pulling == mob)
@@ -175,7 +180,6 @@
var/mob/M = L[1]
if(M)
if ((get_dist(mob, M) <= 1 || M.loc == mob.loc))
- var/turf/T = mob.loc
. = ..()
if (isturf(M.loc))
var/diag = get_dir(mob, M)
@@ -297,6 +301,16 @@
anim(mobloc,mob,'icons/mob/mob.dmi',,"shadow",,L.dir)
L.loc = get_step(L, direct)
L.dir = direct
+ if(3) //Incorporeal move, but blocked by holy-watered tiles
+ var/turf/simulated/floor/stepTurf = get_step(L, direct)
+ if(stepTurf.flags & NOJAUNT)
+ L << "Holy energies block your path."
+ L.notransform = 1
+ spawn(2)
+ L.notransform = 0
+ else
+ L.loc = get_step(L, direct)
+ L.dir = direct
return 1
@@ -330,8 +344,6 @@
continue
if(AM.density)
if(AM.anchored)
- if(istype(AM, /obj/item/projectile)) //"You grab the bullet and push off of it!" No
- continue
return 1
if(pulling == AM)
continue
diff --git a/code/modules/nano/nanoexternal.dm b/code/modules/nano/nanoexternal.dm
index d6d2833e1e3..265629ec4df 100644
--- a/code/modules/nano/nanoexternal.dm
+++ b/code/modules/nano/nanoexternal.dm
@@ -39,5 +39,8 @@
/atom/movable/proc/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
return
+/atom/movable/proc/get_ui_data(mob/user)
+ return list()
+
// Used by the Nano UI SubSystem (/datum/subsystem/nano) to track UIs opened by this mob
/mob/var/list/open_uis = list()
diff --git a/code/modules/nano/nanomanager.dm b/code/modules/nano/nanomanager.dm
index 09b8a4796be..5f47c8da5ca 100644
--- a/code/modules/nano/nanomanager.dm
+++ b/code/modules/nano/nanomanager.dm
@@ -1,3 +1,27 @@
+ /**
+ * Get an open /nanoui ui for the current user, or create a new one.
+ *
+ * @param user /mob The mob who opened/owns the ui
+ * @param src_object /obj|/mob The obj or mob which the ui belongs to
+ * @param ui_key string A string key used for the ui
+ * @param ui /datum/nanoui An existing instance of the ui (can be null)
+ * @param data list The data to be passed to the ui, if it exists
+ *
+ * @return /nanoui Returns the new or found ui
+ */
+/datum/subsystem/nano/proc/push_open_or_new_ui(var/mob/user, var/atom/movable/src_object, ui_key, var/datum/nanoui/ui, template, title, width, height, auto_update)
+ var/list/data = src_object.get_ui_data(user)
+ if (!data)
+ data = list()
+
+ ui = try_update_ui(user, src_object, ui_key, ui, data)
+
+ if (isnull(ui))
+ ui = new /datum/nanoui(user, src_object, ui_key, template, title, width, height)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(auto_update)
+
/**
* Get an open /nanoui ui for the current user, src_object and ui_key and try to update it with data
*
@@ -11,9 +35,8 @@
*/
/datum/subsystem/nano/proc/try_update_ui(var/mob/user, src_object, ui_key, var/datum/nanoui/ui, data)
if (isnull(ui)) // no ui has been passed, so we'll search for one
- {
ui = get_open_ui(user, src_object, ui_key)
- }
+
if (!isnull(ui))
// The UI is already open so push the data to it
ui.push_data(data)
@@ -186,4 +209,4 @@
//Send all needed nano ui files to the client
/datum/subsystem/nano/proc/send_resources(client)
for(var/file in asset_files)
- client << browse_rsc(file)
+ client << browse_rsc(file)
\ No newline at end of file
diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm
index 5bebfcb8682..729f0327a4b 100644
--- a/code/modules/nano/nanoui.dm
+++ b/code/modules/nano/nanoui.dm
@@ -131,8 +131,13 @@ nanoui is used to open and update nano browser uis
set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility)
else
var/dist = get_dist(src_object, user)
+ var/isTK = 0
- if (dist > 4)
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ isTK = H.dna.check_mutation(TK)
+
+ if (dist > 4 && !isTK)
close()
return
@@ -141,10 +146,10 @@ nanoui is used to open and update nano browser uis
else if (user.restrained() || user.lying)
set_status(STATUS_UPDATE, push_update) // update only (orange visibility)
else if (!(src_object in view(4, user))) // If the src object is not in visable, set status to 0
- set_status(STATUS_DISABLED, push_update) // interactive (green visibility)
+ set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility)
else if (dist <= 1)
set_status(STATUS_INTERACTIVE, push_update) // interactive (green visibility)
- else if (dist <= 2)
+ else if (dist <= 2 || isTK)
set_status(STATUS_UPDATE, push_update) // update only (orange visibility)
else if (dist <= 4)
set_status(STATUS_DISABLED, push_update) // no updates, completely disabled (red visibility)
diff --git a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm
index f664c87a8b9..9b2fb90596d 100644
--- a/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm
+++ b/code/modules/ninja/suit/n_suit_verbs/energy_net_nets.dm
@@ -124,7 +124,6 @@ It is possible to destroy the net by the occupant or someone else.
/obj/effect/energy_net/hitby(AM as mob|obj)
..()
- visible_message("[src] was hit by [AM].")
var/tforce = 0
if(ismob(AM))
tforce = 10
diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm
index ac8e32ecf63..8ae11c8f83c 100644
--- a/code/modules/paperwork/clipboard.dm
+++ b/code/modules/paperwork/clipboard.dm
@@ -28,7 +28,8 @@
/obj/item/weapon/clipboard/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/paper))
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
toppaper = W
user << "You clip the paper onto \the [src]."
@@ -76,7 +77,8 @@
if(!haspen)
if(istype(usr.get_active_hand(), /obj/item/weapon/pen))
var/obj/item/weapon/pen/W = usr.get_active_hand()
- usr.drop_item()
+ if(!usr.unEquip(W))
+ return
W.loc = src
haspen = W
usr << "You slot [W] into [src]."
diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm
index 351443ec5bb..4d071708fb3 100644
--- a/code/modules/paperwork/filingcabinet.dm
+++ b/code/modules/paperwork/filingcabinet.dm
@@ -43,8 +43,9 @@
/obj/structure/filingcabinet/attackby(obj/item/P, mob/user, params)
if(istype(P, /obj/item/weapon/paper) || istype(P, /obj/item/weapon/folder) || istype(P, /obj/item/weapon/photo) || istype(P, /obj/item/documents))
+ if(!user.drop_item())
+ return
user << "You put [P] in [src]."
- user.drop_item()
P.loc = src
icon_state = "[initial(icon_state)]-open"
sleep(5)
diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm
index b75140b9c43..6f725e04187 100644
--- a/code/modules/paperwork/folders.dm
+++ b/code/modules/paperwork/folders.dm
@@ -31,7 +31,8 @@
/obj/item/weapon/folder/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/paper) || istype(W, /obj/item/weapon/photo) || istype(W, /obj/item/documents))
- user.drop_item()
+ if(!user.unEquip(W))
+ return
W.loc = src
user << "You put [W] into [src]."
update_icon()
diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm
index 96c8f83e2b0..bd947c4b7a3 100644
--- a/code/modules/paperwork/handlabeler.dm
+++ b/code/modules/paperwork/handlabeler.dm
@@ -55,8 +55,9 @@
/obj/item/weapon/hand_labeler/attackby(obj/item/I as obj, mob/user as mob, params)
..()
if(istype(I, /obj/item/hand_labeler_refill))
+ if(!user.unEquip(I))
+ return
user << "You insert [I] into [src]."
- user.drop_item()
qdel(I)
labels_left = initial(labels_left)
return
diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm
index fbad5ce1f85..dd672a6d11c 100644
--- a/code/modules/paperwork/paperbin.dm
+++ b/code/modules/paperwork/paperbin.dm
@@ -71,7 +71,8 @@
if(!istype(i))
return ..()
- user.drop_item()
+ if(!user.unEquip(i))
+ return
i.loc = src
user << "You put [i] in [src]."
papers.Add(i)
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index 9159c1a6e6a..d5efcbe8dd4 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -24,6 +24,9 @@
pressure_resistance = 2
var/colour = "black" //what colour the ink is!
+/obj/item/weapon/pen/suicide_act(mob/user)
+ user.visible_message("[user] is scribbling numbers all over themself with [src]! It looks like they're trying to commit sudoku!")
+ return(BRUTELOSS)
/obj/item/weapon/pen/blue
desc = "It's a normal blue ink pen."
@@ -93,19 +96,25 @@
if(M.client)
M.mind_initialize() //give them a mind datum if they don't have one.
if(user.mind in ticker.mode.A_bosses)
- if(ticker.mode.add_gangster(M.mind,"A"))
- M.Paralyse(5)
- cooldown(max(0,ticker.mode.B_gang.len - ticker.mode.A_gang.len))
- else
- user << "This mind is resistant to recruitment!"
+ var/recruitable = ticker.mode.add_gangster(M.mind,"A")
+ switch(recruitable)
+ if(2)
+ M.Paralyse(5)
+ cooldown(max(0,ticker.mode.B_gang.len - ticker.mode.A_gang.len))
+ if(1)
+ user << "This mind has already been recruited by another gang!"
+ else
+ user << "This mind is resistant to recruitment!"
else if(user.mind in ticker.mode.B_bosses)
- if(ticker.mode.add_gangster(M.mind,"B"))
- M.Paralyse(5)
- cooldown(max(0,ticker.mode.A_gang.len - ticker.mode.B_gang.len))
- else
- user << "This mind is resistant to recruitment!"
- else
- user << "This mind is so vacant that it is not susceptible to influence!"
+ var/recruitable = ticker.mode.add_gangster(M.mind,"B")
+ switch(recruitable)
+ if(2)
+ M.Paralyse(5)
+ cooldown(max(0,ticker.mode.A_gang.len - ticker.mode.B_gang.len))
+ if(1)
+ user << "This mind has already been recruited by another gang!"
+ else
+ user << "This mind is resistant to recruitment!"
/obj/item/weapon/pen/gang/proc/cooldown(modifier)
cooldown = 1
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
index 92f82705db9..35e87edada7 100644
--- a/code/modules/paperwork/photocopier.dm
+++ b/code/modules/paperwork/photocopier.dm
@@ -223,7 +223,8 @@
/obj/machinery/photocopier/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/weapon/paper))
if(copier_empty())
- user.drop_item()
+ if(!user.drop_item())
+ return
copy = O
O.loc = src
user << "You insert [O] into [src]."
@@ -234,7 +235,8 @@
else if(istype(O, /obj/item/weapon/photo))
if(copier_empty())
- user.drop_item()
+ if(!user.drop_item())
+ return
photocopy = O
O.loc = src
user << "You insert [O] into [src]."
@@ -245,7 +247,8 @@
else if(istype(O, /obj/item/device/toner))
if(toner <= 0)
- user.drop_item()
+ if(!user.drop_item())
+ return
qdel(O)
toner = 40
user << "You insert [O] into [src]."
diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm
index 378ec945f85..0832ab226f3 100644
--- a/code/modules/paperwork/photography.dm
+++ b/code/modules/paperwork/photography.dm
@@ -140,8 +140,9 @@
if(pictures_left)
user << "[src] still has some film in it!"
return
+ if(!user.unEquip(I))
+ return
user << "You insert [I] into [src]."
- user.drop_item()
qdel(I)
pictures_left = pictures_max
return
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 7ddb67eefeb..4f9dbe520be 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -413,7 +413,8 @@
if (stat & MAINT)
user << "There is no connector for your power cell!"
return
- user.drop_item()
+ if(!user.drop_item())
+ return
W.loc = src
cell = W
user.visible_message(\
@@ -663,6 +664,9 @@
if(!user)
return
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "apc.tmpl", "[area.name] - APC", 520, user.has_unlimited_silicon_privilege ? 465 : 420, 1)
+
+/obj/machinery/power/apc/get_ui_data(mob/user)
var/list/data = list(
"locked" = locked,
"isOperating" = operating,
@@ -708,19 +712,7 @@
)
)
)
-
- // update the ui if it exists, returns null if no ui is passed/found
- ui = SSnano.try_update_ui(user, src, ui_key, ui, data)
- if (!ui)
- // the ui does not exist, so we'll create a new() one
- // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
- ui = new(user, src, ui_key, "apc.tmpl", "[area.name] - APC", 520, data["siliconUser"] ? 465 : 420)
- // when the ui is first opened this is the data it will use
- ui.set_initial_data(data)
- // open the new ui window
- ui.open()
- // auto update every Master Controller tick
- ui.set_auto_update(1)
+ return data
/obj/machinery/power/apc/proc/report()
return "[area.name] : [equipment]/[lighting]/[environ] ([lastused_equip+lastused_light+lastused_environ]) : [cell? cell.percent() : "N/C"] ([charging])"
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 00eb9f8c827..3608dde2b80 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -347,6 +347,8 @@
src.add_fingerprint(user)
var/obj/item/weapon/light/L = W
if(istype(L, light_type))
+ if(!user.drop_item())
+ return
status = L.status
user << "You insert the [L.name]."
switchcount = L.switchcount
@@ -355,7 +357,6 @@
on = has_power()
update()
- user.drop_item() //drop the item to update overlays and such
qdel(L)
if(on && rigged)
diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm
index 3202414ffb7..82c2955ad09 100644
--- a/code/modules/power/singularity/collector.dm
+++ b/code/modules/power/singularity/collector.dm
@@ -64,7 +64,8 @@ var/global/list/rad_collectors = list()
if(src.P)
user << "There's already a plasma tank loaded!"
return 1
- user.drop_item()
+ if(!user.drop_item())
+ return 1
src.P = W
W.loc = src
update_icons()
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index 92d7b8105c1..1ab4c078d11 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -89,15 +89,15 @@
if(src.active==1)
src.active = 0
user << "You turn off \the [src]."
- message_admins("Emitter turned off by [key_name(user, user.client)](?) in ([x],[y],[z] - JMP)",0,1)
- log_game("Emitter turned off by [user.ckey]([user]) in ([x],[y],[z])")
- investigate_log("turned off by [user.key]","singulo")
+ message_admins("Emitter turned off by [key_name_admin(user)](?) (FLW) in ([x],[y],[z] - JMP)",0,1)
+ log_game("Emitter turned off by [key_name(user)] in ([x],[y],[z])")
+ investigate_log("turned off by [key_name(user)]","singulo")
else
src.active = 1
user << "You turn on \the [src]."
src.shot_number = 0
src.fire_delay = maximum_fire_delay
- investigate_log("turned on by [user.key]","singulo")
+ investigate_log("turned on by [key_name(user)]","singulo")
update_icon()
else
user << "The controls are locked!"
diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm
index da304074573..c5fe52da089 100644
--- a/code/modules/power/singularity/particle_accelerator/particle_control.dm
+++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm
@@ -119,9 +119,9 @@
if(strength > strength_upper_limit)
strength = strength_upper_limit
else
- message_admins("PA Control Computer increased to [strength] by [key_name(usr, usr.client)](?) in ([x],[y],[z] - JMP)",0,1)
- log_game("PA Control Computer increased to [strength] by [usr.ckey]([usr]) in ([x],[y],[z])")
- investigate_log("increased to [strength] by [usr.key]","singulo")
+ message_admins("PA Control Computer increased to [strength] by [key_name_admin(usr)](?) (FLW) in ([x],[y],[z] - JMP)",0,1)
+ log_game("PA Control Computer increased to [strength] by [key_name(usr)] in ([x],[y],[z])")
+ investigate_log("increased to [strength] by [key_name(usr)]","singulo")
strength_change()
/obj/machinery/particle_accelerator/control_box/proc/remove_strength(var/s)
@@ -130,9 +130,9 @@
if(strength < 0)
strength = 0
else
- message_admins("PA Control Computer decreased to [strength] by [key_name(usr, usr.client)](?) in ([x],[y],[z] - JMP)",0,1)
- log_game("PA Control Computer decreased to [strength] by [usr.ckey]([usr]) in ([x],[y],[z])")
- investigate_log("decreased to [strength] by [usr.key]","singulo")
+ message_admins("PA Control Computer decreased to [strength] by [key_name_admin(usr)](?) (FLW) in ([x],[y],[z] - JMP)",0,1)
+ log_game("PA Control Computer decreased to [strength] by [key_name(usr)] in ([x],[y],[z])")
+ investigate_log("decreased to [strength] by [key_name(usr)]","singulo")
strength_change()
/obj/machinery/particle_accelerator/control_box/power_change()
@@ -210,9 +210,9 @@
/obj/machinery/particle_accelerator/control_box/proc/toggle_power()
src.active = !src.active
- investigate_log("turned [active?"ON":"OFF"] by [usr ? usr.key : "outside forces"]","singulo")
- message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? key_name(usr, usr.client) : "outside forces"](?) in ([x],[y],[z] - JMP)",0,1)
- log_game("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? "[usr.ckey]([usr])" : "outside forces"] in ([x],[y],[z])")
+ investigate_log("turned [active?"ON":"OFF"] by [usr ? key_name(usr) : "outside forces"]","singulo")
+ message_admins("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? key_name_admin(usr) : "outside forces"](?) (FLW) in ([x],[y],[z] - JMP)",0,1)
+ log_game("PA Control Computer turned [active ?"ON":"OFF"] by [usr ? "[key_name(usr)]" : "outside forces"] in ([x],[y],[z])")
if(src.active)
src.use_power = 2
for(var/obj/structure/particle_accelerator/part in connected_parts)
diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm
index 85d8089d926..9a30df83891 100644
--- a/code/modules/power/singularity/singularity.dm
+++ b/code/modules/power/singularity/singularity.dm
@@ -25,6 +25,7 @@
var/target = null //its target. moves towards the target if it has one
var/last_failed_movement = 0//Will not move in the same dir if it couldnt before, will help with the getting stuck on fields thing
var/last_warning
+ var/consumedSupermatter = 0 //If the singularity has eaten a supermatter shard and can go to stage six
allow_spin = 0
/obj/singularity/New(loc, var/starting_energy = 50, var/temp = 0)
//CARN: admin-alert for chuckle-fuckery.
@@ -129,6 +130,8 @@
var/temp_allowed_size = src.allowed_size
if(force_size)
temp_allowed_size = force_size
+ if(temp_allowed_size >= STAGE_SIX && !consumedSupermatter)
+ temp_allowed_size = STAGE_FIVE
switch(temp_allowed_size)
if(STAGE_ONE)
current_size = STAGE_ONE
@@ -185,6 +188,15 @@
grav_pull = 10
consume_range = 4
dissipate = 0 //It cant go smaller due to e loss
+ if(STAGE_SIX) //This only happens if a stage 5 singulo consumes a supermatter shard.
+ current_size = STAGE_SIX
+ icon = 'icons/effects/352x352.dmi'
+ icon_state = "singularity_s11"
+ pixel_x = -160
+ pixel_y = -160
+ grav_pull = 15
+ consume_range = 5
+ dissipate = 0
if(current_size == allowed_size)
investigate_log("grew to size [current_size]","singulo")
return 1
@@ -199,6 +211,8 @@
investigate_log("collapsed.","singulo")
qdel(src)
return 0
+ if(energy > 2999 && !consumedSupermatter)
+ energy = 2000
switch(energy)//Some of these numbers might need to be changed up later -Mport
if(1 to 199)
allowed_size = STAGE_ONE
@@ -208,8 +222,10 @@
allowed_size = STAGE_THREE
if(1000 to 1999)
allowed_size = STAGE_FOUR
- if(2000 to INFINITY)
+ if(2000 to 2999)
allowed_size = STAGE_FIVE
+ if(3000 to INFINITY)
+ allowed_size = STAGE_SIX
if(current_size != allowed_size)
expand()
return 1
@@ -230,6 +246,11 @@
/obj/singularity/proc/consume(var/atom/A)
var/gain = A.singularity_act(current_size)
src.energy += gain
+ if(istype(A, /obj/machinery/power/supermatter_shard) && !consumedSupermatter)
+ desc = "[initial(desc)] It glows fiercely with inner fire."
+ name = "supermatter-charged [initial(name)]"
+ consumedSupermatter = 1
+ luminosity = 10
return
@@ -326,6 +347,10 @@
toxmob()
if(4)//Stun mobs who lack optic scanners
mezzer()
+ if(5,6) //Sets all nearby mobs on fire
+ if(current_size < STAGE_SIX)
+ return 0
+ combust_mobs()
else
return 0
return 1
@@ -347,6 +372,15 @@
return
+/obj/singularity/proc/combust_mobs()
+ for(var/mob/living/carbon/C in orange(20, src))
+ C.visible_message("[C]'s skin bursts into flame!", \
+ "You feel an inner fire as your skin is suddenly covered in fire!")
+ C.adjust_fire_stacks(5)
+ C.IgniteMob()
+ return
+
+
/obj/singularity/proc/mezzer()
for(var/mob/living/carbon/M in oviewers(8, src))
if(istype(M, /mob/living/carbon/brain)) //Ignore brains
diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm
index e97f5462d7d..f5c64014ddf 100644
--- a/code/modules/power/smes.dm
+++ b/code/modules/power/smes.dm
@@ -326,6 +326,10 @@
if(!user)
return
+ // update the ui if it exists, create a new one if it doesn't
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "smes.tmpl", "SMES - [name]", 350, 560, 1)
+
+/obj/machinery/power/smes/get_ui_data()
var/list/data = list(
"capacityPercent" = round(100.0*charge/capacity, 0.1),
"capacity" = capacity,
@@ -343,19 +347,7 @@
"outputLevelMax" = output_level_max,
"outputUsed" = output_used
)
-
- // update the ui if it exists, returns null if no ui is passed/found
- ui = SSnano.try_update_ui(user, src, ui_key, ui, data)
- if (!ui)
- // the ui does not exist, so we'll create a new() one
- // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
- ui = new(user, src, ui_key, "smes.tmpl", "SMES - [name]", 350, 560)
- // when the ui is first opened this is the data it will use
- ui.set_initial_data(data)
- // open the new ui window
- ui.open()
- // auto update every Master Controller tick
- ui.set_auto_update(1)
+ return data
/obj/machinery/power/smes/Topic(href, href_list)
// world << "[href] ; [href_list[href]]"
diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm
index 1c8838e4311..16a5f58588e 100644
--- a/code/modules/power/solar.dm
+++ b/code/modules/power/solar.dm
@@ -253,8 +253,9 @@
if(!tracker)
if(istype(W, /obj/item/weapon/tracker_electronics))
+ if(!user.drop_item())
+ return
tracker = 1
- user.drop_item()
qdel(W)
user.visible_message("[user] inserts the electronics into the solar assembly.", "You insert the electronics into the solar assembly.")
return 1
@@ -369,8 +370,10 @@
if(!..())
ui_interact(user)
-/obj/machinery/power/solar_control/ui_interact(mob/user, ui_key = "main")
+/obj/machinery/power/solar_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "solar_control.tmpl", name, 490, 420, 1)
+/obj/machinery/power/solar_control/get_ui_data()
var/data = list()
data["generated"] = round(lastgen)
@@ -383,16 +386,7 @@
data["connected_panels"] = connected_panels.len
data["connected_tracker"] = (connected_tracker ? 1 : 0)
-
- var/datum/nanoui/ui = SSnano.get_open_ui(user, src, ui_key)
- if (!ui)
- ui = new(user, src, ui_key, "solar_control.tmpl", name, 490, 420)
- ui.set_initial_data(data)
- ui.open()
- ui.set_auto_update(1)
- else
- ui.push_data(data)
- return
+ return data
/obj/machinery/power/solar_control/attackby(I as obj, user as mob, params)
if(istype(I, /obj/item/weapon/screwdriver))
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index a48cff67f93..8520b330ec3 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -187,6 +187,7 @@
return 1
+/obj/machinery/power/supermatter_shard
/obj/machinery/power/supermatter_shard/bullet_act(var/obj/item/projectile/Proj)
var/turf/L = loc
@@ -205,6 +206,16 @@
damage += Proj.damage * config_bullet_energy
return 0
+/obj/machinery/power/supermatter_shard/singularity_act()
+ var/gain = 100
+ investigate_log("Supermatter shard consumed by singularity.","singulo")
+ message_admins("Singularity has consumed a supermatter shard and can now become stage six.")
+ visible_message("[src] is consumed by the singularity!")
+ for(var/mob/M in mob_list)
+ M << 'sound/effects/supermatter.ogg' //everyone goan know bout this
+ M << "A horrible screeching fills your ears, and a wave of dread washes over you..."
+ qdel(src)
+ return(gain)
/obj/machinery/power/supermatter_shard/attack_paw(mob/user as mob)
return attack_hand(user)
@@ -272,12 +283,12 @@
var/mob/living/user = AM
user.dust()
power += 200
- message_admins("[src] has consumed [key_name(user)]? (JMP).")
+ message_admins("[src] has consumed [key_name_admin(user)]? (FLW) (JMP).")
+ investigate_log("has consumed [key_name(user)].", "supermatter")
else if(isobj(AM) && !istype(AM, /obj/effect))
+ investigate_log("has consumed [AM].", "supermatter")
qdel(AM)
- investigate_log("has consumed [AM].", "supermatter")
-
power += 200
//Some poor sod got eaten, go ahead and irradiate people nearby.
diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm
index 405880f4249..6e72debce5f 100644
--- a/code/modules/power/turbine.dm
+++ b/code/modules/power/turbine.dm
@@ -25,7 +25,7 @@
/obj/machinery/power/compressor
name = "compressor"
desc = "The compressor stage of a gas turbine generator."
- icon = 'icons/obj/pipes.dmi'
+ icon = 'icons/obj/atmospherics/pipes/simple.dmi'
icon_state = "compressor"
anchored = 1
density = 1
@@ -43,7 +43,7 @@
/obj/machinery/power/turbine
name = "gas turbine generator"
desc = "A gas turbine used for backup power generation."
- icon = 'icons/obj/pipes.dmi'
+ icon = 'icons/obj/atmospherics/pipes/simple.dmi'
icon_state = "turbine"
anchored = 1
density = 1
@@ -168,13 +168,13 @@
if(rpm>50000)
- overlays += image('icons/obj/pipes.dmi', "comp-o4", FLY_LAYER)
+ overlays += image('icons/obj/atmospherics/pipes/simple.dmi', "comp-o4", FLY_LAYER)
else if(rpm>10000)
- overlays += image('icons/obj/pipes.dmi', "comp-o3", FLY_LAYER)
+ overlays += image('icons/obj/atmospherics/pipes/simple.dmi', "comp-o3", FLY_LAYER)
else if(rpm>2000)
- overlays += image('icons/obj/pipes.dmi', "comp-o2", FLY_LAYER)
+ overlays += image('icons/obj/atmospherics/pipes/simple.dmi', "comp-o2", FLY_LAYER)
else if(rpm>500)
- overlays += image('icons/obj/pipes.dmi', "comp-o1", FLY_LAYER)
+ overlays += image('icons/obj/atmospherics/pipes/simple.dmi', "comp-o1", FLY_LAYER)
//TODO: DEFERRED
// These are crucial to working of a turbine - the stats modify the power output. TurbGenQ modifies how much raw energy can you get from
@@ -268,7 +268,7 @@
// If it works, put an overlay that it works!
if(lastgen > 100)
- overlays += image('icons/obj/pipes.dmi', "turb-o", FLY_LAYER)
+ overlays += image('icons/obj/atmospherics/pipes/simple.dmi', "turb-o", FLY_LAYER)
updateDialog()
diff --git a/code/modules/projectiles/ammunition/ammo_casings.dm b/code/modules/projectiles/ammunition/ammo_casings.dm
index 3e363056825..5afe311cb22 100644
--- a/code/modules/projectiles/ammunition/ammo_casings.dm
+++ b/code/modules/projectiles/ammunition/ammo_casings.dm
@@ -160,6 +160,18 @@
/obj/item/ammo_casing/shotgun/dart/attackby()
return
+/obj/item/ammo_casing/shotgun/dart/bioterror
+ desc = "A shotgun dart filled with deadly toxins."
+
+/obj/item/ammo_casing/shotgun/dart/bioterror/New()
+ ..()
+ reagents.add_reagent("neurotoxin", 5)
+ reagents.add_reagent("morphine", 5)
+ reagents.add_reagent("spore", 5)
+ reagents.add_reagent("mutetoxin", 5) //;HELP OPS IN MAINT
+ reagents.add_reagent("initropidril", 5)
+ reagents.add_reagent("sodium_thiopental", 5)
+
/obj/item/ammo_casing/a762
desc = "A 7.62mm bullet casing."
icon_state = "762-casing"
@@ -232,7 +244,8 @@
desc = "Its nerf or nothing! ... Although, this one doesn't look too safe."
user << "You pop the safety cap off of [src]."
else if ((istype(A, /obj/item/weapon/pen)) && modified && !BB.contents.len)
- user.drop_item()
+ if(!user.unEquip(A))
+ return
A.loc = BB
BB.damage = 5
BB.nodamage = 0
diff --git a/code/modules/projectiles/ammunition/magazines.dm b/code/modules/projectiles/ammunition/magazines.dm
index 342f7234c62..3f66bc2b997 100644
--- a/code/modules/projectiles/ammunition/magazines.dm
+++ b/code/modules/projectiles/ammunition/magazines.dm
@@ -53,7 +53,7 @@
desc = "Oh god, this shouldn't be here"
ammo_type = /obj/item/ammo_casing/shotgun/buckshot
caliber = "shotgun"
- max_ammo = 8
+ max_ammo = 6
multiload = 0
/obj/item/ammo_box/magazine/internal/cylinder/dualshot
@@ -134,6 +134,17 @@
..()
icon_state = "45-[ammo_count() ? "8" : "0"]"
+/obj/item/ammo_box/magazine/uzim9mm
+ name = "uzi magazine (9mm)"
+ icon_state = "uzi9mm-32"
+ ammo_type = /obj/item/ammo_casing/c9mm
+ caliber = "9mm"
+ max_ammo = 32
+
+/obj/item/ammo_box/magazine/uzim9mm/update_icon()
+ ..()
+ icon_state = "uzi9mm-[round(ammo_count(),4)]"
+
/obj/item/ammo_box/magazine/smgm9mm
name = "SMG magazine (9mm)"
icon_state = "smg9mm-20"
@@ -157,11 +168,11 @@
..()
icon_state = "c20r45-[round(ammo_count(),2)]"
-obj/item/ammo_box/magazine/tommygunm9mm
- name = "drum magazine (9mm)"
+obj/item/ammo_box/magazine/tommygunm45
+ name = "drum magazine (.45)"
icon_state = "drum45"
- ammo_type = /obj/item/ammo_casing/c9mm
- caliber = "9mm"
+ ammo_type = /obj/item/ammo_casing/c45
+ caliber = ".45"
max_ammo = 50
/obj/item/ammo_box/magazine/m50
@@ -203,10 +214,11 @@ obj/item/ammo_box/magazine/tommygunm9mm
icon_state = "a762-[round(ammo_count(),10)]"
+
/obj/item/ammo_box/magazine/m12g
- name = "shotgun magazine (12g buckshot)"
+ name = "shotgun magazine (12g slugs)"
icon_state = "m12gb"
- ammo_type = /obj/item/ammo_casing/shotgun/buckshot
+ ammo_type = /obj/item/ammo_casing/shotgun
origin_tech = "combat=3;syndicate=1"
caliber = "shotgun"
max_ammo = 8
@@ -215,6 +227,11 @@ obj/item/ammo_box/magazine/tommygunm9mm
..()
icon_state = "[initial(icon_state)]-[Ceiling(ammo_count(0)/8)*8]"
+/obj/item/ammo_box/magazine/m12g/buckshot
+ name = "shotgun magazine (12g buckshot slugs)"
+ icon_state = "m12gb"
+ ammo_type = /obj/item/ammo_casing/shotgun/buckshot
+
/obj/item/ammo_box/magazine/m12g/stun
name = "shotgun magazine (12g taser slugs)"
icon_state = "m12gs"
@@ -225,6 +242,11 @@ obj/item/ammo_box/magazine/tommygunm9mm
icon_state = "m12gf"
ammo_type = /obj/item/ammo_casing/shotgun/incendiary/dragonsbreath
+/obj/item/ammo_box/magazine/m12g/bioterror
+ name = "shotgun magazine (12g bioterror)"
+ icon_state = "m12gt"
+ ammo_type = /obj/item/ammo_casing/shotgun/dart/bioterror
+
/obj/item/ammo_box/magazine/toy
name = "foam force META magazine"
ammo_type = /obj/item/ammo_casing/caseless/foam_dart
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index 9b1666fd2f0..dd9c381e2d6 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -98,8 +98,8 @@
if(heavy_weapon)
if(user.get_inactive_hand())
if(prob(15))
- user.visible_message("[src] flies out of [user]'s hands!", "[src] kicks out of your grip!")
- user.drop_item()
+ if(user.drop_item())
+ user.visible_message("[src] flies out of [user]'s hands!", "[src] kicks out of your grip!")
/obj/item/weapon/gun/emp_act(severity)
for(var/obj/O in contents)
@@ -235,7 +235,8 @@
if(user.l_hand != src && user.r_hand != src)
user << "You'll need [src] in your hands to do that!"
return
- user.drop_item()
+ if(!user.unEquip(A))
+ return
user << "You click [S] into place on [src]."
if(S.on)
SetLuminosity(0)
diff --git a/code/modules/projectiles/guns/grenade_launcher.dm b/code/modules/projectiles/guns/grenade_launcher.dm
index 9ae8b1e8c6f..2075ebeaa60 100644
--- a/code/modules/projectiles/guns/grenade_launcher.dm
+++ b/code/modules/projectiles/guns/grenade_launcher.dm
@@ -20,7 +20,8 @@
if((istype(I, /obj/item/weapon/grenade)))
if(grenades.len < max_grenades)
- user.drop_item()
+ if(!user.unEquip(I))
+ return
I.loc = src
grenades += I
user << "You put the grenade in the grenade launcher."
diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm
index 66184119b45..7bea46b2f96 100644
--- a/code/modules/projectiles/guns/projectile.dm
+++ b/code/modules/projectiles/guns/projectile.dm
@@ -68,7 +68,8 @@
if(user.l_hand != src && user.r_hand != src)
user << "You'll need [src] in your hands to do that."
return
- user.drop_item()
+ if(!user.unEquip(A))
+ return
user << "You screw [S] onto [src]."
suppressed = A
S.oldsound = fire_sound
diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm
index badf178b878..19545232181 100644
--- a/code/modules/projectiles/guns/projectile/automatic.dm
+++ b/code/modules/projectiles/guns/projectile/automatic.dm
@@ -106,7 +106,13 @@
icon_state = "c20r[magazine ? "-[Ceiling(get_ammo(0)/4)*4]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
return
-
+/obj/item/weapon/gun/projectile/automatic/mini_uzi
+ name = "uzi"
+ desc = "A lightweight, burst-fire submachine gun, for when you really want someone dead. Uses 9mm rounds."
+ icon_state = "mini-uzi"
+ origin_tech = "combat=5;materials=2;syndicate=8"
+ mag_type = /obj/item/ammo_box/magazine/uzim9mm
+ burst_size = 2
/obj/item/weapon/gun/projectile/automatic/l6_saw
name = "syndicate LMG"
@@ -237,7 +243,7 @@
w_class = 5
slot_flags = 0
origin_tech = "combat=5;materials=1;syndicate=2"
- mag_type = /obj/item/ammo_box/magazine/tommygunm9mm
+ mag_type = /obj/item/ammo_box/magazine/tommygunm45
fire_sound = 'sound/weapons/Gunshot_smg.ogg'
can_suppress = 0
burst_size = 4
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index 7178c36469f..9e1dc22e592 100644
--- a/code/modules/projectiles/guns/projectile/revolver.dm
+++ b/code/modules/projectiles/guns/projectile/revolver.dm
@@ -79,7 +79,7 @@
playsound(user, fire_sound, 50, 1)
user << "[src] blows up in your face!"
user.take_organ_damage(0,20)
- user.drop_item()
+ user.unEquip(src)
qdel(src)
return 0
..()
diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm
index 2d0da86aed1..56a312e9c19 100644
--- a/code/modules/projectiles/guns/projectile/shotgun.dm
+++ b/code/modules/projectiles/guns/projectile/shotgun.dm
@@ -62,16 +62,6 @@
if (chambered)
user << "A [chambered.BB ? "live" : "spent"] one is in the chamber."
-// COMBAT SHOTGUN //
-
-/obj/item/weapon/gun/projectile/shotgun/combat
- name = "combat shotgun"
- desc = "A traditional shotgun with tactical furniture and an eight-shell capacity underneath."
- icon_state = "cshotgun"
- origin_tech = "combat=5;materials=2"
- mag_type = /obj/item/ammo_box/magazine/internal/shotcom
- w_class = 5
-
// RIOT SHOTGUN //
/obj/item/weapon/gun/projectile/shotgun/riot //for spawn in the armory
@@ -293,3 +283,17 @@
..()
empty_alarm()
return
+
+/obj/item/weapon/gun/projectile/shotgun/automatic/shoot_live_shot(mob/living/user as mob|obj)
+ ..()
+ src.pump(user)
+
+// COMBAT SHOTGUN //
+
+/obj/item/weapon/gun/projectile/shotgun/automatic/combat
+ name = "combat shotgun"
+ desc = "A semi automatic shotgun with tactical furniture and a six-shell capacity underneath."
+ icon_state = "cshotgun"
+ origin_tech = "combat=5;materials=2"
+ mag_type = /obj/item/ammo_box/magazine/internal/shotcom
+ w_class = 5
\ No newline at end of file
diff --git a/code/modules/projectiles/guns/syringe_gun.dm b/code/modules/projectiles/guns/syringe_gun.dm
index f0a17314848..6ed12b01b64 100644
--- a/code/modules/projectiles/guns/syringe_gun.dm
+++ b/code/modules/projectiles/guns/syringe_gun.dm
@@ -63,7 +63,8 @@
/obj/item/weapon/gun/syringe/attackby(var/obj/item/A as obj, mob/user as mob, params, var/show_msg = 1)
if(istype(A, /obj/item/weapon/reagent_containers/syringe))
if(syringes.len < max_syringes)
- user.drop_item()
+ if(!user.unEquip(A))
+ return
user << "You load [A] into \the [src]."
syringes.Add(A)
A.loc = src
diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm
index acc5f311420..123e35a2fd8 100644
--- a/code/modules/projectiles/pins.dm
+++ b/code/modules/projectiles/pins.dm
@@ -30,7 +30,8 @@
user << "You remove [G]'s old pin."
if(!G.pin)
- user.drop_item()
+ if(!user.unEquip(src))
+ return
gun_insert(user, G)
user << "You insert [src] into [G]."
else
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index 93579b5f0d8..8fc1a4622f9 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -108,7 +108,6 @@
loc = target_turf
if(A)
permutated.Add(A)
- Range()
return 0
else
if(A && A.density && !ismob(A) && !(A.flags & ON_BORDER)) //if we hit a dense non-border obj or dense turf then we also hit one of the mobs on that tile.
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index e87808254e6..00cd2fc1a42 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -30,6 +30,7 @@
icon_state = "xray"
damage = 15
irradiate = 30
+ range = 15
forcedodge = 1
/obj/item/projectile/beam/disabler
diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm
index 75ba81b7dc1..efc20cedfd7 100644
--- a/code/modules/projectiles/projectile/magic.dm
+++ b/code/modules/projectiles/projectile/magic.dm
@@ -227,9 +227,10 @@
ready_dna(H)
if(H.dna && prob(50))
var/list/all_species = list()
- for(var/datum/species/S in typesof(/datum/species) - /datum/species)
+ for(var/speciestype in typesof(/datum/species) - /datum/species)
+ var/datum/species/S = new speciestype()
if(!S.dangerous_existence)
- all_species += S
+ all_species += speciestype
hardset_dna(H, null, null, null, null, pick(all_species))
H.update_icons()
else
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index 3dab9a3442a..5c79572d938 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -75,8 +75,10 @@
if(stat & (BROKEN)) return
if(user.stat || user.restrained()) return
- // this is the data which will be sent to the ui
- var/data[0]
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "chem_dispenser.tmpl", "[uiname]", 490, 710, 0)
+
+/obj/machinery/chem_dispenser/get_ui_data()
+ var/data = list()
data["amount"] = amount
data["energy"] = energy
data["maxEnergy"] = max_energy
@@ -103,17 +105,7 @@
if(temp)
chemicals.Add(list(list("title" = temp.name, "id" = temp.id, "commands" = list("dispense" = temp.id)))) // list in a list because Byond merges the first list...
data["chemicals"] = chemicals
-
- // update the ui if it exists, returns null if no ui is passed/found
- ui = SSnano.try_update_ui(user, src, ui_key, ui, data)
- if (!ui)
- // the ui does not exist, so we'll create a new() one
- // for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
- ui = new(user, src, ui_key, "chem_dispenser.tmpl", "[uiname]", 490, 710)
- // when the ui is first opened this is the data it will use
- ui.set_initial_data(data)
- // open the new ui window
- ui.open()
+ return data
/obj/machinery/chem_dispenser/Topic(href, href_list)
if(stat & (BROKEN))
@@ -155,9 +147,10 @@
if(src.beaker)
user << "A beaker is already loaded into the machine!"
return
+ if(!user.drop_item())
+ return
src.beaker = B
- user.drop_item()
B.loc = src
user << "You add the beaker to the machine."
SSnano.update_uis(src) // update all UIs attached to src
@@ -290,8 +283,10 @@
if(src.beaker)
user << "A beaker is already loaded into the machine!"
return
+ if(!user.drop_item())
+ return
+
src.beaker = B
- user.drop_item()
B.loc = src
user << "You add the beaker to the machine."
src.updateUsrDialog()
@@ -301,8 +296,10 @@
if(src.loaded_pill_bottle)
user << "A pill bottle is already loaded into the machine!"
return
+ if(!user.drop_item())
+ return
+
src.loaded_pill_bottle = B
- user.drop_item()
B.loc = src
user << "You add the pill bottle into the dispenser slot."
src.updateUsrDialog()
@@ -619,8 +616,10 @@
if(src.beaker)
user << "A beaker is already loaded into the machine!"
return
+ if(!user.drop_item())
+ return
+
src.beaker = B
- user.drop_item()
B.loc = src
user << "You add the beaker to the machine."
src.updateUsrDialog()
@@ -630,8 +629,10 @@
if(src.loaded_pill_bottle)
user << "A pill bottle is already loaded into the machine!"
return
+ if(!user.drop_item())
+ return
+
src.loaded_pill_bottle = B
- user.drop_item()
B.loc = src
user << "You add the pill bottle into the dispenser slot."
src.updateUsrDialog()
@@ -919,9 +920,10 @@
if(src.beaker)
user << "A beaker is already loaded into the machine!"
return
+ if(!user.drop_item())
+ return
src.beaker = I
- user.drop_item()
I.loc = src
user << "You add the beaker to the machine."
src.updateUsrDialog()
@@ -1053,8 +1055,9 @@
if (beaker)
return 1
else
+ if(!user.drop_item())
+ return 1
src.beaker = O
- user.drop_item()
O.loc = src
update_icon()
src.updateUsrDialog()
@@ -1499,7 +1502,10 @@
/obj/machinery/chem_heater/ui_interact(var/mob/user, ui_key = "main", var/datum/nanoui/ui = null)
if(user.stat || user.restrained()) return
- var/data[0]
+ ui = SSnano.push_open_or_new_ui(user, src, ui_key, ui, "chem_heater.tmpl", "ChemHeater", 350, 270, 0)
+
+/obj/machinery/chem_heater/get_ui_data()
+ var/data = list()
data["targetTemp"] = desired_temp
data["isActive"] = on
data["isBeakerLoaded"] = beaker ? 1 : 0
@@ -1514,13 +1520,7 @@
for(var/datum/reagent/R in beaker.reagents.reagent_list)
beakerContents.Add(list(list("name" = R.name, "volume" = R.volume))) // list in a list because Byond merges the first list...
data["beakerContents"] = beakerContents
-
- // update the ui if it exists, returns null if no ui is passed/found
- ui = SSnano.try_update_ui(user, src, ui_key, ui, data)
- if (!ui)
- ui = new(user, src, ui_key, "chem_heater.tmpl", "ChemHeater", 350, 270)
- ui.set_initial_data(data)
- ui.open()
+ return data
///////////////////////////////////////////////////////////////////////////
@@ -1548,8 +1548,9 @@
if (beaker)
return 1
else
+ if(!user.drop_item())
+ return 1
src.beaker = O
- user.drop_item()
O.loc = src
update_icon()
src.updateUsrDialog()
diff --git a/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm
index c9ade32e68b..f3706a7e76b 100644
--- a/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm
@@ -163,20 +163,6 @@
send_message(M)
M.reagents.add_reagent("omnizine", 11)
-/datum/reagent/blob/morphine
- name = "Morphine"
- id = "b_morphine"
- description = ""
- color = "#335555"
- message = "The blob squirts something at you"
- message_living = ", and you feel numb"
-
-/datum/reagent/blob/morphine/reaction_mob(var/mob/living/M as mob, var/method=TOUCH, var/volume, var/show_message = 1)
- if(method == TOUCH)
- if(show_message)
- send_message(M)
- M.reagents.add_reagent("morphine", 16)
-
/datum/reagent/blob/spacedrugs
name = "Space drugs"
id = "b_space_drugs"
@@ -211,4 +197,4 @@
if(message_living && !issilicon(M))
totalmessage += message_living
totalmessage += "!"
- M << "[totalmessage]"
\ No newline at end of file
+ M << "[totalmessage]"
diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm
index 7cdb73ae78a..9555c8a126a 100644
--- a/code/modules/reagents/Chemistry-Recipes.dm
+++ b/code/modules/reagents/Chemistry-Recipes.dm
@@ -59,7 +59,7 @@
var/mob/M = get(A, /mob)
if(M)
- message += " - Carried By: [M.real_name] ([M.key]) (PP) (?)"
+ message += " - Carried By: [key_name_admin(M)](?) (FLW)"
else
message += " - Last Fingerprint: [(A.fingerprintslast ? A.fingerprintslast : "N/A")]"
diff --git a/code/modules/reagents/Chemistry-Recipes/Slime_extracts.dm b/code/modules/reagents/Chemistry-Recipes/Slime_extracts.dm
index 7c26d80e4c2..996604a0822 100644
--- a/code/modules/reagents/Chemistry-Recipes/Slime_extracts.dm
+++ b/code/modules/reagents/Chemistry-Recipes/Slime_extracts.dm
@@ -502,11 +502,27 @@
notify_ghosts("Golem rune created in [get_area(Z)].", 'sound/effects/ghost2.ogg')
//Bluespace
+/datum/chemical_reaction/slimefloor2
+ name = "Bluespace Floor"
+ id = "m_floor2"
+ result = null
+ required_reagents = list("blood" = 1)
+ result_amount = 1
+ required_container = /obj/item/slime_extract/bluespace
+ required_other = 1
+
+/datum/chemical_reaction/slimefloor2/on_reaction(var/datum/reagents/holder, var/created_volume)
+ feedback_add_details("slime_cores_used","[replacetext(name," ","_")]")
+ var/obj/item/stack/tile/bluespace/P = new /obj/item/stack/tile/bluespace
+ P.amount = 25
+ P.loc = get_turf(holder.my_atom)
+
+
/datum/chemical_reaction/slimecrystal
name = "Slime Crystal"
id = "m_crystal"
result = null
- required_reagents = list("blood" = 1)
+ required_reagents = list("plasma" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/bluespace
required_other = 1
@@ -555,7 +571,7 @@
name = "Slime Camera"
id = "m_camera"
result = null
- required_reagents = list("blood" = 1)
+ required_reagents = list("water" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/sepia
required_other = 1
@@ -564,19 +580,22 @@
feedback_add_details("slime_cores_used","[replacetext(name," ","_")]")
var/obj/item/device/camera/P = new /obj/item/device/camera
P.loc = get_turf(holder.my_atom)
+ var/obj/item/device/camera_film/Z = new /obj/item/device/camera_film
+ Z.loc = get_turf(holder.my_atom)
-/datum/chemical_reaction/slimefilm
- name = "Slime Film"
- id = "m_film"
+/datum/chemical_reaction/slimefloor
+ name = "Sepia Floor"
+ id = "m_floor"
result = null
- required_reagents = list("water" = 1)
+ required_reagents = list("blood" = 1)
result_amount = 1
required_container = /obj/item/slime_extract/sepia
required_other = 1
-/datum/chemical_reaction/slimefilm/on_reaction(var/datum/reagents/holder)
+/datum/chemical_reaction/slimefloor/on_reaction(var/datum/reagents/holder)
feedback_add_details("slime_cores_used","[replacetext(name," ","_")]")
- var/obj/item/device/camera_film/P = new /obj/item/device/camera_film
+ var/obj/item/stack/tile/sepia/P = new /obj/item/stack/tile/sepia
+ P.amount = 25
P.loc = get_turf(holder.my_atom)
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index 4ef5f0d72ed..553f6c9cfbc 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -157,7 +157,8 @@
/obj/structure/reagent_dispensers/water_cooler/attackby(var/obj/item/I, var/mob/user, params)
if(istype(I, /obj/item/weapon/paper))
- user.drop_item()
+ if(!user.drop_item())
+ return
qdel(I)
cups++
return
diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm
index 69ffea18298..bf75185292d 100644
--- a/code/modules/recycling/disposal-construction.dm
+++ b/code/modules/recycling/disposal-construction.dm
@@ -5,7 +5,7 @@
name = "disposal pipe segment"
desc = "A huge pipe segment used for constructing disposal systems."
- icon = 'icons/obj/pipes/disposal.dmi'
+ icon = 'icons/obj/atmospherics/pipes/disposal.dmi'
icon_state = "conpipe-s"
anchored = 0
density = 0
@@ -173,11 +173,11 @@
if(T.intact && istype(T, /turf/simulated/floor))
user << "You can only attach the [nicetype] if the floor plating is removed!"
return
-
+
if(!ispipe && istype(T, /turf/simulated/wall))
user << "You can't build [nicetype]s on walls, only disposal pipes!"
return
-
+
var/obj/structure/disposalpipe/CP = locate() in T
if(istype(I, /obj/item/weapon/wrench))
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index d3fa4a658a6..f1afbfe34ee 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -10,7 +10,7 @@
/obj/machinery/disposal
name = "disposal unit"
desc = "A pneumatic waste disposal unit."
- icon = 'icons/obj/pipes/disposal.dmi'
+ icon = 'icons/obj/atmospherics/pipes/disposal.dmi'
icon_state = "disposal"
anchored = 1
density = 1
@@ -123,9 +123,9 @@
stuff_mob_in(G.affecting, user)
return
- if(!I || I.flags & NODROP) return
+ if(!user.drop_item())
+ return
- user.drop_item()
I.loc = src
user.visible_message("[user.name] places \the [I] into \the [src].", \
"You place \the [I] into \the [src].")
@@ -311,7 +311,7 @@
// flush handle
if(flush)
- overlays += image('icons/obj/pipes/disposal.dmi', "dispover-handle")
+ overlays += image('icons/obj/atmospherics/pipes/disposal.dmi', "dispover-handle")
// only handle is shown if no power
if(stat & NOPOWER || mode == -1)
@@ -319,13 +319,13 @@
// check for items in disposal - occupied light
if(contents.len > 0)
- overlays += image('icons/obj/pipes/disposal.dmi', "dispover-full")
+ overlays += image('icons/obj/atmospherics/pipes/disposal.dmi', "dispover-full")
// charging and ready light
if(mode == 1)
- overlays += image('icons/obj/pipes/disposal.dmi', "dispover-charge")
+ overlays += image('icons/obj/atmospherics/pipes/disposal.dmi', "dispover-charge")
else if(mode == 2)
- overlays += image('icons/obj/pipes/disposal.dmi', "dispover-ready")
+ overlays += image('icons/obj/atmospherics/pipes/disposal.dmi', "dispover-ready")
// timed process
// charge the gas reservoir and perform flush if ready
@@ -456,6 +456,13 @@
stored.density = 1
stored.update()
..()
+
+//How disposal handles getting a storage dump from a storage object
+/obj/machinery/disposal/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
+ for(var/obj/item/I in src_object)
+ src_object.remove_from_storage(I, src)
+ return 1
+
// virtual disposal object
// travels through pipes in lieu of actual items
// contents will be items flushed by the disposal
@@ -591,7 +598,7 @@
// Disposal pipes
/obj/structure/disposalpipe
- icon = 'icons/obj/pipes/disposal.dmi'
+ icon = 'icons/obj/atmospherics/pipes/disposal.dmi'
name = "disposal pipe"
desc = "An underfloor disposal pipe."
anchored = 1
@@ -1201,7 +1208,7 @@
/obj/structure/disposaloutlet
name = "disposal outlet"
desc = "An outlet for the pneumatic disposal system."
- icon = 'icons/obj/pipes/disposal.dmi'
+ icon = 'icons/obj/atmospherics/pipes/disposal.dmi'
icon_state = "outlet"
density = 1
anchored = 1
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index b8d71cc1dca..c397712a6b1 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -117,7 +117,7 @@
id = "ci-medhud"
req_tech = list("materials" = 6, "programming" = 4, "biotech" = 4)
build_type = PROTOLATHE | MECHFAB
- materials = list("$metal" = 200, "$glass" = 200, "$silver" = 200, "$gold" = 100)
+ materials = list("$metal" = 200, "$glass" = 200, "$silver" = 500, "$gold" = 500)
build_path = /obj/item/cybernetic_implant/eyes/hud/medical
category = list("Medical Designs")
@@ -127,7 +127,7 @@
id = "ci-sechud"
req_tech = list("materials" = 6, "programming" = 5, "biotech" = 4, "combat" = 2)
build_type = PROTOLATHE | MECHFAB
- materials = list("$metal" = 200, "$glass" = 200, "$silver" = 300, "$gold" = 300)
+ materials = list("$metal" = 200, "$glass" = 200, "$silver" = 750, "$gold" = 750)
build_path = /obj/item/cybernetic_implant/eyes/hud/security
category = list("Medical Designs")
@@ -135,9 +135,9 @@
name = "X-Ray implant"
desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile."
id = "ci-xray"
- req_tech = list("materials" = 7, "programming" = 5, "biotech" = 6, "magnets" = 5, "plasmatech" = 3)
+ req_tech = list("materials" = 7, "programming" = 5, "biotech" = 6, "magnets" = 5)
build_type = PROTOLATHE | MECHFAB
- materials = list("$metal" = 200, "$glass" = 200, "$silver" = 200, "$gold" = 200, "$plasma" = 200, "$uranium" = 500, "$diamond" = 1000)
+ materials = list("$metal" = 200, "$glass" = 200, "$silver" = 600, "$gold" = 600, "$plasma" = 1000, "$uranium" = 1000, "$diamond" = 2000)
build_path = /obj/item/cybernetic_implant/eyes/xray
category = list("Medical Designs")
@@ -145,9 +145,9 @@
name = "Thermals implant"
desc = "These cybernetic eyes will give you Thermal vision. Vertical slit pupil included."
id = "ci-thermals"
- req_tech = list("materials" = 7, "programming" = 5, "biotech" = 5, "magnets" = 5, "plasmatech" = 3, "syndicate" = 4)
+ req_tech = list("materials" = 7, "programming" = 5, "biotech" = 5, "magnets" = 5, "syndicate" = 5)
build_type = PROTOLATHE | MECHFAB
- materials = list("$metal" = 200, "$glass" = 200, "$silver" = 200, "$gold" = 200, "$plasma" = 200, "$diamond" = 1000)
+ materials = list("$metal" = 200, "$glass" = 200, "$silver" = 600, "$gold" = 600, "$plasma" = 1000, "$diamond" = 2000)
build_path = /obj/item/cybernetic_implant/eyes/thermals
category = list("Medical Designs")
@@ -171,13 +171,14 @@
build_path = /obj/item/cybernetic_implant/brain/anti_stun
category = list("Medical Designs")
-/*/datum/design/cyberimp_nutriment
+/datum/design/cyberimp_nutriment
name = "Nutriment pump implant"
desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are starving."
id = "ci-nutriment"
req_tech = list("materials" = 6, "programming" = 4, "biotech" = 5)
build_type = PROTOLATHE | MECHFAB
materials = list("$metal" = 200, "$glass" = 200, "$gold" = 500, "$uranium" = 500)
+ build_path = /obj/item/cybernetic_implant/chest/nutriment
category = list("Medical Designs")
/datum/design/cyberimp_nutriment_plus
@@ -187,4 +188,15 @@
req_tech = list("materials" = 6, "programming" = 4, "biotech" = 6)
build_type = PROTOLATHE | MECHFAB
materials = list("$metal" = 200, "$glass" = 200, "$gold" = 500, "$uranium" = 750)
- category = list("Medical Designs")*/
\ No newline at end of file
+ build_path = /obj/item/cybernetic_implant/chest/nutriment/plus
+ category = list("Medical Designs")
+
+/datum/design/cyberimp_reviver
+ name = "Reviver implant"
+ desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!"
+ id = "ci-reviver"
+ req_tech = list("materials" = 6, "programming" = 4, "biotech" = 7, "syndicate" = 4)
+ build_type = PROTOLATHE | MECHFAB
+ materials = list("$metal" = 200, "$glass" = 200, "$gold" = 500, "$uranium" = 1000, "$diamond" = 2000)
+ build_path = /obj/item/cybernetic_implant/chest/reviver
+ category = list("Medical Designs")
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index be722fe8fb0..1eeb4731c18 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -152,9 +152,10 @@
if(O.reliability < 90 && O.crit_fail == 0)
usr << "Item is neither reliable enough or broken enough to learn from."
return
+ if(!user.drop_item())
+ return
busy = 1
loaded_item = O
- user.drop_item()
O.loc = src
user << "You add the [O.name] to the machine."
flick("h_lathe_load", src)
@@ -589,8 +590,8 @@
//~~~~~~~~Admin logging proc, aka the Powergamer Alarm~~~~~~~~
/obj/machinery/r_n_d/experimentor/proc/warn_admins(var/mob/user, var/ReactionName)
var/turf/T = get_turf(src)
- message_admins("Experimentor reaction: [ReactionName] generated by [key_name(user, user.client)](?) at ([T.x],[T.y],[T.z] - JMP)",0,1)
- log_game("Experimentor reaction: [ReactionName] generated by [user.ckey]([user]) in ([T.x],[T.y],[T.z])")
+ message_admins("Experimentor reaction: [ReactionName] generated by [key_name_admin(user)](?) (FLW) at ([T.x],[T.y],[T.z] - JMP)",0,1)
+ log_game("Experimentor reaction: [ReactionName] generated by [key_name(user)] in ([T.x],[T.y],[T.z])")
#undef SCANTYPE_POKE
#undef SCANTYPE_IRRADIATE
@@ -733,8 +734,8 @@
//Admin Warning proc for relics
/obj/item/weapon/relic/proc/warn_admins(var/mob/user, var/RelicType, var/priority = 1)
var/turf/T = get_turf(src)
- var/log_msg = "[RelicType] relic used by [user.ckey]([user]) in ([T.x],[T.y],[T.z])"
+ var/log_msg = "[RelicType] relic used by [key_name(user)] in ([T.x],[T.y],[T.z])"
if(priority) //For truly dangerous relics that may need an admin's attention. BWOINK!
- message_admins("[RelicType] relic activated by [key_name(user, user.client)](?) in ([T.x],[T.y],[T.z] - JMP)",0,1)
+ message_admins("[RelicType] relic activated by [key_name_admin(user)](?) (FLW) in ([T.x],[T.y],[T.z] - JMP)",0,1)
log_game(log_msg)
investigate_log(log_msg, "experimentor")
diff --git a/code/modules/research/message_server.dm b/code/modules/research/message_server.dm
index 2df53886ab3..6c584bc1a15 100644
--- a/code/modules/research/message_server.dm
+++ b/code/modules/research/message_server.dm
@@ -17,8 +17,9 @@ var/global/list/obj/machinery/message_server/message_servers = list()
var/recipient = "Unspecified" //name of the person
var/sender = "Unspecified" //name of the sender
var/message = "Blank" //transferred message
+ var/image/photo = null //Attached photo
-/datum/data_pda_msg/New(var/param_rec = "",var/param_sender = "",var/param_message = "")
+/datum/data_pda_msg/New(var/param_rec = "",var/param_sender = "",var/param_message = "",var/param_photo=null)
if(param_rec)
recipient = param_rec
@@ -26,6 +27,19 @@ var/global/list/obj/machinery/message_server/message_servers = list()
sender = param_sender
if(param_message)
message = param_message
+ if(param_photo)
+ photo = param_photo
+
+/datum/data_pda_msg/Topic(href,href_list)
+ ..()
+ if(href_list["photo"])
+ var/mob/M = usr
+ M << browse_rsc(photo, "pda_photo.png")
+ M << browse("PDA Photo" \
+ + "" \
+ + "
" \
+ + "", "window=book;size=192x192")
+ onclose(M, "PDA Photo")
/datum/data_rc_msg
var/rec_dpt = "Unspecified" //name of the person
@@ -105,8 +119,9 @@ var/global/list/obj/machinery/message_server/message_servers = list()
/obj/machinery/message_server/proc/send_chat_message(var/sender = "", var/channel = "", var/message = "")
chat_msgs += new/datum/data_chat_msg(sender,channel,message)
-/obj/machinery/message_server/proc/send_pda_message(var/recipient = "",var/sender = "",var/message = "")
- pda_msgs += new/datum/data_pda_msg(recipient,sender,message)
+/obj/machinery/message_server/proc/send_pda_message(var/recipient = "",var/sender = "",var/message = "",var/photo=null)
+ . = new/datum/data_pda_msg(recipient,sender,message,photo)
+ pda_msgs += .
/obj/machinery/message_server/proc/send_rc_message(var/recipient = "",var/sender = "",var/message = "",var/stamp = "", var/id_auth = "", var/priority = 1)
rc_msgs += new/datum/data_rc_msg(recipient,sender,message,stamp,id_auth)
diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm
index 3182c0156d0..a194ed5327f 100644
--- a/code/modules/research/rdconsole.dm
+++ b/code/modules/research/rdconsole.dm
@@ -157,7 +157,8 @@ won't update every console in existence) but it's more of a hassle to do. Also,
else
user << "Machine cannot accept disks in that format."
return
- user.drop_item()
+ if(!user.drop_item())
+ return
D.loc = src
user << "You add the disk to the machine!"
else
diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm
index 42f7474deac..fb56e869fe8 100644
--- a/code/modules/research/server.dm
+++ b/code/modules/research/server.dm
@@ -177,7 +177,8 @@
/obj/machinery/computer/rdservercontrol
name = "R&D Server Controller"
desc = "Used to manage access to research and manufacturing databases."
- icon_state = "rdcomp"
+ icon_screen = "rdcomp"
+ icon_keyboard = "rd_key"
var/screen = 0
var/obj/machinery/r_n_d/server/temp_server
var/list/servers = list()
diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm
index fd4c133308f..19892b22d1e 100644
--- a/code/modules/research/xenobiology/xenobiology.dm
+++ b/code/modules/research/xenobiology/xenobiology.dm
@@ -472,3 +472,50 @@
qdel(src)
return
sleep(1)
+
+
+
+/obj/item/stack/tile/bluespace
+ name = "bluespace floor tile"
+ singular_name = "floor tile"
+ desc = "Through a series of micro-teleports these tiles let people move at incredible speeds"
+ icon_state = "tile-bluespace"
+ w_class = 3.0
+ force = 6.0
+ m_amt = 937.5
+ throwforce = 10.0
+ throw_speed = 3
+ throw_range = 7
+ flags = CONDUCT
+ max_amount = 60
+ turf_type = /turf/simulated/floor/bluespace
+
+
+/turf/simulated/floor/bluespace
+ slowdown = -1
+ icon_state = "bluespace"
+ desc = "Through a series of micro-teleports these tiles let people move at incredible speeds"
+ floor_tile = /obj/item/stack/tile/bluespace
+
+
+/obj/item/stack/tile/sepia
+ name = "sepia floor tile"
+ singular_name = "floor tile"
+ desc = "Time seems to flow very slowly around these tiles"
+ icon_state = "tile-sepia"
+ w_class = 3.0
+ force = 6.0
+ m_amt = 937.5
+ throwforce = 10.0
+ throw_speed = 3
+ throw_range = 7
+ flags = CONDUCT
+ max_amount = 60
+ turf_type = /turf/simulated/floor/sepia
+
+
+/turf/simulated/floor/sepia
+ slowdown = 2
+ icon_state = "sepia"
+ desc = "Time seems to flow very slowly around these tiles"
+ floor_tile = /obj/item/stack/tile/sepia
\ No newline at end of file
diff --git a/code/modules/shuttle/shuttle.dm b/code/modules/shuttle/shuttle.dm
index db7b923c0f5..673e7176eaa 100644
--- a/code/modules/shuttle/shuttle.dm
+++ b/code/modules/shuttle/shuttle.dm
@@ -567,7 +567,7 @@
return
cooldown = 1
usr << "Your request has been recieved by Centcom."
- admins << "FERRY: [key_name(usr)] (?) (JMP) (Move Ferry) is requesting to move the transport ferry to Centcom."
+ admins << "FERRY: [key_name_admin(usr)] (?) (FLW) (Move Ferry) is requesting to move the transport ferry to Centcom."
spawn(600) //One minute cooldown
cooldown = 0
diff --git a/code/modules/surgery/cybernetic_implants.dm b/code/modules/surgery/cybernetic_implants.dm
index 3f4dcb5210c..ced4776f535 100644
--- a/code/modules/surgery/cybernetic_implants.dm
+++ b/code/modules/surgery/cybernetic_implants.dm
@@ -70,9 +70,10 @@
if(full)
user << "You can't seem to implant anything else into the [target]'s [target_zone]!"
else
+ if(!user.drop_item())
+ return
user.visible_message("[user] inserts [implant] into the [target]'s [target_zone == "head" ? "brain" : target_zone]!", "You insert [implant] into the [target]'s [target_zone == "head" ? "brain" : target_zone].")
implant.owner = target
implant.function()
- user.drop_item()
target.internal_organs |= implant
implant.loc = target
\ No newline at end of file
diff --git a/code/modules/surgery/limb augmentation.dm b/code/modules/surgery/limb augmentation.dm
index 950c4a536b0..22d168044c0 100644
--- a/code/modules/surgery/limb augmentation.dm
+++ b/code/modules/surgery/limb augmentation.dm
@@ -71,6 +71,8 @@
user << "That is the wrong robotic limb for this body part."
return 0
+ if(!user.drop_item())
+ return 0
var/mob/living/carbon/human/H = target
user.visible_message("[user] successfully augments [target]'s [parse_zone(target_zone)]!", "You successfully augment [target]'s [parse_zone(target_zone)].")
L.loc = get_turf(target)
@@ -92,7 +94,6 @@
H.organs += new /obj/item/organ/limb/robot/chest(src)
for(var/datum/disease/appendicitis/A in H.viruses) //If they already have Appendicitis, Remove it
A.cure(1)
- user.drop_item()
qdel(tool)
H.update_damage_overlays(0)
H.update_augments() //Gives them the Cyber limb overlay
diff --git a/code/modules/surgery/organs/cybernetic_implants.dm b/code/modules/surgery/organs/cybernetic_implants.dm
index 5a6d84c3019..a54491e6f41 100644
--- a/code/modules/surgery/organs/cybernetic_implants.dm
+++ b/code/modules/surgery/organs/cybernetic_implants.dm
@@ -75,7 +75,7 @@
desc = "These cybernetic eyes will give you X-ray vision. Blinking is futile."
eye_color = "000"
implant_color = "#000000"
- origin_tech = "materials=6;programming=4;biotech=5;magnets=5;plasmatech=2"
+ origin_tech = "materials=6;programming=4;biotech=6;magnets=5"
/obj/item/cybernetic_implant/eyes/xray/function()
if(!owner)
@@ -95,7 +95,7 @@
eye_color = "FC0"
implant_color = "#FFCC00"
flash_protect = -1
- origin_tech = "materials=6;programming=4;biotech=5;magnets=5;plasmatech=2;syndicate=4"
+ origin_tech = "materials=6;programming=4;biotech=5;magnets=5;syndicate=4"
/obj/item/cybernetic_implant/eyes/thermals/function()
if(!owner)
@@ -295,7 +295,7 @@
/obj/item/cybernetic_implant/chest/nutriment/plus
name = "Nutriment pump implant PLUS"
- desc = "This implant with synthesize and pump into your bloodstream a small amount of nutriment when you are hungry."
+ desc = "This implant will synthesize and pump into your bloodstream a small amount of nutriment when you are hungry."
icon_state = "chest_implant"
implant_color = "#006607"
hunger_threshold = NUTRITION_LEVEL_HUNGRY
@@ -307,4 +307,81 @@
if(!owner)
return
owner.reagents.add_reagent("????",poison_amount / severity) //food poisoning
- owner << "You feel like your insides are burning."
+ owner << "You feel like your insides are burning."
+
+
+/obj/item/cybernetic_implant/chest/reviver
+ name = "Reviver implant"
+ desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!"
+ icon_state = "chest_implant"
+ implant_color = "#AD0000"
+ origin_tech = "materials=6;programming=3;biotech=6;syndicate=4"
+ var/revive_cost = 0
+ var/reviving = 0
+
+/obj/item/cybernetic_implant/chest/reviver/function()
+ SSobj.processing |= src
+
+/obj/item/cybernetic_implant/chest/reviver/process()
+ if(!owner)
+ SSobj.processing.Remove(src)
+ qdel(src)
+ return
+
+ if(reviving)
+ if(owner.stat == UNCONSCIOUS)
+ spawn(30)
+ if(prob(90) && owner.getOxyLoss())
+ owner.adjustOxyLoss(-3)
+ revive_cost += 0.1
+ if(prob(75) && owner.getBruteLoss())
+ owner.adjustBruteLoss(-1)
+ revive_cost += 0.5
+ if(prob(75) && owner.getFireLoss())
+ owner.adjustFireLoss(-1)
+ revive_cost += 0.5
+ if(prob(40) && owner.getToxLoss())
+ owner.adjustToxLoss(-1)
+ revive_cost++
+ else
+ revive_cost = (revive_cost * 100) + world.time
+ reviving = 0
+ return
+
+ if(revive_cost > world.time)
+ return
+ if(owner.stat != UNCONSCIOUS)
+ return
+ if(owner.suiciding)
+ SSobj.processing.Remove(src)
+ return
+
+ revive_cost = 0
+ reviving = 1
+
+/obj/item/cybernetic_implant/chest/reviver/emp_act(severity)
+ revive_cost = world.time + 200
+ if(prob(50 / severity))
+ owner.heart_attack = 1
+ spawn(600 / severity)
+ owner.heart_attack = 0
+
+
+//BOX O' IMPLANTS
+
+/obj/item/weapon/storage/box/cyber_implants
+ name = "boxed cybernetic implants"
+ desc = "A sleek, sturdy box."
+ icon_state = "cyber_implants"
+ var/list/boxed = list(/obj/item/cybernetic_implant/eyes/xray,/obj/item/cybernetic_implant/eyes/thermals,
+ /obj/item/cybernetic_implant/brain/anti_drop, /obj/item/cybernetic_implant/brain/anti_stun,
+ /obj/item/cybernetic_implant/chest/nutriment/plus, /obj/item/cybernetic_implant/chest/reviver)
+ var/amount = 5
+
+/obj/item/weapon/storage/box/cyber_implants/New()
+ ..()
+ var/i
+ var/implant
+ for(i = 0, i < amount, i++)
+ implant = pick(boxed)
+ new implant(src)
\ No newline at end of file
diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm
index 76365b0790c..2c7f7ddbec4 100644
--- a/code/modules/surgery/surgery_step.dm
+++ b/code/modules/surgery/surgery_step.dm
@@ -77,9 +77,9 @@
return 1
/datum/surgery_step/saw/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- if(ishuman(target))
- var/mob/living/carbon/human/H = target
- H.apply_damage(75,"brute","[target_zone]")
+ if(ishuman(target) || ismonkey(target) || isalienadult(target))
+ var/mob/living/carbon/M = target
+ M.apply_damage(75,"brute","[target_zone]")
user.visible_message("[user] saws [target]'s [parse_zone(target_zone)] open!", "You saw [target]'s [parse_zone(target_zone)] open.")
feedback_add_details("surgery_step_success","[src.type]")
return 1
diff --git a/code/modules/telesci/bscrystal.dm b/code/modules/telesci/bscrystal.dm
index c006939d876..74b9807dade 100644
--- a/code/modules/telesci/bscrystal.dm
+++ b/code/modules/telesci/bscrystal.dm
@@ -21,7 +21,7 @@
PoolOrNew(/obj/effect/effect/sparks, loc)
playsound(src.loc, "sparks", 50, 1)
blink_mob(user)
- user.drop_item()
+ user.unEquip(src)
qdel(src)
/obj/item/bluespace_crystal/proc/blink_mob(var/mob/living/L)
diff --git a/code/modules/telesci/telesci_computer.dm b/code/modules/telesci/telesci_computer.dm
index aa0343a1641..0450b8109c1 100644
--- a/code/modules/telesci/telesci_computer.dm
+++ b/code/modules/telesci/telesci_computer.dm
@@ -58,7 +58,8 @@
if(crystals.len >= max_crystals)
user << "There are not enough crystal slots."
return
- user.drop_item()
+ if(!user.drop_item())
+ return
crystals += W
W.loc = null
user.visible_message("[user] inserts [W] into \the [src]'s crystal slot.", "You insert [W] into \the [src]'s crystal slot.")
diff --git a/config/game_options.txt b/config/game_options.txt
index ed44c926e10..ff0e47dc246 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -66,8 +66,8 @@ ALERT_GREEN All threats to the station have passed. Security may not have weapon
ALERT_BLUE_UPTO The station has received reliable information about possible hostile activity on the station. Security staff may have weapons visible, random searches are permitted.
ALERT_BLUE_DOWNTO The immediate threat has passed. Security may no longer have weapons drawn at all times, but may continue to have them visible. Random searches are still allowed.
ALERT_RED_UPTO There is an immediate serious threat to the station. Security may have weapons unholstered at all times. Random searches are allowed and advised.
-ALERT_RED_DOWNTO The self-destruct mechanism has been deactivated, there is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised.
-ALERT_DELTA The station's self-destruct mechanism has been engaged. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill.
+ALERT_RED_DOWNTO The station's destruction has been averted. There is still however an immediate serious threat to the station. Security may have weapons unholstered at all times, random searches are allowed and advised.
+ALERT_DELTA Destruction of the station is imminent. All crew are instructed to obey all instructions given by heads of staff. Any violations of these orders can be punished by death. This is not a drill.
@@ -280,3 +280,18 @@ MIDROUND_ANTAG_LIFE_CHECK 0.7
//Uncomment for explosions that react to doors and walls
REACTIONARY_EXPLOSIONS
+### Configure the bomb cap
+## This caps all explosions to the specified range. Used for both balance reasons and to prevent overloading the server and lagging the game out.
+## This is given as the 3rd number(light damage) in the standard (1,2,3) explosion notation. The other numbers are derived by dividing by 2 and 4.
+## eg: If you give the number 20. The bomb cap will be 5,10,20.
+## Can be any number between 4 and 128, some examples are provided below.
+
+## Default (3,7,14)
+BOMBCAP 14
+## One 'step' up (4,8,16) (recommended if you enable REACTIONARY_EXPLOSIONS above)
+#BOMBCAP 16
+## LagHell (7,14,28)
+#BOMBCAP 28
+
+
+
diff --git a/config/tips.txt b/config/tips.txt
index dd6b2f23f85..04ea4ab50d0 100644
--- a/config/tips.txt
+++ b/config/tips.txt
@@ -85,3 +85,6 @@ You can use . or # instead of : for radio channels. Building this habit reduces
While pulling something, clicking on a tile with an empty hand will move it to that tile. No more getting stuck in maint while dragging something!
Things that override clicks like decks of cards or paper bins can still be picked up by dragging them to your character. Equipped things that override click can be unequipped by dragging it to an empty hand.
In the job selection menu, from the lobby, you can use right click on the "Low/Medium/High" priority button to make it cycle backwards.
+If you stay out of camera range for 10 seconds, the AI's track on you will break.
+You can shoot cameras with bullets to disable them remotely.
+Disabling a camera with wirecutters will not cause a camera alarm, but bludgeoning it will.
diff --git a/html/changelog.html b/html/changelog.html
index 75546b08648..baceb83765d 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -55,6 +55,134 @@
-->
+
22 June 2015
+
Iamgoofball updated:
+
+ - Removed failure chance and delay when emagging an APC.
+
+
KorPhaeron updated:
+
+ - Rebalanced armor to be less effective, reducing the melee, bullet and/or laser damage reduction of all armor suits.
+
+
LaharlMontogmmery updated:
+
+ - You can now click and drag a storage container to empty it's contents into another container, disposal bin or floor tile.
+
+
Xhuis updated:
+
+ - Revenants have received a considerable overhaul.
+ - Revenants will no longer share spawn points with space carp and will spawn in locations like the morgue and prisoner transfer center.
+ - Revenants can no longer cross tiles covered in holy water.
+ - Revenants have a new ability called Defile for 30E. It will cause robots to malfunction, holy water over tiles to evaporate, and a few other effects.
+ - Upon death, revenants will appear and play a sound before rapidly fading away and leaving behind glimmering residue as evidence of their demise.
+ - This residue lingers with the essence of the revenant. If left unattended, it may reform into a new revenant. Simply scattering it is enough to stop this, but it also has high research levels.
+ - Revenants now have fluff objectives as well as a set essence goal.
+ - Revenanants will be revealed for longer when using abilities and also receive feedback on this revealing.
+ - Revenants can now only spawn via random event with a specific amount of dead mobs on the station. The default for this is 10.
+ - Revenants can no longer use abilities from inside walls.
+ - Directly lethal abilities have been removed from revenants. In addition, they can no longer harvest unconscious people, only the dead.
+
+
+
21 June 2015
+
GunHog updated:
+
+ - The Hostile Lockdown ability for Malfunctioning AIs has been nerfed. It now costs 30 CPU, is much more obvious, and automatically resets in 90 seconds.
+ - Buffed the Upgrade Turrets Malfunction ability. Turrets will now fire heavy lasers instead of simply shooting faster.
+ - Nanotrasen has released an Artificial Intelligence firmware upgrade under the ID 41ST0L3MYB1K3. It contains drivers for interacting with all variants of exosuit technology, from the Ripley APLU design to even experimental Phazon units. Simply upload your AI to the exosuit's internal computer via the InteliCard device. Per safety regulations, the exosuit must have maintenance protocols enabled in order to remove an AI from it.
+ - Malfunctioning AIs may wirelessly steal mechs via a new power, Mech Domination. For 30 CPU, a Malf AI may permanently upload itself to a mech, ejecting any pilots. Malf AIs will still lose if they leave the Z-level, and the Malf will be gibbed if the mech is destroyed - they cannot be carded out of the mech or shunt to an APC.
+
+
Iamgoofball updated:
+
+ - Blobs can no longer have Morphine as their chemical.
+
+
duncathan updated:
+
+ - Heat exchangers now update their color to match that of the pipe connected to them.
+ - Heat exchangers are on longer dense.
+
+
+
20 June 2015
+
Dorsisdwarf updated:
+
+ - Syndicate Bulldog Shotguns now use slug ammo instead of buckshot by default
+ - Nuke Ops can now buy team grab-bags of bulldog ammo at a discount.
+
+
Ikarrus updated:
+
+ - Wearing your gang's outfit now increases influence and shortens takeover time faster.
+ - Added several more options for gang outfits
+ - Pinpointers will now point at active dominators.
+ - Gang outfits are now slightly armored
+ - Gang tags are now named 'graffiti' to make them harder to detect
+ - Initial takeover timer is now capped at 5 minutes (50% control)
+ - Server Operators: The default Delta Alert texts have changed. Please check if your game_options.txt is up to date.
+ - Loyalty implants now treat gangs as it treats cultists. Implants can no longer deconvert gangsters, but it can still prevent recruitments.
+ - Replaced tommy guns with 9mm 2-burst 32 mag uzis that costs 40 influence. Unlike tommy guns gangs will be able to purchase ammo for uzis.
+
+
Jordie0608 updated:
+
+ - For Admins: Jump-to-Mob (JMP) notification command replaced with Follow (FLW).
+ - Message and Follow links added to many notifications.
+ - New buttons to toggle nuke and set security level.
+ - Flamethrowers are logged in attack_log.
+
+
Thunder12345 updated:
+
+ - Combat shotguns are now semi automatic, and will be pumped automatically after firing.
+ - Combat shotgun capacity has been reduced to six shells.
+
+
Xhuis updated:
+
+ - You will now trip over securitrons if you run over them whilst they are chasing a target.
+ - An admin-spawnable drone dispenser has been added that will automatically create drone shells when supplied with materials.
+ - Airlock charges are available to traitors and will cause a lethal explosion on the next person to open the door.
+ - Nuclear operatives can now buy drum magazines for their Bulldog shotguns filled with lethal poison-filled darts.
+ - When a malfunctioning AI declares Delta, all blue tiles in its core will begin flashing red.
+ - Back-worn cloaks have been added for all heads except the HoP. LARPers rejoice!
+ - More suicide messages have been added for a few items.
+
+
+
18 June 2015
+
AnturK updated:
+
+ - Added new photo-over-pda function. Apply the photo to PDA to send it with your next message!
+
+
Ikarrus updated:
+
+ - Department Management consoles have been added to Head of Staff offices. These will enable heads to modify ID's access to their department, as well as preform demotions.
+
+
Miauw updated:
+
+ - Bullets can now damage cameras.
+ - Camera alarms now trigger 90 seconds after the first EMP pulse, instead of when all EMP pulses run out.
+ - Makes the force required to damage cameras greater than or equal to ten instead of greater than ten.
+ - Camera alarms now trigger when cameras are disabled with brute force or bullets.
+
+
Xhuis updated:
+
+ - Nanotrasen scientists have determined that a delaminating supermatter shard combining with a gravitational singularity is an extremely bad idea. They advise keeping the two as far apart as possible.
+
+
phil235 updated:
+
+ - Nerfed the xray gun. Its range is now 15 tiles.
+
+
+
15 June 2015
+
Incoming5643 updated:
+
+ - Lizards can now choose from a wide varity of physical appearances in character creation! Sprites made by WJohn. Hiss Responsibly.
+
+
Kor updated:
+
+ - A terrible new creature stalks the halls of SS13.
+ - The wizard has a new artefact related to said creature.
+ - Added a new sepia slime plasma reaction. Try it out!
+
+
spasticVerbalizer updated:
+
+ - Drones can now properly quick-equip.
+
+
14 June 2015
Ikarrus updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index ce032d53f7b..0a91a248be7 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -2764,3 +2764,129 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
- tweak: Tommy guns no longer deal stamina damage.
- rscdel: Gangtools can no longer recall the shuttle if the game mode is not Gang
War
+2015-06-15:
+ Incoming5643:
+ - rscadd: Lizards can now choose from a wide varity of physical appearances in character
+ creation! Sprites made by WJohn. Hiss Responsibly.
+ Kor:
+ - rscadd: A terrible new creature stalks the halls of SS13.
+ - rscadd: The wizard has a new artefact related to said creature.
+ - rscadd: Added a new sepia slime plasma reaction. Try it out!
+ spasticVerbalizer:
+ - bugfix: Drones can now properly quick-equip.
+2015-06-18:
+ AnturK:
+ - rscadd: Added new photo-over-pda function. Apply the photo to PDA to send it with
+ your next message!
+ Ikarrus:
+ - rscadd: Department Management consoles have been added to Head of Staff offices.
+ These will enable heads to modify ID's access to their department, as well as
+ preform demotions.
+ Miauw:
+ - tweak: Bullets can now damage cameras.
+ - tweak: Camera alarms now trigger 90 seconds after the first EMP pulse, instead
+ of when all EMP pulses run out.
+ - tweak: Makes the force required to damage cameras greater than or equal to ten
+ instead of greater than ten.
+ - tweak: Camera alarms now trigger when cameras are disabled with brute force or
+ bullets.
+ Xhuis:
+ - rscadd: Nanotrasen scientists have determined that a delaminating supermatter
+ shard combining with a gravitational singularity is an extremely bad idea. They
+ advise keeping the two as far apart as possible.
+ phil235:
+ - rscdel: Nerfed the xray gun. Its range is now 15 tiles.
+2015-06-20:
+ Dorsisdwarf:
+ - tweak: Syndicate Bulldog Shotguns now use slug ammo instead of buckshot by default
+ - rscadd: Nuke Ops can now buy team grab-bags of bulldog ammo at a discount.
+ Ikarrus:
+ - rscadd: Wearing your gang's outfit now increases influence and shortens takeover
+ time faster.
+ - rscadd: Added several more options for gang outfits
+ - rscadd: Pinpointers will now point at active dominators.
+ - tweak: Gang outfits are now slightly armored
+ - tweak: Gang tags are now named 'graffiti' to make them harder to detect
+ - tweak: Initial takeover timer is now capped at 5 minutes (50% control)
+ - tweak: 'Server Operators: The default Delta Alert texts have changed. Please check
+ if your game_options.txt is up to date.'
+ - rscdel: Loyalty implants now treat gangs as it treats cultists. Implants can no
+ longer deconvert gangsters, but it can still prevent recruitments.
+ - tweak: Replaced tommy guns with 9mm 2-burst 32 mag uzis that costs 40 influence.
+ Unlike tommy guns gangs will be able to purchase ammo for uzis.
+ Jordie0608:
+ - tweak: 'For Admins: Jump-to-Mob (JMP) notification command replaced with Follow
+ (FLW).'
+ - rscadd: Message and Follow links added to many notifications.
+ - rscadd: New buttons to toggle nuke and set security level.
+ - spellcheck: Flamethrowers are logged in attack_log.
+ Thunder12345:
+ - rscadd: Combat shotguns are now semi automatic, and will be pumped automatically
+ after firing.
+ - tweak: Combat shotgun capacity has been reduced to six shells.
+ Xhuis:
+ - rscadd: You will now trip over securitrons if you run over them whilst they are
+ chasing a target.
+ - rscadd: An admin-spawnable drone dispenser has been added that will automatically
+ create drone shells when supplied with materials.
+ - rscadd: Airlock charges are available to traitors and will cause a lethal explosion
+ on the next person to open the door.
+ - rscadd: Nuclear operatives can now buy drum magazines for their Bulldog shotguns
+ filled with lethal poison-filled darts.
+ - rscadd: When a malfunctioning AI declares Delta, all blue tiles in its core will
+ begin flashing red.
+ - rscadd: Back-worn cloaks have been added for all heads except the HoP. LARPers
+ rejoice!
+ - rscadd: More suicide messages have been added for a few items.
+2015-06-21:
+ GunHog:
+ - tweak: The Hostile Lockdown ability for Malfunctioning AIs has been nerfed. It
+ now costs 30 CPU, is much more obvious, and automatically resets in 90 seconds.
+ - tweak: Buffed the Upgrade Turrets Malfunction ability. Turrets will now fire heavy
+ lasers instead of simply shooting faster.
+ - rscadd: Nanotrasen has released an Artificial Intelligence firmware upgrade under
+ the ID 41ST0L3MYB1K3. It contains drivers for interacting with all variants
+ of exosuit technology, from the Ripley APLU design to even experimental Phazon
+ units. Simply upload your AI to the exosuit's internal computer via the InteliCard
+ device. Per safety regulations, the exosuit must have maintenance protocols
+ enabled in order to remove an AI from it.
+ - rscadd: Malfunctioning AIs may wirelessly steal mechs via a new power, Mech Domination.
+ For 30 CPU, a Malf AI may permanently upload itself to a mech, ejecting any
+ pilots. Malf AIs will still lose if they leave the Z-level, and the Malf will
+ be gibbed if the mech is destroyed - they cannot be carded out of the mech or
+ shunt to an APC.
+ Iamgoofball:
+ - rscdel: Blobs can no longer have Morphine as their chemical.
+ duncathan:
+ - tweak: Heat exchangers now update their color to match that of the pipe connected
+ to them.
+ - tweak: Heat exchangers are on longer dense.
+2015-06-22:
+ Iamgoofball:
+ - rscdel: Removed failure chance and delay when emagging an APC.
+ KorPhaeron:
+ - tweak: Rebalanced armor to be less effective, reducing the melee, bullet and/or
+ laser damage reduction of all armor suits.
+ LaharlMontogmmery:
+ - rscadd: You can now click and drag a storage container to empty it's contents
+ into another container, disposal bin or floor tile.
+ Xhuis:
+ - experiment: Revenants have received a considerable overhaul.
+ - rscadd: Revenants will no longer share spawn points with space carp and will spawn
+ in locations like the morgue and prisoner transfer center.
+ - rscadd: Revenants can no longer cross tiles covered in holy water.
+ - rscadd: Revenants have a new ability called Defile for 30E. It will cause robots
+ to malfunction, holy water over tiles to evaporate, and a few other effects.
+ - rscadd: Upon death, revenants will appear and play a sound before rapidly fading
+ away and leaving behind glimmering residue as evidence of their demise.
+ - rscadd: This residue lingers with the essence of the revenant. If left unattended,
+ it may reform into a new revenant. Simply scattering it is enough to stop this,
+ but it also has high research levels.
+ - rscadd: Revenants now have fluff objectives as well as a set essence goal.
+ - tweak: Revenanants will be revealed for longer when using abilities and also receive
+ feedback on this revealing.
+ - tweak: Revenants can now only spawn via random event with a specific amount of
+ dead mobs on the station. The default for this is 10.
+ - bugfix: Revenants can no longer use abilities from inside walls.
+ - rscdel: Directly lethal abilities have been removed from revenants. In addition,
+ they can no longer harvest unconscious people, only the dead.
diff --git a/html/changelogs/Fayrik-TheNanoingFixes.yml b/html/changelogs/Fayrik-TheNanoingFixes.yml
new file mode 100644
index 00000000000..ee0cc06c287
--- /dev/null
+++ b/html/changelogs/Fayrik-TheNanoingFixes.yml
@@ -0,0 +1,10 @@
+author: Fayrik
+
+delete-after: True
+
+changes:
+- rscadd: "NanoUI is now Telekenesis aware, but due to other constraints, NanoUI interfaces are read only at a distance."
+- tweak: "Refactored all NanoUI interfaces to use a more universal proc."
+- tweak: "Adjusted the refresh time of the NanoUI SubSystem. All interfaces will update less, but register mouse clicks faster."
+- bugfix: "Removed automatic updates on atmospheric pumps, canisters and tanks, making them respond to button clicks much faster."
+- bugfix: "Atmos alarm reset buttons work now. Probably."
\ No newline at end of file
diff --git a/html/changelogs/Incoming5643-Lizard-Hypercustomization.yml b/html/changelogs/Incoming5643-Lizard-Hypercustomization.yml
deleted file mode 100644
index 2851e7a2230..00000000000
--- a/html/changelogs/Incoming5643-Lizard-Hypercustomization.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: Incoming5643
-delete-after: True
-
-changes:
- - rscadd: "Lizards can now choose from a wide varity of physical appearances in character creation! Sprites made by WJohn. Hiss Responsibly."
\ No newline at end of file
diff --git a/html/changelogs/KorPhaeron-demon.yml b/html/changelogs/KorPhaeron-demon.yml
deleted file mode 100644
index 550bffea37a..00000000000
--- a/html/changelogs/KorPhaeron-demon.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-################################
-# Example Changelog File
-#
-# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
-#
-# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
-# When it is, any changes listed below will disappear.
-#
-# Valid Prefixes:
-# bugfix
-# wip (For works in progress)
-# tweak
-# soundadd
-# sounddel
-# rscadd (general adding of nice things)
-# rscdel (general deleting of nice things)
-# imageadd
-# imagedel
-# spellcheck (typo fixes)
-# experiment
-# tgs (TG-ported fixes?)
-#################################
-
-# Your name.
-author: Kor
-
-# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
-delete-after: True
-
-# Any changes you've made. See valid prefix list above.
-# INDENT WITH TWO SPACES. NOT TABS. SPACES.
-# SCREW THIS UP AND IT WON'T WORK.
-# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
-# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
-changes:
- - rscadd: "A terrible new creature stalks the halls of SS13."
- - rscadd: "The wizard has a new artefact related to said creature."
diff --git a/html/changelogs/KorPhaeron-sepia.yml b/html/changelogs/KorPhaeron-sepia.yml
deleted file mode 100644
index 064e20c5f71..00000000000
--- a/html/changelogs/KorPhaeron-sepia.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-################################
-# Example Changelog File
-#
-# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
-#
-# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
-# When it is, any changes listed below will disappear.
-#
-# Valid Prefixes:
-# bugfix
-# wip (For works in progress)
-# tweak
-# soundadd
-# sounddel
-# rscadd (general adding of nice things)
-# rscdel (general deleting of nice things)
-# imageadd
-# imagedel
-# spellcheck (typo fixes)
-# experiment
-# tgs (TG-ported fixes?)
-#################################
-
-# Your name.
-author: Kor
-
-# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
-delete-after: True
-
-# Any changes you've made. See valid prefix list above.
-# INDENT WITH TWO SPACES. NOT TABS. SPACES.
-# SCREW THIS UP AND IT WON'T WORK.
-# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
-# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
-changes:
- - rscadd: "Added a new sepia slime plasma reaction. Try it out!"
-
diff --git a/html/changelogs/spasticVerbalizer-droneQuickEquip.yml b/html/changelogs/spasticVerbalizer-droneQuickEquip.yml
deleted file mode 100644
index eb18e8577f5..00000000000
--- a/html/changelogs/spasticVerbalizer-droneQuickEquip.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: spasticVerbalizer
-delete-after: True
-
-changes:
- - rscfix: "Drones can now properly quick-equip."
diff --git a/html/changelogs/vekter - 10092.yml b/html/changelogs/vekter - 10092.yml
new file mode 100644
index 00000000000..2f6be0d85f2
--- /dev/null
+++ b/html/changelogs/vekter - 10092.yml
@@ -0,0 +1,9 @@
+author: Vekter
+
+delete-after: True
+
+changes:
+ - bugfix: "Finally fixed immovable rods! They will now properly bisect the station (and crit anyone unlucky enough to be in their path)."
+ - tweak: "Increased Meteor activity detected in the vicinity of the station. Be advised that many storms may be more violent than they once were."
+ - rscadd: "Gravitational anomalies will now throw items at mobs in their vicinity. Take care while scanning them."
+ - rscadd: "Flux anomalies explode much more violently now. Get there and destroy them, or risk losing half a department."
diff --git a/html/changelogs/xxalpha-fixfixfix.yml b/html/changelogs/xxalpha-fixfixfix.yml
new file mode 100644
index 00000000000..8d94cfb1e84
--- /dev/null
+++ b/html/changelogs/xxalpha-fixfixfix.yml
@@ -0,0 +1,10 @@
+author: xxalpha
+
+delete-after: True
+
+changes:
+ - rscadd: "Added a new Reviver implant: now it revives you from unconsciousness rather than death."
+ - rscadd: "Added cybernetic implants and a cybernetic implants bundle to the Nuke Ops uplink."
+ - bugfix: "Fixed Nutriment pump implant printing."
+ - tweak: "Health Analyzers now have the ability to detect cybernetic implants."
+ - tweak: "X-Ray implants are now much harder to unlock."
\ No newline at end of file
diff --git a/icons/effects/352x352.dmi b/icons/effects/352x352.dmi
new file mode 100644
index 00000000000..86b40959d56
Binary files /dev/null and b/icons/effects/352x352.dmi differ
diff --git a/icons/effects/effects.dmi b/icons/effects/effects.dmi
index dc275c2512d..2e9d5216270 100644
Binary files a/icons/effects/effects.dmi and b/icons/effects/effects.dmi differ
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index c59228819bb..0e417793b0c 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index 6572955ff2b..3b14ad7d0cb 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi
index 1ffa26810ac..ea688d4249d 100644
Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ
diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi
index 3258cb936d1..1c9beb6551c 100644
Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ
diff --git a/icons/obj/atmospherics/binary_devices.dmi b/icons/obj/atmospherics/binary_devices.dmi
index 76b9f874a9d..d127cabed58 100644
Binary files a/icons/obj/atmospherics/binary_devices.dmi and b/icons/obj/atmospherics/binary_devices.dmi differ
diff --git a/icons/obj/atmospherics/cold_sink.dmi b/icons/obj/atmospherics/cold_sink.dmi
deleted file mode 100644
index 09f9be43514..00000000000
Binary files a/icons/obj/atmospherics/cold_sink.dmi and /dev/null differ
diff --git a/icons/obj/atmospherics/digital_valve.dmi b/icons/obj/atmospherics/digital_valve.dmi
deleted file mode 100644
index db27b43f849..00000000000
Binary files a/icons/obj/atmospherics/digital_valve.dmi and /dev/null differ
diff --git a/icons/obj/atmospherics/dp_vent_pump.dmi b/icons/obj/atmospherics/dp_vent_pump.dmi
deleted file mode 100644
index e9d5ddb707c..00000000000
Binary files a/icons/obj/atmospherics/dp_vent_pump.dmi and /dev/null differ
diff --git a/icons/obj/atmospherics/heat_exchanger.dmi b/icons/obj/atmospherics/heat_exchanger.dmi
deleted file mode 100644
index 4d11d89ff56..00000000000
Binary files a/icons/obj/atmospherics/heat_exchanger.dmi and /dev/null differ
diff --git a/icons/obj/atmospherics/oxygen_generator.dmi b/icons/obj/atmospherics/oxygen_generator.dmi
deleted file mode 100644
index 0c94506c368..00000000000
Binary files a/icons/obj/atmospherics/oxygen_generator.dmi and /dev/null differ
diff --git a/icons/obj/atmospherics/pipe_vent.dmi b/icons/obj/atmospherics/pipe_vent.dmi
deleted file mode 100644
index 3de36bef6fb..00000000000
Binary files a/icons/obj/atmospherics/pipe_vent.dmi and /dev/null differ
diff --git a/icons/obj/pipes/disposal.dmi b/icons/obj/atmospherics/pipes/disposal.dmi
similarity index 100%
rename from icons/obj/pipes/disposal.dmi
rename to icons/obj/atmospherics/pipes/disposal.dmi
diff --git a/icons/obj/pipes/heat.dmi b/icons/obj/atmospherics/pipes/heat.dmi
similarity index 100%
rename from icons/obj/pipes/heat.dmi
rename to icons/obj/atmospherics/pipes/heat.dmi
diff --git a/icons/obj/atmospherics/pipes/junction.dmi b/icons/obj/atmospherics/pipes/junction.dmi
new file mode 100644
index 00000000000..f3ff732c56c
Binary files /dev/null and b/icons/obj/atmospherics/pipes/junction.dmi differ
diff --git a/icons/obj/pipes/large.dmi b/icons/obj/atmospherics/pipes/large.dmi
similarity index 100%
rename from icons/obj/pipes/large.dmi
rename to icons/obj/atmospherics/pipes/large.dmi
diff --git a/icons/obj/atmospherics/pipe_manifold.dmi b/icons/obj/atmospherics/pipes/manifold.dmi
similarity index 100%
rename from icons/obj/atmospherics/pipe_manifold.dmi
rename to icons/obj/atmospherics/pipes/manifold.dmi
diff --git a/icons/obj/atmospherics/pipes/pipe_item.dmi b/icons/obj/atmospherics/pipes/pipe_item.dmi
new file mode 100644
index 00000000000..376fb40b49f
Binary files /dev/null and b/icons/obj/atmospherics/pipes/pipe_item.dmi differ
diff --git a/icons/obj/atmospherics/pipe_tank.dmi b/icons/obj/atmospherics/pipes/pressure_tank.dmi
similarity index 100%
rename from icons/obj/atmospherics/pipe_tank.dmi
rename to icons/obj/atmospherics/pipes/pressure_tank.dmi
diff --git a/icons/obj/atmospherics/pipes/simple.dmi b/icons/obj/atmospherics/pipes/simple.dmi
new file mode 100644
index 00000000000..6bb4a9ad0eb
Binary files /dev/null and b/icons/obj/atmospherics/pipes/simple.dmi differ
diff --git a/icons/obj/pipes/transit_tube.dmi b/icons/obj/atmospherics/pipes/transit_tube.dmi
similarity index 100%
rename from icons/obj/pipes/transit_tube.dmi
rename to icons/obj/atmospherics/pipes/transit_tube.dmi
diff --git a/icons/obj/pipes/transit_tube_pod.dmi b/icons/obj/atmospherics/pipes/transit_tube_pod.dmi
similarity index 100%
rename from icons/obj/pipes/transit_tube_pod.dmi
rename to icons/obj/atmospherics/pipes/transit_tube_pod.dmi
diff --git a/icons/obj/pipes/transit_tube_station.dmi b/icons/obj/atmospherics/pipes/transit_tube_station.dmi
similarity index 100%
rename from icons/obj/pipes/transit_tube_station.dmi
rename to icons/obj/atmospherics/pipes/transit_tube_station.dmi
diff --git a/icons/obj/atmospherics/portables_connector.dmi b/icons/obj/atmospherics/portables_connector.dmi
deleted file mode 100644
index 2ac06a96b84..00000000000
Binary files a/icons/obj/atmospherics/portables_connector.dmi and /dev/null differ
diff --git a/icons/obj/atmospherics/trinary_devices.dmi b/icons/obj/atmospherics/trinary_devices.dmi
index 13f9a6e4f49..7eabbd65d01 100644
Binary files a/icons/obj/atmospherics/trinary_devices.dmi and b/icons/obj/atmospherics/trinary_devices.dmi differ
diff --git a/icons/obj/atmospherics/unary_devices.dmi b/icons/obj/atmospherics/unary_devices.dmi
index bc43f452e17..6681804dd4f 100644
Binary files a/icons/obj/atmospherics/unary_devices.dmi and b/icons/obj/atmospherics/unary_devices.dmi differ
diff --git a/icons/obj/atmospherics/valve.dmi b/icons/obj/atmospherics/valve.dmi
deleted file mode 100644
index 8df0d933d90..00000000000
Binary files a/icons/obj/atmospherics/valve.dmi and /dev/null differ
diff --git a/icons/obj/atmospherics/vent_pump.dmi b/icons/obj/atmospherics/vent_pump.dmi
deleted file mode 100644
index 9ba74046416..00000000000
Binary files a/icons/obj/atmospherics/vent_pump.dmi and /dev/null differ
diff --git a/icons/obj/clothing/cloaks.dmi b/icons/obj/clothing/cloaks.dmi
new file mode 100644
index 00000000000..3677fa15258
Binary files /dev/null and b/icons/obj/clothing/cloaks.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index deca94b24fa..647f1384e17 100644
Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ
diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi
index 28247e78c06..4fbc9bd674a 100644
Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ
diff --git a/icons/obj/computer.dmi b/icons/obj/computer.dmi
index 567fa80e5a7..6c8fd8bc903 100644
Binary files a/icons/obj/computer.dmi and b/icons/obj/computer.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 5a3e80c66f7..092eb92a6ce 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi
index c613bee4949..61e622a2135 100644
Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ
diff --git a/icons/obj/items.dmi b/icons/obj/items.dmi
index 4979d68a241..36e34fa6229 100644
Binary files a/icons/obj/items.dmi and b/icons/obj/items.dmi differ
diff --git a/icons/obj/machines/droneDispenser.dmi b/icons/obj/machines/droneDispenser.dmi
new file mode 100644
index 00000000000..a78990d8a1a
Binary files /dev/null and b/icons/obj/machines/droneDispenser.dmi differ
diff --git a/icons/obj/pipe-item.dmi b/icons/obj/pipe-item.dmi
deleted file mode 100644
index ced78f92214..00000000000
Binary files a/icons/obj/pipe-item.dmi and /dev/null differ
diff --git a/icons/obj/pipes.dmi b/icons/obj/pipes.dmi
deleted file mode 100644
index 79e6661e386..00000000000
Binary files a/icons/obj/pipes.dmi and /dev/null differ
diff --git a/icons/obj/pipes/junction.dmi b/icons/obj/pipes/junction.dmi
deleted file mode 100644
index 0b1625f563f..00000000000
Binary files a/icons/obj/pipes/junction.dmi and /dev/null differ
diff --git a/icons/obj/pipes/regular.dmi b/icons/obj/pipes/regular.dmi
deleted file mode 100644
index 3bc0f0b7649..00000000000
Binary files a/icons/obj/pipes/regular.dmi and /dev/null differ
diff --git a/icons/obj/pipes2.dmi b/icons/obj/pipes2.dmi
deleted file mode 100644
index 6e800711aa6..00000000000
Binary files a/icons/obj/pipes2.dmi and /dev/null differ
diff --git a/icons/obj/stationobjs.dmi b/icons/obj/stationobjs.dmi
index 1797ac7cee0..91fac6c336d 100644
Binary files a/icons/obj/stationobjs.dmi and b/icons/obj/stationobjs.dmi differ
diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi
index 682103c7dcb..1a7b8fb091c 100644
Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ
diff --git a/icons/obj/wallmounts.dmi b/icons/obj/wallmounts.dmi
index edd89610bac..67d05103da0 100644
Binary files a/icons/obj/wallmounts.dmi and b/icons/obj/wallmounts.dmi differ
diff --git a/icons/turf/floors.dmi b/icons/turf/floors.dmi
index 56c0c7d5afa..f988d836e36 100644
Binary files a/icons/turf/floors.dmi and b/icons/turf/floors.dmi differ
diff --git a/nano/templates/air_alarm.tmpl b/nano/templates/air_alarm.tmpl
index f3a64d9efd8..a5556180308 100644
--- a/nano/templates/air_alarm.tmpl
+++ b/nano/templates/air_alarm.tmpl
@@ -91,7 +91,7 @@ Used In File(s): \code\game\machinery\alarm.dm
{{if mode==3}}
{{:~link('PANIC SIPHON ACTIVE - Turn siphoning off', null, { 'mode' : 1}, null, 'redButton')}}
- {{else}}
+ {{else}}
{{:~link('ACTIVATE PANIC SIPHON IN AREA', null, { 'mode' : 3}, null, 'yellowButton')}}
{{/if}}
{{else screen == 2}}
diff --git a/sound/machines/lockenable.ogg b/sound/machines/lockenable.ogg
deleted file mode 100644
index 5003b3fe155..00000000000
Binary files a/sound/machines/lockenable.ogg and /dev/null differ
diff --git a/sound/machines/lockreset.ogg b/sound/machines/lockreset.ogg
deleted file mode 100644
index 6f61430ad73..00000000000
Binary files a/sound/machines/lockreset.ogg and /dev/null differ
diff --git a/sound/machines/locktoggle.ogg b/sound/machines/locktoggle.ogg
new file mode 100644
index 00000000000..d8af48d9318
Binary files /dev/null and b/sound/machines/locktoggle.ogg differ
diff --git a/sound/magic/TIMEPARADOX2.ogg b/sound/magic/TIMEPARADOX2.ogg
index d35aeb389f6..1a025a895b0 100644
Binary files a/sound/magic/TIMEPARADOX2.ogg and b/sound/magic/TIMEPARADOX2.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index 6f47e668fda..98922e497d9 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -381,6 +381,7 @@
#include "code\game\machinery\deployable.dm"
#include "code\game\machinery\door_control.dm"
#include "code\game\machinery\doppler_array.dm"
+#include "code\game\machinery\droneDispenser.dm"
#include "code\game\machinery\flasher.dm"
#include "code\game\machinery\Freezer.dm"
#include "code\game\machinery\hologram.dm"
@@ -552,6 +553,7 @@
#include "code\game\objects\effects\spawners\bombspawner.dm"
#include "code\game\objects\effects\spawners\gibspawner.dm"
#include "code\game\objects\effects\spawners\lootdrop.dm"
+#include "code\game\objects\effects\spawners\structure.dm"
#include "code\game\objects\effects\spawners\vaultspawner.dm"
#include "code\game\objects\items\apc_frame.dm"
#include "code\game\objects\items\blueprints.dm"
@@ -569,6 +571,7 @@
#include "code\game\objects\items\devices\aicard.dm"
#include "code\game\objects\items\devices\camera_bug.dm"
#include "code\game\objects\items\devices\chameleonproj.dm"
+#include "code\game\objects\items\devices\doorCharge.dm"
#include "code\game\objects\items\devices\flash.dm"
#include "code\game\objects\items\devices\flashlight.dm"
#include "code\game\objects\items\devices\instruments.dm"
@@ -695,6 +698,7 @@
#include "code\game\objects\structures\electricchair.dm"
#include "code\game\objects\structures\extinguisher.dm"
#include "code\game\objects\structures\false_walls.dm"
+#include "code\game\objects\structures\fireaxe.dm"
#include "code\game\objects\structures\flora.dm"
#include "code\game\objects\structures\girders.dm"
#include "code\game\objects\structures\grille.dm"
@@ -729,7 +733,6 @@
#include "code\game\objects\structures\crates_lockers\crates.dm"
#include "code\game\objects\structures\crates_lockers\largecrate.dm"
#include "code\game\objects\structures\crates_lockers\closets\crittercrate.dm"
-#include "code\game\objects\structures\crates_lockers\closets\fireaxe.dm"
#include "code\game\objects\structures\crates_lockers\closets\fitness.dm"
#include "code\game\objects\structures\crates_lockers\closets\gimmick.dm"
#include "code\game\objects\structures\crates_lockers\closets\job_closets.dm"
@@ -802,6 +805,7 @@
#include "code\modules\admin\newbanjob.dm"
#include "code\modules\admin\player_notes.dm"
#include "code\modules\admin\player_panel.dm"
+#include "code\modules\admin\secrets.dm"
#include "code\modules\admin\topic.dm"
#include "code\modules\admin\DB ban\functions.dm"
#include "code\modules\admin\permissionverbs\permissionedit.dm"
@@ -869,6 +873,7 @@
#include "code\modules\client\preferences.dm"
#include "code\modules\client\preferences_savefile.dm"
#include "code\modules\client\preferences_toggles.dm"
+#include "code\modules\clothing\cloaks.dm"
#include "code\modules\clothing\clothing.dm"
#include "code\modules\clothing\glasses\engine_goggles.dm"
#include "code\modules\clothing\glasses\glasses.dm"